Commit ecd70581 authored by feng@chromium.org's avatar feng@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1837 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9926c85e
......@@ -54,6 +54,14 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
// -- 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 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
__ 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 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
__ 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);
}
......
......@@ -4656,11 +4656,6 @@ THREADED_TEST(CallAsFunction) {
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());
}
......
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