blob: eb883427bbabb5c08d20e9405680e54b23784ac0 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/interpreter/interpreter.h"
6
Ben Murdoch097c5b22016-05-18 11:27:45 +01007#include "src/ast/prettyprinter.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/code-factory.h"
9#include "src/compiler.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/factory.h"
11#include "src/interpreter/bytecode-generator.h"
12#include "src/interpreter/bytecodes.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010013#include "src/interpreter/interpreter-assembler.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014#include "src/zone.h"
15
16namespace v8 {
17namespace internal {
18namespace interpreter {
19
20using compiler::Node;
21
22#define __ assembler->
23
Ben Murdoch097c5b22016-05-18 11:27:45 +010024Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
25 memset(&dispatch_table_, 0, sizeof(dispatch_table_));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026}
27
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028void Interpreter::Initialize() {
29 DCHECK(FLAG_ignition);
Ben Murdoch097c5b22016-05-18 11:27:45 +010030 if (IsDispatchTableInitialized()) return;
31 Zone zone;
32 HandleScope scope(isolate_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000033
Ben Murdoch097c5b22016-05-18 11:27:45 +010034#define GENERATE_CODE(Name, ...) \
35 { \
36 InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name); \
37 Do##Name(&assembler); \
38 Handle<Code> code = assembler.GenerateCode(); \
39 TraceCodegen(code, #Name); \
40 dispatch_table_[Bytecodes::ToByte(Bytecode::k##Name)] = *code; \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000041 }
Ben Murdoch097c5b22016-05-18 11:27:45 +010042 BYTECODE_LIST(GENERATE_CODE)
43#undef GENERATE_CODE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044}
45
Ben Murdoch097c5b22016-05-18 11:27:45 +010046Code* Interpreter::GetBytecodeHandler(Bytecode bytecode) {
47 DCHECK(IsDispatchTableInitialized());
48 return dispatch_table_[Bytecodes::ToByte(bytecode)];
49}
50
51void Interpreter::IterateDispatchTable(ObjectVisitor* v) {
52 v->VisitPointers(
53 reinterpret_cast<Object**>(&dispatch_table_[0]),
54 reinterpret_cast<Object**>(&dispatch_table_[0] + kDispatchTableSize));
55}
56
57// static
58int Interpreter::InterruptBudget() {
59 // TODO(ignition): Tune code size multiplier.
60 const int kCodeSizeMultiplier = 32;
61 return FLAG_interrupt_budget * kCodeSizeMultiplier;
62}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000063
64bool Interpreter::MakeBytecode(CompilationInfo* info) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010065 if (FLAG_print_bytecode || FLAG_print_source || FLAG_print_ast) {
66 OFStream os(stdout);
67 base::SmartArrayPointer<char> name = info->GetDebugName();
68 os << "[generating bytecode for function: " << info->GetDebugName().get()
69 << "]" << std::endl
70 << std::flush;
71 }
72
73#ifdef DEBUG
74 if (info->parse_info() && FLAG_print_source) {
75 OFStream os(stdout);
76 os << "--- Source from AST ---" << std::endl
77 << PrettyPrinter(info->isolate()).PrintProgram(info->literal())
78 << std::endl
79 << std::flush;
80 }
81
82 if (info->parse_info() && FLAG_print_ast) {
83 OFStream os(stdout);
84 os << "--- AST ---" << std::endl
85 << AstPrinter(info->isolate()).PrintProgram(info->literal()) << std::endl
86 << std::flush;
87 }
88#endif // DEBUG
89
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000090 BytecodeGenerator generator(info->isolate(), info->zone());
91 info->EnsureFeedbackVector();
92 Handle<BytecodeArray> bytecodes = generator.MakeBytecode(info);
93 if (FLAG_print_bytecode) {
94 OFStream os(stdout);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000095 bytecodes->Print(os);
96 os << std::flush;
97 }
98
99 info->SetBytecodeArray(bytecodes);
100 info->SetCode(info->isolate()->builtins()->InterpreterEntryTrampoline());
101 return true;
102}
103
Ben Murdoch097c5b22016-05-18 11:27:45 +0100104bool Interpreter::IsDispatchTableInitialized() {
105 if (FLAG_trace_ignition) {
106 // Regenerate table to add bytecode tracing operations.
107 return false;
108 }
109 return dispatch_table_[0] != nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110}
111
Ben Murdoch097c5b22016-05-18 11:27:45 +0100112void Interpreter::TraceCodegen(Handle<Code> code, const char* name) {
113#ifdef ENABLE_DISASSEMBLER
114 if (FLAG_trace_ignition_codegen) {
115 OFStream os(stdout);
116 code->Disassemble(name, os);
117 os << std::flush;
118 }
119#endif // ENABLE_DISASSEMBLER
120}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000121
122// LdaZero
123//
124// Load literal '0' into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100125void Interpreter::DoLdaZero(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000126 Node* zero_value = __ NumberConstant(0.0);
127 __ SetAccumulator(zero_value);
128 __ Dispatch();
129}
130
131
132// LdaSmi8 <imm8>
133//
134// Load an 8-bit integer literal into the accumulator as a Smi.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100135void Interpreter::DoLdaSmi8(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 Node* raw_int = __ BytecodeOperandImm(0);
137 Node* smi_int = __ SmiTag(raw_int);
138 __ SetAccumulator(smi_int);
139 __ Dispatch();
140}
141
Ben Murdoch097c5b22016-05-18 11:27:45 +0100142void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000143 Node* index = __ BytecodeOperandIdx(0);
144 Node* constant = __ LoadConstantPoolEntry(index);
145 __ SetAccumulator(constant);
146 __ Dispatch();
147}
148
149
150// LdaConstant <idx>
151//
152// Load constant literal at |idx| in the constant pool into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100153void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 DoLoadConstant(assembler);
155}
156
157
158// LdaConstantWide <idx>
159//
160// Load constant literal at |idx| in the constant pool into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100161void Interpreter::DoLdaConstantWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000162 DoLoadConstant(assembler);
163}
164
165
166// LdaUndefined
167//
168// Load Undefined into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100169void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000170 Node* undefined_value =
171 __ HeapConstant(isolate_->factory()->undefined_value());
172 __ SetAccumulator(undefined_value);
173 __ Dispatch();
174}
175
176
177// LdaNull
178//
179// Load Null into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100180void Interpreter::DoLdaNull(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181 Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
182 __ SetAccumulator(null_value);
183 __ Dispatch();
184}
185
186
187// LdaTheHole
188//
189// Load TheHole into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100190void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
192 __ SetAccumulator(the_hole_value);
193 __ Dispatch();
194}
195
196
197// LdaTrue
198//
199// Load True into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100200void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 Node* true_value = __ HeapConstant(isolate_->factory()->true_value());
202 __ SetAccumulator(true_value);
203 __ Dispatch();
204}
205
206
207// LdaFalse
208//
209// Load False into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100210void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211 Node* false_value = __ HeapConstant(isolate_->factory()->false_value());
212 __ SetAccumulator(false_value);
213 __ Dispatch();
214}
215
216
217// Ldar <src>
218//
219// Load accumulator with value from register <src>.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100220void Interpreter::DoLdar(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221 Node* reg_index = __ BytecodeOperandReg(0);
222 Node* value = __ LoadRegister(reg_index);
223 __ SetAccumulator(value);
224 __ Dispatch();
225}
226
227
228// Star <dst>
229//
230// Store accumulator to register <dst>.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100231void Interpreter::DoStar(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000232 Node* reg_index = __ BytecodeOperandReg(0);
233 Node* accumulator = __ GetAccumulator();
234 __ StoreRegister(accumulator, reg_index);
235 __ Dispatch();
236}
237
238
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000239// Mov <src> <dst>
240//
241// Stores the value of register <src> to register <dst>.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100242void Interpreter::DoMov(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243 Node* src_index = __ BytecodeOperandReg(0);
244 Node* src_value = __ LoadRegister(src_index);
245 Node* dst_index = __ BytecodeOperandReg(1);
246 __ StoreRegister(src_value, dst_index);
247 __ Dispatch();
248}
249
250
Ben Murdoch097c5b22016-05-18 11:27:45 +0100251// MovWide <src> <dst>
252//
253// Stores the value of register <src> to register <dst>.
254void Interpreter::DoMovWide(InterpreterAssembler* assembler) {
255 DoMov(assembler);
256}
257
258void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000259 // Get the global object.
260 Node* context = __ GetContext();
261 Node* native_context =
262 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
263 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX);
264
265 // Load the global via the LoadIC.
266 Node* code_target = __ HeapConstant(ic.code());
267 Node* constant_index = __ BytecodeOperandIdx(0);
268 Node* name = __ LoadConstantPoolEntry(constant_index);
269 Node* raw_slot = __ BytecodeOperandIdx(1);
270 Node* smi_slot = __ SmiTag(raw_slot);
271 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100272 Node* result = __ CallStub(ic.descriptor(), code_target, context, global,
273 name, smi_slot, type_feedback_vector);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000274 __ SetAccumulator(result);
275 __ Dispatch();
276}
277
Ben Murdoch097c5b22016-05-18 11:27:45 +0100278// LdaGlobal <name_index> <slot>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279//
280// Load the global with name in constant pool entry <name_index> into the
Ben Murdoch097c5b22016-05-18 11:27:45 +0100281// accumulator using FeedBackVector slot <slot> outside of a typeof.
282void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000283 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100284 UNINITIALIZED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 DoLoadGlobal(ic, assembler);
286}
287
Ben Murdoch097c5b22016-05-18 11:27:45 +0100288// LdaGlobalInsideTypeof <name_index> <slot>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000289//
290// Load the global with name in constant pool entry <name_index> into the
Ben Murdoch097c5b22016-05-18 11:27:45 +0100291// accumulator using FeedBackVector slot <slot> inside of a typeof.
292void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) {
293 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
294 UNINITIALIZED);
295 DoLoadGlobal(ic, assembler);
296}
297
298// LdaGlobalWide <name_index> <slot>
299//
300// Load the global with name in constant pool entry <name_index> into the
301// accumulator using FeedBackVector slot <slot> outside of a typeof.
302void Interpreter::DoLdaGlobalWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000303 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100304 UNINITIALIZED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305 DoLoadGlobal(ic, assembler);
306}
307
Ben Murdoch097c5b22016-05-18 11:27:45 +0100308// LdaGlobalInsideTypeofWide <name_index> <slot>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000309//
310// Load the global with name in constant pool entry <name_index> into the
Ben Murdoch097c5b22016-05-18 11:27:45 +0100311// accumulator using FeedBackVector slot <slot> inside of a typeof.
312void Interpreter::DoLdaGlobalInsideTypeofWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000313 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100314 UNINITIALIZED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000315 DoLoadGlobal(ic, assembler);
316}
317
318
Ben Murdoch097c5b22016-05-18 11:27:45 +0100319void Interpreter::DoStoreGlobal(Callable ic, InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000320 // Get the global object.
321 Node* context = __ GetContext();
322 Node* native_context =
323 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
324 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX);
325
326 // Store the global via the StoreIC.
327 Node* code_target = __ HeapConstant(ic.code());
328 Node* constant_index = __ BytecodeOperandIdx(0);
329 Node* name = __ LoadConstantPoolEntry(constant_index);
330 Node* value = __ GetAccumulator();
331 Node* raw_slot = __ BytecodeOperandIdx(1);
332 Node* smi_slot = __ SmiTag(raw_slot);
333 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100334 __ CallStub(ic.descriptor(), code_target, context, global, name, value,
335 smi_slot, type_feedback_vector);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000336
337 __ Dispatch();
338}
339
340
341// StaGlobalSloppy <name_index> <slot>
342//
343// Store the value in the accumulator into the global with name in constant pool
344// entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100345void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000346 Callable ic =
347 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
348 DoStoreGlobal(ic, assembler);
349}
350
351
352// StaGlobalStrict <name_index> <slot>
353//
354// Store the value in the accumulator into the global with name in constant pool
355// entry <name_index> using FeedBackVector slot <slot> in strict mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100356void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000357 Callable ic =
358 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
359 DoStoreGlobal(ic, assembler);
360}
361
362
363// StaGlobalSloppyWide <name_index> <slot>
364//
365// Store the value in the accumulator into the global with name in constant pool
366// entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100367void Interpreter::DoStaGlobalSloppyWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368 Callable ic =
369 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
370 DoStoreGlobal(ic, assembler);
371}
372
373
374// StaGlobalStrictWide <name_index> <slot>
375//
376// Store the value in the accumulator into the global with name in constant pool
377// entry <name_index> using FeedBackVector slot <slot> in strict mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100378void Interpreter::DoStaGlobalStrictWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 Callable ic =
380 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
381 DoStoreGlobal(ic, assembler);
382}
383
384
385// LdaContextSlot <context> <slot_index>
386//
387// Load the object in |slot_index| of |context| into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100388void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 Node* reg_index = __ BytecodeOperandReg(0);
390 Node* context = __ LoadRegister(reg_index);
391 Node* slot_index = __ BytecodeOperandIdx(1);
392 Node* result = __ LoadContextSlot(context, slot_index);
393 __ SetAccumulator(result);
394 __ Dispatch();
395}
396
397
398// LdaContextSlotWide <context> <slot_index>
399//
400// Load the object in |slot_index| of |context| into the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100401void Interpreter::DoLdaContextSlotWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000402 DoLdaContextSlot(assembler);
403}
404
405
406// StaContextSlot <context> <slot_index>
407//
408// Stores the object in the accumulator into |slot_index| of |context|.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100409void Interpreter::DoStaContextSlot(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000410 Node* value = __ GetAccumulator();
411 Node* reg_index = __ BytecodeOperandReg(0);
412 Node* context = __ LoadRegister(reg_index);
413 Node* slot_index = __ BytecodeOperandIdx(1);
414 __ StoreContextSlot(context, slot_index, value);
415 __ Dispatch();
416}
417
418
419// StaContextSlot <context> <slot_index>
420//
421// Stores the object in the accumulator into |slot_index| of |context|.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100422void Interpreter::DoStaContextSlotWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000423 DoStaContextSlot(assembler);
424}
425
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000426void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100427 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000428 Node* index = __ BytecodeOperandIdx(0);
429 Node* name = __ LoadConstantPoolEntry(index);
430 Node* context = __ GetContext();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100431 Node* result = __ CallRuntime(function_id, context, name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000432 __ SetAccumulator(result);
433 __ Dispatch();
434}
435
436
437// LdaLookupSlot <name_index>
438//
439// Lookup the object with the name in constant pool entry |name_index|
440// dynamically.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100441void Interpreter::DoLdaLookupSlot(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000442 DoLoadLookupSlot(Runtime::kLoadLookupSlot, assembler);
443}
444
445
446// LdaLookupSlotInsideTypeof <name_index>
447//
448// Lookup the object with the name in constant pool entry |name_index|
449// dynamically without causing a NoReferenceError.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100450void Interpreter::DoLdaLookupSlotInsideTypeof(InterpreterAssembler* assembler) {
451 DoLoadLookupSlot(Runtime::kLoadLookupSlotInsideTypeof, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452}
453
454
455// LdaLookupSlotWide <name_index>
456//
457// Lookup the object with the name in constant pool entry |name_index|
458// dynamically.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100459void Interpreter::DoLdaLookupSlotWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460 DoLdaLookupSlot(assembler);
461}
462
463
464// LdaLookupSlotInsideTypeofWide <name_index>
465//
466// Lookup the object with the name in constant pool entry |name_index|
467// dynamically without causing a NoReferenceError.
468void Interpreter::DoLdaLookupSlotInsideTypeofWide(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100469 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000470 DoLdaLookupSlotInsideTypeof(assembler);
471}
472
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000473void Interpreter::DoStoreLookupSlot(LanguageMode language_mode,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100474 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475 Node* value = __ GetAccumulator();
476 Node* index = __ BytecodeOperandIdx(0);
477 Node* name = __ LoadConstantPoolEntry(index);
478 Node* context = __ GetContext();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100479 Node* result = __ CallRuntime(is_strict(language_mode)
480 ? Runtime::kStoreLookupSlot_Strict
481 : Runtime::kStoreLookupSlot_Sloppy,
482 context, name, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000483 __ SetAccumulator(result);
484 __ Dispatch();
485}
486
487
488// StaLookupSlotSloppy <name_index>
489//
490// Store the object in accumulator to the object with the name in constant
491// pool entry |name_index| in sloppy mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100492void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000493 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler);
494}
495
496
497// StaLookupSlotStrict <name_index>
498//
499// Store the object in accumulator to the object with the name in constant
500// pool entry |name_index| in strict mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100501void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000502 DoStoreLookupSlot(LanguageMode::STRICT, assembler);
503}
504
505
506// StaLookupSlotSloppyWide <name_index>
507//
508// Store the object in accumulator to the object with the name in constant
509// pool entry |name_index| in sloppy mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100510void Interpreter::DoStaLookupSlotSloppyWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000511 DoStaLookupSlotSloppy(assembler);
512}
513
514
515// StaLookupSlotStrictWide <name_index>
516//
517// Store the object in accumulator to the object with the name in constant
518// pool entry |name_index| in strict mode.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100519void Interpreter::DoStaLookupSlotStrictWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000520 DoStaLookupSlotStrict(assembler);
521}
522
Ben Murdoch097c5b22016-05-18 11:27:45 +0100523void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000524 Node* code_target = __ HeapConstant(ic.code());
525 Node* register_index = __ BytecodeOperandReg(0);
526 Node* object = __ LoadRegister(register_index);
527 Node* constant_index = __ BytecodeOperandIdx(1);
528 Node* name = __ LoadConstantPoolEntry(constant_index);
529 Node* raw_slot = __ BytecodeOperandIdx(2);
530 Node* smi_slot = __ SmiTag(raw_slot);
531 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100532 Node* context = __ GetContext();
533 Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
534 name, smi_slot, type_feedback_vector);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000535 __ SetAccumulator(result);
536 __ Dispatch();
537}
538
Ben Murdoch097c5b22016-05-18 11:27:45 +0100539// LoadIC <object> <name_index> <slot>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000540//
Ben Murdoch097c5b22016-05-18 11:27:45 +0100541// Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
542// constant pool entry <name_index>.
543void Interpreter::DoLoadIC(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000544 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100545 UNINITIALIZED);
546 DoLoadIC(ic, assembler);
547}
548
549// LoadICWide <object> <name_index> <slot>
550//
551// Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at
552// constant pool entry <name_index>.
553void Interpreter::DoLoadICWide(InterpreterAssembler* assembler) {
554 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
555 UNINITIALIZED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556 DoLoadIC(ic, assembler);
557}
558
559
Ben Murdoch097c5b22016-05-18 11:27:45 +0100560void Interpreter::DoKeyedLoadIC(Callable ic, InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000561 Node* code_target = __ HeapConstant(ic.code());
562 Node* reg_index = __ BytecodeOperandReg(0);
563 Node* object = __ LoadRegister(reg_index);
564 Node* name = __ GetAccumulator();
565 Node* raw_slot = __ BytecodeOperandIdx(1);
566 Node* smi_slot = __ SmiTag(raw_slot);
567 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100568 Node* context = __ GetContext();
569 Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
570 name, smi_slot, type_feedback_vector);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000571 __ SetAccumulator(result);
572 __ Dispatch();
573}
574
Ben Murdoch097c5b22016-05-18 11:27:45 +0100575// KeyedLoadIC <object> <slot>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000576//
Ben Murdoch097c5b22016-05-18 11:27:45 +0100577// Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
578// in the accumulator.
579void Interpreter::DoKeyedLoadIC(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000580 Callable ic =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100581 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, UNINITIALIZED);
582 DoKeyedLoadIC(ic, assembler);
583}
584
585// KeyedLoadICWide <object> <slot>
586//
587// Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key
588// in the accumulator.
589void Interpreter::DoKeyedLoadICWide(InterpreterAssembler* assembler) {
590 Callable ic =
591 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, UNINITIALIZED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592 DoKeyedLoadIC(ic, assembler);
593}
594
595
Ben Murdoch097c5b22016-05-18 11:27:45 +0100596void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000597 Node* code_target = __ HeapConstant(ic.code());
598 Node* object_reg_index = __ BytecodeOperandReg(0);
599 Node* object = __ LoadRegister(object_reg_index);
600 Node* constant_index = __ BytecodeOperandIdx(1);
601 Node* name = __ LoadConstantPoolEntry(constant_index);
602 Node* value = __ GetAccumulator();
603 Node* raw_slot = __ BytecodeOperandIdx(2);
604 Node* smi_slot = __ SmiTag(raw_slot);
605 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100606 Node* context = __ GetContext();
607 __ CallStub(ic.descriptor(), code_target, context, object, name, value,
608 smi_slot, type_feedback_vector);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000609 __ Dispatch();
610}
611
612
613// StoreICSloppy <object> <name_index> <slot>
614//
615// Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
616// the name in constant pool entry <name_index> with the value in the
617// accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100618void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000619 Callable ic =
620 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
621 DoStoreIC(ic, assembler);
622}
623
624
625// StoreICStrict <object> <name_index> <slot>
626//
627// Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
628// the name in constant pool entry <name_index> with the value in the
629// accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100630void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000631 Callable ic =
632 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
633 DoStoreIC(ic, assembler);
634}
635
636
637// StoreICSloppyWide <object> <name_index> <slot>
638//
639// Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
640// the name in constant pool entry <name_index> with the value in the
641// accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100642void Interpreter::DoStoreICSloppyWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000643 Callable ic =
644 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
645 DoStoreIC(ic, assembler);
646}
647
648
649// StoreICStrictWide <object> <name_index> <slot>
650//
651// Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
652// the name in constant pool entry <name_index> with the value in the
653// accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100654void Interpreter::DoStoreICStrictWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000655 Callable ic =
656 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
657 DoStoreIC(ic, assembler);
658}
659
Ben Murdoch097c5b22016-05-18 11:27:45 +0100660void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000661 Node* code_target = __ HeapConstant(ic.code());
662 Node* object_reg_index = __ BytecodeOperandReg(0);
663 Node* object = __ LoadRegister(object_reg_index);
664 Node* name_reg_index = __ BytecodeOperandReg(1);
665 Node* name = __ LoadRegister(name_reg_index);
666 Node* value = __ GetAccumulator();
667 Node* raw_slot = __ BytecodeOperandIdx(2);
668 Node* smi_slot = __ SmiTag(raw_slot);
669 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100670 Node* context = __ GetContext();
671 __ CallStub(ic.descriptor(), code_target, context, object, name, value,
672 smi_slot, type_feedback_vector);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000673 __ Dispatch();
674}
675
676
677// KeyedStoreICSloppy <object> <key> <slot>
678//
679// Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
680// and the key <key> with the value in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100681void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000682 Callable ic =
683 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
684 DoKeyedStoreIC(ic, assembler);
685}
686
687
688// KeyedStoreICStore <object> <key> <slot>
689//
690// Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
691// and the key <key> with the value in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100692void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000693 Callable ic =
694 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
695 DoKeyedStoreIC(ic, assembler);
696}
697
698
699// KeyedStoreICSloppyWide <object> <key> <slot>
700//
701// Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
702// and the key <key> with the value in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100703void Interpreter::DoKeyedStoreICSloppyWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704 Callable ic =
705 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
706 DoKeyedStoreIC(ic, assembler);
707}
708
709
710// KeyedStoreICStoreWide <object> <key> <slot>
711//
712// Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
713// and the key <key> with the value in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100714void Interpreter::DoKeyedStoreICStrictWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000715 Callable ic =
716 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
717 DoKeyedStoreIC(ic, assembler);
718}
719
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000720// PushContext <context>
721//
Ben Murdoch097c5b22016-05-18 11:27:45 +0100722// Saves the current context in <context>, and pushes the accumulator as the
723// new current context.
724void Interpreter::DoPushContext(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000725 Node* reg_index = __ BytecodeOperandReg(0);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100726 Node* new_context = __ GetAccumulator();
727 Node* old_context = __ GetContext();
728 __ StoreRegister(old_context, reg_index);
729 __ SetContext(new_context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000730 __ Dispatch();
731}
732
733
734// PopContext <context>
735//
736// Pops the current context and sets <context> as the new context.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100737void Interpreter::DoPopContext(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000738 Node* reg_index = __ BytecodeOperandReg(0);
739 Node* context = __ LoadRegister(reg_index);
740 __ SetContext(context);
741 __ Dispatch();
742}
743
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000744void Interpreter::DoBinaryOp(Runtime::FunctionId function_id,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100745 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000746 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized
747 // operations, instead of calling builtins directly.
748 Node* reg_index = __ BytecodeOperandReg(0);
749 Node* lhs = __ LoadRegister(reg_index);
750 Node* rhs = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100751 Node* context = __ GetContext();
752 Node* result = __ CallRuntime(function_id, context, lhs, rhs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000753 __ SetAccumulator(result);
754 __ Dispatch();
755}
756
757
758// Add <src>
759//
760// Add register <src> to accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100761void Interpreter::DoAdd(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000762 DoBinaryOp(Runtime::kAdd, assembler);
763}
764
765
766// Sub <src>
767//
768// Subtract register <src> from accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100769void Interpreter::DoSub(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000770 DoBinaryOp(Runtime::kSubtract, assembler);
771}
772
773
774// Mul <src>
775//
776// Multiply accumulator by register <src>.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100777void Interpreter::DoMul(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000778 DoBinaryOp(Runtime::kMultiply, assembler);
779}
780
781
782// Div <src>
783//
784// Divide register <src> by accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100785void Interpreter::DoDiv(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786 DoBinaryOp(Runtime::kDivide, assembler);
787}
788
789
790// Mod <src>
791//
792// Modulo register <src> by accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100793void Interpreter::DoMod(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794 DoBinaryOp(Runtime::kModulus, assembler);
795}
796
797
798// BitwiseOr <src>
799//
800// BitwiseOr register <src> to accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100801void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000802 DoBinaryOp(Runtime::kBitwiseOr, assembler);
803}
804
805
806// BitwiseXor <src>
807//
808// BitwiseXor register <src> to accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100809void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000810 DoBinaryOp(Runtime::kBitwiseXor, assembler);
811}
812
813
814// BitwiseAnd <src>
815//
816// BitwiseAnd register <src> to accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100817void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818 DoBinaryOp(Runtime::kBitwiseAnd, assembler);
819}
820
821
822// ShiftLeft <src>
823//
824// Left shifts register <src> by the count specified in the accumulator.
825// Register <src> is converted to an int32 and the accumulator to uint32
826// before the operation. 5 lsb bits from the accumulator are used as count
827// i.e. <src> << (accumulator & 0x1F).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100828void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000829 DoBinaryOp(Runtime::kShiftLeft, assembler);
830}
831
832
833// ShiftRight <src>
834//
835// Right shifts register <src> by the count specified in the accumulator.
836// Result is sign extended. Register <src> is converted to an int32 and the
837// accumulator to uint32 before the operation. 5 lsb bits from the accumulator
838// are used as count i.e. <src> >> (accumulator & 0x1F).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100839void Interpreter::DoShiftRight(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000840 DoBinaryOp(Runtime::kShiftRight, assembler);
841}
842
843
844// ShiftRightLogical <src>
845//
846// Right Shifts register <src> by the count specified in the accumulator.
847// Result is zero-filled. The accumulator and register <src> are converted to
848// uint32 before the operation 5 lsb bits from the accumulator are used as
849// count i.e. <src> << (accumulator & 0x1F).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100850void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000851 DoBinaryOp(Runtime::kShiftRightLogical, assembler);
852}
853
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000854void Interpreter::DoCountOp(Runtime::FunctionId function_id,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100855 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000856 Node* value = __ GetAccumulator();
857 Node* one = __ NumberConstant(1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100858 Node* context = __ GetContext();
859 Node* result = __ CallRuntime(function_id, context, value, one);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000860 __ SetAccumulator(result);
861 __ Dispatch();
862}
863
864
865// Inc
866//
867// Increments value in the accumulator by one.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100868void Interpreter::DoInc(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000869 DoCountOp(Runtime::kAdd, assembler);
870}
871
872
873// Dec
874//
875// Decrements value in the accumulator by one.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100876void Interpreter::DoDec(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000877 DoCountOp(Runtime::kSubtract, assembler);
878}
879
880
881// LogicalNot
882//
883// Perform logical-not on the accumulator, first casting the
884// accumulator to a boolean value if required.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100885void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100887 Node* context = __ GetContext();
888 Node* result =
889 __ CallRuntime(Runtime::kInterpreterLogicalNot, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890 __ SetAccumulator(result);
891 __ Dispatch();
892}
893
894
895// TypeOf
896//
897// Load the accumulator with the string representating type of the
898// object in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100899void Interpreter::DoTypeOf(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000900 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100901 Node* context = __ GetContext();
902 Node* result =
903 __ CallRuntime(Runtime::kInterpreterTypeOf, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000904 __ SetAccumulator(result);
905 __ Dispatch();
906}
907
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000908void Interpreter::DoDelete(Runtime::FunctionId function_id,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100909 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000910 Node* reg_index = __ BytecodeOperandReg(0);
911 Node* object = __ LoadRegister(reg_index);
912 Node* key = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100913 Node* context = __ GetContext();
914 Node* result = __ CallRuntime(function_id, context, object, key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000915 __ SetAccumulator(result);
916 __ Dispatch();
917}
918
919
920// DeletePropertyStrict
921//
922// Delete the property specified in the accumulator from the object
923// referenced by the register operand following strict mode semantics.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100924void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000925 DoDelete(Runtime::kDeleteProperty_Strict, assembler);
926}
927
928
929// DeletePropertySloppy
930//
931// Delete the property specified in the accumulator from the object
932// referenced by the register operand following sloppy mode semantics.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100933void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000934 DoDelete(Runtime::kDeleteProperty_Sloppy, assembler);
935}
936
Ben Murdoch097c5b22016-05-18 11:27:45 +0100937void Interpreter::DoJSCall(InterpreterAssembler* assembler,
938 TailCallMode tail_call_mode) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000939 Node* function_reg = __ BytecodeOperandReg(0);
940 Node* function = __ LoadRegister(function_reg);
941 Node* receiver_reg = __ BytecodeOperandReg(1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100942 Node* receiver_arg = __ RegisterLocation(receiver_reg);
943 Node* receiver_args_count = __ BytecodeOperandCount(2);
944 Node* receiver_count = __ Int32Constant(1);
945 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
946 Node* context = __ GetContext();
947 // TODO(rmcilroy): Use the call type feedback slot to call via CallStub.
948 Node* result =
949 __ CallJS(function, context, receiver_arg, args_count, tail_call_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 __ SetAccumulator(result);
951 __ Dispatch();
952}
953
954
955// Call <callable> <receiver> <arg_count>
956//
957// Call a JSfunction or Callable in |callable| with the |receiver| and
958// |arg_count| arguments in subsequent registers.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100959void Interpreter::DoCall(InterpreterAssembler* assembler) {
960 DoJSCall(assembler, TailCallMode::kDisallow);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000961}
962
963
964// CallWide <callable> <receiver> <arg_count>
965//
966// Call a JSfunction or Callable in |callable| with the |receiver| and
967// |arg_count| arguments in subsequent registers.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100968void Interpreter::DoCallWide(InterpreterAssembler* assembler) {
969 DoJSCall(assembler, TailCallMode::kDisallow);
970}
971
972// TailCall <callable> <receiver> <arg_count>
973//
974// Tail call a JSfunction or Callable in |callable| with the |receiver| and
975// |arg_count| arguments in subsequent registers.
976void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
977 DoJSCall(assembler, TailCallMode::kAllow);
978}
979
980// TailCallWide <callable> <receiver> <arg_count>
981//
982// Tail call a JSfunction or Callable in |callable| with the |receiver| and
983// |arg_count| arguments in subsequent registers.
984void Interpreter::DoTailCallWide(InterpreterAssembler* assembler) {
985 DoJSCall(assembler, TailCallMode::kAllow);
986}
987
988void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) {
989 Node* function_id = __ BytecodeOperandIdx(0);
990 Node* first_arg_reg = __ BytecodeOperandReg(1);
991 Node* first_arg = __ RegisterLocation(first_arg_reg);
992 Node* args_count = __ BytecodeOperandCount(2);
993 Node* context = __ GetContext();
994 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count);
995 __ SetAccumulator(result);
996 __ Dispatch();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000997}
998
999
1000// CallRuntime <function_id> <first_arg> <arg_count>
1001//
1002// Call the runtime function |function_id| with the first argument in
1003// register |first_arg| and |arg_count| arguments in subsequent
1004// registers.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001005void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) {
1006 DoCallRuntimeCommon(assembler);
1007}
1008
1009
1010// CallRuntime <function_id> <first_arg> <arg_count>
1011//
1012// Call the runtime function |function_id| with the first argument in
1013// register |first_arg| and |arg_count| arguments in subsequent
1014// registers.
1015void Interpreter::DoCallRuntimeWide(InterpreterAssembler* assembler) {
1016 DoCallRuntimeCommon(assembler);
1017}
1018
1019void Interpreter::DoCallRuntimeForPairCommon(InterpreterAssembler* assembler) {
1020 // Call the runtime function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001021 Node* function_id = __ BytecodeOperandIdx(0);
1022 Node* first_arg_reg = __ BytecodeOperandReg(1);
1023 Node* first_arg = __ RegisterLocation(first_arg_reg);
1024 Node* args_count = __ BytecodeOperandCount(2);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001025 Node* context = __ GetContext();
1026 Node* result_pair =
1027 __ CallRuntimeN(function_id, context, first_arg, args_count, 2);
1028
1029 // Store the results in <first_return> and <first_return + 1>
1030 Node* first_return_reg = __ BytecodeOperandReg(3);
1031 Node* second_return_reg = __ NextRegister(first_return_reg);
1032 Node* result0 = __ Projection(0, result_pair);
1033 Node* result1 = __ Projection(1, result_pair);
1034 __ StoreRegister(result0, first_return_reg);
1035 __ StoreRegister(result1, second_return_reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001036 __ Dispatch();
1037}
1038
1039
1040// CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
1041//
1042// Call the runtime function |function_id| which returns a pair, with the
1043// first argument in register |first_arg| and |arg_count| arguments in
1044// subsequent registers. Returns the result in <first_return> and
1045// <first_return + 1>
Ben Murdoch097c5b22016-05-18 11:27:45 +01001046void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
1047 DoCallRuntimeForPairCommon(assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001048}
1049
1050
Ben Murdoch097c5b22016-05-18 11:27:45 +01001051// CallRuntimeForPairWide <function_id> <first_arg> <arg_count> <first_return>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001052//
Ben Murdoch097c5b22016-05-18 11:27:45 +01001053// Call the runtime function |function_id| which returns a pair, with the
1054// first argument in register |first_arg| and |arg_count| arguments in
1055// subsequent registers. Returns the result in <first_return> and
1056// <first_return + 1>
1057void Interpreter::DoCallRuntimeForPairWide(InterpreterAssembler* assembler) {
1058 DoCallRuntimeForPairCommon(assembler);
1059}
1060
1061void Interpreter::DoCallJSRuntimeCommon(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001062 Node* context_index = __ BytecodeOperandIdx(0);
1063 Node* receiver_reg = __ BytecodeOperandReg(1);
1064 Node* first_arg = __ RegisterLocation(receiver_reg);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001065 Node* receiver_args_count = __ BytecodeOperandCount(2);
1066 Node* receiver_count = __ Int32Constant(1);
1067 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001068
1069 // Get the function to call from the native context.
1070 Node* context = __ GetContext();
1071 Node* native_context =
1072 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
1073 Node* function = __ LoadContextSlot(native_context, context_index);
1074
1075 // Call the function.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001076 Node* result = __ CallJS(function, context, first_arg, args_count,
1077 TailCallMode::kDisallow);
1078 __ SetAccumulator(result);
1079 __ Dispatch();
1080}
1081
1082
1083// CallJSRuntime <context_index> <receiver> <arg_count>
1084//
1085// Call the JS runtime function that has the |context_index| with the receiver
1086// in register |receiver| and |arg_count| arguments in subsequent registers.
1087void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) {
1088 DoCallJSRuntimeCommon(assembler);
1089}
1090
1091
1092// CallJSRuntimeWide <context_index> <receiver> <arg_count>
1093//
1094// Call the JS runtime function that has the |context_index| with the receiver
1095// in register |receiver| and |arg_count| arguments in subsequent registers.
1096void Interpreter::DoCallJSRuntimeWide(InterpreterAssembler* assembler) {
1097 DoCallJSRuntimeCommon(assembler);
1098}
1099
1100void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
1101 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
1102 Node* new_target = __ GetAccumulator();
1103 Node* constructor_reg = __ BytecodeOperandReg(0);
1104 Node* constructor = __ LoadRegister(constructor_reg);
1105 Node* first_arg_reg = __ BytecodeOperandReg(1);
1106 Node* first_arg = __ RegisterLocation(first_arg_reg);
1107 Node* args_count = __ BytecodeOperandCount(2);
1108 Node* context = __ GetContext();
1109 Node* result =
1110 __ CallConstruct(constructor, context, new_target, first_arg, args_count);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001111 __ SetAccumulator(result);
1112 __ Dispatch();
1113}
1114
1115
1116// New <constructor> <first_arg> <arg_count>
1117//
1118// Call operator new with |constructor| and the first argument in
1119// register |first_arg| and |arg_count| arguments in subsequent
Ben Murdoch097c5b22016-05-18 11:27:45 +01001120// registers. The new.target is in the accumulator.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001121//
Ben Murdoch097c5b22016-05-18 11:27:45 +01001122void Interpreter::DoNew(InterpreterAssembler* assembler) {
1123 DoCallConstruct(assembler);
1124}
1125
1126
1127// NewWide <constructor> <first_arg> <arg_count>
1128//
1129// Call operator new with |constructor| and the first argument in
1130// register |first_arg| and |arg_count| arguments in subsequent
1131// registers. The new.target is in the accumulator.
1132//
1133void Interpreter::DoNewWide(InterpreterAssembler* assembler) {
1134 DoCallConstruct(assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001135}
1136
1137
1138// TestEqual <src>
1139//
1140// Test if the value in the <src> register equals the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001141void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
1142 DoBinaryOp(Runtime::kEqual, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001143}
1144
1145
1146// TestNotEqual <src>
1147//
1148// Test if the value in the <src> register is not equal to the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001149void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
1150 DoBinaryOp(Runtime::kNotEqual, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001151}
1152
1153
1154// TestEqualStrict <src>
1155//
1156// Test if the value in the <src> register is strictly equal to the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001157void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
1158 DoBinaryOp(Runtime::kStrictEqual, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001159}
1160
1161
1162// TestNotEqualStrict <src>
1163//
1164// Test if the value in the <src> register is not strictly equal to the
1165// accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001166void Interpreter::DoTestNotEqualStrict(InterpreterAssembler* assembler) {
1167 DoBinaryOp(Runtime::kStrictNotEqual, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001168}
1169
1170
1171// TestLessThan <src>
1172//
1173// Test if the value in the <src> register is less than the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001174void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
1175 DoBinaryOp(Runtime::kLessThan, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001176}
1177
1178
1179// TestGreaterThan <src>
1180//
1181// Test if the value in the <src> register is greater than the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001182void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
1183 DoBinaryOp(Runtime::kGreaterThan, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001184}
1185
1186
1187// TestLessThanOrEqual <src>
1188//
1189// Test if the value in the <src> register is less than or equal to the
1190// accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001191void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
1192 DoBinaryOp(Runtime::kLessThanOrEqual, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001193}
1194
1195
1196// TestGreaterThanOrEqual <src>
1197//
1198// Test if the value in the <src> register is greater than or equal to the
1199// accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001200void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
1201 DoBinaryOp(Runtime::kGreaterThanOrEqual, assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001202}
1203
1204
1205// TestIn <src>
1206//
1207// Test if the object referenced by the register operand is a property of the
1208// object referenced by the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001209void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001210 DoBinaryOp(Runtime::kHasProperty, assembler);
1211}
1212
1213
1214// TestInstanceOf <src>
1215//
1216// Test if the object referenced by the <src> register is an an instance of type
1217// referenced by the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001218void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001219 DoBinaryOp(Runtime::kInstanceOf, assembler);
1220}
1221
1222
1223// ToName
1224//
1225// Cast the object referenced by the accumulator to a name.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001226void Interpreter::DoToName(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001227 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001228 Node* context = __ GetContext();
1229 Node* result = __ CallRuntime(Runtime::kToName, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001230 __ SetAccumulator(result);
1231 __ Dispatch();
1232}
1233
1234
1235// ToNumber
1236//
1237// Cast the object referenced by the accumulator to a number.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001238void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001239 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001240 Node* context = __ GetContext();
1241 Node* result = __ CallRuntime(Runtime::kToNumber, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001242 __ SetAccumulator(result);
1243 __ Dispatch();
1244}
1245
1246
1247// ToObject
1248//
1249// Cast the object referenced by the accumulator to a JSObject.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001250void Interpreter::DoToObject(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001251 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001252 Node* context = __ GetContext();
1253 Node* result = __ CallRuntime(Runtime::kToObject, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001254 __ SetAccumulator(result);
1255 __ Dispatch();
1256}
1257
1258
1259// Jump <imm8>
1260//
1261// Jump by number of bytes represented by the immediate operand |imm8|.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001262void Interpreter::DoJump(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001263 Node* relative_jump = __ BytecodeOperandImm(0);
1264 __ Jump(relative_jump);
1265}
1266
1267
1268// JumpConstant <idx8>
1269//
1270// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001271void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001272 Node* index = __ BytecodeOperandIdx(0);
1273 Node* constant = __ LoadConstantPoolEntry(index);
1274 Node* relative_jump = __ SmiUntag(constant);
1275 __ Jump(relative_jump);
1276}
1277
1278
1279// JumpConstantWide <idx16>
1280//
1281// Jump by number of bytes in the Smi in the |idx16| entry in the
1282// constant pool.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001283void Interpreter::DoJumpConstantWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001284 DoJumpConstant(assembler);
1285}
1286
1287
1288// JumpIfTrue <imm8>
1289//
1290// Jump by number of bytes represented by an immediate operand if the
1291// accumulator contains true.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001292void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001293 Node* accumulator = __ GetAccumulator();
1294 Node* relative_jump = __ BytecodeOperandImm(0);
1295 Node* true_value = __ BooleanConstant(true);
1296 __ JumpIfWordEqual(accumulator, true_value, relative_jump);
1297}
1298
1299
1300// JumpIfTrueConstant <idx8>
1301//
1302// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
1303// if the accumulator contains true.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001304void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001305 Node* accumulator = __ GetAccumulator();
1306 Node* index = __ BytecodeOperandIdx(0);
1307 Node* constant = __ LoadConstantPoolEntry(index);
1308 Node* relative_jump = __ SmiUntag(constant);
1309 Node* true_value = __ BooleanConstant(true);
1310 __ JumpIfWordEqual(accumulator, true_value, relative_jump);
1311}
1312
1313
1314// JumpIfTrueConstantWide <idx16>
1315//
1316// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1317// if the accumulator contains true.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001318void Interpreter::DoJumpIfTrueConstantWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001319 DoJumpIfTrueConstant(assembler);
1320}
1321
1322
1323// JumpIfFalse <imm8>
1324//
1325// Jump by number of bytes represented by an immediate operand if the
1326// accumulator contains false.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001327void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001328 Node* accumulator = __ GetAccumulator();
1329 Node* relative_jump = __ BytecodeOperandImm(0);
1330 Node* false_value = __ BooleanConstant(false);
1331 __ JumpIfWordEqual(accumulator, false_value, relative_jump);
1332}
1333
1334
1335// JumpIfFalseConstant <idx8>
1336//
1337// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
1338// if the accumulator contains false.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001339void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001340 Node* accumulator = __ GetAccumulator();
1341 Node* index = __ BytecodeOperandIdx(0);
1342 Node* constant = __ LoadConstantPoolEntry(index);
1343 Node* relative_jump = __ SmiUntag(constant);
1344 Node* false_value = __ BooleanConstant(false);
1345 __ JumpIfWordEqual(accumulator, false_value, relative_jump);
1346}
1347
1348
1349// JumpIfFalseConstant <idx16>
1350//
1351// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1352// if the accumulator contains false.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001353void Interpreter::DoJumpIfFalseConstantWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001354 DoJumpIfFalseConstant(assembler);
1355}
1356
1357
1358// JumpIfToBooleanTrue <imm8>
1359//
1360// Jump by number of bytes represented by an immediate operand if the object
1361// referenced by the accumulator is true when the object is cast to boolean.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001362void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001363 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001364 Node* context = __ GetContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001365 Node* to_boolean_value =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001366 __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001367 Node* relative_jump = __ BytecodeOperandImm(0);
1368 Node* true_value = __ BooleanConstant(true);
1369 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
1370}
1371
1372
1373// JumpIfToBooleanTrueConstant <idx8>
1374//
1375// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
1376// if the object referenced by the accumulator is true when the object is cast
1377// to boolean.
1378void Interpreter::DoJumpIfToBooleanTrueConstant(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001379 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001380 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001381 Node* context = __ GetContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001382 Node* to_boolean_value =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001383 __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001384 Node* index = __ BytecodeOperandIdx(0);
1385 Node* constant = __ LoadConstantPoolEntry(index);
1386 Node* relative_jump = __ SmiUntag(constant);
1387 Node* true_value = __ BooleanConstant(true);
1388 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
1389}
1390
1391
1392// JumpIfToBooleanTrueConstantWide <idx16>
1393//
1394// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1395// if the object referenced by the accumulator is true when the object is cast
1396// to boolean.
1397void Interpreter::DoJumpIfToBooleanTrueConstantWide(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001398 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001399 DoJumpIfToBooleanTrueConstant(assembler);
1400}
1401
1402
1403// JumpIfToBooleanFalse <imm8>
1404//
1405// Jump by number of bytes represented by an immediate operand if the object
1406// referenced by the accumulator is false when the object is cast to boolean.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001407void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001408 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001409 Node* context = __ GetContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001410 Node* to_boolean_value =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001411 __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001412 Node* relative_jump = __ BytecodeOperandImm(0);
1413 Node* false_value = __ BooleanConstant(false);
1414 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
1415}
1416
1417
1418// JumpIfToBooleanFalseConstant <idx8>
1419//
1420// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
1421// if the object referenced by the accumulator is false when the object is cast
1422// to boolean.
1423void Interpreter::DoJumpIfToBooleanFalseConstant(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001424 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001425 Node* accumulator = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001426 Node* context = __ GetContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001427 Node* to_boolean_value =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001428 __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001429 Node* index = __ BytecodeOperandIdx(0);
1430 Node* constant = __ LoadConstantPoolEntry(index);
1431 Node* relative_jump = __ SmiUntag(constant);
1432 Node* false_value = __ BooleanConstant(false);
1433 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
1434}
1435
1436
1437// JumpIfToBooleanFalseConstantWide <idx16>
1438//
1439// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1440// if the object referenced by the accumulator is false when the object is cast
1441// to boolean.
1442void Interpreter::DoJumpIfToBooleanFalseConstantWide(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001443 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001444 DoJumpIfToBooleanFalseConstant(assembler);
1445}
1446
1447
1448// JumpIfNull <imm8>
1449//
1450// Jump by number of bytes represented by an immediate operand if the object
1451// referenced by the accumulator is the null constant.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001452void Interpreter::DoJumpIfNull(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001453 Node* accumulator = __ GetAccumulator();
1454 Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
1455 Node* relative_jump = __ BytecodeOperandImm(0);
1456 __ JumpIfWordEqual(accumulator, null_value, relative_jump);
1457}
1458
1459
1460// JumpIfNullConstant <idx8>
1461//
1462// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
1463// if the object referenced by the accumulator is the null constant.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001464void Interpreter::DoJumpIfNullConstant(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001465 Node* accumulator = __ GetAccumulator();
1466 Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
1467 Node* index = __ BytecodeOperandIdx(0);
1468 Node* constant = __ LoadConstantPoolEntry(index);
1469 Node* relative_jump = __ SmiUntag(constant);
1470 __ JumpIfWordEqual(accumulator, null_value, relative_jump);
1471}
1472
1473
1474// JumpIfNullConstantWide <idx16>
1475//
1476// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1477// if the object referenced by the accumulator is the null constant.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001478void Interpreter::DoJumpIfNullConstantWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001479 DoJumpIfNullConstant(assembler);
1480}
1481
Ben Murdoch097c5b22016-05-18 11:27:45 +01001482// JumpIfUndefined <imm8>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001483//
1484// Jump by number of bytes represented by an immediate operand if the object
1485// referenced by the accumulator is the undefined constant.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001486void Interpreter::DoJumpIfUndefined(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001487 Node* accumulator = __ GetAccumulator();
1488 Node* undefined_value =
1489 __ HeapConstant(isolate_->factory()->undefined_value());
1490 Node* relative_jump = __ BytecodeOperandImm(0);
1491 __ JumpIfWordEqual(accumulator, undefined_value, relative_jump);
1492}
1493
1494
1495// JumpIfUndefinedConstant <idx8>
1496//
1497// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
1498// if the object referenced by the accumulator is the undefined constant.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001499void Interpreter::DoJumpIfUndefinedConstant(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001500 Node* accumulator = __ GetAccumulator();
1501 Node* undefined_value =
1502 __ HeapConstant(isolate_->factory()->undefined_value());
1503 Node* index = __ BytecodeOperandIdx(0);
1504 Node* constant = __ LoadConstantPoolEntry(index);
1505 Node* relative_jump = __ SmiUntag(constant);
1506 __ JumpIfWordEqual(accumulator, undefined_value, relative_jump);
1507}
1508
1509
1510// JumpIfUndefinedConstantWide <idx16>
1511//
1512// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1513// if the object referenced by the accumulator is the undefined constant.
1514void Interpreter::DoJumpIfUndefinedConstantWide(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001515 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001516 DoJumpIfUndefinedConstant(assembler);
1517}
1518
Ben Murdoch097c5b22016-05-18 11:27:45 +01001519// JumpIfNotHole <imm8>
1520//
1521// Jump by number of bytes represented by an immediate operand if the object
1522// referenced by the accumulator is the hole.
1523void Interpreter::DoJumpIfNotHole(InterpreterAssembler* assembler) {
1524 Node* accumulator = __ GetAccumulator();
1525 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
1526 Node* relative_jump = __ BytecodeOperandImm(0);
1527 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
1528}
1529
1530// JumpIfNotHoleConstant <idx8>
1531//
1532// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
1533// if the object referenced by the accumulator is the hole constant.
1534void Interpreter::DoJumpIfNotHoleConstant(InterpreterAssembler* assembler) {
1535 Node* accumulator = __ GetAccumulator();
1536 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
1537 Node* index = __ BytecodeOperandIdx(0);
1538 Node* constant = __ LoadConstantPoolEntry(index);
1539 Node* relative_jump = __ SmiUntag(constant);
1540 __ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
1541}
1542
1543// JumpIfNotHoleConstantWide <idx16>
1544//
1545// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
1546// if the object referenced by the accumulator is the hole constant.
1547void Interpreter::DoJumpIfNotHoleConstantWide(InterpreterAssembler* assembler) {
1548 DoJumpIfNotHoleConstant(assembler);
1549}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001550
1551void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001552 InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001553 Node* index = __ BytecodeOperandIdx(0);
1554 Node* constant_elements = __ LoadConstantPoolEntry(index);
1555 Node* literal_index_raw = __ BytecodeOperandIdx(1);
1556 Node* literal_index = __ SmiTag(literal_index_raw);
1557 Node* flags_raw = __ BytecodeOperandImm(2);
1558 Node* flags = __ SmiTag(flags_raw);
1559 Node* closure = __ LoadRegister(Register::function_closure());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001560 Node* context = __ GetContext();
1561 Node* result = __ CallRuntime(function_id, context, closure, literal_index,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001562 constant_elements, flags);
1563 __ SetAccumulator(result);
1564 __ Dispatch();
1565}
1566
1567
1568// CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
1569//
1570// Creates a regular expression literal for literal index <literal_idx> with
1571// <flags> and the pattern in <pattern_idx>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001572void Interpreter::DoCreateRegExpLiteral(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001573 DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler);
1574}
1575
1576
1577// CreateRegExpLiteralWide <pattern_idx> <literal_idx> <flags>
1578//
1579// Creates a regular expression literal for literal index <literal_idx> with
1580// <flags> and the pattern in <pattern_idx>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001581void Interpreter::DoCreateRegExpLiteralWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001582 DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler);
1583}
1584
1585
1586// CreateArrayLiteral <element_idx> <literal_idx> <flags>
1587//
1588// Creates an array literal for literal index <literal_idx> with flags <flags>
1589// and constant elements in <element_idx>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001590void Interpreter::DoCreateArrayLiteral(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001591 DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
1592}
1593
1594
1595// CreateArrayLiteralWide <element_idx> <literal_idx> <flags>
1596//
1597// Creates an array literal for literal index <literal_idx> with flags <flags>
1598// and constant elements in <element_idx>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001599void Interpreter::DoCreateArrayLiteralWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001600 DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
1601}
1602
1603
1604// CreateObjectLiteral <element_idx> <literal_idx> <flags>
1605//
1606// Creates an object literal for literal index <literal_idx> with flags <flags>
1607// and constant elements in <element_idx>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001608void Interpreter::DoCreateObjectLiteral(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001609 DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
1610}
1611
1612
1613// CreateObjectLiteralWide <element_idx> <literal_idx> <flags>
1614//
1615// Creates an object literal for literal index <literal_idx> with flags <flags>
1616// and constant elements in <element_idx>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001617void Interpreter::DoCreateObjectLiteralWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001618 DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
1619}
1620
1621
1622// CreateClosure <index> <tenured>
1623//
1624// Creates a new closure for SharedFunctionInfo at position |index| in the
1625// constant pool and with the PretenureFlag <tenured>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001626void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001627 // TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of
1628 // calling into the runtime.
1629 Node* index = __ BytecodeOperandIdx(0);
1630 Node* shared = __ LoadConstantPoolEntry(index);
1631 Node* tenured_raw = __ BytecodeOperandImm(1);
1632 Node* tenured = __ SmiTag(tenured_raw);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001633 Node* context = __ GetContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001634 Node* result =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001635 __ CallRuntime(Runtime::kInterpreterNewClosure, context, shared, tenured);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001636 __ SetAccumulator(result);
1637 __ Dispatch();
1638}
1639
1640
1641// CreateClosureWide <index> <tenured>
1642//
1643// Creates a new closure for SharedFunctionInfo at position |index| in the
1644// constant pool and with the PretenureFlag <tenured>.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001645void Interpreter::DoCreateClosureWide(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001646 return DoCreateClosure(assembler);
1647}
1648
1649
1650// CreateMappedArguments
1651//
1652// Creates a new mapped arguments object.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001653void Interpreter::DoCreateMappedArguments(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001654 Node* closure = __ LoadRegister(Register::function_closure());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001655 Node* context = __ GetContext();
1656 Node* result =
1657 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001658 __ SetAccumulator(result);
1659 __ Dispatch();
1660}
1661
1662
1663// CreateUnmappedArguments
1664//
1665// Creates a new unmapped arguments object.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001666void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) {
1667 Callable callable = CodeFactory::FastNewStrictArguments(isolate_);
1668 Node* target = __ HeapConstant(callable.code());
1669 Node* context = __ GetContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001670 Node* closure = __ LoadRegister(Register::function_closure());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001671 Node* result = __ CallStub(callable.descriptor(), target, context, closure);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001672 __ SetAccumulator(result);
1673 __ Dispatch();
1674}
1675
Ben Murdoch097c5b22016-05-18 11:27:45 +01001676// CreateRestParameter
1677//
1678// Creates a new rest parameter array.
1679void Interpreter::DoCreateRestParameter(InterpreterAssembler* assembler) {
1680 Callable callable = CodeFactory::FastNewRestParameter(isolate_);
1681 Node* target = __ HeapConstant(callable.code());
1682 Node* closure = __ LoadRegister(Register::function_closure());
1683 Node* context = __ GetContext();
1684 Node* result = __ CallStub(callable.descriptor(), target, context, closure);
1685 __ SetAccumulator(result);
1686 __ Dispatch();
1687}
1688
1689// StackCheck
1690//
1691// Performs a stack guard check.
1692void Interpreter::DoStackCheck(InterpreterAssembler* assembler) {
1693 __ StackCheck();
1694 __ Dispatch();
1695}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001696
1697// Throw
1698//
1699// Throws the exception in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001700void Interpreter::DoThrow(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001701 Node* exception = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001702 Node* context = __ GetContext();
1703 __ CallRuntime(Runtime::kThrow, context, exception);
1704 // We shouldn't ever return from a throw.
1705 __ Abort(kUnexpectedReturnFromThrow);
1706}
1707
1708
1709// ReThrow
1710//
1711// Re-throws the exception in the accumulator.
1712void Interpreter::DoReThrow(InterpreterAssembler* assembler) {
1713 Node* exception = __ GetAccumulator();
1714 Node* context = __ GetContext();
1715 __ CallRuntime(Runtime::kReThrow, context, exception);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001716 // We shouldn't ever return from a throw.
1717 __ Abort(kUnexpectedReturnFromThrow);
1718}
1719
1720
1721// Return
1722//
1723// Return the value in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001724void Interpreter::DoReturn(InterpreterAssembler* assembler) {
1725 __ InterpreterReturn();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001726}
1727
Ben Murdoch097c5b22016-05-18 11:27:45 +01001728// Debugger
1729//
1730// Call runtime to handle debugger statement.
1731void Interpreter::DoDebugger(InterpreterAssembler* assembler) {
1732 Node* context = __ GetContext();
1733 __ CallRuntime(Runtime::kHandleDebuggerStatement, context);
1734 __ Dispatch();
1735}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001736
Ben Murdoch097c5b22016-05-18 11:27:45 +01001737// DebugBreak
1738//
1739// Call runtime to handle a debug break.
1740#define DEBUG_BREAK(Name, ...) \
1741 void Interpreter::Do##Name(InterpreterAssembler* assembler) { \
1742 Node* context = __ GetContext(); \
1743 Node* original_handler = __ CallRuntime(Runtime::kDebugBreak, context); \
1744 __ DispatchToBytecodeHandler(original_handler); \
1745 }
1746DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
1747#undef DEBUG_BREAK
1748
1749// ForInPrepare <cache_info_triple>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001750//
1751// Returns state for for..in loop execution based on the object in the
Ben Murdoch097c5b22016-05-18 11:27:45 +01001752// accumulator. The result is output in registers |cache_info_triple| to
1753// |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
1754// and cache_length respectively.
1755void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001756 Node* object = __ GetAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001757 Node* context = __ GetContext();
1758 Node* result_triple = __ CallRuntime(Runtime::kForInPrepare, context, object);
1759
1760 // Set output registers:
1761 // 0 == cache_type, 1 == cache_array, 2 == cache_length
1762 Node* output_register = __ BytecodeOperandReg(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001763 for (int i = 0; i < 3; i++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001764 Node* cache_info = __ Projection(i, result_triple);
1765 __ StoreRegister(cache_info, output_register);
1766 output_register = __ NextRegister(output_register);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001767 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001768 __ Dispatch();
1769}
1770
1771
1772// ForInPrepareWide <cache_info_triple>
1773//
1774// Returns state for for..in loop execution based on the object in the
1775// accumulator. The result is output in registers |cache_info_triple| to
1776// |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
1777// and cache_length respectively.
1778void Interpreter::DoForInPrepareWide(InterpreterAssembler* assembler) {
1779 DoForInPrepare(assembler);
1780}
1781
1782
1783// ForInNext <receiver> <index> <cache_info_pair>
1784//
1785// Returns the next enumerable property in the the accumulator.
1786void Interpreter::DoForInNext(InterpreterAssembler* assembler) {
1787 Node* receiver_reg = __ BytecodeOperandReg(0);
1788 Node* receiver = __ LoadRegister(receiver_reg);
1789 Node* index_reg = __ BytecodeOperandReg(1);
1790 Node* index = __ LoadRegister(index_reg);
1791 Node* cache_type_reg = __ BytecodeOperandReg(2);
1792 Node* cache_type = __ LoadRegister(cache_type_reg);
1793 Node* cache_array_reg = __ NextRegister(cache_type_reg);
1794 Node* cache_array = __ LoadRegister(cache_array_reg);
1795 Node* context = __ GetContext();
1796 Node* result = __ CallRuntime(Runtime::kForInNext, context, receiver,
1797 cache_array, cache_type, index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001798 __ SetAccumulator(result);
1799 __ Dispatch();
1800}
1801
1802
Ben Murdoch097c5b22016-05-18 11:27:45 +01001803// ForInNextWide <receiver> <index> <cache_info_pair>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001804//
1805// Returns the next enumerable property in the the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001806void Interpreter::DoForInNextWide(InterpreterAssembler* assembler) {
1807 return DoForInNext(assembler);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001808}
1809
1810
1811// ForInDone <index> <cache_length>
1812//
1813// Returns true if the end of the enumerable properties has been reached.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001814void Interpreter::DoForInDone(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001815 // TODO(oth): Implement directly rather than making a runtime call.
1816 Node* index_reg = __ BytecodeOperandReg(0);
1817 Node* index = __ LoadRegister(index_reg);
1818 Node* cache_length_reg = __ BytecodeOperandReg(1);
1819 Node* cache_length = __ LoadRegister(cache_length_reg);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001820 Node* context = __ GetContext();
1821 Node* result =
1822 __ CallRuntime(Runtime::kForInDone, context, index, cache_length);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001823 __ SetAccumulator(result);
1824 __ Dispatch();
1825}
1826
1827
1828// ForInStep <index>
1829//
1830// Increments the loop counter in register |index| and stores the result
1831// in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001832void Interpreter::DoForInStep(InterpreterAssembler* assembler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001833 // TODO(oth): Implement directly rather than making a runtime call.
1834 Node* index_reg = __ BytecodeOperandReg(0);
1835 Node* index = __ LoadRegister(index_reg);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001836 Node* context = __ GetContext();
1837 Node* result = __ CallRuntime(Runtime::kForInStep, context, index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001838 __ SetAccumulator(result);
1839 __ Dispatch();
1840}
1841
1842} // namespace interpreter
1843} // namespace internal
1844} // namespace v8