Author: [email protected]
Date: Fri May 1 12:01:19 2009
New Revision: 1837
Modified:
branches/bleeding_edge/src/ia32/builtins-ia32.cc
branches/bleeding_edge/test/cctest/test-api.cc
Log:
A simple fix of issue
http://code.google.com/p/chromium/issues/detail?id=3285
NPN_Construct allows a NPObject to be called as a construct. For example,
the
test case
var s = new app.Packages.java.lang.Integer(5);
app.Packages.java.lang.Integer is a NPObject, and it implements
NPN_Construct.
This fix allows a JSObject created by an API function be called as a
construct
if it can be called
as a function. This is done by generating the same code for
var s = new app.Packages.java.lang.Integer(5); as
var s = app.Packages.java.lang.Integer(5);
and the caller handles both case correctly. A more sophiscated fix is to one
extra JSConstructCall
frame and allow CallAsConstructor in Builtin::HandleApiCallAsFunction.
This change itself shouldn't affect the semantic of normal case such as:
var a = {};
var s = new a();
A TypeError exception will be thrown in CALL_NON_FUNCTION (runtime.js).
Another part of fix is in the binding code, V8NPObject, which makes
NPN_InvokeDefault or NPN_Construct
call depending on which function is available.
Review URL: http://codereview.chromium.org/100243
Modified: branches/bleeding_edge/src/ia32/builtins-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/builtins-ia32.cc (original)
+++ branches/bleeding_edge/src/ia32/builtins-ia32.cc Fri May 1 12:01:19
2009
@@ -54,6 +54,14 @@
// -- edi: constructor function
// -----------------------------------
+ Label non_function_call;
+ // Check that function is not a smi.
+ __ test(edi, Immediate(kSmiTagMask));
+ __ j(zero, &non_function_call);
+ // Check that function is a JSFunction.
+ __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+ __ j(not_equal, &non_function_call);
+
// Enter a construct frame.
__ EnterConstructFrame();
@@ -75,12 +83,6 @@
__ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0));
__ j(not_equal, &rt_call);
#endif
- // Check that function is not a Smi.
- __ test(edi, Immediate(kSmiTagMask));
- __ j(zero, &rt_call);
- // Check that function is a JSFunction
- __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax);
- __ j(not_equal, &rt_call);
// Verified that the constructor is a JSFunction.
// Load the initial map and verify that it is in fact a map.
@@ -302,6 +304,16 @@
__ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~
receiver
__ push(ecx);
__ ret(0);
+
+ // edi: called object
+ // eax: number of arguments
+ __ bind(&non_function_call);
+
+ // Set expected number of arguments to zero (not changing eax).
+ __ Set(ebx, Immediate(0));
+ __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
+ __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
+ RelocInfo::CODE_TARGET);
}
Modified: branches/bleeding_edge/test/cctest/test-api.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-api.cc (original)
+++ branches/bleeding_edge/test/cctest/test-api.cc Fri May 1 12:01:19 2009
@@ -4656,11 +4656,6 @@
value = Script::Compile(v8_str(call_17))->Run();
CHECK(!try_catch.HasCaught());
CHECK_EQ(17, value->Int32Value());
-
- // Try something that will cause an exception: Call the object as a
- // constructor. This should be the last test.
- value = Script::Compile(v8_str("new obj(42)"))->Run();
- CHECK(try_catch.HasCaught());
}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---