Chromium Code Reviews| 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 |