| Index: src/execution.cc
|
| diff --git a/src/execution.cc b/src/execution.cc
|
| index bdbdca81bb7cfcdf5cf34316ce4d541abab5fed6..cdea005829fb4e1fec14d4402272592cb58138d5 100644
|
| --- a/src/execution.cc
|
| +++ b/src/execution.cc
|
| @@ -149,12 +149,28 @@ 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()) {
|
| + // Careful, func->context()->global()->global_receiver() gives
|
| + // the JSBuiltinsObject if func is a builtin. Not what we want here.
|
| + receiver =
|
| + Handle<Object>(func->GetIsolate()->global()->global_receiver());
|
| + } else {
|
| + receiver = ToObject(receiver, pending_exception);
|
| + }
|
| + if (*pending_exception) return callable;
|
| + }
|
| +
|
| return Invoke(false, func, receiver, argc, args, pending_exception);
|
| }
|
|
|
| @@ -210,10 +226,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 +250,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 +283,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 +311,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 +597,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);
|
| }
|
|
|
|
|