OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2780 return; | 2780 return; |
2781 } | 2781 } |
2782 frame_->SpillAll(); | 2782 frame_->SpillAll(); |
2783 | 2783 |
2784 done.Jump(); | 2784 done.Jump(); |
2785 | 2785 |
2786 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { | 2786 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { |
2787 frame_->SpillAll(); | 2787 frame_->SpillAll(); |
2788 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); | 2788 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); |
2789 // Only generate the fast case for locals that rewrite to slots. | 2789 // Only generate the fast case for locals that rewrite to slots. |
2790 // This rules out argument loads. | 2790 // This rules out argument loads because eval forces arguments |
2791 // access to be through the arguments object. | |
2791 if (potential_slot != NULL) { | 2792 if (potential_slot != NULL) { |
2792 __ ldr(r0, | 2793 __ ldr(r0, |
2793 ContextSlotOperandCheckExtensions(potential_slot, | 2794 ContextSlotOperandCheckExtensions(potential_slot, |
2794 r1, | 2795 r1, |
2795 r2, | 2796 r2, |
2796 &slow)); | 2797 &slow)); |
2797 if (potential_slot->var()->mode() == Variable::CONST) { | 2798 if (potential_slot->var()->mode() == Variable::CONST) { |
2798 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2799 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
2799 __ cmp(r0, ip); | 2800 __ cmp(r0, ip); |
2800 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | 2801 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3695 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); | 3696 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); |
3696 CodeForSourcePosition(node->position()); | 3697 CodeForSourcePosition(node->position()); |
3697 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, | 3698 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, |
3698 arg_count + 1); | 3699 arg_count + 1); |
3699 __ ldr(cp, frame_->Context()); | 3700 __ ldr(cp, frame_->Context()); |
3700 frame_->EmitPush(r0); | 3701 frame_->EmitPush(r0); |
3701 | 3702 |
3702 } else if (var != NULL && var->slot() != NULL && | 3703 } else if (var != NULL && var->slot() != NULL && |
3703 var->slot()->type() == Slot::LOOKUP) { | 3704 var->slot()->type() == Slot::LOOKUP) { |
3704 // ---------------------------------- | 3705 // ---------------------------------- |
3705 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj | 3706 // JavaScript examples: |
3707 // | |
3708 // with (obj) foo(1, 2, 3) // foo is in obj | |
Erik Corry
2010/05/07 10:38:31
As I understand it the point of this code is to go
| |
3709 // | |
3710 // function f() {}; | |
3711 // function g() { | |
3712 // eval(...); | |
3713 // f(); // f could be in extension object | |
Erik Corry
2010/05/07 10:38:31
Full stop.
| |
3714 // } | |
3706 // ---------------------------------- | 3715 // ---------------------------------- |
3707 | 3716 |
3717 // JumpTargets do not yet support merging frames so the frame must be | |
3718 // spilled when jumping to these targets. | |
3719 JumpTarget slow; | |
3720 JumpTarget done; | |
3721 | |
3722 // Generate fast-case code for variables that might be shadowed by | |
3723 // eval-introduced variables. Eval is used a lot without | |
3724 // introducing variables. In those cases, we do not want to | |
3725 // perform a runtime call for all variables in the scope | |
3726 // containing the eval. | |
3727 if (var->mode() == Variable::DYNAMIC_GLOBAL) { | |
3728 LoadFromGlobalSlotCheckExtensions(var->slot(), NOT_INSIDE_TYPEOF, &slow); | |
3729 frame_->EmitPush(r0); | |
3730 LoadGlobalReceiver(r1); | |
3731 done.Jump(); | |
3732 | |
3733 } else if (var->mode() == Variable::DYNAMIC_LOCAL) { | |
3734 Slot* potential_slot = var->local_if_not_shadowed()->slot(); | |
3735 // Only generate the fast case for locals that rewrite to slots. | |
3736 // This rules out argument loads because eval forces arguments | |
3737 // access to be through the arguments object. | |
3738 if (potential_slot != NULL) { | |
3739 __ ldr(r0, | |
3740 ContextSlotOperandCheckExtensions(potential_slot, | |
3741 r1, | |
3742 r2, | |
3743 &slow)); | |
3744 if (potential_slot->var()->mode() == Variable::CONST) { | |
3745 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
3746 __ cmp(r0, ip); | |
3747 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | |
3748 } | |
3749 frame_->EmitPush(r0); | |
3750 LoadGlobalReceiver(r1); | |
3751 done.Jump(); | |
3752 } | |
3753 } | |
3754 | |
3755 slow.Bind(); | |
3708 // Load the function | 3756 // Load the function |
3709 frame_->EmitPush(cp); | 3757 frame_->EmitPush(cp); |
3710 __ mov(r0, Operand(var->name())); | 3758 __ mov(r0, Operand(var->name())); |
3711 frame_->EmitPush(r0); | 3759 frame_->EmitPush(r0); |
3712 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); | 3760 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); |
3713 // r0: slot value; r1: receiver | 3761 // r0: slot value; r1: receiver |
3714 | 3762 |
3715 // Load the receiver. | 3763 // Load the receiver. |
3716 frame_->EmitPush(r0); // function | 3764 frame_->EmitPush(r0); // function |
3717 frame_->EmitPush(r1); // receiver | 3765 frame_->EmitPush(r1); // receiver |
3718 | 3766 |
3719 // Call the function. | 3767 done.Bind(); |
3768 // Call the function. At this point, everything is spilled but the | |
3769 // function and receiver are in r0 and r1. | |
3720 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); | 3770 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); |
3721 frame_->EmitPush(r0); | 3771 frame_->EmitPush(r0); |
3722 | 3772 |
3723 } else if (property != NULL) { | 3773 } else if (property != NULL) { |
3724 // Check if the key is a literal string. | 3774 // Check if the key is a literal string. |
3725 Literal* literal = property->key()->AsLiteral(); | 3775 Literal* literal = property->key()->AsLiteral(); |
3726 | 3776 |
3727 if (literal != NULL && literal->handle()->IsSymbol()) { | 3777 if (literal != NULL && literal->handle()->IsSymbol()) { |
3728 // ------------------------------------------------------------------ | 3778 // ------------------------------------------------------------------ |
3729 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' | 3779 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' |
(...skipping 6171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9901 | 9951 |
9902 // Just jump to runtime to add the two strings. | 9952 // Just jump to runtime to add the two strings. |
9903 __ bind(&string_add_runtime); | 9953 __ bind(&string_add_runtime); |
9904 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 9954 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
9905 } | 9955 } |
9906 | 9956 |
9907 | 9957 |
9908 #undef __ | 9958 #undef __ |
9909 | 9959 |
9910 } } // namespace v8::internal | 9960 } } // namespace v8::internal |
OLD | NEW |