[torque] Port Boolean constructor to Torque

Add torque implementation of GetDerivedMap

Bug: v8:9240
Change-Id: I9f2203f5c79fad84f67894c9cbaf28e6f7685f58
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1609804
Commit-Queue: Nico Hartmann <nicohartmann@google.com>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61535}
This commit is contained in:
Nico Hartmann 2019-05-15 15:02:51 +02:00 committed by Commit Bot
parent d6b51cba23
commit b8c97dd2a8
9 changed files with 102 additions and 43 deletions

View File

@ -938,6 +938,7 @@ torque_files = [
"src/builtins/array-unshift.tq",
"src/builtins/array.tq",
"src/builtins/base.tq",
"src/builtins/boolean.tq",
"src/builtins/collections.tq",
"src/builtins/data-view.tq",
"src/builtins/extras-utils.tq",
@ -1001,6 +1002,7 @@ torque_namespaces = [
"array-unshift",
"array-lastindexof",
"base",
"boolean",
"collections",
"data-view",
"extras-utils",
@ -2056,7 +2058,6 @@ v8_source_set("v8_base_without_compiler") {
"src/builtins/builtins-array.cc",
"src/builtins/builtins-arraybuffer.cc",
"src/builtins/builtins-bigint.cc",
"src/builtins/builtins-boolean.cc",
"src/builtins/builtins-call.cc",
"src/builtins/builtins-callsite.cc",
"src/builtins/builtins-collections.cc",

View File

@ -58,6 +58,8 @@ type bool generates 'TNode<BoolT>' constexpr 'bool';
type bint generates 'TNode<BInt>' constexpr 'BInt';
type string constexpr 'const char*';
type NameDictionary extends FixedArray;
type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
type Code extends HeapObject generates 'TNode<Code>';
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
@ -235,6 +237,23 @@ macro NewJSObject(implicit context: Context)(): JSObject {
};
}
macro GetDerivedMap(implicit context: Context)(
target: JSFunction, newTarget: JSReceiver): Map {
try {
const constructor = Cast<JSFunction>(newTarget) otherwise SlowPath;
const map =
Cast<Map>(constructor.prototype_or_initial_map) otherwise SlowPath;
if (LoadConstructorOrBackPointer(map) != target) {
goto SlowPath;
}
return map;
}
label SlowPath {
return runtime::GetDerivedMap(context, target, newTarget);
}
}
extern class JSFunction extends JSObject {
shared_function_info: SharedFunctionInfo;
context: Context;
@ -666,6 +685,7 @@ type PrimitiveType constexpr 'PrimitiveType';
type ToIntegerTruncationMode
constexpr 'CodeStubAssembler::ToIntegerTruncationMode';
type AllocationFlags constexpr 'AllocationFlags';
type SlackTrackingMode constexpr 'SlackTrackingMode';
type UnicodeEncoding constexpr 'UnicodeEncoding';
const UTF16:
@ -846,6 +866,11 @@ const kPretenured:
const kAllowLargeObjectAllocation: constexpr AllocationFlags
generates 'CodeStubAssembler::kAllowLargeObjectAllocation';
const kWithSlackTracking: constexpr SlackTrackingMode
generates 'SlackTrackingMode::kWithSlackTracking';
const kNoSlackTracking: constexpr SlackTrackingMode
generates 'SlackTrackingMode::kNoSlackTracking';
type FixedUint8Array extends FixedTypedArray;
type FixedInt8Array extends FixedTypedArray;
type FixedUint16Array extends FixedTypedArray;
@ -1751,6 +1776,12 @@ Cast<Map>(implicit context: Context)(o: HeapObject): Map
goto CastError;
}
Cast<JSValue>(o: HeapObject): JSValue
labels CastError {
if (IsJSValue(o)) return %RawDownCast<JSValue>(o);
goto CastError;
}
Cast<JSArgumentsObjectWithLength>(implicit context: Context)(o: HeapObject):
JSArgumentsObjectWithLength
labels CastError {
@ -2224,6 +2255,8 @@ extern macro GetNumberDictionaryNumberOfElements(NumberDictionary): Smi;
extern macro GetIteratorMethod(implicit context: Context)(HeapObject): Object
labels IfIteratorUndefined;
extern macro LoadConstructorOrBackPointer(Map): Object;
extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr): Object
labels NotData, IfHole;
extern macro BasicStoreNumberDictionaryElement(NumberDictionary, intptr, Object)
@ -2290,6 +2323,9 @@ extern macro AllocateJSArray(constexpr ElementsKind, Map, intptr, Smi): JSArray;
extern macro AllocateJSArray(constexpr ElementsKind, Map, Smi, Smi): JSArray;
extern macro AllocateJSArray(Map, FixedArrayBase, Smi): JSArray;
extern macro AllocateJSObjectFromMap(Map): JSObject;
extern macro AllocateJSObjectFromMap(
Map, FixedArray, FixedArray, constexpr AllocationFlags,
constexpr SlackTrackingMode): JSObject;
extern macro LoadDoubleWithHoleCheck(FixedDoubleArray, Smi): float64
labels IfHole;
@ -2560,6 +2596,7 @@ extern macro IsOddball(HeapObject): bool;
extern macro IsSymbol(HeapObject): bool;
extern macro IsJSArrayMap(Map): bool;
extern macro IsExtensibleMap(Map): bool;
extern macro IsJSValue(HeapObject): bool;
extern macro IsCustomElementsReceiverInstanceType(int32): bool;
extern macro IsFastJSArrayWithNoCustomIteration(implicit context: Context)(
Object): bool;
@ -2702,6 +2739,11 @@ macro IsFastJSArrayWithNoCustomIteration(context: Context, o: Object): bool {
extern transitioning runtime
CreateDataProperty(implicit context: Context)(JSReceiver, Object, Object);
namespace runtime {
extern runtime
GetDerivedMap(Context, JSFunction, JSReceiver): Map;
}
transitioning builtin FastCreateDataProperty(implicit context: Context)(
receiver: JSReceiver, key: Object, value: Object): Object {
try {

42
src/builtins/boolean.tq Normal file
View File

@ -0,0 +1,42 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
namespace boolean {
const kNameDictionaryInitialCapacity:
constexpr int32 generates 'NameDictionary::kInitialCapacity';
extern macro ConstructorBuiltinsAssembler::IsDictionaryMap(Map): bool;
extern macro CodeStubAssembler::AllocateNameDictionary(constexpr int32):
NameDictionary;
// TODO(v8:9120): This is a workaround to get access to target and new.target
// in javascript builtins. Requires cleanup once this is fully supported by
// torque.
const NEW_TARGET_INDEX:
constexpr int32 generates 'Descriptor::kJSNewTarget';
const TARGET_INDEX: constexpr int32 generates 'Descriptor::kJSTarget';
extern macro Parameter(constexpr int32): Object;
javascript builtin
BooleanConstructor(context: Context, receiver: Object, ...arguments): Object {
const value = SelectBooleanConstant(ToBoolean(arguments[0]));
const newTarget = Parameter(NEW_TARGET_INDEX);
if (newTarget == Undefined) {
return value;
}
const target = UnsafeCast<JSFunction>(Parameter(TARGET_INDEX));
const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget));
let properties = kEmptyFixedArray;
if (IsDictionaryMap(map)) {
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity);
}
const obj = UnsafeCast<JSValue>(AllocateJSObjectFromMap(
map, properties, kEmptyFixedArray, kNone, kWithSlackTracking));
obj.value = value;
return obj;
}
}

View File

@ -1,39 +0,0 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
#include "src/counters.h"
#include "src/heap/heap-inl.h" // For ToBoolean. TODO(jkummerow): Drop.
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
// -----------------------------------------------------------------------------
// ES #sec-boolean-objects
// ES #sec-boolean-constructor
BUILTIN(BooleanConstructor) {
HandleScope scope(isolate);
if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
Handle<Object> value = args.atOrUndefined(isolate, 1);
return isolate->heap()->ToBoolean(value->BooleanValue(isolate));
}
// [[Construct]]
Handle<Object> value = args.atOrUndefined(isolate, 1);
Handle<JSFunction> target = args.target();
Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
DCHECK(*target == target->native_context()->boolean_function());
Handle<JSObject> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
JSObject::New(target, new_target, Handle<AllocationSite>::null()));
Handle<JSValue>::cast(result)->set_value(
isolate->heap()->ToBoolean(value->BooleanValue(isolate)));
return *result;
}
} // namespace internal
} // namespace v8

View File

@ -398,8 +398,6 @@ namespace internal {
CPP(BigIntPrototypeValueOf) \
\
/* Boolean */ \
/* ES #sec-boolean-constructor */ \
CPP(BooleanConstructor) \
/* ES6 #sec-boolean.prototype.tostring */ \
TFJ(BooleanPrototypeToString, 0, kReceiver) \
/* ES6 #sec-boolean.prototype.valueof */ \

View File

@ -864,6 +864,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
LoadObjectField(object, offset, MachineType::AnyTagged()));
}
TNode<Object> LoadConstructorOrBackPointer(TNode<Map> map) {
return LoadObjectField(map, Map::kConstructorOrBackPointerOffset);
}
// Reference is the CSA-equivalent of a Torque reference value,
// representing an inner pointer into a HeapObject.
struct Reference {

View File

@ -737,6 +737,15 @@ RUNTIME_FUNCTION(Runtime_NewObject) {
JSObject::New(target, new_target, Handle<AllocationSite>::null()));
}
RUNTIME_FUNCTION(Runtime_GetDerivedMap) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
RETURN_RESULT_OR_FAILURE(
isolate, JSFunction::GetDerivedMap(isolate, target, new_target));
}
RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) {
DisallowHeapAllocation no_gc;
HandleScope scope(isolate);

View File

@ -296,6 +296,7 @@ namespace internal {
F(DefineGetterPropertyUnchecked, 4, 1) \
F(DefineSetterPropertyUnchecked, 4, 1) \
F(DeleteProperty, 3, 1) \
F(GetDerivedMap, 2, 1) \
F(GetFunctionName, 1, 1) \
F(GetOwnPropertyDescriptor, 2, 1) \
F(GetOwnPropertyKeys, 2, 1) \

View File

@ -1404,7 +1404,8 @@ struct TorqueGrammar : Grammar {
TorqueGrammar() : Grammar(&file) { SetWhitespace(MatchWhitespace); }
// Result: std::string
Symbol identifier = {Rule({Pattern(MatchIdentifier)}, YieldMatchedInput)};
Symbol identifier = {Rule({Pattern(MatchIdentifier)}, YieldMatchedInput),
Rule({Token("runtime")}, YieldMatchedInput)};
// Result: Identifier*
Symbol name = {Rule({&identifier}, MakeIdentifier)};