[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:
parent
d6b51cba23
commit
b8c97dd2a8
3
BUILD.gn
3
BUILD.gn
@ -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",
|
||||
|
@ -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
42
src/builtins/boolean.tq
Normal 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;
|
||||
}
|
||||
}
|
@ -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
|
@ -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 */ \
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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)};
|
||||
|
Loading…
Reference in New Issue
Block a user