Revert of [Interpreter] Support for operator new. (patchset #17 id:290001 of https://codereview.chromium.org/1402943002/ )
Reason for revert: [Sheriff] Breaks arm64 debug: http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20arm64%20-%20sim%20-%20debug/builds/4595 Original issue's description: > [Interpreter] Support for operator new. > > This change add a new bytecode for operator new and implements it using > the Construct() builtin. > > BUG=v8:4280 > LOG=N > > Committed: https://crrev.com/8e4f9963d53913eab7fbd2f61a5733d8dc2169e7 > Cr-Commit-Position: refs/heads/master@{#31293} TBR=rmcilroy@chromium.org,bmeurer@chromium.org,oth@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=v8:4280 Review URL: https://codereview.chromium.org/1402153004 Cr-Commit-Position: refs/heads/master@{#31298}
This commit is contained in:
parent
f4c9f2221b
commit
0937cdbfbd
@ -976,19 +976,6 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
|
||||
Register limit, Register scratch) {
|
||||
Label loop_header, loop_check;
|
||||
__ b(al, &loop_check);
|
||||
__ bind(&loop_header);
|
||||
__ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex));
|
||||
__ push(scratch);
|
||||
__ bind(&loop_check);
|
||||
__ cmp(index, limit);
|
||||
__ b(gt, &loop_header);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -997,40 +984,27 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -- r1 : the target to call (can be any Object).
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ add(r3, r0, Operand(1)); // Add one for receiver.
|
||||
__ mov(r3, Operand(r3, LSL, kPointerSizeLog2));
|
||||
__ sub(r3, r2, r3);
|
||||
|
||||
Generate_InterpreterPushArgs(masm, r2, r3, r4);
|
||||
// Push the arguments.
|
||||
Label loop_header, loop_check;
|
||||
__ b(al, &loop_check);
|
||||
__ bind(&loop_header);
|
||||
__ ldr(r4, MemOperand(r2, -kPointerSize, PostIndex));
|
||||
__ push(r4);
|
||||
__ bind(&loop_check);
|
||||
__ cmp(r2, r3);
|
||||
__ b(gt, &loop_header);
|
||||
|
||||
// Call the target.
|
||||
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : argument count (not including receiver)
|
||||
// -- r3 : original constructor
|
||||
// -- r1 : constructor to call
|
||||
// -- r2 : address of the first argument
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ mov(r4, Operand(r0, LSL, kPointerSizeLog2));
|
||||
__ sub(r4, r2, r4);
|
||||
|
||||
Generate_InterpreterPushArgs(masm, r2, r4, r5);
|
||||
|
||||
// Call the constructor with r0, r1, and r3 unmodified.
|
||||
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
|
||||
CallRuntimePassFunction(masm, Runtime::kCompileLazy);
|
||||
GenerateTailCallToReturnedCode(masm);
|
||||
|
@ -420,18 +420,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r0, // argument count (not including receiver)
|
||||
r3, // original constructor
|
||||
r1, // constructor to call
|
||||
r2 // address of the first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -1769,7 +1769,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -- x1 : the target to call (can be any Object).
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ add(x3, x0, Operand(1)); // Add one for receiver.
|
||||
@ -1794,37 +1793,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : argument count (not including receiver)
|
||||
// -- x3 : original constructor
|
||||
// -- x1 : constructor to call
|
||||
// -- x2 : address of the first argument
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ lsl(x5, x0, kPointerSizeLog2);
|
||||
__ sub(x4, x2, x5);
|
||||
|
||||
// Push the arguments.
|
||||
Label loop_header, loop_check;
|
||||
__ Mov(x6, jssp);
|
||||
__ Claim(x5, 1);
|
||||
__ B(&loop_check);
|
||||
__ Bind(&loop_header);
|
||||
// TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
|
||||
__ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex));
|
||||
__ Str(x5, MemOperand(x6, -kPointerSize, PreIndex));
|
||||
__ Bind(&loop_check);
|
||||
__ Cmp(x2, x4);
|
||||
__ B(gt, &loop_header);
|
||||
|
||||
// Call the constructor with x0, x1, and x3 unmodified.
|
||||
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline");
|
||||
// ----------- S t a t e -------------
|
||||
|
@ -449,18 +449,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
x0, // argument count (not including receiver)
|
||||
x3, // original constructor
|
||||
x1, // constructor to call
|
||||
x2 // address of the first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -104,7 +104,6 @@ enum BuiltinExtraArguments {
|
||||
V(InterpreterEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
V(InterpreterExitTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
V(InterpreterPushArgsAndCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
V(InterpreterPushArgsAndConstruct, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
\
|
||||
V(LoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
@ -309,7 +308,6 @@ class Builtins {
|
||||
static void Generate_InterpreterEntryTrampoline(MacroAssembler* masm);
|
||||
static void Generate_InterpreterExitTrampoline(MacroAssembler* masm);
|
||||
static void Generate_InterpreterPushArgsAndCall(MacroAssembler* masm);
|
||||
static void Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm);
|
||||
|
||||
#define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C) \
|
||||
static void Generate_Make##C##CodeYoungAgainEvenMarking( \
|
||||
|
@ -275,13 +275,6 @@ Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(),
|
||||
InterpreterPushArgsAndConstructDescriptor(isolate));
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Callable CodeFactory::InterpreterCEntry(Isolate* isolate) {
|
||||
// TODO(rmcilroy): Deal with runtime functions that return two values.
|
||||
|
@ -98,7 +98,6 @@ class CodeFactory final {
|
||||
CallFunctionFlags flags);
|
||||
|
||||
static Callable InterpreterPushArgsAndCall(Isolate* isolate);
|
||||
static Callable InterpreterPushArgsAndConstruct(Isolate* isolate);
|
||||
static Callable InterpreterCEntry(Isolate* isolate);
|
||||
};
|
||||
|
||||
|
@ -357,12 +357,6 @@ void BytecodeGraphBuilder::VisitCallRuntime(
|
||||
}
|
||||
|
||||
|
||||
void BytecodeGraphBuilder::VisitNew(
|
||||
const interpreter::BytecodeArrayIterator& iterator) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
void BytecodeGraphBuilder::BuildBinaryOp(
|
||||
const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
|
||||
Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
|
||||
|
@ -317,26 +317,6 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() {
|
||||
}
|
||||
|
||||
|
||||
Node* InterpreterAssembler::CallConstruct(Node* original_constructor,
|
||||
Node* constructor, Node* first_arg,
|
||||
Node* arg_count) {
|
||||
Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate());
|
||||
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
|
||||
isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
|
||||
|
||||
Node* code_target = HeapConstant(callable.code());
|
||||
|
||||
Node** args = zone()->NewArray<Node*>(5);
|
||||
args[0] = arg_count;
|
||||
args[1] = original_constructor;
|
||||
args[2] = constructor;
|
||||
args[3] = first_arg;
|
||||
args[4] = GetContext();
|
||||
|
||||
return CallN(descriptor, code_target, args);
|
||||
}
|
||||
|
||||
|
||||
Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
|
||||
Node** args) {
|
||||
Node* stack_pointer_before_call = nullptr;
|
||||
|
@ -101,17 +101,8 @@ class InterpreterAssembler {
|
||||
// Load the TypeFeedbackVector for the current function.
|
||||
Node* LoadTypeFeedbackVector();
|
||||
|
||||
// Call constructor |constructor| with |arg_count| arguments (not
|
||||
// including receiver) and the first argument located at
|
||||
// |first_arg|. The |original_constructor| is the same as the
|
||||
// |constructor| for the new keyword, but differs for the super
|
||||
// keyword.
|
||||
Node* CallConstruct(Node* original_constructor, Node* constructor,
|
||||
Node* first_arg, Node* arg_count);
|
||||
|
||||
// Call JSFunction or Callable |function| with |arg_count|
|
||||
// arguments (not including receiver) and the first argument
|
||||
// located at |first_arg|.
|
||||
// Call JSFunction or Callable |function| with |arg_count| (not including
|
||||
// receiver) and the first argument located at |first_arg|.
|
||||
Node* CallJS(Node* function, Node* first_arg, Node* arg_count);
|
||||
|
||||
// Call an IC code stub.
|
||||
|
@ -724,24 +724,6 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||
Register array_limit) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- ebx : Pointer to the last argument in the args array.
|
||||
// -- array_limit : Pointer to one before the first argument in the
|
||||
// args array.
|
||||
// -----------------------------------
|
||||
Label loop_header, loop_check;
|
||||
__ jmp(&loop_check);
|
||||
__ bind(&loop_header);
|
||||
__ Push(Operand(ebx, 0));
|
||||
__ sub(ebx, Immediate(kPointerSize));
|
||||
__ bind(&loop_check);
|
||||
__ cmp(ebx, array_limit);
|
||||
__ j(greater, &loop_header, Label::kNear);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -750,7 +732,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -- edi : the target to call (can be any Object).
|
||||
// -----------------------------------
|
||||
|
||||
// Pop return address to allow tail-call after pushing arguments.
|
||||
__ Pop(edx);
|
||||
@ -762,7 +743,15 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
__ neg(ecx);
|
||||
__ add(ecx, ebx);
|
||||
|
||||
Generate_InterpreterPushArgs(masm, ecx);
|
||||
// Push the arguments.
|
||||
Label loop_header, loop_check;
|
||||
__ jmp(&loop_check);
|
||||
__ bind(&loop_header);
|
||||
__ Push(Operand(ebx, 0));
|
||||
__ sub(ebx, Immediate(kPointerSize));
|
||||
__ bind(&loop_check);
|
||||
__ cmp(ebx, ecx);
|
||||
__ j(greater, &loop_header, Label::kNear);
|
||||
|
||||
// Call the target.
|
||||
__ Push(edx); // Re-push return address.
|
||||
@ -770,53 +759,13 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : the number of arguments (not including the receiver)
|
||||
// -- edx : the original constructor
|
||||
// -- edi : the constructor
|
||||
// -- ebx : the address of the first argument to be pushed. Subsequent
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -----------------------------------
|
||||
|
||||
// Save number of arguments on the stack below where arguments are going
|
||||
// to be pushed.
|
||||
__ mov(ecx, eax);
|
||||
__ neg(ecx);
|
||||
__ mov(Operand(esp, ecx, times_pointer_size, -kPointerSize), eax);
|
||||
__ mov(eax, ecx);
|
||||
|
||||
// Pop return address to allow tail-call after pushing arguments.
|
||||
__ Pop(ecx);
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ shl(eax, kPointerSizeLog2);
|
||||
__ add(eax, ebx);
|
||||
|
||||
// Push padding for receiver.
|
||||
__ Push(Immediate(0));
|
||||
|
||||
Generate_InterpreterPushArgs(masm, eax);
|
||||
|
||||
// Restore number of arguments from slot on stack.
|
||||
__ mov(eax, Operand(esp, -kPointerSize));
|
||||
|
||||
// Re-push return address.
|
||||
__ Push(ecx);
|
||||
|
||||
// Call the constructor with unmodified eax, edi, ebi values.
|
||||
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
|
||||
CallRuntimePassFunction(masm, Runtime::kCompileLazy);
|
||||
GenerateTailCallToReturnedCode(masm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push a copy of the function.
|
||||
|
@ -401,18 +401,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
eax, // argument count (not including receiver)
|
||||
edx, // original constructor
|
||||
edi, // constructor
|
||||
ebx, // address of first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -71,7 +71,6 @@ class PlatformInterfaceDescriptor;
|
||||
V(MathRoundVariantCallFromUnoptimizedCode) \
|
||||
V(MathRoundVariantCallFromOptimizedCode) \
|
||||
V(InterpreterPushArgsAndCall) \
|
||||
V(InterpreterPushArgsAndConstruct) \
|
||||
V(InterpreterCEntry)
|
||||
|
||||
|
||||
@ -717,14 +716,6 @@ class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor {
|
||||
};
|
||||
|
||||
|
||||
class InterpreterPushArgsAndConstructDescriptor
|
||||
: public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR(InterpreterPushArgsAndConstructDescriptor,
|
||||
CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
|
||||
class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor)
|
||||
|
@ -599,16 +599,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
|
||||
}
|
||||
|
||||
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
|
||||
Register first_arg,
|
||||
size_t arg_count) {
|
||||
DCHECK(FitsInIdx8Operand(arg_count));
|
||||
Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(),
|
||||
static_cast<uint8_t>(arg_count));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
|
||||
Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
|
||||
DCHECK(FitsInIdx16Operand(function_id));
|
||||
|
@ -100,19 +100,13 @@ class BytecodeArrayBuilder {
|
||||
BytecodeArrayBuilder& Call(Register callable, Register receiver,
|
||||
size_t arg_count);
|
||||
|
||||
// Call the new operator. The |constructor| register is followed by
|
||||
// |arg_count| consecutive registers containing arguments to be
|
||||
// applied to the constructor.
|
||||
BytecodeArrayBuilder& New(Register constructor, Register first_arg,
|
||||
size_t arg_count);
|
||||
|
||||
// Call the runtime function with |function_id|. The first argument should be
|
||||
// in |first_arg| and all subsequent arguments should be in registers
|
||||
// <first_arg + 1> to <first_arg + 1 + arg_count>.
|
||||
BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
|
||||
Register first_arg, size_t arg_count);
|
||||
|
||||
// Operators (register holds the lhs value, accumulator holds the rhs value).
|
||||
// Operators (register == lhs, accumulator = rhs).
|
||||
BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg,
|
||||
Strength strength);
|
||||
|
||||
|
@ -934,25 +934,6 @@ void BytecodeGenerator::VisitProperty(Property* expr) {
|
||||
}
|
||||
|
||||
|
||||
Register BytecodeGenerator::VisitArguments(
|
||||
ZoneList<Expression*>* args, TemporaryRegisterScope* register_scope) {
|
||||
// Visit arguments and place in a contiguous block of temporary registers.
|
||||
// Return the first temporary register corresponding to the first argument.
|
||||
DCHECK_GT(args->length(), 0);
|
||||
Register first_arg = register_scope->NewRegister();
|
||||
Visit(args->at(0));
|
||||
builder()->StoreAccumulatorInRegister(first_arg);
|
||||
for (int i = 1; i < static_cast<int>(args->length()); i++) {
|
||||
Register ith_arg = register_scope->NewRegister();
|
||||
Visit(args->at(i));
|
||||
builder()->StoreAccumulatorInRegister(ith_arg);
|
||||
DCHECK(ith_arg.index() - i == first_arg.index());
|
||||
}
|
||||
|
||||
return first_arg;
|
||||
}
|
||||
|
||||
|
||||
void BytecodeGenerator::VisitCall(Call* expr) {
|
||||
Expression* callee_expr = expr->expression();
|
||||
Call::CallType call_type = expr->GetCallType(isolate());
|
||||
@ -1000,9 +981,11 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
||||
// Evaluate all arguments to the function call and store in sequential
|
||||
// registers.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
if (args->length() > 0) {
|
||||
Register first_arg = VisitArguments(args, &temporary_register_scope);
|
||||
CHECK_EQ(first_arg.index(), receiver.index() + 1);
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Visit(args->at(i));
|
||||
Register arg = temporary_register_scope.NewRegister();
|
||||
DCHECK(arg.index() - i == receiver.index() + 1);
|
||||
builder()->StoreAccumulatorInRegister(arg);
|
||||
}
|
||||
|
||||
// TODO(rmcilroy): Deal with possible direct eval here?
|
||||
@ -1011,22 +994,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
||||
}
|
||||
|
||||
|
||||
void BytecodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
TemporaryRegisterScope temporary_register_scope(builder());
|
||||
Register constructor = temporary_register_scope.NewRegister();
|
||||
Visit(expr->expression());
|
||||
builder()->StoreAccumulatorInRegister(constructor);
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
if (args->length() > 0) {
|
||||
Register first_arg = VisitArguments(args, &temporary_register_scope);
|
||||
builder()->New(constructor, first_arg, args->length());
|
||||
} else {
|
||||
// The second argument here will be ignored as there are zero
|
||||
// arguments. Using the constructor register avoids avoid
|
||||
// allocating a temporary just to fill the operands.
|
||||
builder()->New(constructor, constructor, 0);
|
||||
}
|
||||
}
|
||||
void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); }
|
||||
|
||||
|
||||
void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
@ -1035,21 +1003,22 @@ void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
// Evaluate all arguments to the runtime call.
|
||||
TemporaryRegisterScope temporary_register_scope(&builder_);
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
TemporaryRegisterScope temporary_register_scope(builder());
|
||||
// Ensure we always have a valid first_arg register even if there are no
|
||||
// arguments to pass.
|
||||
Register first_arg = temporary_register_scope.NewRegister();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Register arg =
|
||||
(i == 0) ? first_arg : temporary_register_scope.NewRegister();
|
||||
Visit(args->at(i));
|
||||
DCHECK_EQ(arg.index() - i, first_arg.index());
|
||||
builder()->StoreAccumulatorInRegister(arg);
|
||||
}
|
||||
|
||||
// TODO(rmcilroy): support multiple return values.
|
||||
DCHECK_LE(expr->function()->result_size, 1);
|
||||
Runtime::FunctionId function_id = expr->function()->function_id;
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
Register first_arg;
|
||||
if (args->length() > 0) {
|
||||
first_arg = VisitArguments(args, &temporary_register_scope);
|
||||
} else {
|
||||
// Allocation here is just to fullfil the requirement that there
|
||||
// is a register operand for the start of the arguments though
|
||||
// there are zero when this is generated.
|
||||
first_arg = temporary_register_scope.NewRegister();
|
||||
}
|
||||
builder()->CallRuntime(function_id, first_arg, args->length());
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,6 @@ class BytecodeGenerator : public AstVisitor {
|
||||
|
||||
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
|
||||
|
||||
Register VisitArguments(ZoneList<Expression*>* arguments,
|
||||
TemporaryRegisterScope* caller_scope);
|
||||
void VisitArithmeticExpression(BinaryOperation* binop);
|
||||
void VisitCommaExpression(BinaryOperation* binop);
|
||||
void VisitLogicalOrExpression(BinaryOperation* binop);
|
||||
|
@ -89,14 +89,11 @@ namespace interpreter {
|
||||
V(LogicalNot, OperandType::kNone) \
|
||||
V(TypeOf, OperandType::kNone) \
|
||||
\
|
||||
/* Call operations */ \
|
||||
/* Call operations. */ \
|
||||
V(Call, OperandType::kReg8, OperandType::kReg8, OperandType::kCount8) \
|
||||
V(CallRuntime, OperandType::kIdx16, OperandType::kReg8, \
|
||||
OperandType::kCount8) \
|
||||
\
|
||||
/* New operator */ \
|
||||
V(New, OperandType::kReg8, OperandType::kReg8, OperandType::kCount8) \
|
||||
\
|
||||
/* Test Operators */ \
|
||||
V(TestEqual, OperandType::kReg8) \
|
||||
V(TestNotEqual, OperandType::kReg8) \
|
||||
|
@ -537,25 +537,6 @@ void Interpreter::DoCallRuntime(compiler::InterpreterAssembler* assembler) {
|
||||
}
|
||||
|
||||
|
||||
// New <constructor> <arg_count>
|
||||
//
|
||||
// Call operator new with |constructor| and the first argument in
|
||||
// register |first_arg| and |arg_count| arguments in subsequent
|
||||
//
|
||||
void Interpreter::DoNew(compiler::InterpreterAssembler* assembler) {
|
||||
Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
|
||||
Node* constructor_index = __ BytecodeOperandReg8(0);
|
||||
Node* constructor = __ LoadRegister(constructor_index);
|
||||
Node* first_arg_reg = __ BytecodeOperandReg8(1);
|
||||
Node* first_arg = __ RegisterLocation(first_arg_reg);
|
||||
Node* args_count = __ BytecodeOperandCount8(2);
|
||||
Node* result =
|
||||
__ CallConstruct(constructor, constructor, first_arg, args_count);
|
||||
__ SetAccumulator(result);
|
||||
__ Dispatch();
|
||||
}
|
||||
|
||||
|
||||
// TestEqual <src>
|
||||
//
|
||||
// Test if the value in the <src> register equals the accumulator.
|
||||
|
@ -986,7 +986,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -- a1 : the target to call (can be any Object).
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ Addu(a3, a0, Operand(1)); // Add one for receiver.
|
||||
@ -1008,34 +1007,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : argument count (not including receiver)
|
||||
// -- a3 : original constructor
|
||||
// -- a1 : constructor to call
|
||||
// -- a2 : address of the first argument
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ sll(t0, a0, kPointerSizeLog2);
|
||||
__ Subu(t0, a2, Operand(t0));
|
||||
|
||||
// Push the arguments.
|
||||
Label loop_header, loop_check;
|
||||
__ Branch(&loop_check);
|
||||
__ bind(&loop_header);
|
||||
__ lw(t1, MemOperand(a2));
|
||||
__ Addu(a2, a2, Operand(-kPointerSize));
|
||||
__ push(t1);
|
||||
__ bind(&loop_check);
|
||||
__ Branch(&loop_header, gt, a2, Operand(t0));
|
||||
|
||||
// Call the constructor with a0, a1, and a3 unmodified.
|
||||
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
|
||||
CallRuntimePassFunction(masm, Runtime::kCompileLazy);
|
||||
GenerateTailCallToReturnedCode(masm);
|
||||
|
@ -395,18 +395,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a0, // argument count (not including receiver)
|
||||
a3, // original constructor
|
||||
a1, // constructor to call
|
||||
a2 // address of the first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -982,7 +982,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -- a1 : the target to call (can be any Object).
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ Daddu(a3, a0, Operand(1)); // Add one for receiver.
|
||||
@ -1004,34 +1003,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : argument count (not including receiver)
|
||||
// -- a3 : original constructor
|
||||
// -- a1 : constructor to call
|
||||
// -- a2 : address of the first argument
|
||||
// -----------------------------------
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ dsll(t0, a0, kPointerSizeLog2);
|
||||
__ Dsubu(t0, a2, Operand(t0));
|
||||
|
||||
// Push the arguments.
|
||||
Label loop_header, loop_check;
|
||||
__ Branch(&loop_check);
|
||||
__ bind(&loop_header);
|
||||
__ ld(t1, MemOperand(a2));
|
||||
__ Daddu(a2, a2, Operand(-kPointerSize));
|
||||
__ push(t1);
|
||||
__ bind(&loop_check);
|
||||
__ Branch(&loop_header, gt, a2, Operand(t0));
|
||||
|
||||
// Call the constructor with a0, a1, and a3 unmodified.
|
||||
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
|
||||
CallRuntimePassFunction(masm, Runtime::kCompileLazy);
|
||||
GenerateTailCallToReturnedCode(masm);
|
||||
|
@ -395,18 +395,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a0, // argument count (not including receiver)
|
||||
a3, // original constructor
|
||||
a1, // constructor to call
|
||||
a2 // address of the first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -983,7 +983,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -- r4 : the target to call (can be any Object).
|
||||
// -----------------------------------
|
||||
|
||||
// Calculate number of arguments (add one for receiver).
|
||||
__ addi(r6, r3, Operand(1));
|
||||
@ -1002,32 +1001,6 @@ void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : argument count (not including receiver)
|
||||
// -- r6 : original constructor
|
||||
// -- r4 : constructor to call
|
||||
// -- r5 : address of the first argument
|
||||
// -----------------------------------
|
||||
|
||||
// Calculate number of arguments (add one for receiver).
|
||||
__ mr(r11, r3);
|
||||
|
||||
// Push the arguments.
|
||||
Label loop;
|
||||
__ addi(r5, r5, Operand(kPointerSize)); // Bias up for LoadPU
|
||||
__ mtctr(r11);
|
||||
__ bind(&loop);
|
||||
__ LoadPU(r11, MemOperand(r5, -kPointerSize));
|
||||
__ push(r11);
|
||||
__ bdnz(&loop);
|
||||
|
||||
// Call the constructor with r3, r4, and r6 unmodified.
|
||||
__ Jump(masm->isolate()->builtins()->Constuct(), RelocInfo::CONSTRUCT_CALL);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
|
||||
CallRuntimePassFunction(masm, Runtime::kCompileLazy);
|
||||
GenerateTailCallToReturnedCode(masm);
|
||||
|
@ -394,18 +394,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r3, // argument count (not including receiver)
|
||||
r6, // original constructor
|
||||
r4, // constructor to call
|
||||
r5 // address of the first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -785,21 +785,21 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||
bool push_receiver) {
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : the number of arguments (not including the receiver)
|
||||
// -- rbx : the address of the first argument to be pushed. Subsequent
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -----------------------------------
|
||||
// -- rdi : the target to call (can be any Object).
|
||||
|
||||
// Pop return address to allow tail-call after pushing arguments.
|
||||
__ Pop(rdx);
|
||||
|
||||
// Find the address of the last argument.
|
||||
__ movp(rcx, rax);
|
||||
if (push_receiver) {
|
||||
__ addp(rcx, Immediate(1)); // Add one for receiver.
|
||||
}
|
||||
|
||||
__ addp(rcx, Immediate(1)); // Add one for receiver.
|
||||
__ shlp(rcx, Immediate(kPointerSizeLog2));
|
||||
__ negp(rcx);
|
||||
__ addp(rcx, rbx);
|
||||
@ -813,58 +813,13 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||
__ bind(&loop_check);
|
||||
__ cmpp(rbx, rcx);
|
||||
__ j(greater, &loop_header, Label::kNear);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : the number of arguments (not including the receiver)
|
||||
// -- rbx : the address of the first argument to be pushed. Subsequent
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -- rdi : the target to call (can be any Object).
|
||||
// -----------------------------------
|
||||
|
||||
// Pop return address to allow tail-call after pushing arguments.
|
||||
__ PopReturnAddressTo(kScratchRegister);
|
||||
|
||||
Generate_InterpreterPushArgs(masm, true);
|
||||
|
||||
// Call the target.
|
||||
__ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
|
||||
__ Push(rdx); // Re-push return address.
|
||||
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : the number of arguments (not including the receiver)
|
||||
// -- rdx : the original constructor (either the same as the constructor or
|
||||
// the JSFunction on which new was invoked initially)
|
||||
// -- rdi : the constructor to call (can be any Object)
|
||||
// -- rbx : the address of the first argument to be pushed. Subsequent
|
||||
// arguments should be consecutive above this, in the same order as
|
||||
// they are to be pushed onto the stack.
|
||||
// -----------------------------------
|
||||
|
||||
// Pop return address to allow tail-call after pushing arguments.
|
||||
__ PopReturnAddressTo(kScratchRegister);
|
||||
|
||||
// Push slot for the receiver to be constructed.
|
||||
__ Push(Immediate(0));
|
||||
|
||||
Generate_InterpreterPushArgs(masm, false);
|
||||
|
||||
// Push return address in preparation for the tail-call.
|
||||
__ PushReturnAddressFrom(kScratchRegister);
|
||||
|
||||
// Call the constructor (rax, rdx, rdi passed on).
|
||||
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
|
||||
CallRuntimePassFunction(masm, Runtime::kCompileLazy);
|
||||
GenerateTailCallToReturnedCode(masm);
|
||||
|
@ -395,18 +395,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rax, // argument count (not including receiver)
|
||||
rdx, // original constructor
|
||||
rdi, // constructor
|
||||
rbx, // address of first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -1015,14 +1015,14 @@ TEST(PropertyCall) {
|
||||
B(LoadICSloppy), R(1), U8(vector->GetIndex(slot2)), //
|
||||
B(Star), R(0), //
|
||||
B(Ldar), R(helper.kLastParamIndex), //
|
||||
B(Star), R(3), //
|
||||
B(Star), R(2), //
|
||||
B(Ldar), R(helper.kLastParamIndex), //
|
||||
B(Add), R(3), //
|
||||
B(Add), R(2), //
|
||||
B(Star), R(2), //
|
||||
B(Ldar), R(helper.kLastParamIndex), //
|
||||
B(Star), R(3), //
|
||||
B(Call), R(0), R(1), U8(2), //
|
||||
B(Return), //
|
||||
B(Return) //
|
||||
},
|
||||
1,
|
||||
{"func"}}};
|
||||
@ -2670,72 +2670,6 @@ TEST(TryFinally) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(CallNew) {
|
||||
InitializedHandleScope handle_scope;
|
||||
BytecodeGeneratorHelper helper;
|
||||
|
||||
ExpectedSnippet<InstanceType> snippets[] = {
|
||||
{"function bar() { this.value = 0; }\n"
|
||||
"function f() { return new bar(); }\n"
|
||||
"f()",
|
||||
kPointerSize,
|
||||
1,
|
||||
9,
|
||||
{
|
||||
B(LdaGlobal), _, //
|
||||
B(Star), R(0), //
|
||||
B(New), R(0), R(0), U8(0), //
|
||||
B(Return), //
|
||||
},
|
||||
0},
|
||||
{"function bar(x) { this.value = 18; this.x = x;}\n"
|
||||
"function f() { return new bar(3); }\n"
|
||||
"f()",
|
||||
2 * kPointerSize,
|
||||
1,
|
||||
13,
|
||||
{
|
||||
B(LdaGlobal), _, //
|
||||
B(Star), R(0), //
|
||||
B(LdaSmi8), U8(3), //
|
||||
B(Star), R(1), //
|
||||
B(New), R(0), R(1), U8(1), //
|
||||
B(Return), //
|
||||
},
|
||||
0},
|
||||
{"function bar(w, x, y, z) {\n"
|
||||
" this.value = 18;\n"
|
||||
" this.x = x;\n"
|
||||
" this.y = y;\n"
|
||||
" this.z = z;\n"
|
||||
"}\n"
|
||||
"function f() { return new bar(3, 4, 5); }\n"
|
||||
"f()",
|
||||
4 * kPointerSize,
|
||||
1,
|
||||
21,
|
||||
{
|
||||
B(LdaGlobal), _, //
|
||||
B(Star), R(0), //
|
||||
B(LdaSmi8), U8(3), //
|
||||
B(Star), R(1), //
|
||||
B(LdaSmi8), U8(4), //
|
||||
B(Star), R(2), //
|
||||
B(LdaSmi8), U8(5), //
|
||||
B(Star), R(3), //
|
||||
B(New), R(0), R(1), U8(3), //
|
||||
B(Return), //
|
||||
},
|
||||
0}};
|
||||
|
||||
for (size_t i = 0; i < arraysize(snippets); i++) {
|
||||
Handle<BytecodeArray> bytecode_array =
|
||||
helper.MakeBytecode(snippets[i].code_snippet, "f");
|
||||
CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace interpreter
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -1728,65 +1728,6 @@ TEST(InterpreterObjectLiterals) {
|
||||
}
|
||||
|
||||
|
||||
TEST(InterpreterConstruct) {
|
||||
HandleAndZoneScope handles;
|
||||
|
||||
std::string source(
|
||||
"function counter() { this.count = 0; }\n"
|
||||
"function " +
|
||||
InterpreterTester::function_name() +
|
||||
"() {\n"
|
||||
" var c = new counter();\n"
|
||||
" return c.count;\n"
|
||||
"}");
|
||||
InterpreterTester tester(handles.main_isolate(), source.c_str());
|
||||
auto callable = tester.GetCallable<>();
|
||||
|
||||
Handle<Object> return_val = callable().ToHandleChecked();
|
||||
CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0));
|
||||
}
|
||||
|
||||
|
||||
TEST(InterpreterConstructWithArgument) {
|
||||
HandleAndZoneScope handles;
|
||||
|
||||
std::string source(
|
||||
"function counter(arg0) { this.count = 17; this.x = arg0; }\n"
|
||||
"function " +
|
||||
InterpreterTester::function_name() +
|
||||
"() {\n"
|
||||
" var c = new counter(3);\n"
|
||||
" return c.x;\n"
|
||||
"}");
|
||||
InterpreterTester tester(handles.main_isolate(), source.c_str());
|
||||
auto callable = tester.GetCallable<>();
|
||||
|
||||
Handle<Object> return_val = callable().ToHandleChecked();
|
||||
CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3));
|
||||
}
|
||||
|
||||
|
||||
TEST(InterpreterConstructWithArguments) {
|
||||
HandleAndZoneScope handles;
|
||||
|
||||
std::string source(
|
||||
"function counter(arg0, arg1) {\n"
|
||||
" this.count = 7; this.x = arg0; this.y = arg1;\n"
|
||||
"}\n"
|
||||
"function " +
|
||||
InterpreterTester::function_name() +
|
||||
"() {\n"
|
||||
" var c = new counter(3, 5);\n"
|
||||
" return c.count + c.x + c.y;\n"
|
||||
"}");
|
||||
InterpreterTester tester(handles.main_isolate(), source.c_str());
|
||||
auto callable = tester.GetCallable<>();
|
||||
|
||||
Handle<Object> return_val = callable().ToHandleChecked();
|
||||
CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(15));
|
||||
}
|
||||
|
||||
|
||||
TEST(InterpreterComma) {
|
||||
HandleAndZoneScope handles;
|
||||
i::Isolate* isolate = handles.main_isolate();
|
||||
|
@ -90,9 +90,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
||||
// Emit unary operator invocations.
|
||||
builder.LogicalNot().TypeOf();
|
||||
|
||||
// Emit new.
|
||||
builder.New(reg, reg, 0);
|
||||
|
||||
// Emit test operator invocations.
|
||||
builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
|
||||
.CompareOperation(Token::Value::NE, reg, Strength::WEAK)
|
||||
|
Loading…
Reference in New Issue
Block a user