Commit e76f06a1 authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

Fix miss in smi check when doing fast api call.

BUG=http://crbug.com/36604

Review URL: http://codereview.chromium.org/660004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3942 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3d765029
...@@ -1223,7 +1223,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object, ...@@ -1223,7 +1223,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
// -- ... // -- ...
// -- esp[(argc + 1) * 4] : receiver // -- esp[(argc + 1) * 4] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss_in_smi_check;
// Get the receiver from the stack. // Get the receiver from the stack.
const int argc = arguments().immediate(); const int argc = arguments().immediate();
...@@ -1232,7 +1232,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object, ...@@ -1232,7 +1232,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
// Check that the receiver isn't a smi. // Check that the receiver isn't a smi.
if (check != NUMBER_CHECK) { if (check != NUMBER_CHECK) {
__ test(edx, Immediate(kSmiTagMask)); __ test(edx, Immediate(kSmiTagMask));
__ j(zero, &miss, not_taken); __ j(zero, &miss_in_smi_check, not_taken);
} }
// Make sure that it's okay not to patch the on stack receiver // Make sure that it's okay not to patch the on stack receiver
...@@ -1241,6 +1241,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object, ...@@ -1241,6 +1241,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
CallOptimization optimization(function); CallOptimization optimization(function);
int depth = kInvalidProtoDepth; int depth = kInvalidProtoDepth;
Label miss;
switch (check) { switch (check) {
case RECEIVER_MAP_CHECK: case RECEIVER_MAP_CHECK:
...@@ -1359,6 +1360,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object, ...@@ -1359,6 +1360,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
if (depth != kInvalidProtoDepth) { if (depth != kInvalidProtoDepth) {
FreeSpaceForFastApiCall(masm(), eax); FreeSpaceForFastApiCall(masm(), eax);
} }
__ bind(&miss_in_smi_check);
Handle<Code> ic = ComputeCallMiss(arguments().immediate()); Handle<Code> ic = ComputeCallMiss(arguments().immediate());
__ jmp(ic, RelocInfo::CODE_TARGET); __ jmp(ic, RelocInfo::CODE_TARGET);
......
...@@ -6433,6 +6433,45 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { ...@@ -6433,6 +6433,45 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
CHECK_GE(interceptor_call_count, 50); CHECK_GE(interceptor_call_count, 50);
} }
THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
int interceptor_call_count = 0;
v8::HandleScope scope;
v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
v8::Handle<v8::FunctionTemplate> method_templ =
v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
v8_str("method_data"),
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
NULL, NULL, NULL, NULL,
v8::External::Wrap(&interceptor_call_count));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
v8::TryCatch try_catch;
v8::Handle<Value> value = CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
"var result = 0;"
"var saved_result = 0;"
"for (var i = 0; i < 100; i++) {"
" result = receiver.method(41);"
" if (i == 50) {"
" saved_result = result;"
" receiver = 333;"
" }"
"}");
CHECK(try_catch.HasCaught());
CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
try_catch.Exception()->ToString());
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
CHECK_GE(interceptor_call_count, 50);
}
THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
int interceptor_call_count = 0; int interceptor_call_count = 0;
v8::HandleScope scope; v8::HandleScope scope;
...@@ -6521,7 +6560,7 @@ THREADED_TEST(CallICFastApi_SimpleSignature) { ...@@ -6521,7 +6560,7 @@ THREADED_TEST(CallICFastApi_SimpleSignature) {
CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
} }
THREADED_TEST(CallICFastApi_SimpleSignature_Miss) { THREADED_TEST(CallICFastApi_SimpleSignature_Miss1) {
v8::HandleScope scope; v8::HandleScope scope;
v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
v8::Handle<v8::FunctionTemplate> method_templ = v8::Handle<v8::FunctionTemplate> method_templ =
...@@ -6552,6 +6591,40 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss) { ...@@ -6552,6 +6591,40 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss) {
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
} }
THREADED_TEST(CallICFastApi_SimpleSignature_Miss2) {
v8::HandleScope scope;
v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
v8::Handle<v8::FunctionTemplate> method_templ =
v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
v8_str("method_data"),
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
v8::TryCatch try_catch;
v8::Handle<Value> value = CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
"var result = 0;"
"var saved_result = 0;"
"for (var i = 0; i < 100; i++) {"
" result = receiver.method(41);"
" if (i == 50) {"
" saved_result = result;"
" receiver = 333;"
" }"
"}");
CHECK(try_catch.HasCaught());
CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
try_catch.Exception()->ToString());
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
}
static int interceptor_call_count = 0; static int interceptor_call_count = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment