Chromium Code Reviews| 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); |
| } |