Commit b10dc352 authored by Mathias Bynens's avatar Mathias Bynens Committed by Commit Bot

[builtins] Refactor the TypedArrayConstructor builtin

This patch removes the TypedArrayConstructor_ConstructStub builtin,
merging its functionality into the refactored TypedArrayConstructor
TurboFan builtin.

This brings us closer to our goal of deprecating the `construct_stub`
field in `SharedFunctionInfo`.

Bug: v8:7503, v8:7518
Change-Id: I264aa0933b3c80814e021b05033636196dc289da
Reviewed-on: https://chromium-review.googlesource.com/956044
Commit-Queue: Mathias Bynens <mathias@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51843}
parent 5a70a5ea
......@@ -3520,7 +3520,7 @@ Handle<JSFunction> Genesis::InstallTypedArray(const char* name,
result->shared()->DontAdaptArguments();
result->shared()->set_length(3);
result->shared()->SetConstructStub(
*BUILTIN_CODE(isolate_, TypedArrayConstructor_ConstructStub));
*BUILTIN_CODE(isolate_, JSBuiltinsConstructStub));
CHECK(JSObject::SetPrototype(result, typed_array_function, false, kDontThrow)
.FromJust());
......
......@@ -1089,8 +1089,6 @@ namespace internal {
TFS(TypedArrayInitializeWithBuffer, kHolder, kLength, kBuffer, kElementSize, \
kByteOffset) \
TFJ(TypedArrayConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(TypedArrayConstructor_ConstructStub, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(TypedArrayPrototypeBuffer) \
/* ES6 #sec-get-%typedarray%.prototype.bytelength */ \
TFJ(TypedArrayPrototypeByteLength, 0) \
......
......@@ -634,87 +634,104 @@ TF_BUILTIN(TypedArrayConstructor, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
// If NewTarget is undefined, throw a TypeError exception.
// All the TypedArray constructors have this as the first step:
// https://tc39.github.io/ecma262/#sec-typedarray-constructors
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
Node* shared = LoadObjectField(target, JSFunction::kSharedFunctionInfoOffset);
Node* name = LoadObjectField(shared, SharedFunctionInfo::kNameOffset);
ThrowTypeError(context, MessageTemplate::kConstructorNotFunction, name);
}
TF_BUILTIN(TypedArrayConstructor_ConstructStub, TypedArrayBuiltinsAssembler) {
Label if_arg1isbuffer(this), if_arg1istypedarray(this),
if_arg1isreceiver(this), if_arg1isnumber(this), done(this);
Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
Label throwtypeerror(this, Label::kDeferred), createtypedarray(this);
Branch(IsUndefined(new_target), &throwtypeerror, &createtypedarray);
TNode<Object> new_target = CAST(Parameter(BuiltinDescriptor::kNewTarget));
CSA_ASSERT(this, IsNotUndefined(new_target));
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
TNode<Object> arg1 = args.GetOptionalArgumentValue(0);
TNode<Object> arg2 = args.GetOptionalArgumentValue(1);
TNode<Object> arg3 = args.GetOptionalArgumentValue(2);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
BIND(&throwtypeerror);
{
Node* shared =
LoadObjectField(target, JSFunction::kSharedFunctionInfoOffset);
Node* name = LoadObjectField(shared, SharedFunctionInfo::kNameOffset);
ThrowTypeError(context, MessageTemplate::kConstructorNotFunction, name);
}
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
ConstructorBuiltinsAssembler constructor_assembler(this->state());
TNode<JSTypedArray> holder = CAST(
constructor_assembler.EmitFastNewObject(context, target, new_target));
BIND(&createtypedarray);
{
Label if_arg1isbuffer(this), if_arg1istypedarray(this),
if_arg1isreceiver(this), if_arg1isnumber(this), done(this);
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
TNode<Object> arg1 = args.GetOptionalArgumentValue(0);
TNode<Object> arg2 = args.GetOptionalArgumentValue(1);
TNode<Object> arg3 = args.GetOptionalArgumentValue(2);
ConstructorBuiltinsAssembler constructor_assembler(this->state());
TNode<JSTypedArray> holder = CAST(
constructor_assembler.EmitFastNewObject(context, target, new_target));
TNode<Smi> element_size =
SmiTag(GetTypedArrayElementSize(LoadElementsKind(holder)));
GotoIf(TaggedIsSmi(arg1), &if_arg1isnumber);
GotoIf(IsJSArrayBuffer(arg1), &if_arg1isbuffer);
GotoIf(IsJSTypedArray(arg1), &if_arg1istypedarray);
GotoIf(IsJSReceiver(arg1), &if_arg1isreceiver);
Goto(&if_arg1isnumber);
// https://tc39.github.io/ecma262/#sec-typedarray-buffer-byteoffset-length
BIND(&if_arg1isbuffer);
{
ConstructByArrayBuffer(context, holder, CAST(arg1), arg2, arg3,
element_size);
Goto(&done);
}
TNode<Smi> element_size =
SmiTag(GetTypedArrayElementSize(LoadElementsKind(holder)));
// https://tc39.github.io/ecma262/#sec-typedarray-typedarray
BIND(&if_arg1istypedarray);
{
TNode<JSTypedArray> typed_array = CAST(arg1);
ConstructByTypedArray(context, holder, typed_array, element_size);
Goto(&done);
}
GotoIf(TaggedIsSmi(arg1), &if_arg1isnumber);
GotoIf(IsJSArrayBuffer(arg1), &if_arg1isbuffer);
GotoIf(IsJSTypedArray(arg1), &if_arg1istypedarray);
GotoIf(IsJSReceiver(arg1), &if_arg1isreceiver);
Goto(&if_arg1isnumber);
// https://tc39.github.io/ecma262/#sec-typedarray-object
BIND(&if_arg1isreceiver);
{
Label if_iteratorundefined(this), if_iteratornotcallable(this);
// Get iterator symbol
TNode<Object> iteratorFn =
CAST(GetMethod(context, arg1, isolate()->factory()->iterator_symbol(),
&if_iteratorundefined));
GotoIf(TaggedIsSmi(iteratorFn), &if_iteratornotcallable);
GotoIfNot(IsCallable(iteratorFn), &if_iteratornotcallable);
ConstructByIterable(context, holder, CAST(arg1), iteratorFn,
element_size);
Goto(&done);
BIND(&if_arg1isbuffer);
ConstructByArrayBuffer(context, holder, CAST(arg1), arg2, arg3, element_size);
Goto(&done);
BIND(&if_iteratorundefined);
{
TNode<HeapObject> array_like = CAST(arg1);
TNode<Object> initial_length =
GetProperty(context, arg1, LengthStringConstant());
BIND(&if_arg1istypedarray);
TNode<JSTypedArray> typed_array = CAST(arg1);
ConstructByTypedArray(context, holder, typed_array, element_size);
Goto(&done);
ConstructByArrayLike(context, holder, array_like, initial_length,
element_size);
Goto(&done);
}
BIND(&if_arg1isreceiver);
{
Label if_iteratorundefined(this), if_iteratornotcallable(this);
// Get iterator symbol
TNode<Object> iteratorFn =
CAST(GetMethod(context, arg1, isolate()->factory()->iterator_symbol(),
&if_iteratorundefined));
GotoIf(TaggedIsSmi(iteratorFn), &if_iteratornotcallable);
GotoIfNot(IsCallable(iteratorFn), &if_iteratornotcallable);
ConstructByIterable(context, holder, CAST(arg1), iteratorFn, element_size);
Goto(&done);
BIND(&if_iteratornotcallable);
{ ThrowTypeError(context, MessageTemplate::kIteratorSymbolNonCallable); }
}
BIND(&if_iteratorundefined);
// The first argument was a number or fell through and is treated as
// a number. https://tc39.github.io/ecma262/#sec-typedarray-length
BIND(&if_arg1isnumber);
{
TNode<HeapObject> array_like = CAST(arg1);
TNode<Object> initial_length =
GetProperty(context, arg1, LengthStringConstant());
ConstructByArrayLike(context, holder, array_like, initial_length,
element_size);
ConstructByLength(context, holder, arg1, element_size);
Goto(&done);
}
BIND(&if_iteratornotcallable);
{ ThrowTypeError(context, MessageTemplate::kIteratorSymbolNonCallable); }
BIND(&done);
{ args.PopAndReturn(holder); }
}
// First arg was a number or fell through and will be treated as a number.
BIND(&if_arg1isnumber);
ConstructByLength(context, holder, arg1, element_size);
Goto(&done);
BIND(&done);
args.PopAndReturn(holder);
}
void TypedArrayBuiltinsAssembler::GenerateTypedArrayPrototypeGetter(
......
......@@ -264,7 +264,6 @@ bool Builtins::IsLazy(int index) {
case kInterpreterEnterBytecodeDispatch:
case kInterpreterEntryTrampoline:
case kPromiseConstructorLazyDeoptContinuation: // https://crbug/v8/6786.
case kTypedArrayConstructor_ConstructStub: // https://crbug.com/v8/6787.
case kProxyConstructor: // https://crbug.com/v8/6787.
case kRecordWrite: // https://crbug.com/chromium/765301.
case kThrowWasmTrapDivByZero: // Required by wasm.
......@@ -609,7 +608,6 @@ bool Builtins::IsIsolateIndependent(int index) {
case kToNumeric:
case kToString:
case kTypedArrayConstructor:
case kTypedArrayConstructor_ConstructStub:
case kTypedArrayPrototypeByteLength:
case kTypedArrayPrototypeByteOffset:
case kTypedArrayPrototypeEntries:
......
......@@ -401,6 +401,9 @@ bool BuiltinToIntrinsicHasNoSideEffect(Builtins::Name builtin_id,
V(Builtins::kArrayMap, W(CreateDataProperty)) \
V(Builtins::kArrayPrototypeSlice, W(CreateDataProperty) W(SetProperty)) \
/* TypedArrays */ \
V(Builtins::kTypedArrayConstructor, \
W(TypedArrayCopyElements) W(InternalSetPrototype) \
W(ThrowInvalidTypedArrayAlignment)) \
V(Builtins::kTypedArrayPrototypeFilter, W(TypedArrayCopyElements)) \
V(Builtins::kTypedArrayPrototypeMap, W(SetProperty))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment