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 |