Index: src/execution.cc |
diff --git a/src/execution.cc b/src/execution.cc |
index bdbdca81bb7cfcdf5cf34316ce4d541abab5fed6..51dc6bafaf69021acefad5c071a5b52f98f59362 100644 |
--- a/src/execution.cc |
+++ b/src/execution.cc |
@@ -149,12 +149,27 @@ Handle<Object> Execution::Call(Handle<Object> callable, |
Handle<Object> receiver, |
int argc, |
Object*** args, |
- bool* pending_exception) { |
+ bool* pending_exception, |
+ bool convert_receiver) { |
if (!callable->IsJSFunction()) { |
callable = TryGetFunctionDelegate(callable, pending_exception); |
if (*pending_exception) return callable; |
} |
Handle<JSFunction> func = Handle<JSFunction>::cast(callable); |
+ |
+ // In non-strict mode, convert receiver. |
+ if (convert_receiver && !receiver->IsJSReceiver() && |
+ !func->shared()->native() && !func->shared()->strict_mode()) { |
+ if (receiver->IsUndefined() || receiver->IsNull()) { |
+ Object* global = func->context()->global()->global_receiver(); |
+ // Is there a way to get the proper global object if func is a builtin? |
Kevin Millikin (Chromium)
2011/09/12 14:42:47
I guess I'm not sure what is proper. isolate()->g
rossberg
2011/09/12 15:17:25
Ah, thanks, the latter is what I was looking for,
|
+ if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global); |
+ } else { |
+ receiver = ToObject(receiver, pending_exception); |
+ } |
+ if (*pending_exception) return callable; |
+ } |
+ |
return Invoke(false, func, receiver, argc, args, pending_exception); |
} |
@@ -210,10 +225,17 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { |
// If you return a function from here, it will be called when an |
// attempt is made to call the given object as a function. |
+ // If object is a function proxies, get its handler. Iterate if necessary. |
+ Object* fun = *object; |
+ while (fun->IsJSFunctionProxy()) { |
+ fun = JSFunctionProxy::cast(fun)->call_trap(); |
+ } |
+ if (fun->IsJSFunction()) return Handle<Object>(fun); |
+ |
// Objects created through the API can have an instance-call handler |
// that should be used when calling the object as a function. |
- if (object->IsHeapObject() && |
- HeapObject::cast(*object)->map()->has_instance_call_handler()) { |
+ if (fun->IsHeapObject() && |
+ HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
return Handle<JSFunction>( |
isolate->global_context()->call_as_function_delegate()); |
} |
@@ -227,10 +249,17 @@ Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, |
ASSERT(!object->IsJSFunction()); |
Isolate* isolate = Isolate::Current(); |
+ // If object is a function proxies, get its handler. Iterate if necessary. |
+ Object* fun = *object; |
+ while (fun->IsJSFunctionProxy()) { |
+ fun = JSFunctionProxy::cast(fun)->call_trap(); |
+ } |
+ if (fun->IsJSFunction()) return Handle<Object>(fun); |
+ |
// Objects created through the API can have an instance-call handler |
// that should be used when calling the object as a function. |
- if (object->IsHeapObject() && |
- HeapObject::cast(*object)->map()->has_instance_call_handler()) { |
+ if (fun->IsHeapObject() && |
+ HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
return Handle<JSFunction>( |
isolate->global_context()->call_as_function_delegate()); |
} |
@@ -253,10 +282,17 @@ Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { |
// If you return a function from here, it will be called when an |
// attempt is made to call the given object as a constructor. |
+ // If object is a function proxies, get its handler. Iterate if necessary. |
+ Object* fun = *object; |
+ while (fun->IsJSFunctionProxy()) { |
+ fun = JSFunctionProxy::cast(fun)->call_trap(); |
+ } |
+ if (fun->IsJSFunction()) return Handle<Object>(fun); |
+ |
// Objects created through the API can have an instance-call handler |
// that should be used when calling the object as a function. |
- if (object->IsHeapObject() && |
- HeapObject::cast(*object)->map()->has_instance_call_handler()) { |
+ if (fun->IsHeapObject() && |
+ HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
return Handle<JSFunction>( |
isolate->global_context()->call_as_constructor_delegate()); |
} |
@@ -274,10 +310,17 @@ Handle<Object> Execution::TryGetConstructorDelegate( |
// If you return a function from here, it will be called when an |
// attempt is made to call the given object as a constructor. |
+ // If object is a function proxies, get its handler. Iterate if necessary. |
+ Object* fun = *object; |
+ while (fun->IsJSFunctionProxy()) { |
+ fun = JSFunctionProxy::cast(fun)->call_trap(); |
+ } |
+ if (fun->IsJSFunction()) return Handle<Object>(fun); |
+ |
// Objects created through the API can have an instance-call handler |
// that should be used when calling the object as a function. |
- if (object->IsHeapObject() && |
- HeapObject::cast(*object)->map()->has_instance_call_handler()) { |
+ if (fun->IsHeapObject() && |
+ HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
return Handle<JSFunction>( |
isolate->global_context()->call_as_constructor_delegate()); |
} |
@@ -553,7 +596,7 @@ Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) { |
Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { |
- if (obj->IsJSObject()) return obj; |
+ if (obj->IsSpecObject()) return obj; |
RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc); |
} |