| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/compiler/interpreter-assembler.h" | 9 #include "src/compiler/interpreter-assembler.h" |
| 10 #include "src/factory.h" | 10 #include "src/factory.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 Node* smi_int = __ SmiTag(raw_int); | 104 Node* smi_int = __ SmiTag(raw_int); |
| 105 __ SetAccumulator(smi_int); | 105 __ SetAccumulator(smi_int); |
| 106 __ Dispatch(); | 106 __ Dispatch(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 | 109 |
| 110 // LdaConstant <idx> | 110 // LdaConstant <idx> |
| 111 // | 111 // |
| 112 // Load constant literal at |idx| in the constant pool into the accumulator. | 112 // Load constant literal at |idx| in the constant pool into the accumulator. |
| 113 void Interpreter::DoLdaConstant(compiler::InterpreterAssembler* assembler) { | 113 void Interpreter::DoLdaConstant(compiler::InterpreterAssembler* assembler) { |
| 114 Node* index = __ BytecodeOperandIdx(0); | 114 Node* index = __ BytecodeOperandIdx8(0); |
| 115 Node* constant = __ LoadConstantPoolEntry(index); | 115 Node* constant = __ LoadConstantPoolEntry(index); |
| 116 __ SetAccumulator(constant); | 116 __ SetAccumulator(constant); |
| 117 __ Dispatch(); | 117 __ Dispatch(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 // LdaUndefined | 121 // LdaUndefined |
| 122 // | 122 // |
| 123 // Load Undefined into the accumulator. | 123 // Load Undefined into the accumulator. |
| 124 void Interpreter::DoLdaUndefined(compiler::InterpreterAssembler* assembler) { | 124 void Interpreter::DoLdaUndefined(compiler::InterpreterAssembler* assembler) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); | 166 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); |
| 167 __ SetAccumulator(false_value); | 167 __ SetAccumulator(false_value); |
| 168 __ Dispatch(); | 168 __ Dispatch(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 // Ldar <src> | 172 // Ldar <src> |
| 173 // | 173 // |
| 174 // Load accumulator with value from register <src>. | 174 // Load accumulator with value from register <src>. |
| 175 void Interpreter::DoLdar(compiler::InterpreterAssembler* assembler) { | 175 void Interpreter::DoLdar(compiler::InterpreterAssembler* assembler) { |
| 176 Node* reg_index = __ BytecodeOperandReg(0); | 176 Node* reg_index = __ BytecodeOperandReg8(0); |
| 177 Node* value = __ LoadRegister(reg_index); | 177 Node* value = __ LoadRegister(reg_index); |
| 178 __ SetAccumulator(value); | 178 __ SetAccumulator(value); |
| 179 __ Dispatch(); | 179 __ Dispatch(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 | 182 |
| 183 // Star <dst> | 183 // Star <dst> |
| 184 // | 184 // |
| 185 // Store accumulator to register <dst>. | 185 // Store accumulator to register <dst>. |
| 186 void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { | 186 void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { |
| 187 Node* reg_index = __ BytecodeOperandReg(0); | 187 Node* reg_index = __ BytecodeOperandReg8(0); |
| 188 Node* accumulator = __ GetAccumulator(); | 188 Node* accumulator = __ GetAccumulator(); |
| 189 __ StoreRegister(accumulator, reg_index); | 189 __ StoreRegister(accumulator, reg_index); |
| 190 __ Dispatch(); | 190 __ Dispatch(); |
| 191 } | 191 } |
| 192 | 192 |
| 193 | 193 |
| 194 // LdaGlobal <slot_index> | 194 // LdaGlobal <slot_index> |
| 195 // | 195 // |
| 196 // Load the global at |slot_index| into the accumulator. | 196 // Load the global at |slot_index| into the accumulator. |
| 197 void Interpreter::DoLdaGlobal(compiler::InterpreterAssembler* assembler) { | 197 void Interpreter::DoLdaGlobal(compiler::InterpreterAssembler* assembler) { |
| 198 Node* slot_index = __ BytecodeOperandIdx(0); | 198 Node* slot_index = __ BytecodeOperandIdx8(0); |
| 199 Node* smi_slot_index = __ SmiTag(slot_index); | 199 Node* smi_slot_index = __ SmiTag(slot_index); |
| 200 Node* result = __ CallRuntime(Runtime::kLoadGlobalViaContext, smi_slot_index); | 200 Node* result = __ CallRuntime(Runtime::kLoadGlobalViaContext, smi_slot_index); |
| 201 __ SetAccumulator(result); | 201 __ SetAccumulator(result); |
| 202 __ Dispatch(); | 202 __ Dispatch(); |
| 203 } | 203 } |
| 204 | 204 |
| 205 | 205 |
| 206 void Interpreter::DoPropertyLoadIC(Callable ic, | 206 void Interpreter::DoPropertyLoadIC(Callable ic, |
| 207 compiler::InterpreterAssembler* assembler) { | 207 compiler::InterpreterAssembler* assembler) { |
| 208 Node* code_target = __ HeapConstant(ic.code()); | 208 Node* code_target = __ HeapConstant(ic.code()); |
| 209 Node* reg_index = __ BytecodeOperandReg(0); | 209 Node* reg_index = __ BytecodeOperandReg8(0); |
| 210 Node* object = __ LoadRegister(reg_index); | 210 Node* object = __ LoadRegister(reg_index); |
| 211 Node* name = __ GetAccumulator(); | 211 Node* name = __ GetAccumulator(); |
| 212 Node* raw_slot = __ BytecodeOperandIdx(1); | 212 Node* raw_slot = __ BytecodeOperandIdx8(1); |
| 213 Node* smi_slot = __ SmiTag(raw_slot); | 213 Node* smi_slot = __ SmiTag(raw_slot); |
| 214 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 214 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
| 215 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, smi_slot, | 215 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, smi_slot, |
| 216 type_feedback_vector); | 216 type_feedback_vector); |
| 217 __ SetAccumulator(result); | 217 __ SetAccumulator(result); |
| 218 __ Dispatch(); | 218 __ Dispatch(); |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 |
| 222 // LoadIC <object> <slot> | 222 // LoadIC <object> <slot> |
| (...skipping 14 matching lines...) Expand all Loading... |
| 237 void Interpreter::DoKeyedLoadIC(compiler::InterpreterAssembler* assembler) { | 237 void Interpreter::DoKeyedLoadIC(compiler::InterpreterAssembler* assembler) { |
| 238 Callable ic = | 238 Callable ic = |
| 239 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 239 CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
| 240 DoPropertyLoadIC(ic, assembler); | 240 DoPropertyLoadIC(ic, assembler); |
| 241 } | 241 } |
| 242 | 242 |
| 243 | 243 |
| 244 void Interpreter::DoPropertyStoreIC(Callable ic, | 244 void Interpreter::DoPropertyStoreIC(Callable ic, |
| 245 compiler::InterpreterAssembler* assembler) { | 245 compiler::InterpreterAssembler* assembler) { |
| 246 Node* code_target = __ HeapConstant(ic.code()); | 246 Node* code_target = __ HeapConstant(ic.code()); |
| 247 Node* object_reg_index = __ BytecodeOperandReg(0); | 247 Node* object_reg_index = __ BytecodeOperandReg8(0); |
| 248 Node* object = __ LoadRegister(object_reg_index); | 248 Node* object = __ LoadRegister(object_reg_index); |
| 249 Node* name_reg_index = __ BytecodeOperandReg(1); | 249 Node* name_reg_index = __ BytecodeOperandReg8(1); |
| 250 Node* name = __ LoadRegister(name_reg_index); | 250 Node* name = __ LoadRegister(name_reg_index); |
| 251 Node* value = __ GetAccumulator(); | 251 Node* value = __ GetAccumulator(); |
| 252 Node* raw_slot = __ BytecodeOperandIdx(2); | 252 Node* raw_slot = __ BytecodeOperandIdx8(2); |
| 253 Node* smi_slot = __ SmiTag(raw_slot); | 253 Node* smi_slot = __ SmiTag(raw_slot); |
| 254 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 254 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
| 255 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, value, | 255 Node* result = __ CallIC(ic.descriptor(), code_target, object, name, value, |
| 256 smi_slot, type_feedback_vector); | 256 smi_slot, type_feedback_vector); |
| 257 __ SetAccumulator(result); | 257 __ SetAccumulator(result); |
| 258 __ Dispatch(); | 258 __ Dispatch(); |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 // StoreIC <object> <name> <slot> | 262 // StoreIC <object> <name> <slot> |
| (...skipping 15 matching lines...) Expand all Loading... |
| 278 Callable ic = | 278 Callable ic = |
| 279 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 279 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
| 280 DoPropertyStoreIC(ic, assembler); | 280 DoPropertyStoreIC(ic, assembler); |
| 281 } | 281 } |
| 282 | 282 |
| 283 | 283 |
| 284 void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, | 284 void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, |
| 285 compiler::InterpreterAssembler* assembler) { | 285 compiler::InterpreterAssembler* assembler) { |
| 286 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized | 286 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized |
| 287 // operations, instead of calling builtins directly. | 287 // operations, instead of calling builtins directly. |
| 288 Node* reg_index = __ BytecodeOperandReg(0); | 288 Node* reg_index = __ BytecodeOperandReg8(0); |
| 289 Node* lhs = __ LoadRegister(reg_index); | 289 Node* lhs = __ LoadRegister(reg_index); |
| 290 Node* rhs = __ GetAccumulator(); | 290 Node* rhs = __ GetAccumulator(); |
| 291 Node* result = __ CallRuntime(function_id, lhs, rhs); | 291 Node* result = __ CallRuntime(function_id, lhs, rhs); |
| 292 __ SetAccumulator(result); | 292 __ SetAccumulator(result); |
| 293 __ Dispatch(); | 293 __ Dispatch(); |
| 294 } | 294 } |
| 295 | 295 |
| 296 | 296 |
| 297 void Interpreter::DoCompareOp(Token::Value op, | 297 void Interpreter::DoCompareOp(Token::Value op, |
| 298 compiler::InterpreterAssembler* assembler) { | 298 compiler::InterpreterAssembler* assembler) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { | 341 void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { |
| 342 DoBinaryOp(Runtime::kModulus, assembler); | 342 DoBinaryOp(Runtime::kModulus, assembler); |
| 343 } | 343 } |
| 344 | 344 |
| 345 | 345 |
| 346 // Call <receiver> <arg_count> | 346 // Call <receiver> <arg_count> |
| 347 // | 347 // |
| 348 // Call a JS function with receiver and |arg_count| arguments in subsequent | 348 // Call a JS function with receiver and |arg_count| arguments in subsequent |
| 349 // registers. The JSfunction or Callable to call is in the accumulator. | 349 // registers. The JSfunction or Callable to call is in the accumulator. |
| 350 void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { | 350 void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { |
| 351 Node* function_reg = __ BytecodeOperandReg(0); | 351 Node* function_reg = __ BytecodeOperandReg8(0); |
| 352 Node* function = __ LoadRegister(function_reg); | 352 Node* function = __ LoadRegister(function_reg); |
| 353 Node* receiver_reg = __ BytecodeOperandReg(1); | 353 Node* receiver_reg = __ BytecodeOperandReg8(1); |
| 354 Node* first_arg = __ RegisterLocation(receiver_reg); | 354 Node* first_arg = __ RegisterLocation(receiver_reg); |
| 355 Node* args_count = __ BytecodeOperandCount(2); | 355 Node* args_count = __ BytecodeOperandCount8(2); |
| 356 Node* result = __ CallJS(function, first_arg, args_count); | 356 Node* result = __ CallJS(function, first_arg, args_count); |
| 357 __ SetAccumulator(result); | 357 __ SetAccumulator(result); |
| 358 __ Dispatch(); | 358 __ Dispatch(); |
| 359 } | 359 } |
| 360 | 360 |
| 361 | 361 |
| 362 // TestEqual <src> | 362 // TestEqual <src> |
| 363 // | 363 // |
| 364 // Test if the value in the <src> register equals the accumulator. | 364 // Test if the value in the <src> register equals the accumulator. |
| 365 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { | 365 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { | 463 void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { |
| 464 Node* relative_jump = __ BytecodeOperandImm8(0); | 464 Node* relative_jump = __ BytecodeOperandImm8(0); |
| 465 __ Jump(relative_jump); | 465 __ Jump(relative_jump); |
| 466 } | 466 } |
| 467 | 467 |
| 468 | 468 |
| 469 // JumpConstant <idx> | 469 // JumpConstant <idx> |
| 470 // | 470 // |
| 471 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool. | 471 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool. |
| 472 void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { | 472 void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { |
| 473 Node* index = __ BytecodeOperandIdx(0); | 473 Node* index = __ BytecodeOperandIdx8(0); |
| 474 Node* constant = __ LoadConstantPoolEntry(index); | 474 Node* constant = __ LoadConstantPoolEntry(index); |
| 475 Node* relative_jump = __ SmiUntag(constant); | 475 Node* relative_jump = __ SmiUntag(constant); |
| 476 __ Jump(relative_jump); | 476 __ Jump(relative_jump); |
| 477 } | 477 } |
| 478 | 478 |
| 479 | 479 |
| 480 // JumpIfTrue <imm8> | 480 // JumpIfTrue <imm8> |
| 481 // | 481 // |
| 482 // Jump by number of bytes represented by an immediate operand if the | 482 // Jump by number of bytes represented by an immediate operand if the |
| 483 // accumulator contains true. | 483 // accumulator contains true. |
| 484 void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { | 484 void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { |
| 485 Node* accumulator = __ GetAccumulator(); | 485 Node* accumulator = __ GetAccumulator(); |
| 486 Node* relative_jump = __ BytecodeOperandImm8(0); | 486 Node* relative_jump = __ BytecodeOperandImm8(0); |
| 487 Node* true_value = __ BooleanConstant(true); | 487 Node* true_value = __ BooleanConstant(true); |
| 488 __ JumpIfWordEqual(accumulator, true_value, relative_jump); | 488 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
| 489 } | 489 } |
| 490 | 490 |
| 491 | 491 |
| 492 // JumpIfTrueConstant <idx> | 492 // JumpIfTrueConstant <idx> |
| 493 // | 493 // |
| 494 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 494 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
| 495 // if the accumulator contains true. | 495 // if the accumulator contains true. |
| 496 void Interpreter::DoJumpIfTrueConstant( | 496 void Interpreter::DoJumpIfTrueConstant( |
| 497 compiler::InterpreterAssembler* assembler) { | 497 compiler::InterpreterAssembler* assembler) { |
| 498 Node* accumulator = __ GetAccumulator(); | 498 Node* accumulator = __ GetAccumulator(); |
| 499 Node* index = __ BytecodeOperandIdx(0); | 499 Node* index = __ BytecodeOperandIdx8(0); |
| 500 Node* constant = __ LoadConstantPoolEntry(index); | 500 Node* constant = __ LoadConstantPoolEntry(index); |
| 501 Node* relative_jump = __ SmiUntag(constant); | 501 Node* relative_jump = __ SmiUntag(constant); |
| 502 Node* true_value = __ BooleanConstant(true); | 502 Node* true_value = __ BooleanConstant(true); |
| 503 __ JumpIfWordEqual(accumulator, true_value, relative_jump); | 503 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
| 504 } | 504 } |
| 505 | 505 |
| 506 | 506 |
| 507 // JumpIfFalse <imm8> | 507 // JumpIfFalse <imm8> |
| 508 // | 508 // |
| 509 // Jump by number of bytes represented by an immediate operand if the | 509 // Jump by number of bytes represented by an immediate operand if the |
| 510 // accumulator contains false. | 510 // accumulator contains false. |
| 511 void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { | 511 void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { |
| 512 Node* accumulator = __ GetAccumulator(); | 512 Node* accumulator = __ GetAccumulator(); |
| 513 Node* relative_jump = __ BytecodeOperandImm8(0); | 513 Node* relative_jump = __ BytecodeOperandImm8(0); |
| 514 Node* false_value = __ BooleanConstant(false); | 514 Node* false_value = __ BooleanConstant(false); |
| 515 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 515 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
| 516 } | 516 } |
| 517 | 517 |
| 518 | 518 |
| 519 // JumpIfFalseConstant <idx> | 519 // JumpIfFalseConstant <idx> |
| 520 // | 520 // |
| 521 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 521 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
| 522 // if the accumulator contains false. | 522 // if the accumulator contains false. |
| 523 void Interpreter::DoJumpIfFalseConstant( | 523 void Interpreter::DoJumpIfFalseConstant( |
| 524 compiler::InterpreterAssembler* assembler) { | 524 compiler::InterpreterAssembler* assembler) { |
| 525 Node* accumulator = __ GetAccumulator(); | 525 Node* accumulator = __ GetAccumulator(); |
| 526 Node* index = __ BytecodeOperandIdx(0); | 526 Node* index = __ BytecodeOperandIdx8(0); |
| 527 Node* constant = __ LoadConstantPoolEntry(index); | 527 Node* constant = __ LoadConstantPoolEntry(index); |
| 528 Node* relative_jump = __ SmiUntag(constant); | 528 Node* relative_jump = __ SmiUntag(constant); |
| 529 Node* false_value = __ BooleanConstant(false); | 529 Node* false_value = __ BooleanConstant(false); |
| 530 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 530 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
| 531 } | 531 } |
| 532 | 532 |
| 533 | 533 |
| 534 // Return | 534 // Return |
| 535 // | 535 // |
| 536 // Return the value in register 0. | 536 // Return the value in register 0. |
| 537 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { | 537 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { |
| 538 __ Return(); | 538 __ Return(); |
| 539 } | 539 } |
| 540 | 540 |
| 541 | 541 |
| 542 } // namespace interpreter | 542 } // namespace interpreter |
| 543 } // namespace internal | 543 } // namespace internal |
| 544 } // namespace v8 | 544 } // namespace v8 |
| OLD | NEW |