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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 // operations, instead of calling builtins directly. | 287 // operations, instead of calling builtins directly. |
288 Node* reg_index = __ BytecodeOperandReg(0); | 288 Node* reg_index = __ BytecodeOperandReg(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, |
| 298 compiler::InterpreterAssembler* assembler) { |
| 299 // TODO(oth): placeholder until compare path fixed. |
| 300 // The accumulator should be set to true on success (or false otherwise) |
| 301 // by the comparisons so it can be used for conditional jumps. |
| 302 DoLdaTrue(assembler); |
| 303 } |
| 304 |
| 305 |
297 // Add <src> | 306 // Add <src> |
298 // | 307 // |
299 // Add register <src> to accumulator. | 308 // Add register <src> to accumulator. |
300 void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) { | 309 void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) { |
301 DoBinaryOp(Runtime::kAdd, assembler); | 310 DoBinaryOp(Runtime::kAdd, assembler); |
302 } | 311 } |
303 | 312 |
304 | 313 |
305 // Sub <src> | 314 // Sub <src> |
306 // | 315 // |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 Node* function = __ LoadRegister(function_reg); | 352 Node* function = __ LoadRegister(function_reg); |
344 Node* receiver_reg = __ BytecodeOperandReg(1); | 353 Node* receiver_reg = __ BytecodeOperandReg(1); |
345 Node* first_arg = __ RegisterLocation(receiver_reg); | 354 Node* first_arg = __ RegisterLocation(receiver_reg); |
346 Node* args_count = __ BytecodeOperandCount(2); | 355 Node* args_count = __ BytecodeOperandCount(2); |
347 Node* result = __ CallJS(function, first_arg, args_count); | 356 Node* result = __ CallJS(function, first_arg, args_count); |
348 __ SetAccumulator(result); | 357 __ SetAccumulator(result); |
349 __ Dispatch(); | 358 __ Dispatch(); |
350 } | 359 } |
351 | 360 |
352 | 361 |
| 362 // TestEqual <src> |
| 363 // |
| 364 // Test if the value in the <src> register equals the accumulator. |
| 365 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { |
| 366 DoCompareOp(Token::Value::EQ, assembler); |
| 367 } |
| 368 |
| 369 |
| 370 // TestNotEqual <src> |
| 371 // |
| 372 // Test if the value in the <src> register is not equal to the accumulator. |
| 373 void Interpreter::DoTestNotEqual(compiler::InterpreterAssembler* assembler) { |
| 374 DoCompareOp(Token::Value::NE, assembler); |
| 375 } |
| 376 |
| 377 |
| 378 // TestEqualStrict <src> |
| 379 // |
| 380 // Test if the value in the <src> register is strictly equal to the accumulator. |
| 381 void Interpreter::DoTestEqualStrict(compiler::InterpreterAssembler* assembler) { |
| 382 DoCompareOp(Token::Value::EQ_STRICT, assembler); |
| 383 } |
| 384 |
| 385 |
| 386 // TestNotEqualStrict <src> |
| 387 // |
| 388 // Test if the value in the <src> register is not strictly equal to the |
| 389 // accumulator. |
| 390 void Interpreter::DoTestNotEqualStrict( |
| 391 compiler::InterpreterAssembler* assembler) { |
| 392 DoCompareOp(Token::Value::NE_STRICT, assembler); |
| 393 } |
| 394 |
| 395 |
| 396 // TestLessThan <src> |
| 397 // |
| 398 // Test if the value in the <src> register is less than the accumulator. |
| 399 void Interpreter::DoTestLessThan(compiler::InterpreterAssembler* assembler) { |
| 400 DoCompareOp(Token::Value::LT, assembler); |
| 401 } |
| 402 |
| 403 |
| 404 // TestGreaterThan <src> |
| 405 // |
| 406 // Test if the value in the <src> register is greater than the accumulator. |
| 407 void Interpreter::DoTestGreaterThan(compiler::InterpreterAssembler* assembler) { |
| 408 DoCompareOp(Token::Value::GT, assembler); |
| 409 } |
| 410 |
| 411 |
| 412 // TestLessThanEqual <src> |
| 413 // |
| 414 // Test if the value in the <src> register is less than or equal to the |
| 415 // accumulator. |
| 416 void Interpreter::DoTestLessThanEqual( |
| 417 compiler::InterpreterAssembler* assembler) { |
| 418 DoCompareOp(Token::Value::LTE, assembler); |
| 419 } |
| 420 |
| 421 |
| 422 // TestGreaterThanEqual <src> |
| 423 // |
| 424 // Test if the value in the <src> register is greater than or equal to the |
| 425 // accumulator. |
| 426 void Interpreter::DoTestGreaterThanEqual( |
| 427 compiler::InterpreterAssembler* assembler) { |
| 428 DoCompareOp(Token::Value::GTE, assembler); |
| 429 } |
| 430 |
| 431 |
| 432 // TestIn <src> |
| 433 // |
| 434 // Test if the value in the <src> register is in the collection referenced |
| 435 // by the accumulator. |
| 436 void Interpreter::DoTestIn(compiler::InterpreterAssembler* assembler) { |
| 437 DoCompareOp(Token::Value::IN, assembler); |
| 438 } |
| 439 |
| 440 |
| 441 // TestInstanceOf <src> |
| 442 // |
| 443 // Test if the object referenced by the <src> register is an an instance of type |
| 444 // referenced by the accumulator. |
| 445 void Interpreter::DoTestInstanceOf(compiler::InterpreterAssembler* assembler) { |
| 446 DoCompareOp(Token::Value::INSTANCEOF, assembler); |
| 447 } |
| 448 |
| 449 |
| 450 // ToBoolean |
| 451 // |
| 452 // Cast the object referenced by the accumulator to a boolean. |
| 453 void Interpreter::DoToBoolean(compiler::InterpreterAssembler* assembler) { |
| 454 // TODO(oth): The next CL for test operations has interpreter specific |
| 455 // runtime calls. This looks like another candidate. |
| 456 __ Dispatch(); |
| 457 } |
| 458 |
| 459 |
| 460 // Jump <imm8> |
| 461 // |
| 462 // Jump by number of bytes represented by an immediate operand. |
| 463 void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { |
| 464 Node* relative_jump = __ BytecodeOperandImm8(0); |
| 465 __ Jump(relative_jump); |
| 466 } |
| 467 |
| 468 |
| 469 // JumpConstant <idx> |
| 470 // |
| 471 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool. |
| 472 void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { |
| 473 Node* index = __ BytecodeOperandIdx(0); |
| 474 Node* constant = __ LoadConstantPoolEntry(index); |
| 475 Node* relative_jump = __ SmiUntag(constant); |
| 476 __ Jump(relative_jump); |
| 477 } |
| 478 |
| 479 |
| 480 // JumpIfTrue <imm8> |
| 481 // |
| 482 // Jump by number of bytes represented by an immediate operand if the |
| 483 // accumulator contains true. |
| 484 void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { |
| 485 Node* accumulator = __ GetAccumulator(); |
| 486 Node* relative_jump = __ BytecodeOperandImm8(0); |
| 487 Node* true_value = __ BooleanConstant(true); |
| 488 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
| 489 } |
| 490 |
| 491 |
| 492 // JumpIfTrueConstant <idx> |
| 493 // |
| 494 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
| 495 // if the accumulator contains true. |
| 496 void Interpreter::DoJumpIfTrueConstant( |
| 497 compiler::InterpreterAssembler* assembler) { |
| 498 Node* accumulator = __ GetAccumulator(); |
| 499 Node* index = __ BytecodeOperandIdx(0); |
| 500 Node* constant = __ LoadConstantPoolEntry(index); |
| 501 Node* relative_jump = __ SmiUntag(constant); |
| 502 Node* true_value = __ BooleanConstant(true); |
| 503 __ JumpIfWordEqual(accumulator, true_value, relative_jump); |
| 504 } |
| 505 |
| 506 |
| 507 // JumpIfFalse <imm8> |
| 508 // |
| 509 // Jump by number of bytes represented by an immediate operand if the |
| 510 // accumulator contains false. |
| 511 void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { |
| 512 Node* accumulator = __ GetAccumulator(); |
| 513 Node* relative_jump = __ BytecodeOperandImm8(0); |
| 514 Node* false_value = __ BooleanConstant(false); |
| 515 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
| 516 } |
| 517 |
| 518 |
| 519 // JumpIfFalseConstant <idx> |
| 520 // |
| 521 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
| 522 // if the accumulator contains false. |
| 523 void Interpreter::DoJumpIfFalseConstant( |
| 524 compiler::InterpreterAssembler* assembler) { |
| 525 Node* accumulator = __ GetAccumulator(); |
| 526 Node* index = __ BytecodeOperandIdx(0); |
| 527 Node* constant = __ LoadConstantPoolEntry(index); |
| 528 Node* relative_jump = __ SmiUntag(constant); |
| 529 Node* false_value = __ BooleanConstant(false); |
| 530 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
| 531 } |
| 532 |
| 533 |
353 // Return | 534 // Return |
354 // | 535 // |
355 // Return the value in register 0. | 536 // Return the value in register 0. |
356 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { | 537 void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { |
357 __ Return(); | 538 __ Return(); |
358 } | 539 } |
359 | 540 |
360 | 541 |
361 } // namespace interpreter | 542 } // namespace interpreter |
362 } // namespace internal | 543 } // namespace internal |
363 } // namespace v8 | 544 } // namespace v8 |
OLD | NEW |