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