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 <fstream> | 7 #include <fstream> |
8 | 8 |
9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 __ Dispatch(); | 286 __ Dispatch(); |
287 } | 287 } |
288 | 288 |
289 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) { | 289 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) { |
290 Node* index = __ BytecodeOperandIdx(0); | 290 Node* index = __ BytecodeOperandIdx(0); |
291 Node* constant = __ LoadConstantPoolEntry(index); | 291 Node* constant = __ LoadConstantPoolEntry(index); |
292 __ SetAccumulator(constant); | 292 __ SetAccumulator(constant); |
293 __ Dispatch(); | 293 __ Dispatch(); |
294 } | 294 } |
295 | 295 |
296 | |
297 // LdaConstant <idx> | 296 // LdaConstant <idx> |
298 // | 297 // |
299 // Load constant literal at |idx| in the constant pool into the accumulator. | 298 // Load constant literal at |idx| in the constant pool into the accumulator. |
300 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) { | 299 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) { |
301 DoLoadConstant(assembler); | 300 DoLoadConstant(assembler); |
302 } | 301 } |
303 | 302 |
304 // LdaUndefined | 303 // LdaUndefined |
305 // | 304 // |
306 // Load Undefined into the accumulator. | 305 // Load Undefined into the accumulator. |
307 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) { | 306 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) { |
308 Node* undefined_value = | 307 Node* undefined_value = |
309 __ HeapConstant(isolate_->factory()->undefined_value()); | 308 __ HeapConstant(isolate_->factory()->undefined_value()); |
310 __ SetAccumulator(undefined_value); | 309 __ SetAccumulator(undefined_value); |
311 __ Dispatch(); | 310 __ Dispatch(); |
312 } | 311 } |
313 | 312 |
314 | |
315 // LdaNull | 313 // LdaNull |
316 // | 314 // |
317 // Load Null into the accumulator. | 315 // Load Null into the accumulator. |
318 void Interpreter::DoLdaNull(InterpreterAssembler* assembler) { | 316 void Interpreter::DoLdaNull(InterpreterAssembler* assembler) { |
319 Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); | 317 Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); |
320 __ SetAccumulator(null_value); | 318 __ SetAccumulator(null_value); |
321 __ Dispatch(); | 319 __ Dispatch(); |
322 } | 320 } |
323 | 321 |
324 | |
325 // LdaTheHole | 322 // LdaTheHole |
326 // | 323 // |
327 // Load TheHole into the accumulator. | 324 // Load TheHole into the accumulator. |
328 void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) { | 325 void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) { |
329 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); | 326 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); |
330 __ SetAccumulator(the_hole_value); | 327 __ SetAccumulator(the_hole_value); |
331 __ Dispatch(); | 328 __ Dispatch(); |
332 } | 329 } |
333 | 330 |
334 | |
335 // LdaTrue | 331 // LdaTrue |
336 // | 332 // |
337 // Load True into the accumulator. | 333 // Load True into the accumulator. |
338 void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) { | 334 void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) { |
339 Node* true_value = __ HeapConstant(isolate_->factory()->true_value()); | 335 Node* true_value = __ HeapConstant(isolate_->factory()->true_value()); |
340 __ SetAccumulator(true_value); | 336 __ SetAccumulator(true_value); |
341 __ Dispatch(); | 337 __ Dispatch(); |
342 } | 338 } |
343 | 339 |
344 | |
345 // LdaFalse | 340 // LdaFalse |
346 // | 341 // |
347 // Load False into the accumulator. | 342 // Load False into the accumulator. |
348 void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) { | 343 void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) { |
349 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); | 344 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); |
350 __ SetAccumulator(false_value); | 345 __ SetAccumulator(false_value); |
351 __ Dispatch(); | 346 __ Dispatch(); |
352 } | 347 } |
353 | 348 |
354 | |
355 // Ldar <src> | 349 // Ldar <src> |
356 // | 350 // |
357 // Load accumulator with value from register <src>. | 351 // Load accumulator with value from register <src>. |
358 void Interpreter::DoLdar(InterpreterAssembler* assembler) { | 352 void Interpreter::DoLdar(InterpreterAssembler* assembler) { |
359 Node* reg_index = __ BytecodeOperandReg(0); | 353 Node* reg_index = __ BytecodeOperandReg(0); |
360 Node* value = __ LoadRegister(reg_index); | 354 Node* value = __ LoadRegister(reg_index); |
361 __ SetAccumulator(value); | 355 __ SetAccumulator(value); |
362 __ Dispatch(); | 356 __ Dispatch(); |
363 } | 357 } |
364 | 358 |
365 | |
366 // Star <dst> | 359 // Star <dst> |
367 // | 360 // |
368 // Store accumulator to register <dst>. | 361 // Store accumulator to register <dst>. |
369 void Interpreter::DoStar(InterpreterAssembler* assembler) { | 362 void Interpreter::DoStar(InterpreterAssembler* assembler) { |
370 Node* reg_index = __ BytecodeOperandReg(0); | 363 Node* reg_index = __ BytecodeOperandReg(0); |
371 Node* accumulator = __ GetAccumulator(); | 364 Node* accumulator = __ GetAccumulator(); |
372 __ StoreRegister(accumulator, reg_index); | 365 __ StoreRegister(accumulator, reg_index); |
373 __ Dispatch(); | 366 __ Dispatch(); |
374 } | 367 } |
375 | 368 |
376 | |
377 // Mov <src> <dst> | 369 // Mov <src> <dst> |
378 // | 370 // |
379 // Stores the value of register <src> to register <dst>. | 371 // Stores the value of register <src> to register <dst>. |
380 void Interpreter::DoMov(InterpreterAssembler* assembler) { | 372 void Interpreter::DoMov(InterpreterAssembler* assembler) { |
381 Node* src_index = __ BytecodeOperandReg(0); | 373 Node* src_index = __ BytecodeOperandReg(0); |
382 Node* src_value = __ LoadRegister(src_index); | 374 Node* src_value = __ LoadRegister(src_index); |
383 Node* dst_index = __ BytecodeOperandReg(1); | 375 Node* dst_index = __ BytecodeOperandReg(1); |
384 __ StoreRegister(src_value, dst_index); | 376 __ StoreRegister(src_value, dst_index); |
385 __ Dispatch(); | 377 __ Dispatch(); |
386 } | 378 } |
387 | 379 |
388 | |
389 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) { | 380 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) { |
390 // Get the global object. | 381 // Get the global object. |
391 Node* context = __ GetContext(); | 382 Node* context = __ GetContext(); |
392 Node* native_context = | 383 Node* native_context = |
393 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); | 384 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); |
394 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); | 385 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); |
395 | 386 |
396 // Load the global via the LoadIC. | 387 // Load the global via the LoadIC. |
397 Node* code_target = __ HeapConstant(ic.code()); | 388 Node* code_target = __ HeapConstant(ic.code()); |
398 Node* constant_index = __ BytecodeOperandIdx(0); | 389 Node* constant_index = __ BytecodeOperandIdx(0); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 Node* name = __ LoadConstantPoolEntry(constant_index); | 430 Node* name = __ LoadConstantPoolEntry(constant_index); |
440 Node* value = __ GetAccumulator(); | 431 Node* value = __ GetAccumulator(); |
441 Node* raw_slot = __ BytecodeOperandIdx(1); | 432 Node* raw_slot = __ BytecodeOperandIdx(1); |
442 Node* smi_slot = __ SmiTag(raw_slot); | 433 Node* smi_slot = __ SmiTag(raw_slot); |
443 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 434 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
444 __ CallStub(ic.descriptor(), code_target, context, global, name, value, | 435 __ CallStub(ic.descriptor(), code_target, context, global, name, value, |
445 smi_slot, type_feedback_vector); | 436 smi_slot, type_feedback_vector); |
446 __ Dispatch(); | 437 __ Dispatch(); |
447 } | 438 } |
448 | 439 |
449 | |
450 // StaGlobalSloppy <name_index> <slot> | 440 // StaGlobalSloppy <name_index> <slot> |
451 // | 441 // |
452 // Store the value in the accumulator into the global with name in constant pool | 442 // Store the value in the accumulator into the global with name in constant pool |
453 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. | 443 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. |
454 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { | 444 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { |
455 Callable ic = | 445 Callable ic = |
456 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 446 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
457 DoStoreGlobal(ic, assembler); | 447 DoStoreGlobal(ic, assembler); |
458 } | 448 } |
459 | 449 |
460 | |
461 // StaGlobalStrict <name_index> <slot> | 450 // StaGlobalStrict <name_index> <slot> |
462 // | 451 // |
463 // Store the value in the accumulator into the global with name in constant pool | 452 // Store the value in the accumulator into the global with name in constant pool |
464 // entry <name_index> using FeedBackVector slot <slot> in strict mode. | 453 // entry <name_index> using FeedBackVector slot <slot> in strict mode. |
465 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) { | 454 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) { |
466 Callable ic = | 455 Callable ic = |
467 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); | 456 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); |
468 DoStoreGlobal(ic, assembler); | 457 DoStoreGlobal(ic, assembler); |
469 } | 458 } |
470 | 459 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 } | 522 } |
534 | 523 |
535 // StaLookupSlotSloppy <name_index> | 524 // StaLookupSlotSloppy <name_index> |
536 // | 525 // |
537 // Store the object in accumulator to the object with the name in constant | 526 // Store the object in accumulator to the object with the name in constant |
538 // pool entry |name_index| in sloppy mode. | 527 // pool entry |name_index| in sloppy mode. |
539 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) { | 528 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) { |
540 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler); | 529 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler); |
541 } | 530 } |
542 | 531 |
543 | |
544 // StaLookupSlotStrict <name_index> | 532 // StaLookupSlotStrict <name_index> |
545 // | 533 // |
546 // Store the object in accumulator to the object with the name in constant | 534 // Store the object in accumulator to the object with the name in constant |
547 // pool entry |name_index| in strict mode. | 535 // pool entry |name_index| in strict mode. |
548 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { | 536 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { |
549 DoStoreLookupSlot(LanguageMode::STRICT, assembler); | 537 DoStoreLookupSlot(LanguageMode::STRICT, assembler); |
550 } | 538 } |
551 | 539 |
552 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) { | 540 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) { |
553 Node* code_target = __ HeapConstant(ic.code()); | 541 Node* code_target = __ HeapConstant(ic.code()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 Node* value = __ GetAccumulator(); | 597 Node* value = __ GetAccumulator(); |
610 Node* raw_slot = __ BytecodeOperandIdx(2); | 598 Node* raw_slot = __ BytecodeOperandIdx(2); |
611 Node* smi_slot = __ SmiTag(raw_slot); | 599 Node* smi_slot = __ SmiTag(raw_slot); |
612 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 600 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
613 Node* context = __ GetContext(); | 601 Node* context = __ GetContext(); |
614 __ CallStub(ic.descriptor(), code_target, context, object, name, value, | 602 __ CallStub(ic.descriptor(), code_target, context, object, name, value, |
615 smi_slot, type_feedback_vector); | 603 smi_slot, type_feedback_vector); |
616 __ Dispatch(); | 604 __ Dispatch(); |
617 } | 605 } |
618 | 606 |
619 | |
620 // StoreICSloppy <object> <name_index> <slot> | 607 // StoreICSloppy <object> <name_index> <slot> |
621 // | 608 // |
622 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and | 609 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and |
623 // the name in constant pool entry <name_index> with the value in the | 610 // the name in constant pool entry <name_index> with the value in the |
624 // accumulator. | 611 // accumulator. |
625 void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) { | 612 void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) { |
626 Callable ic = | 613 Callable ic = |
627 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 614 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
628 DoStoreIC(ic, assembler); | 615 DoStoreIC(ic, assembler); |
629 } | 616 } |
630 | 617 |
631 | |
632 // StoreICStrict <object> <name_index> <slot> | 618 // StoreICStrict <object> <name_index> <slot> |
633 // | 619 // |
634 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and | 620 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and |
635 // the name in constant pool entry <name_index> with the value in the | 621 // the name in constant pool entry <name_index> with the value in the |
636 // accumulator. | 622 // accumulator. |
637 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) { | 623 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) { |
638 Callable ic = | 624 Callable ic = |
639 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); | 625 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); |
640 DoStoreIC(ic, assembler); | 626 DoStoreIC(ic, assembler); |
641 } | 627 } |
642 | 628 |
643 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { | 629 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { |
644 Node* code_target = __ HeapConstant(ic.code()); | 630 Node* code_target = __ HeapConstant(ic.code()); |
645 Node* object_reg_index = __ BytecodeOperandReg(0); | 631 Node* object_reg_index = __ BytecodeOperandReg(0); |
646 Node* object = __ LoadRegister(object_reg_index); | 632 Node* object = __ LoadRegister(object_reg_index); |
647 Node* name_reg_index = __ BytecodeOperandReg(1); | 633 Node* name_reg_index = __ BytecodeOperandReg(1); |
648 Node* name = __ LoadRegister(name_reg_index); | 634 Node* name = __ LoadRegister(name_reg_index); |
649 Node* value = __ GetAccumulator(); | 635 Node* value = __ GetAccumulator(); |
650 Node* raw_slot = __ BytecodeOperandIdx(2); | 636 Node* raw_slot = __ BytecodeOperandIdx(2); |
651 Node* smi_slot = __ SmiTag(raw_slot); | 637 Node* smi_slot = __ SmiTag(raw_slot); |
652 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 638 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
653 Node* context = __ GetContext(); | 639 Node* context = __ GetContext(); |
654 __ CallStub(ic.descriptor(), code_target, context, object, name, value, | 640 __ CallStub(ic.descriptor(), code_target, context, object, name, value, |
655 smi_slot, type_feedback_vector); | 641 smi_slot, type_feedback_vector); |
656 __ Dispatch(); | 642 __ Dispatch(); |
657 } | 643 } |
658 | 644 |
659 | |
660 // KeyedStoreICSloppy <object> <key> <slot> | 645 // KeyedStoreICSloppy <object> <key> <slot> |
661 // | 646 // |
662 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> | 647 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> |
663 // and the key <key> with the value in the accumulator. | 648 // and the key <key> with the value in the accumulator. |
664 void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) { | 649 void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) { |
665 Callable ic = | 650 Callable ic = |
666 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 651 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
667 DoKeyedStoreIC(ic, assembler); | 652 DoKeyedStoreIC(ic, assembler); |
668 } | 653 } |
669 | 654 |
670 | |
671 // KeyedStoreICStore <object> <key> <slot> | 655 // KeyedStoreICStore <object> <key> <slot> |
672 // | 656 // |
673 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> | 657 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> |
674 // and the key <key> with the value in the accumulator. | 658 // and the key <key> with the value in the accumulator. |
675 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) { | 659 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) { |
676 Callable ic = | 660 Callable ic = |
677 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); | 661 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); |
678 DoKeyedStoreIC(ic, assembler); | 662 DoKeyedStoreIC(ic, assembler); |
679 } | 663 } |
680 | 664 |
681 // PushContext <context> | 665 // PushContext <context> |
682 // | 666 // |
683 // Saves the current context in <context>, and pushes the accumulator as the | 667 // Saves the current context in <context>, and pushes the accumulator as the |
684 // new current context. | 668 // new current context. |
685 void Interpreter::DoPushContext(InterpreterAssembler* assembler) { | 669 void Interpreter::DoPushContext(InterpreterAssembler* assembler) { |
686 Node* reg_index = __ BytecodeOperandReg(0); | 670 Node* reg_index = __ BytecodeOperandReg(0); |
687 Node* new_context = __ GetAccumulator(); | 671 Node* new_context = __ GetAccumulator(); |
688 Node* old_context = __ GetContext(); | 672 Node* old_context = __ GetContext(); |
689 __ StoreRegister(old_context, reg_index); | 673 __ StoreRegister(old_context, reg_index); |
690 __ SetContext(new_context); | 674 __ SetContext(new_context); |
691 __ Dispatch(); | 675 __ Dispatch(); |
692 } | 676 } |
693 | 677 |
694 | |
695 // PopContext <context> | 678 // PopContext <context> |
696 // | 679 // |
697 // Pops the current context and sets <context> as the new context. | 680 // Pops the current context and sets <context> as the new context. |
698 void Interpreter::DoPopContext(InterpreterAssembler* assembler) { | 681 void Interpreter::DoPopContext(InterpreterAssembler* assembler) { |
699 Node* reg_index = __ BytecodeOperandReg(0); | 682 Node* reg_index = __ BytecodeOperandReg(0); |
700 Node* context = __ LoadRegister(reg_index); | 683 Node* context = __ LoadRegister(reg_index); |
701 __ SetContext(context); | 684 __ SetContext(context); |
702 __ Dispatch(); | 685 __ Dispatch(); |
703 } | 686 } |
704 | 687 |
705 void Interpreter::DoBinaryOp(Callable callable, | 688 void Interpreter::DoBinaryOp(Callable callable, |
706 InterpreterAssembler* assembler) { | 689 InterpreterAssembler* assembler) { |
707 // TODO(bmeurer): Collect definition side type feedback for various | 690 // TODO(bmeurer): Collect definition side type feedback for various |
708 // binary operations. | 691 // binary operations. |
709 Node* target = __ HeapConstant(callable.code()); | 692 Node* target = __ HeapConstant(callable.code()); |
710 Node* reg_index = __ BytecodeOperandReg(0); | 693 Node* reg_index = __ BytecodeOperandReg(0); |
711 Node* lhs = __ LoadRegister(reg_index); | 694 Node* lhs = __ LoadRegister(reg_index); |
712 Node* rhs = __ GetAccumulator(); | 695 Node* rhs = __ GetAccumulator(); |
713 Node* context = __ GetContext(); | 696 Node* context = __ GetContext(); |
714 Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs); | 697 Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs); |
715 __ SetAccumulator(result); | 698 __ SetAccumulator(result); |
716 __ Dispatch(); | 699 __ Dispatch(); |
717 } | 700 } |
718 | 701 |
719 void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, | |
720 InterpreterAssembler* assembler) { | |
721 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized | |
722 // operations, instead of calling builtins directly. | |
723 Node* reg_index = __ BytecodeOperandReg(0); | |
724 Node* lhs = __ LoadRegister(reg_index); | |
725 Node* rhs = __ GetAccumulator(); | |
726 Node* context = __ GetContext(); | |
727 Node* result = __ CallRuntime(function_id, context, lhs, rhs); | |
728 __ SetAccumulator(result); | |
729 __ Dispatch(); | |
730 } | |
731 | |
732 template <class Generator> | 702 template <class Generator> |
733 void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) { | 703 void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) { |
734 Node* reg_index = __ BytecodeOperandReg(0); | 704 Node* reg_index = __ BytecodeOperandReg(0); |
735 Node* lhs = __ LoadRegister(reg_index); | 705 Node* lhs = __ LoadRegister(reg_index); |
736 Node* rhs = __ GetAccumulator(); | 706 Node* rhs = __ GetAccumulator(); |
737 Node* context = __ GetContext(); | 707 Node* context = __ GetContext(); |
738 Node* result = Generator::Generate(assembler, lhs, rhs, context); | 708 Node* result = Generator::Generate(assembler, lhs, rhs, context); |
739 __ SetAccumulator(result); | 709 __ SetAccumulator(result); |
740 __ Dispatch(); | 710 __ Dispatch(); |
741 } | 711 } |
742 | 712 |
743 // Add <src> | 713 // Add <src> |
744 // | 714 // |
745 // Add register <src> to accumulator. | 715 // Add register <src> to accumulator. |
746 void Interpreter::DoAdd(InterpreterAssembler* assembler) { | 716 void Interpreter::DoAdd(InterpreterAssembler* assembler) { |
747 DoBinaryOp<AddStub>(assembler); | 717 DoBinaryOp<AddStub>(assembler); |
748 } | 718 } |
749 | 719 |
750 | |
751 // Sub <src> | 720 // Sub <src> |
752 // | 721 // |
753 // Subtract register <src> from accumulator. | 722 // Subtract register <src> from accumulator. |
754 void Interpreter::DoSub(InterpreterAssembler* assembler) { | 723 void Interpreter::DoSub(InterpreterAssembler* assembler) { |
755 DoBinaryOp<SubtractStub>(assembler); | 724 DoBinaryOp<SubtractStub>(assembler); |
756 } | 725 } |
757 | 726 |
758 | |
759 // Mul <src> | 727 // Mul <src> |
760 // | 728 // |
761 // Multiply accumulator by register <src>. | 729 // Multiply accumulator by register <src>. |
762 void Interpreter::DoMul(InterpreterAssembler* assembler) { | 730 void Interpreter::DoMul(InterpreterAssembler* assembler) { |
763 DoBinaryOp<MultiplyStub>(assembler); | 731 DoBinaryOp<MultiplyStub>(assembler); |
764 } | 732 } |
765 | 733 |
766 | |
767 // Div <src> | 734 // Div <src> |
768 // | 735 // |
769 // Divide register <src> by accumulator. | 736 // Divide register <src> by accumulator. |
770 void Interpreter::DoDiv(InterpreterAssembler* assembler) { | 737 void Interpreter::DoDiv(InterpreterAssembler* assembler) { |
771 DoBinaryOp<DivideStub>(assembler); | 738 DoBinaryOp<DivideStub>(assembler); |
772 } | 739 } |
773 | 740 |
774 | |
775 // Mod <src> | 741 // Mod <src> |
776 // | 742 // |
777 // Modulo register <src> by accumulator. | 743 // Modulo register <src> by accumulator. |
778 void Interpreter::DoMod(InterpreterAssembler* assembler) { | 744 void Interpreter::DoMod(InterpreterAssembler* assembler) { |
779 DoBinaryOp<ModulusStub>(assembler); | 745 DoBinaryOp<ModulusStub>(assembler); |
780 } | 746 } |
781 | 747 |
782 | |
783 // BitwiseOr <src> | 748 // BitwiseOr <src> |
784 // | 749 // |
785 // BitwiseOr register <src> to accumulator. | 750 // BitwiseOr register <src> to accumulator. |
786 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { | 751 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { |
787 DoBinaryOp<BitwiseOrStub>(assembler); | 752 DoBinaryOp<BitwiseOrStub>(assembler); |
788 } | 753 } |
789 | 754 |
790 | |
791 // BitwiseXor <src> | 755 // BitwiseXor <src> |
792 // | 756 // |
793 // BitwiseXor register <src> to accumulator. | 757 // BitwiseXor register <src> to accumulator. |
794 void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) { | 758 void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) { |
795 DoBinaryOp<BitwiseXorStub>(assembler); | 759 DoBinaryOp<BitwiseXorStub>(assembler); |
796 } | 760 } |
797 | 761 |
798 | |
799 // BitwiseAnd <src> | 762 // BitwiseAnd <src> |
800 // | 763 // |
801 // BitwiseAnd register <src> to accumulator. | 764 // BitwiseAnd register <src> to accumulator. |
802 void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) { | 765 void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) { |
803 DoBinaryOp<BitwiseAndStub>(assembler); | 766 DoBinaryOp<BitwiseAndStub>(assembler); |
804 } | 767 } |
805 | 768 |
806 | |
807 // ShiftLeft <src> | 769 // ShiftLeft <src> |
808 // | 770 // |
809 // Left shifts register <src> by the count specified in the accumulator. | 771 // Left shifts register <src> by the count specified in the accumulator. |
810 // Register <src> is converted to an int32 and the accumulator to uint32 | 772 // Register <src> is converted to an int32 and the accumulator to uint32 |
811 // before the operation. 5 lsb bits from the accumulator are used as count | 773 // before the operation. 5 lsb bits from the accumulator are used as count |
812 // i.e. <src> << (accumulator & 0x1F). | 774 // i.e. <src> << (accumulator & 0x1F). |
813 void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) { | 775 void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) { |
814 DoBinaryOp<ShiftLeftStub>(assembler); | 776 DoBinaryOp<ShiftLeftStub>(assembler); |
815 } | 777 } |
816 | 778 |
817 | |
818 // ShiftRight <src> | 779 // ShiftRight <src> |
819 // | 780 // |
820 // Right shifts register <src> by the count specified in the accumulator. | 781 // Right shifts register <src> by the count specified in the accumulator. |
821 // Result is sign extended. Register <src> is converted to an int32 and the | 782 // Result is sign extended. Register <src> is converted to an int32 and the |
822 // accumulator to uint32 before the operation. 5 lsb bits from the accumulator | 783 // accumulator to uint32 before the operation. 5 lsb bits from the accumulator |
823 // are used as count i.e. <src> >> (accumulator & 0x1F). | 784 // are used as count i.e. <src> >> (accumulator & 0x1F). |
824 void Interpreter::DoShiftRight(InterpreterAssembler* assembler) { | 785 void Interpreter::DoShiftRight(InterpreterAssembler* assembler) { |
825 DoBinaryOp<ShiftRightStub>(assembler); | 786 DoBinaryOp<ShiftRightStub>(assembler); |
826 } | 787 } |
827 | 788 |
828 | |
829 // ShiftRightLogical <src> | 789 // ShiftRightLogical <src> |
830 // | 790 // |
831 // Right Shifts register <src> by the count specified in the accumulator. | 791 // Right Shifts register <src> by the count specified in the accumulator. |
832 // Result is zero-filled. The accumulator and register <src> are converted to | 792 // Result is zero-filled. The accumulator and register <src> are converted to |
833 // uint32 before the operation 5 lsb bits from the accumulator are used as | 793 // uint32 before the operation 5 lsb bits from the accumulator are used as |
834 // count i.e. <src> << (accumulator & 0x1F). | 794 // count i.e. <src> << (accumulator & 0x1F). |
835 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { | 795 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { |
836 DoBinaryOp<ShiftRightLogicalStub>(assembler); | 796 DoBinaryOp<ShiftRightLogicalStub>(assembler); |
837 } | 797 } |
838 | 798 |
| 799 void Interpreter::DoUnaryOp(Callable callable, |
| 800 InterpreterAssembler* assembler) { |
| 801 Node* target = __ HeapConstant(callable.code()); |
| 802 Node* accumulator = __ GetAccumulator(); |
| 803 Node* context = __ GetContext(); |
| 804 Node* result = |
| 805 __ CallStub(callable.descriptor(), target, context, accumulator); |
| 806 __ SetAccumulator(result); |
| 807 __ Dispatch(); |
| 808 } |
| 809 |
839 template <class Generator> | 810 template <class Generator> |
840 void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) { | 811 void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) { |
841 Node* value = __ GetAccumulator(); | 812 Node* value = __ GetAccumulator(); |
842 Node* context = __ GetContext(); | 813 Node* context = __ GetContext(); |
843 Node* result = Generator::Generate(assembler, value, context); | 814 Node* result = Generator::Generate(assembler, value, context); |
844 __ SetAccumulator(result); | 815 __ SetAccumulator(result); |
845 __ Dispatch(); | 816 __ Dispatch(); |
846 } | 817 } |
847 | 818 |
| 819 // ToName |
| 820 // |
| 821 // Cast the object referenced by the accumulator to a name. |
| 822 void Interpreter::DoToName(InterpreterAssembler* assembler) { |
| 823 DoUnaryOp(CodeFactory::ToName(isolate_), assembler); |
| 824 } |
| 825 |
| 826 // ToNumber |
| 827 // |
| 828 // Cast the object referenced by the accumulator to a number. |
| 829 void Interpreter::DoToNumber(InterpreterAssembler* assembler) { |
| 830 DoUnaryOp(CodeFactory::ToNumber(isolate_), assembler); |
| 831 } |
| 832 |
| 833 // ToObject |
| 834 // |
| 835 // Cast the object referenced by the accumulator to a JSObject. |
| 836 void Interpreter::DoToObject(InterpreterAssembler* assembler) { |
| 837 DoUnaryOp(CodeFactory::ToObject(isolate_), assembler); |
| 838 } |
| 839 |
848 // Inc | 840 // Inc |
849 // | 841 // |
850 // Increments value in the accumulator by one. | 842 // Increments value in the accumulator by one. |
851 void Interpreter::DoInc(InterpreterAssembler* assembler) { | 843 void Interpreter::DoInc(InterpreterAssembler* assembler) { |
852 DoUnaryOp<IncStub>(assembler); | 844 DoUnaryOp<IncStub>(assembler); |
853 } | 845 } |
854 | 846 |
855 // Dec | 847 // Dec |
856 // | 848 // |
857 // Decrements value in the accumulator by one. | 849 // Decrements value in the accumulator by one. |
858 void Interpreter::DoDec(InterpreterAssembler* assembler) { | 850 void Interpreter::DoDec(InterpreterAssembler* assembler) { |
859 DoUnaryOp<DecStub>(assembler); | 851 DoUnaryOp<DecStub>(assembler); |
860 } | 852 } |
861 | 853 |
862 void Interpreter::DoLogicalNotOp(Node* value, InterpreterAssembler* assembler) { | 854 Node* Interpreter::BuildToBoolean(Node* value, |
| 855 InterpreterAssembler* assembler) { |
| 856 Node* context = __ GetContext(); |
| 857 return ToBooleanStub::Generate(assembler, value, context); |
| 858 } |
| 859 |
| 860 Node* Interpreter::BuildLogicalNot(Node* value, |
| 861 InterpreterAssembler* assembler) { |
| 862 Variable result(assembler, MachineRepresentation::kTagged); |
863 Label if_true(assembler), if_false(assembler), end(assembler); | 863 Label if_true(assembler), if_false(assembler), end(assembler); |
864 Node* true_value = __ BooleanConstant(true); | 864 Node* true_value = __ BooleanConstant(true); |
865 Node* false_value = __ BooleanConstant(false); | 865 Node* false_value = __ BooleanConstant(false); |
866 __ BranchIfWordEqual(value, true_value, &if_true, &if_false); | 866 __ BranchIfWordEqual(value, true_value, &if_true, &if_false); |
867 __ Bind(&if_true); | 867 __ Bind(&if_true); |
868 { | 868 { |
869 __ SetAccumulator(false_value); | 869 result.Bind(false_value); |
870 __ Goto(&end); | 870 __ Goto(&end); |
871 } | 871 } |
872 __ Bind(&if_false); | 872 __ Bind(&if_false); |
873 { | 873 { |
874 if (FLAG_debug_code) { | 874 if (FLAG_debug_code) { |
875 __ AbortIfWordNotEqual(value, false_value, | 875 __ AbortIfWordNotEqual(value, false_value, |
876 BailoutReason::kExpectedBooleanValue); | 876 BailoutReason::kExpectedBooleanValue); |
877 } | 877 } |
878 __ SetAccumulator(true_value); | 878 result.Bind(true_value); |
879 __ Goto(&end); | 879 __ Goto(&end); |
880 } | 880 } |
881 __ Bind(&end); | 881 __ Bind(&end); |
| 882 return result.value(); |
882 } | 883 } |
883 | 884 |
884 // ToBooleanLogicalNot | 885 // LogicalNot |
885 // | 886 // |
886 // Perform logical-not on the accumulator, first casting the | 887 // Perform logical-not on the accumulator, first casting the |
887 // accumulator to a boolean value if required. | 888 // accumulator to a boolean value if required. |
| 889 // ToBooleanLogicalNot |
888 void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) { | 890 void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) { |
889 Callable callable = CodeFactory::ToBoolean(isolate_); | 891 Node* value = __ GetAccumulator(); |
890 Node* target = __ HeapConstant(callable.code()); | 892 Node* to_boolean_value = BuildToBoolean(value, assembler); |
891 Node* accumulator = __ GetAccumulator(); | 893 Node* result = BuildLogicalNot(to_boolean_value, assembler); |
892 Node* context = __ GetContext(); | 894 __ SetAccumulator(result); |
893 Node* to_boolean_value = | |
894 __ CallStub(callable.descriptor(), target, context, accumulator); | |
895 DoLogicalNotOp(to_boolean_value, assembler); | |
896 __ Dispatch(); | 895 __ Dispatch(); |
897 } | 896 } |
898 | 897 |
899 // LogicalNot | 898 // LogicalNot |
900 // | 899 // |
901 // Perform logical-not on the accumulator, which must already be a boolean | 900 // Perform logical-not on the accumulator, which must already be a boolean |
902 // value. | 901 // value. |
903 void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) { | 902 void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) { |
904 Node* value = __ GetAccumulator(); | 903 Node* value = __ GetAccumulator(); |
905 DoLogicalNotOp(value, assembler); | 904 Node* result = BuildLogicalNot(value, assembler); |
| 905 __ SetAccumulator(result); |
906 __ Dispatch(); | 906 __ Dispatch(); |
907 } | 907 } |
908 | 908 |
909 // TypeOf | 909 // TypeOf |
910 // | 910 // |
911 // Load the accumulator with the string representating type of the | 911 // Load the accumulator with the string representating type of the |
912 // object in the accumulator. | 912 // object in the accumulator. |
913 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { | 913 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { |
914 Callable callable = CodeFactory::Typeof(isolate_); | 914 DoUnaryOp(CodeFactory::Typeof(isolate_), assembler); |
915 Node* target = __ HeapConstant(callable.code()); | |
916 Node* accumulator = __ GetAccumulator(); | |
917 Node* context = __ GetContext(); | |
918 Node* result = | |
919 __ CallStub(callable.descriptor(), target, context, accumulator); | |
920 __ SetAccumulator(result); | |
921 __ Dispatch(); | |
922 } | 915 } |
923 | 916 |
924 void Interpreter::DoDelete(Runtime::FunctionId function_id, | 917 void Interpreter::DoDelete(Runtime::FunctionId function_id, |
925 InterpreterAssembler* assembler) { | 918 InterpreterAssembler* assembler) { |
926 Node* reg_index = __ BytecodeOperandReg(0); | 919 Node* reg_index = __ BytecodeOperandReg(0); |
927 Node* object = __ LoadRegister(reg_index); | 920 Node* object = __ LoadRegister(reg_index); |
928 Node* key = __ GetAccumulator(); | 921 Node* key = __ GetAccumulator(); |
929 Node* context = __ GetContext(); | 922 Node* context = __ GetContext(); |
930 Node* result = __ CallRuntime(function_id, context, object, key); | 923 Node* result = __ CallRuntime(function_id, context, object, key); |
931 __ SetAccumulator(result); | 924 __ SetAccumulator(result); |
932 __ Dispatch(); | 925 __ Dispatch(); |
933 } | 926 } |
934 | 927 |
935 | |
936 // DeletePropertyStrict | 928 // DeletePropertyStrict |
937 // | 929 // |
938 // Delete the property specified in the accumulator from the object | 930 // Delete the property specified in the accumulator from the object |
939 // referenced by the register operand following strict mode semantics. | 931 // referenced by the register operand following strict mode semantics. |
940 void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) { | 932 void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) { |
941 DoDelete(Runtime::kDeleteProperty_Strict, assembler); | 933 DoDelete(Runtime::kDeleteProperty_Strict, assembler); |
942 } | 934 } |
943 | 935 |
944 | |
945 // DeletePropertySloppy | 936 // DeletePropertySloppy |
946 // | 937 // |
947 // Delete the property specified in the accumulator from the object | 938 // Delete the property specified in the accumulator from the object |
948 // referenced by the register operand following sloppy mode semantics. | 939 // referenced by the register operand following sloppy mode semantics. |
949 void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) { | 940 void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) { |
950 DoDelete(Runtime::kDeleteProperty_Sloppy, assembler); | 941 DoDelete(Runtime::kDeleteProperty_Sloppy, assembler); |
951 } | 942 } |
952 | 943 |
953 void Interpreter::DoJSCall(InterpreterAssembler* assembler, | 944 void Interpreter::DoJSCall(InterpreterAssembler* assembler, |
954 TailCallMode tail_call_mode) { | 945 TailCallMode tail_call_mode) { |
955 Node* function_reg = __ BytecodeOperandReg(0); | 946 Node* function_reg = __ BytecodeOperandReg(0); |
956 Node* function = __ LoadRegister(function_reg); | 947 Node* function = __ LoadRegister(function_reg); |
957 Node* receiver_reg = __ BytecodeOperandReg(1); | 948 Node* receiver_reg = __ BytecodeOperandReg(1); |
958 Node* receiver_arg = __ RegisterLocation(receiver_reg); | 949 Node* receiver_arg = __ RegisterLocation(receiver_reg); |
959 Node* receiver_args_count = __ BytecodeOperandCount(2); | 950 Node* receiver_args_count = __ BytecodeOperandCount(2); |
960 Node* receiver_count = __ Int32Constant(1); | 951 Node* receiver_count = __ Int32Constant(1); |
961 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); | 952 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); |
962 Node* context = __ GetContext(); | 953 Node* context = __ GetContext(); |
963 // TODO(rmcilroy): Use the call type feedback slot to call via CallStub. | 954 // TODO(rmcilroy): Use the call type feedback slot to call via CallStub. |
964 Node* result = | 955 Node* result = |
965 __ CallJS(function, context, receiver_arg, args_count, tail_call_mode); | 956 __ CallJS(function, context, receiver_arg, args_count, tail_call_mode); |
966 __ SetAccumulator(result); | 957 __ SetAccumulator(result); |
967 __ Dispatch(); | 958 __ Dispatch(); |
968 } | 959 } |
969 | 960 |
970 | |
971 // Call <callable> <receiver> <arg_count> | 961 // Call <callable> <receiver> <arg_count> |
972 // | 962 // |
973 // Call a JSfunction or Callable in |callable| with the |receiver| and | 963 // Call a JSfunction or Callable in |callable| with the |receiver| and |
974 // |arg_count| arguments in subsequent registers. | 964 // |arg_count| arguments in subsequent registers. |
975 void Interpreter::DoCall(InterpreterAssembler* assembler) { | 965 void Interpreter::DoCall(InterpreterAssembler* assembler) { |
976 DoJSCall(assembler, TailCallMode::kDisallow); | 966 DoJSCall(assembler, TailCallMode::kDisallow); |
977 } | 967 } |
978 | 968 |
979 // TailCall <callable> <receiver> <arg_count> | 969 // TailCall <callable> <receiver> <arg_count> |
980 // | 970 // |
981 // Tail call a JSfunction or Callable in |callable| with the |receiver| and | 971 // Tail call a JSfunction or Callable in |callable| with the |receiver| and |
982 // |arg_count| arguments in subsequent registers. | 972 // |arg_count| arguments in subsequent registers. |
983 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { | 973 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { |
984 DoJSCall(assembler, TailCallMode::kAllow); | 974 DoJSCall(assembler, TailCallMode::kAllow); |
985 } | 975 } |
986 | 976 |
987 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) { | 977 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) { |
988 Node* function_id = __ BytecodeOperandRuntimeId(0); | 978 Node* function_id = __ BytecodeOperandRuntimeId(0); |
989 Node* first_arg_reg = __ BytecodeOperandReg(1); | 979 Node* first_arg_reg = __ BytecodeOperandReg(1); |
990 Node* first_arg = __ RegisterLocation(first_arg_reg); | 980 Node* first_arg = __ RegisterLocation(first_arg_reg); |
991 Node* args_count = __ BytecodeOperandCount(2); | 981 Node* args_count = __ BytecodeOperandCount(2); |
992 Node* context = __ GetContext(); | 982 Node* context = __ GetContext(); |
993 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); | 983 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); |
994 __ SetAccumulator(result); | 984 __ SetAccumulator(result); |
995 __ Dispatch(); | 985 __ Dispatch(); |
996 } | 986 } |
997 | 987 |
998 | |
999 // CallRuntime <function_id> <first_arg> <arg_count> | 988 // CallRuntime <function_id> <first_arg> <arg_count> |
1000 // | 989 // |
1001 // Call the runtime function |function_id| with the first argument in | 990 // Call the runtime function |function_id| with the first argument in |
1002 // register |first_arg| and |arg_count| arguments in subsequent | 991 // register |first_arg| and |arg_count| arguments in subsequent |
1003 // registers. | 992 // registers. |
1004 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { | 993 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { |
1005 DoCallRuntimeCommon(assembler); | 994 DoCallRuntimeCommon(assembler); |
1006 } | 995 } |
1007 | 996 |
1008 // InvokeIntrinsic <function_id> <first_arg> <arg_count> | 997 // InvokeIntrinsic <function_id> <first_arg> <arg_count> |
(...skipping 26 matching lines...) Expand all Loading... |
1035 // Store the results in <first_return> and <first_return + 1> | 1024 // Store the results in <first_return> and <first_return + 1> |
1036 Node* first_return_reg = __ BytecodeOperandReg(3); | 1025 Node* first_return_reg = __ BytecodeOperandReg(3); |
1037 Node* second_return_reg = __ NextRegister(first_return_reg); | 1026 Node* second_return_reg = __ NextRegister(first_return_reg); |
1038 Node* result0 = __ Projection(0, result_pair); | 1027 Node* result0 = __ Projection(0, result_pair); |
1039 Node* result1 = __ Projection(1, result_pair); | 1028 Node* result1 = __ Projection(1, result_pair); |
1040 __ StoreRegister(result0, first_return_reg); | 1029 __ StoreRegister(result0, first_return_reg); |
1041 __ StoreRegister(result1, second_return_reg); | 1030 __ StoreRegister(result1, second_return_reg); |
1042 __ Dispatch(); | 1031 __ Dispatch(); |
1043 } | 1032 } |
1044 | 1033 |
1045 | |
1046 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> | 1034 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> |
1047 // | 1035 // |
1048 // Call the runtime function |function_id| which returns a pair, with the | 1036 // Call the runtime function |function_id| which returns a pair, with the |
1049 // first argument in register |first_arg| and |arg_count| arguments in | 1037 // first argument in register |first_arg| and |arg_count| arguments in |
1050 // subsequent registers. Returns the result in <first_return> and | 1038 // subsequent registers. Returns the result in <first_return> and |
1051 // <first_return + 1> | 1039 // <first_return + 1> |
1052 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { | 1040 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { |
1053 DoCallRuntimeForPairCommon(assembler); | 1041 DoCallRuntimeForPairCommon(assembler); |
1054 } | 1042 } |
1055 | 1043 |
(...skipping 11 matching lines...) Expand all Loading... |
1067 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); | 1055 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); |
1068 Node* function = __ LoadContextSlot(native_context, context_index); | 1056 Node* function = __ LoadContextSlot(native_context, context_index); |
1069 | 1057 |
1070 // Call the function. | 1058 // Call the function. |
1071 Node* result = __ CallJS(function, context, first_arg, args_count, | 1059 Node* result = __ CallJS(function, context, first_arg, args_count, |
1072 TailCallMode::kDisallow); | 1060 TailCallMode::kDisallow); |
1073 __ SetAccumulator(result); | 1061 __ SetAccumulator(result); |
1074 __ Dispatch(); | 1062 __ Dispatch(); |
1075 } | 1063 } |
1076 | 1064 |
1077 | |
1078 // CallJSRuntime <context_index> <receiver> <arg_count> | 1065 // CallJSRuntime <context_index> <receiver> <arg_count> |
1079 // | 1066 // |
1080 // Call the JS runtime function that has the |context_index| with the receiver | 1067 // Call the JS runtime function that has the |context_index| with the receiver |
1081 // in register |receiver| and |arg_count| arguments in subsequent registers. | 1068 // in register |receiver| and |arg_count| arguments in subsequent registers. |
1082 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { | 1069 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { |
1083 DoCallJSRuntimeCommon(assembler); | 1070 DoCallJSRuntimeCommon(assembler); |
1084 } | 1071 } |
1085 | 1072 |
1086 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) { | 1073 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) { |
1087 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); | 1074 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); |
1088 Node* new_target = __ GetAccumulator(); | 1075 Node* new_target = __ GetAccumulator(); |
1089 Node* constructor_reg = __ BytecodeOperandReg(0); | 1076 Node* constructor_reg = __ BytecodeOperandReg(0); |
1090 Node* constructor = __ LoadRegister(constructor_reg); | 1077 Node* constructor = __ LoadRegister(constructor_reg); |
1091 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1078 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1092 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1079 Node* first_arg = __ RegisterLocation(first_arg_reg); |
1093 Node* args_count = __ BytecodeOperandCount(2); | 1080 Node* args_count = __ BytecodeOperandCount(2); |
1094 Node* context = __ GetContext(); | 1081 Node* context = __ GetContext(); |
1095 Node* result = | 1082 Node* result = |
1096 __ CallConstruct(constructor, context, new_target, first_arg, args_count); | 1083 __ CallConstruct(constructor, context, new_target, first_arg, args_count); |
1097 __ SetAccumulator(result); | 1084 __ SetAccumulator(result); |
1098 __ Dispatch(); | 1085 __ Dispatch(); |
1099 } | 1086 } |
1100 | 1087 |
1101 | |
1102 // New <constructor> <first_arg> <arg_count> | 1088 // New <constructor> <first_arg> <arg_count> |
1103 // | 1089 // |
1104 // Call operator new with |constructor| and the first argument in | 1090 // Call operator new with |constructor| and the first argument in |
1105 // register |first_arg| and |arg_count| arguments in subsequent | 1091 // register |first_arg| and |arg_count| arguments in subsequent |
1106 // registers. The new.target is in the accumulator. | 1092 // registers. The new.target is in the accumulator. |
1107 // | 1093 // |
1108 void Interpreter::DoNew(InterpreterAssembler* assembler) { | 1094 void Interpreter::DoNew(InterpreterAssembler* assembler) { |
1109 DoCallConstruct(assembler); | 1095 DoCallConstruct(assembler); |
1110 } | 1096 } |
1111 | 1097 |
1112 // TestEqual <src> | 1098 // TestEqual <src> |
1113 // | 1099 // |
1114 // Test if the value in the <src> register equals the accumulator. | 1100 // Test if the value in the <src> register equals the accumulator. |
1115 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { | 1101 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { |
1116 DoBinaryOp(CodeFactory::Equal(isolate_), assembler); | 1102 DoBinaryOp(CodeFactory::Equal(isolate_), assembler); |
1117 } | 1103 } |
1118 | 1104 |
1119 | |
1120 // TestNotEqual <src> | 1105 // TestNotEqual <src> |
1121 // | 1106 // |
1122 // Test if the value in the <src> register is not equal to the accumulator. | 1107 // Test if the value in the <src> register is not equal to the accumulator. |
1123 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { | 1108 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { |
1124 DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler); | 1109 DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler); |
1125 } | 1110 } |
1126 | 1111 |
1127 | |
1128 // TestEqualStrict <src> | 1112 // TestEqualStrict <src> |
1129 // | 1113 // |
1130 // Test if the value in the <src> register is strictly equal to the accumulator. | 1114 // Test if the value in the <src> register is strictly equal to the accumulator. |
1131 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { | 1115 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { |
1132 DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler); | 1116 DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler); |
1133 } | 1117 } |
1134 | 1118 |
1135 | |
1136 // TestLessThan <src> | 1119 // TestLessThan <src> |
1137 // | 1120 // |
1138 // Test if the value in the <src> register is less than the accumulator. | 1121 // Test if the value in the <src> register is less than the accumulator. |
1139 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { | 1122 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { |
1140 DoBinaryOp(CodeFactory::LessThan(isolate_), assembler); | 1123 DoBinaryOp(CodeFactory::LessThan(isolate_), assembler); |
1141 } | 1124 } |
1142 | 1125 |
1143 | |
1144 // TestGreaterThan <src> | 1126 // TestGreaterThan <src> |
1145 // | 1127 // |
1146 // Test if the value in the <src> register is greater than the accumulator. | 1128 // Test if the value in the <src> register is greater than the accumulator. |
1147 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { | 1129 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { |
1148 DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler); | 1130 DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler); |
1149 } | 1131 } |
1150 | 1132 |
1151 | |
1152 // TestLessThanOrEqual <src> | 1133 // TestLessThanOrEqual <src> |
1153 // | 1134 // |
1154 // Test if the value in the <src> register is less than or equal to the | 1135 // Test if the value in the <src> register is less than or equal to the |
1155 // accumulator. | 1136 // accumulator. |
1156 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { | 1137 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { |
1157 DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler); | 1138 DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler); |
1158 } | 1139 } |
1159 | 1140 |
1160 | |
1161 // TestGreaterThanOrEqual <src> | 1141 // TestGreaterThanOrEqual <src> |
1162 // | 1142 // |
1163 // Test if the value in the <src> register is greater than or equal to the | 1143 // Test if the value in the <src> register is greater than or equal to the |
1164 // accumulator. | 1144 // accumulator. |
1165 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { | 1145 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { |
1166 DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler); | 1146 DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler); |
1167 } | 1147 } |
1168 | 1148 |
1169 | |
1170 // TestIn <src> | 1149 // TestIn <src> |
1171 // | 1150 // |
1172 // Test if the object referenced by the register operand is a property of the | 1151 // Test if the object referenced by the register operand is a property of the |
1173 // object referenced by the accumulator. | 1152 // object referenced by the accumulator. |
1174 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { | 1153 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { |
1175 DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler); | 1154 DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler); |
1176 } | 1155 } |
1177 | 1156 |
1178 | |
1179 // TestInstanceOf <src> | 1157 // TestInstanceOf <src> |
1180 // | 1158 // |
1181 // Test if the object referenced by the <src> register is an an instance of type | 1159 // Test if the object referenced by the <src> register is an an instance of type |
1182 // referenced by the accumulator. | 1160 // referenced by the accumulator. |
1183 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { | 1161 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { |
1184 DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler); | 1162 DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler); |
1185 } | 1163 } |
1186 | 1164 |
1187 void Interpreter::DoTypeConversionOp(Callable callable, | |
1188 InterpreterAssembler* assembler) { | |
1189 Node* target = __ HeapConstant(callable.code()); | |
1190 Node* accumulator = __ GetAccumulator(); | |
1191 Node* context = __ GetContext(); | |
1192 Node* result = | |
1193 __ CallStub(callable.descriptor(), target, context, accumulator); | |
1194 __ SetAccumulator(result); | |
1195 __ Dispatch(); | |
1196 } | |
1197 | |
1198 // ToName | |
1199 // | |
1200 // Cast the object referenced by the accumulator to a name. | |
1201 void Interpreter::DoToName(InterpreterAssembler* assembler) { | |
1202 DoTypeConversionOp(CodeFactory::ToName(isolate_), assembler); | |
1203 } | |
1204 | |
1205 | |
1206 // ToNumber | |
1207 // | |
1208 // Cast the object referenced by the accumulator to a number. | |
1209 void Interpreter::DoToNumber(InterpreterAssembler* assembler) { | |
1210 DoTypeConversionOp(CodeFactory::ToNumber(isolate_), assembler); | |
1211 } | |
1212 | |
1213 | |
1214 // ToObject | |
1215 // | |
1216 // Cast the object referenced by the accumulator to a JSObject. | |
1217 void Interpreter::DoToObject(InterpreterAssembler* assembler) { | |
1218 DoTypeConversionOp(CodeFactory::ToObject(isolate_), assembler); | |
1219 } | |
1220 | |
1221 // Jump <imm> | 1165 // Jump <imm> |
1222 // | 1166 // |
1223 // Jump by number of bytes represented by the immediate operand |imm|. | 1167 // Jump by number of bytes represented by the immediate operand |imm|. |
1224 void Interpreter::DoJump(InterpreterAssembler* assembler) { | 1168 void Interpreter::DoJump(InterpreterAssembler* assembler) { |
1225 Node* relative_jump = __ BytecodeOperandImm(0); | 1169 Node* relative_jump = __ BytecodeOperandImm(0); |
1226 __ Jump(relative_jump); | 1170 __ Jump(relative_jump); |
1227 } | 1171 } |
1228 | 1172 |
1229 // JumpConstant <idx> | 1173 // JumpConstant <idx> |
1230 // | 1174 // |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 Node* relative_jump = __ SmiUntag(constant); | 1226 Node* relative_jump = __ SmiUntag(constant); |
1283 Node* false_value = __ BooleanConstant(false); | 1227 Node* false_value = __ BooleanConstant(false); |
1284 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 1228 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
1285 } | 1229 } |
1286 | 1230 |
1287 // JumpIfToBooleanTrue <imm> | 1231 // JumpIfToBooleanTrue <imm> |
1288 // | 1232 // |
1289 // Jump by number of bytes represented by an immediate operand if the object | 1233 // Jump by number of bytes represented by an immediate operand if the object |
1290 // referenced by the accumulator is true when the object is cast to boolean. | 1234 // referenced by the accumulator is true when the object is cast to boolean. |
1291 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { | 1235 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { |
1292 Callable callable = CodeFactory::ToBoolean(isolate_); | |
1293 Node* target = __ HeapConstant(callable.code()); | |
1294 Node* accumulator = __ GetAccumulator(); | 1236 Node* accumulator = __ GetAccumulator(); |
1295 Node* context = __ GetContext(); | 1237 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
1296 Node* to_boolean_value = | |
1297 __ CallStub(callable.descriptor(), target, context, accumulator); | |
1298 Node* relative_jump = __ BytecodeOperandImm(0); | 1238 Node* relative_jump = __ BytecodeOperandImm(0); |
1299 Node* true_value = __ BooleanConstant(true); | 1239 Node* true_value = __ BooleanConstant(true); |
1300 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); | 1240 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); |
1301 } | 1241 } |
1302 | 1242 |
1303 // JumpIfToBooleanTrueConstant <idx> | 1243 // JumpIfToBooleanTrueConstant <idx> |
1304 // | 1244 // |
1305 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 1245 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
1306 // if the object referenced by the accumulator is true when the object is cast | 1246 // if the object referenced by the accumulator is true when the object is cast |
1307 // to boolean. | 1247 // to boolean. |
1308 void Interpreter::DoJumpIfToBooleanTrueConstant( | 1248 void Interpreter::DoJumpIfToBooleanTrueConstant( |
1309 InterpreterAssembler* assembler) { | 1249 InterpreterAssembler* assembler) { |
1310 Callable callable = CodeFactory::ToBoolean(isolate_); | |
1311 Node* target = __ HeapConstant(callable.code()); | |
1312 Node* accumulator = __ GetAccumulator(); | 1250 Node* accumulator = __ GetAccumulator(); |
1313 Node* context = __ GetContext(); | 1251 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
1314 Node* to_boolean_value = | |
1315 __ CallStub(callable.descriptor(), target, context, accumulator); | |
1316 Node* index = __ BytecodeOperandIdx(0); | 1252 Node* index = __ BytecodeOperandIdx(0); |
1317 Node* constant = __ LoadConstantPoolEntry(index); | 1253 Node* constant = __ LoadConstantPoolEntry(index); |
1318 Node* relative_jump = __ SmiUntag(constant); | 1254 Node* relative_jump = __ SmiUntag(constant); |
1319 Node* true_value = __ BooleanConstant(true); | 1255 Node* true_value = __ BooleanConstant(true); |
1320 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); | 1256 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); |
1321 } | 1257 } |
1322 | 1258 |
1323 // JumpIfToBooleanFalse <imm> | 1259 // JumpIfToBooleanFalse <imm> |
1324 // | 1260 // |
1325 // Jump by number of bytes represented by an immediate operand if the object | 1261 // Jump by number of bytes represented by an immediate operand if the object |
1326 // referenced by the accumulator is false when the object is cast to boolean. | 1262 // referenced by the accumulator is false when the object is cast to boolean. |
1327 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { | 1263 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { |
1328 Callable callable = CodeFactory::ToBoolean(isolate_); | |
1329 Node* target = __ HeapConstant(callable.code()); | |
1330 Node* accumulator = __ GetAccumulator(); | 1264 Node* accumulator = __ GetAccumulator(); |
1331 Node* context = __ GetContext(); | 1265 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
1332 Node* to_boolean_value = | |
1333 __ CallStub(callable.descriptor(), target, context, accumulator); | |
1334 Node* relative_jump = __ BytecodeOperandImm(0); | 1266 Node* relative_jump = __ BytecodeOperandImm(0); |
1335 Node* false_value = __ BooleanConstant(false); | 1267 Node* false_value = __ BooleanConstant(false); |
1336 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); | 1268 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); |
1337 } | 1269 } |
1338 | 1270 |
1339 // JumpIfToBooleanFalseConstant <idx> | 1271 // JumpIfToBooleanFalseConstant <idx> |
1340 // | 1272 // |
1341 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 1273 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
1342 // if the object referenced by the accumulator is false when the object is cast | 1274 // if the object referenced by the accumulator is false when the object is cast |
1343 // to boolean. | 1275 // to boolean. |
1344 void Interpreter::DoJumpIfToBooleanFalseConstant( | 1276 void Interpreter::DoJumpIfToBooleanFalseConstant( |
1345 InterpreterAssembler* assembler) { | 1277 InterpreterAssembler* assembler) { |
1346 Callable callable = CodeFactory::ToBoolean(isolate_); | |
1347 Node* target = __ HeapConstant(callable.code()); | |
1348 Node* accumulator = __ GetAccumulator(); | 1278 Node* accumulator = __ GetAccumulator(); |
1349 Node* context = __ GetContext(); | 1279 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
1350 Node* to_boolean_value = | |
1351 __ CallStub(callable.descriptor(), target, context, accumulator); | |
1352 Node* index = __ BytecodeOperandIdx(0); | 1280 Node* index = __ BytecodeOperandIdx(0); |
1353 Node* constant = __ LoadConstantPoolEntry(index); | 1281 Node* constant = __ LoadConstantPoolEntry(index); |
1354 Node* relative_jump = __ SmiUntag(constant); | 1282 Node* relative_jump = __ SmiUntag(constant); |
1355 Node* false_value = __ BooleanConstant(false); | 1283 Node* false_value = __ BooleanConstant(false); |
1356 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); | 1284 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); |
1357 } | 1285 } |
1358 | 1286 |
1359 // JumpIfNull <imm> | 1287 // JumpIfNull <imm> |
1360 // | 1288 // |
1361 // Jump by number of bytes represented by an immediate operand if the object | 1289 // Jump by number of bytes represented by an immediate operand if the object |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 | 1500 |
1573 __ Bind(&if_duplicate_parameters); | 1501 __ Bind(&if_duplicate_parameters); |
1574 { | 1502 { |
1575 Node* result = | 1503 Node* result = |
1576 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure); | 1504 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure); |
1577 __ SetAccumulator(result); | 1505 __ SetAccumulator(result); |
1578 __ Dispatch(); | 1506 __ Dispatch(); |
1579 } | 1507 } |
1580 } | 1508 } |
1581 | 1509 |
1582 | |
1583 // CreateUnmappedArguments | 1510 // CreateUnmappedArguments |
1584 // | 1511 // |
1585 // Creates a new unmapped arguments object. | 1512 // Creates a new unmapped arguments object. |
1586 void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) { | 1513 void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) { |
1587 // TODO(rmcilroy): Inline FastNewStrictArguments when it is a TurboFan stub. | 1514 // TODO(rmcilroy): Inline FastNewStrictArguments when it is a TurboFan stub. |
1588 Callable callable = CodeFactory::FastNewStrictArguments(isolate_, true); | 1515 Callable callable = CodeFactory::FastNewStrictArguments(isolate_, true); |
1589 Node* target = __ HeapConstant(callable.code()); | 1516 Node* target = __ HeapConstant(callable.code()); |
1590 Node* context = __ GetContext(); | 1517 Node* context = __ GetContext(); |
1591 Node* closure = __ LoadRegister(Register::function_closure()); | 1518 Node* closure = __ LoadRegister(Register::function_closure()); |
1592 Node* result = __ CallStub(callable.descriptor(), target, context, closure); | 1519 Node* result = __ CallStub(callable.descriptor(), target, context, closure); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 // | 1559 // |
1633 // Throws the exception in the accumulator. | 1560 // Throws the exception in the accumulator. |
1634 void Interpreter::DoThrow(InterpreterAssembler* assembler) { | 1561 void Interpreter::DoThrow(InterpreterAssembler* assembler) { |
1635 Node* exception = __ GetAccumulator(); | 1562 Node* exception = __ GetAccumulator(); |
1636 Node* context = __ GetContext(); | 1563 Node* context = __ GetContext(); |
1637 __ CallRuntime(Runtime::kThrow, context, exception); | 1564 __ CallRuntime(Runtime::kThrow, context, exception); |
1638 // We shouldn't ever return from a throw. | 1565 // We shouldn't ever return from a throw. |
1639 __ Abort(kUnexpectedReturnFromThrow); | 1566 __ Abort(kUnexpectedReturnFromThrow); |
1640 } | 1567 } |
1641 | 1568 |
1642 | |
1643 // ReThrow | 1569 // ReThrow |
1644 // | 1570 // |
1645 // Re-throws the exception in the accumulator. | 1571 // Re-throws the exception in the accumulator. |
1646 void Interpreter::DoReThrow(InterpreterAssembler* assembler) { | 1572 void Interpreter::DoReThrow(InterpreterAssembler* assembler) { |
1647 Node* exception = __ GetAccumulator(); | 1573 Node* exception = __ GetAccumulator(); |
1648 Node* context = __ GetContext(); | 1574 Node* context = __ GetContext(); |
1649 __ CallRuntime(Runtime::kReThrow, context, exception); | 1575 __ CallRuntime(Runtime::kReThrow, context, exception); |
1650 // We shouldn't ever return from a throw. | 1576 // We shouldn't ever return from a throw. |
1651 __ Abort(kUnexpectedReturnFromThrow); | 1577 __ Abort(kUnexpectedReturnFromThrow); |
1652 } | 1578 } |
1653 | 1579 |
1654 | |
1655 // Return | 1580 // Return |
1656 // | 1581 // |
1657 // Return the value in the accumulator. | 1582 // Return the value in the accumulator. |
1658 void Interpreter::DoReturn(InterpreterAssembler* assembler) { | 1583 void Interpreter::DoReturn(InterpreterAssembler* assembler) { |
1659 __ UpdateInterruptBudgetOnReturn(); | 1584 __ UpdateInterruptBudgetOnReturn(); |
1660 Node* accumulator = __ GetAccumulator(); | 1585 Node* accumulator = __ GetAccumulator(); |
1661 __ Return(accumulator); | 1586 __ Return(accumulator); |
1662 } | 1587 } |
1663 | 1588 |
1664 // Debugger | 1589 // Debugger |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1855 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 1780 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
1856 __ SmiTag(new_state)); | 1781 __ SmiTag(new_state)); |
1857 __ SetAccumulator(old_state); | 1782 __ SetAccumulator(old_state); |
1858 | 1783 |
1859 __ Dispatch(); | 1784 __ Dispatch(); |
1860 } | 1785 } |
1861 | 1786 |
1862 } // namespace interpreter | 1787 } // namespace interpreter |
1863 } // namespace internal | 1788 } // namespace internal |
1864 } // namespace v8 | 1789 } // namespace v8 |
OLD | NEW |