Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 7039036: Fix calls of strict mode function with an implicit receiver. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix presubmit Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3895 matching lines...) Expand 10 before | Expand all | Expand 10 after
3906 void StackCheckStub::Generate(MacroAssembler* masm) { 3906 void StackCheckStub::Generate(MacroAssembler* masm) {
3907 __ TailCallRuntime(Runtime::kStackGuard, 0, 1); 3907 __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
3908 } 3908 }
3909 3909
3910 3910
3911 void CallFunctionStub::Generate(MacroAssembler* masm) { 3911 void CallFunctionStub::Generate(MacroAssembler* masm) {
3912 Label slow; 3912 Label slow;
3913 3913
3914 // If the receiver might be a value (string, number or boolean) check for this 3914 // If the receiver might be a value (string, number or boolean) check for this
3915 // and box it if it is. 3915 // and box it if it is.
3916 if (ReceiverMightBeValue()) { 3916 if (ReceiverMightBeValue() || NonValueReceiverMightBeImplicit()) {
Kevin Millikin (Chromium) 2011/05/18 15:57:23 I can't figure out if these are separate bits or i
Mads Ager (chromium) 2011/05/23 16:31:34 I can't actually hit the non-object case in the ca
3917 Label explicit_receiver, receiver_is_value, receiver_is_js_object;
3918
3917 // Get the receiver from the stack. 3919 // Get the receiver from the stack.
3918 // +1 ~ return address 3920 // +1 ~ return address
3919 Label receiver_is_value, receiver_is_js_object;
3920 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); 3921 __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize));
3922 // Implicit global receiver is indicated with the hole.
3923 __ cmp(eax, masm->isolate()->factory()->the_hole_value());
3924 __ j(not_equal, &explicit_receiver, Label::kNear);
3925 // Patch the receiver on the stack with the global receiver object.
3926 __ mov(ebx, GlobalObjectOperand());
3927 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
Kevin Millikin (Chromium) 2011/05/18 15:57:23 This should go in eax? Otherwise the ReceiverMigh
Mads Ager (chromium) 2011/05/23 16:31:34 Doesn't matter. We unconditionally jmp over the TO
3928 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), ebx);
3929 // Mark as implicit receiver call.
Kevin Millikin (Chromium) 2011/05/18 15:57:23 We should be able to avoid setting ecx to check it
Mads Ager (chromium) 2011/05/23 16:31:34 Done.
3930 __ SetReceiverType(ecx, IMPLICIT_RECEIVER);
3931 __ jmp(&receiver_is_js_object);
3932 __ bind(&explicit_receiver);
3933 __ SetReceiverType(ecx, EXPLICIT_RECEIVER);
3921 3934
3922 // Check if receiver is a smi (which is a number value). 3935 if (ReceiverMightBeValue()) {
3923 __ test(eax, Immediate(kSmiTagMask)); 3936 // Check if receiver is a smi (which is a number value).
3924 __ j(zero, &receiver_is_value); 3937 __ test(eax, Immediate(kSmiTagMask));
3938 __ j(zero, &receiver_is_value);
3925 3939
3926 // Check if the receiver is a valid JS object. 3940 // Check if the receiver is a valid JS object.
3927 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edi); 3941 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edi);
3928 __ j(above_equal, &receiver_is_js_object); 3942 __ j(above_equal, &receiver_is_js_object);
3929 3943
3930 // Call the runtime to box the value. 3944 // Call the runtime to box the value.
3931 __ bind(&receiver_is_value); 3945 __ bind(&receiver_is_value);
3932 __ EnterInternalFrame(); 3946 __ EnterInternalFrame();
3933 __ push(eax); 3947 // Save implicit receiver information.
3934 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 3948 __ push(ecx);
3935 __ LeaveInternalFrame(); 3949 __ push(eax);
3936 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax); 3950 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
3937 3951 // Restore implicit receiver information.
3952 __ pop(ecx);
3953 __ LeaveInternalFrame();
3954 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax);
3955 }
3938 __ bind(&receiver_is_js_object); 3956 __ bind(&receiver_is_js_object);
3939 } 3957 }
3940 3958
3941 // Get the function to call from the stack. 3959 // Get the function to call from the stack.
3942 // +2 ~ receiver, return address 3960 // +2 ~ receiver, return address
3943 __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); 3961 __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize));
3944 3962
3945 // Check that the function really is a JavaScript function. 3963 // Check that the function really is a JavaScript function.
3946 __ test(edi, Immediate(kSmiTagMask)); 3964 __ test(edi, Immediate(kSmiTagMask));
3947 __ j(zero, &slow); 3965 __ j(zero, &slow);
3948 // Goto slow case if we do not have a function. 3966 // Goto slow case if we do not have a function.
3949 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 3967 __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax);
3950 __ j(not_equal, &slow); 3968 __ j(not_equal, &slow);
3951 3969
3952 // Fast-case: Just invoke the function. 3970 // Fast-case: Just invoke the function.
3953 ParameterCount actual(argc_); 3971 ParameterCount actual(argc_);
3954 __ InvokeFunction(edi, actual, JUMP_FUNCTION); 3972
3973 if (ReceiverMightBeValue() || NonValueReceiverMightBeImplicit()) {
3974 Label implicit_receiver_call;
3975 __ test(ecx, Operand(ecx));
3976 __ j(not_zero, &implicit_receiver_call);
3977 __ InvokeFunction(edi, actual, JUMP_FUNCTION);
3978 __ bind(&implicit_receiver_call);
3979 }
3980 __ InvokeFunction(edi,
3981 actual,
3982 JUMP_FUNCTION,
3983 NullCallWrapper(),
3984 IMPLICIT_RECEIVER);
3955 3985
3956 // Slow-case: Non-function called. 3986 // Slow-case: Non-function called.
3957 __ bind(&slow); 3987 __ bind(&slow);
3958 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 3988 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
3959 // of the original receiver from the call site). 3989 // of the original receiver from the call site).
3960 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); 3990 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
3961 __ Set(eax, Immediate(argc_)); 3991 __ Set(eax, Immediate(argc_));
3962 __ Set(ebx, Immediate(0)); 3992 __ Set(ebx, Immediate(0));
3963 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 3993 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
3964 Handle<Code> adaptor = 3994 Handle<Code> adaptor =
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
4238 Builtins::kJSConstructEntryTrampoline, 4268 Builtins::kJSConstructEntryTrampoline,
4239 masm->isolate()); 4269 masm->isolate());
4240 __ mov(edx, Immediate(construct_entry)); 4270 __ mov(edx, Immediate(construct_entry));
4241 } else { 4271 } else {
4242 ExternalReference entry(Builtins::kJSEntryTrampoline, 4272 ExternalReference entry(Builtins::kJSEntryTrampoline,
4243 masm->isolate()); 4273 masm->isolate());
4244 __ mov(edx, Immediate(entry)); 4274 __ mov(edx, Immediate(entry));
4245 } 4275 }
4246 __ mov(edx, Operand(edx, 0)); // deref address 4276 __ mov(edx, Operand(edx, 0)); // deref address
4247 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); 4277 __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
4278 __ SetReceiverType(ecx, EXPLICIT_RECEIVER);
4248 __ call(Operand(edx)); 4279 __ call(Operand(edx));
4249 4280
4250 // Unlink this frame from the handler chain. 4281 // Unlink this frame from the handler chain.
4251 __ PopTryHandler(); 4282 __ PopTryHandler();
4252 4283
4253 __ bind(&exit); 4284 __ bind(&exit);
4254 #ifdef ENABLE_LOGGING_AND_PROFILING 4285 #ifdef ENABLE_LOGGING_AND_PROFILING
4255 // Check if the current stack frame is marked as the outermost JS frame. 4286 // Check if the current stack frame is marked as the outermost JS frame.
4256 __ pop(ebx); 4287 __ pop(ebx);
4257 __ cmp(Operand(ebx), 4288 __ cmp(Operand(ebx),
(...skipping 1894 matching lines...) Expand 10 before | Expand all | Expand 10 after
6152 __ Drop(1); 6183 __ Drop(1);
6153 __ ret(2 * kPointerSize); 6184 __ ret(2 * kPointerSize);
6154 } 6185 }
6155 6186
6156 6187
6157 #undef __ 6188 #undef __
6158 6189
6159 } } // namespace v8::internal 6190 } } // namespace v8::internal
6160 6191
6161 #endif // V8_TARGET_ARCH_IA32 6192 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698