Commit c7bf46ea authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[baseline] Omit calling default ctors

I.e., implement a baseline handler for the FindNonDefaultConstructor
bytecode.

Bug: v8:13091
Change-Id: If1b119ae0479e54d2a89143bf8f40faeadb1abaf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3871206Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83076}
parent 9459c27b
...@@ -1161,8 +1161,10 @@ void BaselineCompiler::VisitGetSuperConstructor() { ...@@ -1161,8 +1161,10 @@ void BaselineCompiler::VisitGetSuperConstructor() {
} }
void BaselineCompiler::VisitFindNonDefaultConstructor() { void BaselineCompiler::VisitFindNonDefaultConstructor() {
// TODO(v8:13091): Implement. CallBuiltin<Builtin::kFindNonDefaultConstructor>(RegisterOperand(0),
CHECK(false); RegisterOperand(1));
StoreRegister(2, kReturnRegister1);
StoreRegister(3, kReturnRegister2);
} }
namespace { namespace {
......
...@@ -1094,6 +1094,7 @@ namespace internal { ...@@ -1094,6 +1094,7 @@ namespace internal {
TFS(CreateDataProperty, kReceiver, kKey, kValue) \ TFS(CreateDataProperty, kReceiver, kKey, kValue) \
ASM(MemCopyUint8Uint8, CCall) \ ASM(MemCopyUint8Uint8, CCall) \
ASM(MemMove, CCall) \ ASM(MemMove, CCall) \
TFC(FindNonDefaultConstructor, FindNonDefaultConstructor) \
\ \
/* Trace */ \ /* Trace */ \
CPP(IsTraceCategoryEnabled) \ CPP(IsTraceCategoryEnabled) \
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "src/ic/keyed-store-generic.h" #include "src/ic/keyed-store-generic.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/objects/debug-objects.h" #include "src/objects/debug-objects.h"
#include "src/objects/scope-info.h"
#include "src/objects/shared-function-info.h" #include "src/objects/shared-function-info.h"
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
...@@ -1501,5 +1502,32 @@ TF_BUILTIN(InstantiateAsmJs, CodeStubAssembler) { ...@@ -1501,5 +1502,32 @@ TF_BUILTIN(InstantiateAsmJs, CodeStubAssembler) {
TailCallJSCode(code, context, function, new_target, arg_count); TailCallJSCode(code, context, function, new_target, arg_count);
} }
TF_BUILTIN(FindNonDefaultConstructor, CodeStubAssembler) {
auto this_function = Parameter<JSFunction>(Descriptor::kThisFunction);
auto new_target = Parameter<Object>(Descriptor::kNewTarget);
auto context = Parameter<Context>(Descriptor::kContext);
TVARIABLE(Object, constructor);
Label found_default_base_ctor(this, &constructor),
found_something_else(this, &constructor);
FindNonDefaultConstructor(context, this_function, constructor,
&found_default_base_ctor, &found_something_else);
BIND(&found_default_base_ctor);
{
// Create an object directly, without calling the default base ctor.
TNode<Object> instance = CallBuiltin(Builtin::kFastNewObject, context,
constructor.value(), new_target);
Return(TrueConstant(), constructor.value(), instance);
}
BIND(&found_something_else);
{
// Not a base ctor (or bailed out).
Return(FalseConstant(), constructor.value(), UndefinedConstant());
}
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -13711,6 +13711,72 @@ TNode<HeapObject> CodeStubAssembler::GetSuperConstructor( ...@@ -13711,6 +13711,72 @@ TNode<HeapObject> CodeStubAssembler::GetSuperConstructor(
return LoadMapPrototype(map); return LoadMapPrototype(map);
} }
void CodeStubAssembler::FindNonDefaultConstructor(
TNode<Context> context, TNode<JSFunction> this_function,
TVariable<Object>& constructor, Label* found_default_base_ctor,
Label* found_something_else) {
Label loop(this, &constructor);
constructor = GetSuperConstructor(this_function);
// Disable the optimization if the debugger is active, so that we can still
// put breakpoints into default constructors.
GotoIf(IsDebugActive(), found_something_else);
// Disable the optimization if the array iterator has been changed. V8 uses
// the array iterator for the spread in default ctors, even though it
// shouldn't, according to the spec. This ensures that omitting default ctors
// doesn't change the behavior. See crbug.com/v8/13249.
GotoIf(IsArrayIteratorProtectorCellInvalid(), found_something_else);
Goto(&loop);
BIND(&loop);
{
// We know constructor can't be a SMI, since it's a prototype. If it's not a
// JSFunction, the error will be thrown by the ThrowIfNotSuperConstructor
// which follows this bytecode.
GotoIfNot(IsJSFunction(CAST(constructor.value())), found_something_else);
// If there are class fields, bail out. TODO(v8:13091): Handle them here.
TNode<Oddball> has_class_fields =
HasProperty(context, constructor.value(), ClassFieldsSymbolConstant(),
kHasProperty);
GotoIf(IsTrue(has_class_fields), found_something_else);
// If there are private methods, bail out. TODO(v8:13091): Handle them here.
TNode<Context> function_context =
LoadJSFunctionContext(CAST(constructor.value()));
TNode<ScopeInfo> scope_info = LoadScopeInfo(function_context);
GotoIf(LoadScopeInfoClassScopeHasPrivateBrand(scope_info),
found_something_else);
const TNode<Uint32T> function_kind =
LoadFunctionKind(CAST(constructor.value()));
// A default base ctor -> stop the search.
GotoIf(Word32Equal(
function_kind,
static_cast<uint32_t>(FunctionKind::kDefaultBaseConstructor)),
found_default_base_ctor);
// Something else than a default derived ctor (e.g., a non-default base
// ctor, a non-default derived ctor, or a normal function) -> stop the
// search.
GotoIfNot(Word32Equal(function_kind,
static_cast<uint32_t>(
FunctionKind::kDefaultDerivedConstructor)),
found_something_else);
constructor = GetSuperConstructor(CAST(constructor.value()));
Goto(&loop);
}
// We don't need to re-check the proctector, since the loop cannot call into
// user code. Even if GetSuperConstructor returns a Proxy, we will throw since
// it's not a constructor, and not invoke [[GetPrototypeOf]] on it.
// TODO(v8:13091): make sure this is still valid after we handle class fields.
}
TNode<JSReceiver> CodeStubAssembler::SpeciesConstructor( TNode<JSReceiver> CodeStubAssembler::SpeciesConstructor(
TNode<Context> context, TNode<Object> object, TNode<Context> context, TNode<Object> object,
TNode<JSReceiver> default_constructor) { TNode<JSReceiver> default_constructor) {
......
...@@ -2043,6 +2043,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2043,6 +2043,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
Label* if_bailout); Label* if_bailout);
TNode<Object> GetConstructor(TNode<Map> map); TNode<Object> GetConstructor(TNode<Map> map);
void FindNonDefaultConstructor(TNode<Context> context,
TNode<JSFunction> this_function,
TVariable<Object>& constructor,
Label* found_default_base_ctor,
Label* found_something_else);
TNode<Map> GetInstanceTypeMap(InstanceType instance_type); TNode<Map> GetInstanceTypeMap(InstanceType instance_type);
TNode<FixedArray> AllocateUninitializedFixedArray(intptr_t capacity) { TNode<FixedArray> AllocateUninitializedFixedArray(intptr_t capacity) {
......
...@@ -72,6 +72,7 @@ namespace internal { ...@@ -72,6 +72,7 @@ namespace internal {
V(CopyDataPropertiesWithExcludedPropertiesOnStack) \ V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
V(CppBuiltinAdaptor) \ V(CppBuiltinAdaptor) \
V(FastNewObject) \ V(FastNewObject) \
V(FindNonDefaultConstructor) \
V(ForInPrepare) \ V(ForInPrepare) \
V(GetIteratorStackParameter) \ V(GetIteratorStackParameter) \
V(GetProperty) \ V(GetProperty) \
...@@ -1816,6 +1817,20 @@ class InterpreterCEntry2Descriptor ...@@ -1816,6 +1817,20 @@ class InterpreterCEntry2Descriptor
static constexpr auto registers(); static constexpr auto registers();
}; };
class FindNonDefaultConstructorDescriptor
: public StaticCallInterfaceDescriptor<
FindNonDefaultConstructorDescriptor> {
public:
DEFINE_RESULT_AND_PARAMETERS(3, kThisFunction, kNewTarget)
DEFINE_RESULT_AND_PARAMETER_TYPES(
MachineType::AnyTagged(), // result 1 (true / false)
MachineType::AnyTagged(), // result 2 (constructor)
MachineType::AnyTagged(), // result 3 (instance)
MachineType::AnyTagged(), // kThisFunction
MachineType::AnyTagged()) // kNewTarget
DECLARE_DESCRIPTOR(FindNonDefaultConstructorDescriptor)
};
class ForInPrepareDescriptor class ForInPrepareDescriptor
: public StaticCallInterfaceDescriptor<ForInPrepareDescriptor> { : public StaticCallInterfaceDescriptor<ForInPrepareDescriptor> {
public: public:
......
...@@ -5683,11 +5683,7 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) { ...@@ -5683,11 +5683,7 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) {
Register new_target = register_allocator()->NewRegister(); Register new_target = register_allocator()->NewRegister();
VisitForRegisterValue(super->new_target_var(), new_target); VisitForRegisterValue(super->new_target_var(), new_target);
// Use the same register for storing the 'constructor' or the 'instance', Register constructor = register_allocator()->NewRegister();
// they won't both be needed at the same time. If we jump to super_ctor_call
// done, only 'instance' is used, and if we don't, only 'constructor' is
// used.
Register& constructor = instance;
if (omit_super_ctor) { if (omit_super_ctor) {
BuildSuperCallOptimization(this_function, new_target, constructor, BuildSuperCallOptimization(this_function, new_target, constructor,
instance, &super_ctor_call_done); instance, &super_ctor_call_done);
......
...@@ -2792,73 +2792,18 @@ IGNITION_HANDLER(ThrowIfNotSuperConstructor, InterpreterAssembler) { ...@@ -2792,73 +2792,18 @@ IGNITION_HANDLER(ThrowIfNotSuperConstructor, InterpreterAssembler) {
IGNITION_HANDLER(FindNonDefaultConstructor, InterpreterAssembler) { IGNITION_HANDLER(FindNonDefaultConstructor, InterpreterAssembler) {
TNode<Context> context = GetContext(); TNode<Context> context = GetContext();
TVARIABLE(Object, constructor); TVARIABLE(Object, constructor);
Label loop(this, &constructor), found_default_base_ctor(this, &constructor), Label found_default_base_ctor(this, &constructor),
found_something_else(this, &constructor); found_something_else(this, &constructor);
TNode<JSFunction> this_function = CAST(LoadRegisterAtOperandIndex(0)); TNode<JSFunction> this_function = CAST(LoadRegisterAtOperandIndex(0));
constructor = GetSuperConstructor(this_function);
// Disable the optimization if the debugger is active, so that we can still FindNonDefaultConstructor(context, this_function, constructor,
// put breakpoints into default constructors. &found_default_base_ctor, &found_something_else);
GotoIf(IsDebugActive(), &found_something_else);
// Disable the optimization if the array iterator has been changed. V8 uses
// the array iterator for the spread in default ctors, even though it
// shouldn't, according to the spec. This ensures that omitting default ctors
// doesn't change the behavior. See crbug.com/v8/13249.
GotoIf(IsArrayIteratorProtectorCellInvalid(), &found_something_else);
TNode<Object> new_target = LoadRegisterAtOperandIndex(1);
Goto(&loop);
BIND(&loop);
{
// We know constructor can't be a SMI, since it's a prototype. If it's not a
// JSFunction, the error will be thrown by the ThrowIfNotSuperConstructor
// which follows this bytecode.
GotoIfNot(IsJSFunction(CAST(constructor.value())), &found_something_else);
// If there are class fields, bail out. TODO(v8:13091): Handle them here.
TNode<Oddball> has_class_fields =
HasProperty(context, constructor.value(), ClassFieldsSymbolConstant(),
kHasProperty);
GotoIf(IsTrue(has_class_fields), &found_something_else);
// If there are private methods, bail out. TODO(v8:13091): Handle them here.
TNode<Context> function_context =
LoadJSFunctionContext(CAST(constructor.value()));
TNode<ScopeInfo> scope_info = LoadScopeInfo(function_context);
GotoIf(LoadScopeInfoClassScopeHasPrivateBrand(scope_info),
&found_something_else);
const TNode<Uint32T> function_kind =
LoadFunctionKind(CAST(constructor.value()));
// A default base ctor -> stop the search.
GotoIf(Word32Equal(
function_kind,
static_cast<uint32_t>(FunctionKind::kDefaultBaseConstructor)),
&found_default_base_ctor);
// Something else than a default derived ctor (e.g., a non-default base
// ctor, a non-default derived ctor, or a normal function) -> stop the
// search.
GotoIfNot(Word32Equal(function_kind,
static_cast<uint32_t>(
FunctionKind::kDefaultDerivedConstructor)),
&found_something_else);
constructor = GetSuperConstructor(CAST(constructor.value()));
Goto(&loop);
}
// We don't need to re-check the proctector, since the loop cannot call into
// user code. Even if GetSuperConstructor returns a Proxy, we will throw since
// it's not a constructor, and not invoke [[GetPrototypeOf]] on it.
// TODO(v8:13091): make sure this is still valid after we handle class fields.
BIND(&found_default_base_ctor); BIND(&found_default_base_ctor);
{ {
// Create an object directly, without calling the default base ctor. // Create an object directly, without calling the default base ctor.
TNode<Object> new_target = LoadRegisterAtOperandIndex(1);
TNode<Object> instance = CallBuiltin(Builtin::kFastNewObject, context, TNode<Object> instance = CallBuiltin(Builtin::kFastNewObject, context,
constructor.value(), new_target); constructor.value(), new_target);
StoreRegisterAtOperandIndex(instance, 3); StoreRegisterAtOperandIndex(instance, 3);
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --omit-default-ctors --no-sparkplug --no-turbofan --no-always-turbofan // Flags: --omit-default-ctors --no-turbofan --no-always-turbofan
// TODO(v8:13091): Enable Sparkplug + TurboFan. // TODO(v8:13091): Enable TurboFan.
// This behavior is not spec compliant, see crbug.com/v8/13249. // This behavior is not spec compliant, see crbug.com/v8/13249.
(function ArrayIteratorMonkeyPatched() { (function ArrayIteratorMonkeyPatched() {
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --omit-default-ctors --no-sparkplug --no-turbofan --no-always-turbofan // Flags: --omit-default-ctors --no-turbofan --no-always-turbofan
// TODO(v8:13091): Enable Sparkplug + TurboFan. // TODO(v8:13091): Enable TurboFan.
(function OmitDefaultBaseCtor() { (function OmitDefaultBaseCtor() {
class A {} // default base ctor -> will be omitted class A {} // default base ctor -> will be omitted
......
...@@ -87,7 +87,7 @@ snippet: " ...@@ -87,7 +87,7 @@ snippet: "
test = new B().constructor; test = new B().constructor;
})(); })();
" "
frame size: 5 frame size: 7
parameter count: 1 parameter count: 1
bytecode array length: 39 bytecode array length: 39
bytecodes: [ bytecodes: [
...@@ -95,10 +95,10 @@ bytecodes: [ ...@@ -95,10 +95,10 @@ bytecodes: [
/* 118 S> */ B(LdaSmi), I8(1), /* 118 S> */ B(LdaSmi), I8(1),
B(Star4), B(Star4),
B(Ldar), R(1), B(Ldar), R(1),
/* 118 E> */ B(GetSuperConstructor), R(3), /* 118 E> */ B(GetSuperConstructor), R(6),
B(ThrowIfNotSuperConstructor), R(3), B(ThrowIfNotSuperConstructor), R(6),
B(Ldar), R(0), B(Ldar), R(0),
/* 118 E> */ B(Construct), R(3), R(4), U8(1), U8(0), /* 118 E> */ B(Construct), R(6), R(4), U8(1), U8(0),
B(Star3), B(Star3),
B(Ldar), R(this), B(Ldar), R(this),
B(ThrowSuperAlreadyCalledIfNotHole), B(ThrowSuperAlreadyCalledIfNotHole),
...@@ -130,16 +130,16 @@ snippet: " ...@@ -130,16 +130,16 @@ snippet: "
test = new B().constructor; test = new B().constructor;
})(); })();
" "
frame size: 4 frame size: 6
parameter count: 1 parameter count: 1
bytecode array length: 36 bytecode array length: 36
bytecodes: [ bytecodes: [
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
/* 117 S> */ B(Ldar), R(1), /* 117 S> */ B(Ldar), R(1),
/* 117 E> */ B(GetSuperConstructor), R(3), /* 117 E> */ B(GetSuperConstructor), R(5),
B(ThrowIfNotSuperConstructor), R(3), B(ThrowIfNotSuperConstructor), R(5),
B(Ldar), R(0), B(Ldar), R(0),
/* 117 E> */ B(Construct), R(3), R(0), U8(0), U8(0), /* 117 E> */ B(Construct), R(5), R(0), U8(0), U8(0),
B(Star3), B(Star3),
B(Ldar), R(this), B(Ldar), R(this),
B(ThrowSuperAlreadyCalledIfNotHole), B(ThrowSuperAlreadyCalledIfNotHole),
......
...@@ -157,7 +157,7 @@ snippet: " ...@@ -157,7 +157,7 @@ snippet: "
}; };
new F; new F;
" "
frame size: 9 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 63 bytecode array length: 63
bytecodes: [ bytecodes: [
...@@ -166,27 +166,27 @@ bytecodes: [ ...@@ -166,27 +166,27 @@ bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star2), B(Star2),
B(Ldar), R(0), B(Ldar), R(0),
/* 89 E> */ B(GetSuperConstructor), R(1), /* 89 E> */ B(GetSuperConstructor), R(3),
B(ThrowIfNotSuperConstructor), R(1), B(ThrowIfNotSuperConstructor), R(3),
B(Ldar), R(2), B(Ldar), R(2),
/* 89 E> */ B(Construct), R(1), R(0), U8(0), U8(0), /* 89 E> */ B(Construct), R(3), R(0), U8(0), U8(0),
B(Star1), B(Star1),
B(LdaCurrentContextSlot), U8(2), B(LdaCurrentContextSlot), U8(2),
B(ThrowSuperAlreadyCalledIfNotHole), B(ThrowSuperAlreadyCalledIfNotHole),
B(Ldar), R(1), B(Ldar), R(1),
B(StaCurrentContextSlot), U8(2), B(StaCurrentContextSlot), U8(2),
B(LdaImmutableContextSlot), R(context), U8(3), U8(1), B(LdaImmutableContextSlot), R(context), U8(3), U8(1),
B(Star4), B(Star5),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star6), B(Star7),
B(Mov), R(1), R(3), B(Mov), R(1), R(4),
B(Mov), R(context), R(5), B(Mov), R(context), R(6),
B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(3), U8(4), B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(4), U8(4),
B(GetNamedProperty), R(0), U8(0), U8(2), B(GetNamedProperty), R(0), U8(0), U8(2),
B(JumpIfUndefined), U8(10), B(JumpIfUndefined), U8(10),
B(Star8), B(Star9),
B(CallProperty0), R(8), R(1), U8(4), B(CallProperty0), R(9), R(1), U8(4),
B(Mov), R(1), R(7), B(Mov), R(1), R(8),
B(Ldar), R(1), B(Ldar), R(1),
/* 96 S> */ B(Return), /* 96 S> */ B(Return),
] ]
...@@ -209,7 +209,7 @@ snippet: " ...@@ -209,7 +209,7 @@ snippet: "
}; };
new G(); new G();
" "
frame size: 9 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 63 bytecode array length: 63
bytecodes: [ bytecodes: [
...@@ -218,27 +218,27 @@ bytecodes: [ ...@@ -218,27 +218,27 @@ bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star2), B(Star2),
B(Ldar), R(0), B(Ldar), R(0),
/* 88 E> */ B(GetSuperConstructor), R(1), /* 88 E> */ B(GetSuperConstructor), R(3),
B(ThrowIfNotSuperConstructor), R(1), B(ThrowIfNotSuperConstructor), R(3),
B(Ldar), R(2), B(Ldar), R(2),
/* 88 E> */ B(Construct), R(1), R(0), U8(0), U8(0), /* 88 E> */ B(Construct), R(3), R(0), U8(0), U8(0),
B(Star1), B(Star1),
B(LdaCurrentContextSlot), U8(2), B(LdaCurrentContextSlot), U8(2),
B(ThrowSuperAlreadyCalledIfNotHole), B(ThrowSuperAlreadyCalledIfNotHole),
B(Ldar), R(1), B(Ldar), R(1),
B(StaCurrentContextSlot), U8(2), B(StaCurrentContextSlot), U8(2),
B(LdaImmutableContextSlot), R(context), U8(3), U8(1), B(LdaImmutableContextSlot), R(context), U8(3), U8(1),
B(Star4), B(Star5),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star6), B(Star7),
B(Mov), R(1), R(3), B(Mov), R(1), R(4),
B(Mov), R(context), R(5), B(Mov), R(context), R(6),
B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(3), U8(4), B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(4), U8(4),
B(GetNamedProperty), R(0), U8(0), U8(2), B(GetNamedProperty), R(0), U8(0), U8(2),
B(JumpIfUndefined), U8(10), B(JumpIfUndefined), U8(10),
B(Star8), B(Star9),
B(CallProperty0), R(8), R(1), U8(4), B(CallProperty0), R(9), R(1), U8(4),
B(Mov), R(1), R(7), B(Mov), R(1), R(8),
B(Ldar), R(1), B(Ldar), R(1),
/* 95 S> */ B(Return), /* 95 S> */ B(Return),
] ]
...@@ -260,7 +260,7 @@ snippet: " ...@@ -260,7 +260,7 @@ snippet: "
}; };
new test('test = () => super(); test()'); new test('test = () => super(); test()');
" "
frame size: 9 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 63 bytecode array length: 63
bytecodes: [ bytecodes: [
...@@ -269,27 +269,27 @@ bytecodes: [ ...@@ -269,27 +269,27 @@ bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star2), B(Star2),
B(Ldar), R(0), B(Ldar), R(0),
/* 88 E> */ B(GetSuperConstructor), R(1), /* 88 E> */ B(GetSuperConstructor), R(3),
B(ThrowIfNotSuperConstructor), R(1), B(ThrowIfNotSuperConstructor), R(3),
B(Ldar), R(2), B(Ldar), R(2),
/* 88 E> */ B(Construct), R(1), R(0), U8(0), U8(0), /* 88 E> */ B(Construct), R(3), R(0), U8(0), U8(0),
B(Star1), B(Star1),
B(LdaCurrentContextSlot), U8(2), B(LdaCurrentContextSlot), U8(2),
B(ThrowSuperAlreadyCalledIfNotHole), B(ThrowSuperAlreadyCalledIfNotHole),
B(Ldar), R(1), B(Ldar), R(1),
B(StaCurrentContextSlot), U8(2), B(StaCurrentContextSlot), U8(2),
B(LdaImmutableContextSlot), R(context), U8(3), U8(1), B(LdaImmutableContextSlot), R(context), U8(3), U8(1),
B(Star4), B(Star5),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star6), B(Star7),
B(Mov), R(1), R(3), B(Mov), R(1), R(4),
B(Mov), R(context), R(5), B(Mov), R(context), R(6),
B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(3), U8(4), B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(4), U8(4),
B(GetNamedProperty), R(0), U8(0), U8(2), B(GetNamedProperty), R(0), U8(0), U8(2),
B(JumpIfUndefined), U8(10), B(JumpIfUndefined), U8(10),
B(Star8), B(Star9),
B(CallProperty0), R(8), R(1), U8(4), B(CallProperty0), R(9), R(1), U8(4),
B(Mov), R(1), R(7), B(Mov), R(1), R(8),
B(Ldar), R(1), B(Ldar), R(1),
/* 95 S> */ B(Return), /* 95 S> */ B(Return),
] ]
......
...@@ -17,7 +17,7 @@ snippet: " ...@@ -17,7 +17,7 @@ snippet: "
test = new B(1, 2, 3).constructor; test = new B(1, 2, 3).constructor;
})(); })();
" "
frame size: 5 frame size: 8
parameter count: 1 parameter count: 1
bytecode array length: 19 bytecode array length: 19
bytecodes: [ bytecodes: [
...@@ -25,10 +25,10 @@ bytecodes: [ ...@@ -25,10 +25,10 @@ bytecodes: [
B(Star2), B(Star2),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
/* 93 S> */ B(Ldar), R(1), /* 93 S> */ B(Ldar), R(1),
/* 93 E> */ B(GetSuperConstructor), R(4), /* 93 E> */ B(GetSuperConstructor), R(7),
B(ThrowIfNotSuperConstructor), R(4), B(ThrowIfNotSuperConstructor), R(7),
B(Ldar), R(0), B(Ldar), R(0),
/* 93 E> */ B(ConstructWithSpread), R(4), R(2), U8(1), U8(0), /* 93 E> */ B(ConstructWithSpread), R(7), R(2), U8(1), U8(0),
/* 93 S> */ B(Return), /* 93 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -49,7 +49,7 @@ snippet: " ...@@ -49,7 +49,7 @@ snippet: "
test = new B(1, 2, 3).constructor; test = new B(1, 2, 3).constructor;
})(); })();
" "
frame size: 8 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 38 bytecode array length: 38
bytecodes: [ bytecodes: [
...@@ -60,11 +60,11 @@ bytecodes: [ ...@@ -60,11 +60,11 @@ bytecodes: [
/* 140 S> */ B(LdaSmi), I8(1), /* 140 S> */ B(LdaSmi), I8(1),
B(Star6), B(Star6),
B(Ldar), R(closure), B(Ldar), R(closure),
/* 140 E> */ B(GetSuperConstructor), R(5), /* 140 E> */ B(GetSuperConstructor), R(9),
B(ThrowIfNotSuperConstructor), R(5), B(ThrowIfNotSuperConstructor), R(9),
B(Ldar), R(0), B(Ldar), R(0),
B(Mov), R(3), R(7), B(Mov), R(3), R(7),
/* 140 E> */ B(ConstructWithSpread), R(5), R(6), U8(2), U8(0), /* 140 E> */ B(ConstructWithSpread), R(9), R(6), U8(2), U8(0),
B(Star5), B(Star5),
B(Ldar), R(this), B(Ldar), R(this),
B(ThrowSuperAlreadyCalledIfNotHole), B(ThrowSuperAlreadyCalledIfNotHole),
......
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