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 3836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3847 if (var != NULL && var->is_possibly_eval()) { | 3847 if (var != NULL && var->is_possibly_eval()) { |
3848 VirtualFrame::SpilledScope spilled_scope(frame_); | 3848 VirtualFrame::SpilledScope spilled_scope(frame_); |
3849 // ---------------------------------- | 3849 // ---------------------------------- |
3850 // JavaScript example: 'eval(arg)' // eval is not known to be shadowed | 3850 // JavaScript example: 'eval(arg)' // eval is not known to be shadowed |
3851 // ---------------------------------- | 3851 // ---------------------------------- |
3852 | 3852 |
3853 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 3853 // In a call to eval, we first call %ResolvePossiblyDirectEval to |
3854 // resolve the function we need to call and the receiver of the | 3854 // resolve the function we need to call and the receiver of the |
3855 // call. Then we call the resolved function using the given | 3855 // call. Then we call the resolved function using the given |
3856 // arguments. | 3856 // arguments. |
| 3857 |
3857 // Prepare stack for call to resolved function. | 3858 // Prepare stack for call to resolved function. |
3858 Load(function); | 3859 Load(function); |
| 3860 |
| 3861 // Allocate a frame slot for the receiver. |
3859 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 3862 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
3860 frame_->EmitPush(r2); // Slot for receiver | 3863 frame_->EmitPush(r2); |
| 3864 |
| 3865 // Load the arguments. |
3861 int arg_count = args->length(); | 3866 int arg_count = args->length(); |
3862 for (int i = 0; i < arg_count; i++) { | 3867 for (int i = 0; i < arg_count; i++) { |
3863 Load(args->at(i)); | 3868 Load(args->at(i)); |
3864 } | 3869 } |
3865 | 3870 |
3866 // Prepare stack for call to ResolvePossiblyDirectEval. | 3871 // If we know that eval can only be shadowed by eval-introduced |
| 3872 // variables we attempt to load the global eval function directly |
| 3873 // in generated code. If we succeed, there is no need to perform a |
| 3874 // context lookup in the runtime system. |
| 3875 JumpTarget done; |
| 3876 if (var->slot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) { |
| 3877 ASSERT(var->slot()->type() == Slot::LOOKUP); |
| 3878 JumpTarget slow; |
| 3879 // Prepare the stack for the call to |
| 3880 // ResolvePossiblyDirectEvalNoLookup by pushing the loaded |
| 3881 // function, the first argument to the eval call and the |
| 3882 // receiver. |
| 3883 LoadFromGlobalSlotCheckExtensions(var->slot(), |
| 3884 NOT_INSIDE_TYPEOF, |
| 3885 &slow); |
| 3886 frame_->EmitPush(r0); |
| 3887 if (arg_count > 0) { |
| 3888 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 3889 frame_->EmitPush(r1); |
| 3890 } else { |
| 3891 frame_->EmitPush(r2); |
| 3892 } |
| 3893 __ ldr(r1, frame_->Receiver()); |
| 3894 frame_->EmitPush(r1); |
| 3895 |
| 3896 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEvalNoLookup, 3); |
| 3897 |
| 3898 done.Jump(); |
| 3899 slow.Bind(); |
| 3900 } |
| 3901 |
| 3902 // Prepare the stack for the call to ResolvePossiblyDirectEval by |
| 3903 // pushing the loaded function, the first argument to the eval |
| 3904 // call and the receiver. |
3867 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize + kPointerSize)); | 3905 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize + kPointerSize)); |
3868 frame_->EmitPush(r1); | 3906 frame_->EmitPush(r1); |
3869 if (arg_count > 0) { | 3907 if (arg_count > 0) { |
3870 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 3908 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
3871 frame_->EmitPush(r1); | 3909 frame_->EmitPush(r1); |
3872 } else { | 3910 } else { |
3873 frame_->EmitPush(r2); | 3911 frame_->EmitPush(r2); |
3874 } | 3912 } |
3875 | |
3876 // Push the receiver. | |
3877 __ ldr(r1, frame_->Receiver()); | 3913 __ ldr(r1, frame_->Receiver()); |
3878 frame_->EmitPush(r1); | 3914 frame_->EmitPush(r1); |
3879 | 3915 |
3880 // Resolve the call. | 3916 // Resolve the call. |
3881 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); | 3917 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); |
3882 | 3918 |
| 3919 // If we generated fast-case code bind the jump-target where fast |
| 3920 // and slow case merge. |
| 3921 if (done.is_linked()) done.Bind(); |
| 3922 |
3883 // Touch up stack with the right values for the function and the receiver. | 3923 // Touch up stack with the right values for the function and the receiver. |
3884 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3924 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
3885 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); | 3925 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
3886 | 3926 |
3887 // Call the function. | 3927 // Call the function. |
3888 CodeForSourcePosition(node->position()); | 3928 CodeForSourcePosition(node->position()); |
3889 | 3929 |
3890 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; | 3930 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; |
3891 CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 3931 CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
3892 frame_->CallStub(&call_function, arg_count + 1); | 3932 frame_->CallStub(&call_function, arg_count + 1); |
(...skipping 6603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10496 __ bind(&string_add_runtime); | 10536 __ bind(&string_add_runtime); |
10497 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 10537 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
10498 } | 10538 } |
10499 | 10539 |
10500 | 10540 |
10501 #undef __ | 10541 #undef __ |
10502 | 10542 |
10503 } } // namespace v8::internal | 10543 } } // namespace v8::internal |
10504 | 10544 |
10505 #endif // V8_TARGET_ARCH_ARM | 10545 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |