Revision: 8109
Author: [email protected]
Date: Mon May 30 06:23:17 2011
Log: Fix a number of IC stubs to correctly set the call kind.
Make the call kind and call wrapper arguments explicit to force
developers to make a choice. This would have avoided the bug in the
first case.
[email protected]
TEST=mjsunit/strict-mode-implicit-receiver.js
Review URL: http://codereview.chromium.org/7086029
http://code.google.com/p/v8/source/detail?r=8109
Added:
/branches/bleeding_edge/test/mjsunit/bugs/bug-1412.js
Modified:
/branches/bleeding_edge/src/arm/builtins-arm.cc
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm/ic-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/ia32/builtins-ia32.cc
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/ic-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/stub-cache.h
/branches/bleeding_edge/src/x64/builtins-x64.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
/branches/bleeding_edge/src/x64/ic-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
/branches/bleeding_edge/test/mjsunit/strict-mode-implicit-receiver.js
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/bugs/bug-1412.js Mon May 30
06:23:17 2011
@@ -0,0 +1,34 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function f() { "use strict"; print(this); }
+
+function g() { assertEquals(void 0, f.apply(undefined, arguments)); }
+
+for (var i = 0; i < 10; i++) g();
+%OptimizeFunctionOnNextCall(g);
+g();
=======================================
--- /branches/bleeding_edge/src/arm/builtins-arm.cc Thu May 26 04:22:29 2011
+++ /branches/bleeding_edge/src/arm/builtins-arm.cc Mon May 30 06:23:17 2011
@@ -915,10 +915,11 @@
masm->isolate()->builtins()->HandleApiCallConstruct();
ParameterCount expected(0);
__ InvokeCode(code, expected, expected,
- RelocInfo::CODE_TARGET, CALL_FUNCTION);
+ RelocInfo::CODE_TARGET, CALL_FUNCTION, CALL_AS_METHOD);
} else {
ParameterCount actual(r0);
- __ InvokeFunction(r1, actual, CALL_FUNCTION);
+ __ InvokeFunction(r1, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Pop the function from the stack.
@@ -1050,7 +1051,8 @@
RelocInfo::CODE_TARGET);
} else {
ParameterCount actual(r0);
- __ InvokeFunction(r1, actual, CALL_FUNCTION);
+ __ InvokeFunction(r1, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Exit the JS frame and remove the parameters (except function), and
return.
@@ -1379,7 +1381,8 @@
ne);
ParameterCount expected(0);
- __ InvokeCode(r3, expected, expected, JUMP_FUNCTION);
+ __ InvokeCode(r3, expected, expected, JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
@@ -1515,7 +1518,8 @@
ParameterCount actual(r0);
__ mov(r0, Operand(r0, ASR, kSmiTagSize));
__ ldr(r1, MemOperand(fp, kFunctionOffset));
- __ InvokeFunction(r1, actual, CALL_FUNCTION);
+ __ InvokeFunction(r1, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
// Tear down the internal frame and remove function, receiver and args.
__ LeaveInternalFrame();
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed May 25 03:35:00
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Mon May 30 06:23:17
2011
@@ -4540,7 +4540,11 @@
Label call_as_function;
__ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
__ b(eq, &call_as_function);
- __ InvokeFunction(r1, actual, JUMP_FUNCTION);
+ __ InvokeFunction(r1,
+ actual,
+ JUMP_FUNCTION,
+ NullCallWrapper(),
+ CALL_AS_METHOD);
__ bind(&call_as_function);
}
__ InvokeFunction(r1,
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Thu May 26 04:22:29
2011
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon May 30 06:23:17
2011
@@ -3175,7 +3175,8 @@
// InvokeFunction requires the function in r1. Move it in there.
__ mov(r1, result_register());
ParameterCount count(arg_count);
- __ InvokeFunction(r1, count, CALL_FUNCTION);
+ __ InvokeFunction(r1, count, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->Plug(r0);
}
=======================================
--- /branches/bleeding_edge/src/arm/ic-arm.cc Tue May 24 07:01:36 2011
+++ /branches/bleeding_edge/src/arm/ic-arm.cc Mon May 30 06:23:17 2011
@@ -557,7 +557,8 @@
// Invoke the function.
ParameterCount actual(argc);
- __ InvokeFunction(r1, actual, JUMP_FUNCTION);
+ __ InvokeFunction(r1, actual, JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu May 26
04:22:29 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon May 30
06:23:17 2011
@@ -2707,6 +2707,9 @@
ASSERT(function.is(r1)); // Required by InvokeFunction.
ASSERT(ToRegister(instr->result()).is(r0));
+ // TODO(1412): This is not correct if the called function is a
+ // strict mode function or a native.
+ //
// If the receiver is null or undefined, we have to pass the global
object
// as a receiver.
Label global_object, receiver_ok;
@@ -2726,6 +2729,8 @@
__ bind(&global_object);
__ ldr(receiver, GlobalObjectOperand());
+ __ ldr(receiver,
+ FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
__ bind(&receiver_ok);
// Copy the arguments to this function possibly from the
@@ -2765,7 +2770,8 @@
// The number of arguments is stored in receiver which is r0, as expected
// by InvokeFunction.
v8::internal::ParameterCount actual(receiver);
- __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
+ __ InvokeFunction(function, actual, CALL_FUNCTION,
+ safepoint_generator, CALL_AS_METHOD);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
@@ -3213,7 +3219,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator generator(this, pointers,
env->deoptimization_index());
ParameterCount count(instr->arity());
- __ InvokeFunction(r1, count, CALL_FUNCTION, generator);
+ __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue May 24
07:01:36 2011
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon May 30
06:23:17 2011
@@ -1048,7 +1048,8 @@
void MacroAssembler::InvokeFunction(JSFunction* function,
const ParameterCount& actual,
- InvokeFlag flag) {
+ InvokeFlag flag,
+ CallKind call_kind) {
ASSERT(function->is_compiled());
// Get the function and setup the context.
@@ -1063,9 +1064,9 @@
// code field in the function to allow recompilation to take effect
// without changing any of the call sites.
ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
- InvokeCode(r3, expected, actual, flag);
+ InvokeCode(r3, expected, actual, flag, NullCallWrapper(), call_kind);
} else {
- InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
+ InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag,
call_kind);
}
}
@@ -2369,10 +2370,12 @@
GetBuiltinEntry(r2, id);
if (flag == CALL_FUNCTION) {
call_wrapper.BeforeCall(CallSize(r2));
+ SetCallKind(r5, CALL_AS_METHOD);
Call(r2);
call_wrapper.AfterCall();
} else {
ASSERT(flag == JUMP_FUNCTION);
+ SetCallKind(r5, CALL_AS_METHOD);
Jump(r2);
}
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Tue May 24
07:01:36 2011
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon May 30
06:23:17 2011
@@ -356,27 +356,28 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
- CallKind call_kind = CALL_AS_METHOD);
+ CallKind call_kind);
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
- InvokeFlag flag);
+ InvokeFlag flag,
+ CallKind call_kind);
void IsObjectJSObjectType(Register heap_object,
Register map,
@@ -1036,8 +1037,8 @@
Register code_reg,
Label* done,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
// Activation support.
void EnterFrame(StackFrame::Type type);
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu May 26 05:07:22
2011
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Mon May 30 06:23:17
2011
@@ -476,7 +476,8 @@
static void GenerateCallFunction(MacroAssembler* masm,
Object* object,
const ParameterCount& arguments,
- Label* miss) {
+ Label* miss,
+ Code::ExtraICState extra_ic_state) {
// ----------- S t a t e -------------
// -- r0: receiver
// -- r1: function to call
@@ -495,7 +496,10 @@
}
// Invoke the function.
- __ InvokeFunction(r1, arguments, JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(),
call_kind);
}
@@ -625,10 +629,12 @@
public:
CallInterceptorCompiler(StubCompiler* stub_compiler,
const ParameterCount& arguments,
- Register name)
+ Register name,
+ Code::ExtraICState extra_ic_state)
: stub_compiler_(stub_compiler),
arguments_(arguments),
- name_(name) {}
+ name_(name),
+ extra_ic_state_(extra_ic_state) {}
MaybeObject* Compile(MacroAssembler* masm,
JSObject* object,
@@ -756,8 +762,11 @@
arguments_.immediate());
if (result->IsFailure()) return result;
} else {
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
__ InvokeFunction(optimization.constant_function(), arguments_,
- JUMP_FUNCTION);
+ JUMP_FUNCTION, call_kind);
}
// Deferred code for fast API call case---clean preallocated space.
@@ -839,6 +848,7 @@
StubCompiler* stub_compiler_;
const ParameterCount& arguments_;
Register name_;
+ Code::ExtraICState extra_ic_state_;
};
@@ -1492,7 +1502,7 @@
Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name,
&miss);
GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
- GenerateCallFunction(masm(), object, arguments(), &miss);
+ GenerateCallFunction(masm(), object, arguments(), &miss,
extra_ic_state_);
// Handle call cache miss.
__ bind(&miss);
@@ -1992,7 +2002,7 @@
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
__ bind(&miss);
// r2: function name.
@@ -2140,7 +2150,7 @@
__ bind(&slow);
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
__ bind(&miss);
// r2: function name.
@@ -2242,7 +2252,7 @@
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
__ bind(&miss);
// r2: function name.
@@ -2430,7 +2440,10 @@
UNREACHABLE();
}
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind);
// Handle call cache miss.
__ bind(&miss);
@@ -2463,7 +2476,7 @@
// Get the receiver from the stack.
__ ldr(r1, MemOperand(sp, argc * kPointerSize));
- CallInterceptorCompiler compiler(this, arguments(), r2);
+ CallInterceptorCompiler compiler(this, arguments(), r2, extra_ic_state_);
MaybeObject* result = compiler.Compile(masm(),
object,
holder,
@@ -2483,7 +2496,7 @@
// Restore receiver.
__ ldr(r0, MemOperand(sp, argc * kPointerSize));
- GenerateCallFunction(masm(), object, arguments(), &miss);
+ GenerateCallFunction(masm(), object, arguments(), &miss,
extra_ic_state_);
// Handle call cache miss.
__ bind(&miss);
@@ -2495,13 +2508,11 @@
}
-MaybeObject* CallStubCompiler::CompileCallGlobal(
- JSObject* object,
- GlobalObject* holder,
- JSGlobalPropertyCell* cell,
- JSFunction* function,
- String* name,
- Code::ExtraICState extra_ic_state) {
+MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
+ GlobalObject* holder,
+ JSGlobalPropertyCell*
cell,
+ JSFunction* function,
+ String* name) {
// ----------- S t a t e -------------
// -- r2 : name
// -- lr : return address
@@ -2543,7 +2554,7 @@
ASSERT(function->is_compiled());
Handle<Code> code(function->code());
ParameterCount expected(function->shared()->formal_parameter_count());
- CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
? CALL_AS_FUNCTION
: CALL_AS_METHOD;
if (V8::UseCrankshaft()) {
=======================================
--- /branches/bleeding_edge/src/ia32/builtins-ia32.cc Thu May 26 04:22:29
2011
+++ /branches/bleeding_edge/src/ia32/builtins-ia32.cc Mon May 30 06:23:17
2011
@@ -340,11 +340,12 @@
Handle<Code> code =
masm->isolate()->builtins()->HandleApiCallConstruct();
ParameterCount expected(0);
- __ InvokeCode(code, expected, expected,
- RelocInfo::CODE_TARGET, CALL_FUNCTION);
+ __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET,
+ CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
} else {
ParameterCount actual(eax);
- __ InvokeFunction(edi, actual, CALL_FUNCTION);
+ __ InvokeFunction(edi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Restore context from the frame.
@@ -443,7 +444,8 @@
RelocInfo::CODE_TARGET);
} else {
ParameterCount actual(eax);
- __ InvokeFunction(edi, actual, CALL_FUNCTION);
+ __ InvokeFunction(edi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Exit the JS frame. Notice that this also removes the empty
@@ -715,7 +717,8 @@
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline());
ParameterCount expected(0);
- __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
+ __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
@@ -845,7 +848,8 @@
ParameterCount actual(eax);
__ SmiUntag(eax);
__ mov(edi, Operand(ebp, 4 * kPointerSize));
- __ InvokeFunction(edi, actual, CALL_FUNCTION);
+ __ InvokeFunction(edi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ LeaveInternalFrame();
__ ret(3 * kPointerSize); // remove this, receiver, and arguments
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Tue May 24 07:01:36
2011
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Mon May 30 06:23:17
2011
@@ -3981,7 +3981,11 @@
Label call_as_function;
__ cmp(eax, masm->isolate()->factory()->the_hole_value());
__ j(equal, &call_as_function);
- __ InvokeFunction(edi, actual, JUMP_FUNCTION);
+ __ InvokeFunction(edi,
+ actual,
+ JUMP_FUNCTION,
+ NullCallWrapper(),
+ CALL_AS_METHOD);
__ bind(&call_as_function);
}
__ InvokeFunction(edi,
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu May 26
04:22:29 2011
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon May 30
06:23:17 2011
@@ -3115,7 +3115,8 @@
// InvokeFunction requires the function in edi. Move it in there.
__ mov(edi, result_register());
ParameterCount count(arg_count);
- __ InvokeFunction(edi, count, CALL_FUNCTION);
+ __ InvokeFunction(edi, count, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
context()->Plug(eax);
}
=======================================
--- /branches/bleeding_edge/src/ia32/ic-ia32.cc Tue May 24 07:01:36 2011
+++ /branches/bleeding_edge/src/ia32/ic-ia32.cc Mon May 30 06:23:17 2011
@@ -877,7 +877,8 @@
// Invoke the function.
ParameterCount actual(argc);
- __ InvokeFunction(edi, actual, JUMP_FUNCTION);
+ __ InvokeFunction(edi, actual, JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// The generated code falls through if the call should be handled by
runtime.
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu May 26
04:22:29 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon May 30
06:23:17 2011
@@ -2602,6 +2602,9 @@
ASSERT(function.is(edi)); // Required by InvokeFunction.
ASSERT(ToRegister(instr->result()).is(eax));
+ // TODO(1412): This is not correct if the called function is a
+ // strict mode function or a native.
+ //
// If the receiver is null or undefined, we have to pass the global
object
// as a receiver.
Label global_object, receiver_ok;
@@ -2623,6 +2626,8 @@
// here.
__ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset));
__ mov(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX));
+ __ mov(receiver,
+ FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
__ bind(&receiver_ok);
// Copy the arguments to this function possibly from the
@@ -2656,7 +2661,8 @@
pointers,
env->deoptimization_index());
ParameterCount actual(eax);
- __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
+ __ InvokeFunction(function, actual, CALL_FUNCTION,
+ safepoint_generator, CALL_AS_METHOD);
}
@@ -3083,7 +3089,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator generator(this, pointers,
env->deoptimization_index());
ParameterCount count(instr->arity());
- __ InvokeFunction(edi, count, CALL_FUNCTION, generator);
+ __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
}
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Tue May 24
07:01:36 2011
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Mon May 30
06:23:17 2011
@@ -1690,7 +1690,8 @@
void MacroAssembler::InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper) {
+ const CallWrapper& call_wrapper,
+ CallKind call_kind) {
ASSERT(function->is_compiled());
// Get the function and setup the context.
mov(edi, Immediate(Handle<JSFunction>(function)));
@@ -1702,11 +1703,11 @@
// code field in the function to allow recompilation to take effect
// without changing any of the call sites.
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
- expected, actual, flag, call_wrapper);
+ expected, actual, flag, call_wrapper, call_kind);
} else {
Handle<Code> code(function->code());
InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET,
- flag, call_wrapper);
+ flag, call_wrapper, call_kind);
}
}
@@ -1723,7 +1724,7 @@
ParameterCount expected(0);
GetBuiltinFunction(edi, id);
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
- expected, expected, flag, call_wrapper);
+ expected, expected, flag, call_wrapper, CALL_AS_METHOD);
}
void MacroAssembler::GetBuiltinFunction(Register target,
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Tue May 24
07:01:36 2011
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Mon May 30
06:23:17 2011
@@ -163,29 +163,30 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper());
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
// Invoke specified builtin JavaScript function. Adds an entry to
// the unresolved list if the name does not resolve.
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue May 24 07:01:36
2011
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Mon May 30 06:23:17
2011
@@ -488,10 +488,12 @@
public:
CallInterceptorCompiler(StubCompiler* stub_compiler,
const ParameterCount& arguments,
- Register name)
+ Register name,
+ Code::ExtraICState extra_ic_state)
: stub_compiler_(stub_compiler),
arguments_(arguments),
- name_(name) {}
+ name_(name),
+ extra_ic_state_(extra_ic_state) {}
MaybeObject* Compile(MacroAssembler* masm,
JSObject* object,
@@ -616,8 +618,11 @@
GenerateFastApiCall(masm, optimization, arguments_.immediate());
if (result->IsFailure()) return result;
} else {
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
__ InvokeFunction(optimization.constant_function(), arguments_,
- JUMP_FUNCTION);
+ JUMP_FUNCTION, NullCallWrapper(), call_kind);
}
// Deferred code for fast API call case---clean preallocated space.
@@ -696,6 +701,7 @@
StubCompiler* stub_compiler_;
const ParameterCount& arguments_;
Register name_;
+ Code::ExtraICState extra_ic_state_;
};
@@ -1383,7 +1389,11 @@
}
// Invoke the function.
- __ InvokeFunction(edi, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
// Handle call cache miss.
__ bind(&miss);
@@ -1869,7 +1879,11 @@
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
__ bind(&miss);
// ecx: function name.
@@ -1999,7 +2013,8 @@
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ bind(&miss);
// ecx: function name.
@@ -2104,7 +2119,8 @@
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ bind(&miss);
// ecx: function name.
@@ -2178,11 +2194,12 @@
}
-MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- CheckType check) {
+MaybeObject* CallStubCompiler::CompileCallConstant(
+ Object* object,
+ JSObject* holder,
+ JSFunction* function,
+ String* name,
+ CheckType check) {
// ----------- S t a t e -------------
// -- ecx : name
// -- esp[0] : return address
@@ -2300,7 +2317,11 @@
UNREACHABLE();
}
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
// Handle call cache miss.
__ bind(&miss);
@@ -2335,7 +2356,7 @@
// Get the receiver from the stack.
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
- CallInterceptorCompiler compiler(this, arguments(), ecx);
+ CallInterceptorCompiler compiler(this, arguments(), ecx,
extra_ic_state_);
MaybeObject* result = compiler.Compile(masm(),
object,
holder,
@@ -2366,7 +2387,11 @@
// Invoke the function.
__ mov(edi, eax);
- __ InvokeFunction(edi, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
// Handle load cache miss.
__ bind(&miss);
@@ -2383,8 +2408,7 @@
GlobalObject* holder,
JSGlobalPropertyCell* cell,
JSFunction* function,
- String* name,
- Code::ExtraICState extra_ic_state) {
+ String* name) {
// ----------- S t a t e -------------
// -- ecx : name
// -- esp[0] : return address
@@ -2427,7 +2451,7 @@
__ IncrementCounter(counters->call_global_inline(), 1);
ASSERT(function->is_compiled());
ParameterCount expected(function->shared()->formal_parameter_count());
- CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
? CALL_AS_FUNCTION
: CALL_AS_METHOD;
if (V8::UseCrankshaft()) {
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Tue May 24 07:01:36 2011
+++ /branches/bleeding_edge/src/stub-cache.cc Mon May 30 06:23:17 2011
@@ -929,12 +929,7 @@
CallStubCompiler compiler(
argc, in_loop, kind, extra_ic_state, cache_holder);
{ MaybeObject* maybe_code =
- compiler.CompileCallGlobal(receiver,
- holder,
- cell,
- function,
- name,
- extra_ic_state);
+ compiler.CompileCallGlobal(receiver, holder, cell, function,
name);
if (!maybe_code->ToObject(&code)) return maybe_code;
}
ASSERT_EQ(flags, Code::cast(code)->flags());
=======================================
--- /branches/bleeding_edge/src/stub-cache.h Tue May 24 07:01:36 2011
+++ /branches/bleeding_edge/src/stub-cache.h Mon May 30 06:23:17 2011
@@ -748,25 +748,30 @@
Code::ExtraICState extra_ic_state,
InlineCacheHolderFlag cache_holder);
- MUST_USE_RESULT MaybeObject* CompileCallField(JSObject* object,
- JSObject* holder,
- int index,
- String* name);
- MUST_USE_RESULT MaybeObject* CompileCallConstant(Object* object,
- JSObject* holder,
- JSFunction* function,
- String* name,
- CheckType check);
- MUST_USE_RESULT MaybeObject* CompileCallInterceptor(JSObject* object,
- JSObject* holder,
- String* name);
+ MUST_USE_RESULT MaybeObject* CompileCallField(
+ JSObject* object,
+ JSObject* holder,
+ int index,
+ String* name);
+
+ MUST_USE_RESULT MaybeObject* CompileCallConstant(
+ Object* object,
+ JSObject* holder,
+ JSFunction* function,
+ String* name,
+ CheckType check);
+
+ MUST_USE_RESULT MaybeObject* CompileCallInterceptor(
+ JSObject* object,
+ JSObject* holder,
+ String* name);
+
MUST_USE_RESULT MaybeObject* CompileCallGlobal(
JSObject* object,
GlobalObject* holder,
JSGlobalPropertyCell* cell,
JSFunction* function,
- String* name,
- Code::ExtraICState extra_ic_state);
+ String* name);
static bool HasCustomCallGenerator(JSFunction* function);
=======================================
--- /branches/bleeding_edge/src/x64/builtins-x64.cc Thu May 26 04:22:29 2011
+++ /branches/bleeding_edge/src/x64/builtins-x64.cc Mon May 30 06:23:17 2011
@@ -343,11 +343,12 @@
Handle<Code> code =
masm->isolate()->builtins()->HandleApiCallConstruct();
ParameterCount expected(0);
- __ InvokeCode(code, expected, expected,
- RelocInfo::CODE_TARGET, CALL_FUNCTION);
+ __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET,
+ CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
} else {
ParameterCount actual(rax);
- __ InvokeFunction(rdi, actual, CALL_FUNCTION);
+ __ InvokeFunction(rdi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Restore context from the frame.
@@ -499,7 +500,8 @@
} else {
ParameterCount actual(rax);
// Function must be in rdi.
- __ InvokeFunction(rdi, actual, CALL_FUNCTION);
+ __ InvokeFunction(rdi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
// Exit the JS frame. Notice that this also removes the empty
@@ -774,7 +776,8 @@
RelocInfo::CODE_TARGET);
ParameterCount expected(0);
- __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION);
+ __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
@@ -914,7 +917,8 @@
ParameterCount actual(rax);
__ SmiToInteger32(rax, rax);
__ movq(rdi, Operand(rbp, kFunctionOffset));
- __ InvokeFunction(rdi, actual, CALL_FUNCTION);
+ __ InvokeFunction(rdi, actual, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ LeaveInternalFrame();
__ ret(3 * kPointerSize); // remove function, receiver, and arguments
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Tue May 24 07:01:36
2011
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Mon May 30 06:23:17
2011
@@ -2982,7 +2982,11 @@
Label call_as_function;
__ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
__ j(equal, &call_as_function);
- __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
+ __ InvokeFunction(rdi,
+ actual,
+ JUMP_FUNCTION,
+ NullCallWrapper(),
+ CALL_AS_METHOD);
__ bind(&call_as_function);
}
__ InvokeFunction(rdi,
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Thu May 26 04:22:29
2011
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Mon May 30 06:23:17
2011
@@ -3067,7 +3067,8 @@
// InvokeFunction requires the function in rdi. Move it in there.
__ movq(rdi, result_register());
ParameterCount count(arg_count);
- __ InvokeFunction(rdi, count, CALL_FUNCTION);
+ __ InvokeFunction(rdi, count, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
context()->Plug(rax);
}
=======================================
--- /branches/bleeding_edge/src/x64/ic-x64.cc Tue May 24 07:01:36 2011
+++ /branches/bleeding_edge/src/x64/ic-x64.cc Mon May 30 06:23:17 2011
@@ -892,7 +892,8 @@
// Invoke the function.
ParameterCount actual(argc);
- __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
+ __ InvokeFunction(rdi, actual, JUMP_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu May 26
04:22:29 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon May 30
06:23:17 2011
@@ -2608,6 +2608,9 @@
ASSERT(function.is(rdi)); // Required by InvokeFunction.
ASSERT(ToRegister(instr->result()).is(rax));
+ // TODO(1412): This is not correct if the called function is a
+ // strict mode function or a native.
+ //
// If the receiver is null or undefined, we have to pass the global
object
// as a receiver.
Label global_object, receiver_ok;
@@ -2627,8 +2630,9 @@
// TODO(kmillikin): We have a hydrogen value for the global object. See
// if it's better to use it than to explicitly fetch it from the context
// here.
- __ movq(receiver, Operand(rbp, StandardFrameConstants::kContextOffset));
- __ movq(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX));
+ __ movq(receiver, ContextOperand(rsi, Context::GLOBAL_INDEX));
+ __ movq(receiver,
+ FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
__ bind(&receiver_ok);
// Copy the arguments to this function possibly from the
@@ -2662,7 +2666,8 @@
pointers,
env->deoptimization_index());
v8::internal::ParameterCount actual(rax);
- __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
+ __ InvokeFunction(function, actual, CALL_FUNCTION,
+ safepoint_generator, CALL_AS_METHOD);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
}
@@ -3075,7 +3080,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator generator(this, pointers,
env->deoptimization_index());
ParameterCount count(instr->arity());
- __ InvokeFunction(rdi, count, CALL_FUNCTION, generator);
+ __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
}
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Tue May 24
07:01:36 2011
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Mon May 30
06:23:17 2011
@@ -800,7 +800,7 @@
// parameter count to avoid emitting code to do the check.
ParameterCount expected(0);
GetBuiltinEntry(rdx, id);
- InvokeCode(rdx, expected, expected, flag, call_wrapper);
+ InvokeCode(rdx, expected, expected, flag, call_wrapper, CALL_AS_METHOD);
}
@@ -2878,7 +2878,8 @@
void MacroAssembler::InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper) {
+ const CallWrapper& call_wrapper,
+ CallKind call_kind) {
ASSERT(function->is_compiled());
// Get the function and setup the context.
Move(rdi, Handle<JSFunction>(function));
@@ -2889,7 +2890,7 @@
// the Code object every time we call the function.
movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
ParameterCount expected(function->shared()->formal_parameter_count());
- InvokeCode(rdx, expected, actual, flag, call_wrapper);
+ InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind);
} else {
// Invoke the cached code.
Handle<Code> code(function->code());
@@ -2899,7 +2900,8 @@
actual,
RelocInfo::CODE_TARGET,
flag,
- call_wrapper);
+ call_wrapper,
+ call_kind);
}
}
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Tue May 24
07:01:36 2011
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Mon May 30
06:23:17 2011
@@ -251,29 +251,30 @@
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
void InvokeCode(Handle<Code> code,
const ParameterCount& expected,
const ParameterCount& actual,
RelocInfo::Mode rmode,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper(),
- CallKind call_kind = CALL_AS_METHOD);
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
void InvokeFunction(JSFunction* function,
const ParameterCount& actual,
InvokeFlag flag,
- const CallWrapper& call_wrapper = NullCallWrapper());
+ const CallWrapper& call_wrapper,
+ CallKind call_kind);
// Invoke specified builtin JavaScript function. Adds an entry to
// the unresolved list if the name does not resolve.
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Tue May 24 07:01:36
2011
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Mon May 30 06:23:17
2011
@@ -478,10 +478,12 @@
public:
CallInterceptorCompiler(StubCompiler* stub_compiler,
const ParameterCount& arguments,
- Register name)
+ Register name,
+ Code::ExtraICState extra_ic_state)
: stub_compiler_(stub_compiler),
arguments_(arguments),
- name_(name) {}
+ name_(name),
+ extra_ic_state_(extra_ic_state) {}
MaybeObject* Compile(MacroAssembler* masm,
JSObject* object,
@@ -606,8 +608,11 @@
arguments_.immediate());
if (result->IsFailure()) return result;
} else {
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
__ InvokeFunction(optimization.constant_function(), arguments_,
- JUMP_FUNCTION);
+ JUMP_FUNCTION, NullCallWrapper(), call_kind);
}
// Deferred code for fast API call case---clean preallocated space.
@@ -686,6 +691,7 @@
StubCompiler* stub_compiler_;
const ParameterCount& arguments_;
Register name_;
+ Code::ExtraICState extra_ic_state_;
};
@@ -1348,7 +1354,11 @@
}
// Invoke the function.
- __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
// Handle call cache miss.
__ bind(&miss);
@@ -1831,7 +1841,11 @@
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
__ bind(&miss);
// rcx: function name.
@@ -1944,7 +1958,11 @@
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
__ bind(&miss);
// rcx: function name.
@@ -2138,7 +2156,11 @@
UNREACHABLE();
}
- __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
// Handle call cache miss.
__ bind(&miss);
@@ -2175,7 +2197,7 @@
// Get the receiver from the stack.
__ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
- CallInterceptorCompiler compiler(this, arguments(), rcx);
+ CallInterceptorCompiler compiler(this, arguments(), rcx,
extra_ic_state_);
MaybeObject* result = compiler.Compile(masm(),
object,
holder,
@@ -2205,7 +2227,11 @@
// Invoke the function.
__ movq(rdi, rax);
- __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION);
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
+ ? CALL_AS_FUNCTION
+ : CALL_AS_METHOD;
+ __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
+ NullCallWrapper(), call_kind);
// Handle load cache miss.
__ bind(&miss);
@@ -2217,13 +2243,11 @@
}
-MaybeObject* CallStubCompiler::CompileCallGlobal(
- JSObject* object,
- GlobalObject* holder,
- JSGlobalPropertyCell* cell,
- JSFunction* function,
- String* name,
- Code::ExtraICState extra_ic_state) {
+MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
+ GlobalObject* holder,
+ JSGlobalPropertyCell*
cell,
+ JSFunction* function,
+ String* name) {
// ----------- S t a t e -------------
// rcx : function name
// rsp[0] : return address
@@ -2268,7 +2292,7 @@
__ IncrementCounter(counters->call_global_inline(), 1);
ASSERT(function->is_compiled());
ParameterCount expected(function->shared()->formal_parameter_count());
- CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
+ CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
? CALL_AS_FUNCTION
: CALL_AS_METHOD;
if (V8::UseCrankshaft()) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/strict-mode-implicit-receiver.js
Tue May 24 07:01:36 2011
+++ /branches/bleeding_edge/test/mjsunit/strict-mode-implicit-receiver.js
Mon May 30 06:23:17 2011
@@ -174,3 +174,19 @@
// global context is used and the global object is passed as the
// receiver.
outer_eval_conversion3(eval, 'object');
+
+function test_constant_function() {
+ var o = { f: function() { "use strict"; return this; } };
+ this.__proto__ = o;
+ for (var i = 0; i < 10; i++) assertEquals(void 0, f());
+}
+test_constant_function();
+
+function test_field() {
+ var o = { };
+ o.f = function() {};
+ o.f = function() { "use strict"; return this; };
+ this.__proto__ = o;
+ for (var i = 0; i < 10; i++) assertEquals(void 0, f());
+}
+test_field();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev