diff options
Diffstat (limited to 'chromium/v8/src/runtime/runtime-proxy.cc')
-rw-r--r-- | chromium/v8/src/runtime/runtime-proxy.cc | 167 |
1 files changed, 129 insertions, 38 deletions
diff --git a/chromium/v8/src/runtime/runtime-proxy.cc b/chromium/v8/src/runtime/runtime-proxy.cc index 4699647b801..3a521c6b7c4 100644 --- a/chromium/v8/src/runtime/runtime-proxy.cc +++ b/chromium/v8/src/runtime/runtime-proxy.cc @@ -5,33 +5,139 @@ #include "src/runtime/runtime-utils.h" #include "src/arguments.h" +#include "src/elements.h" #include "src/factory.h" +#include "src/isolate-inl.h" #include "src/objects-inl.h" namespace v8 { namespace internal { -RUNTIME_FUNCTION(Runtime_CreateJSProxy) { + +// ES6 9.5.13 [[Call]] (thisArgument, argumentsList) +RUNTIME_FUNCTION(Runtime_JSProxyCall) { HandleScope scope(isolate); - DCHECK(args.length() == 2); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); - if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); - return *isolate->factory()->NewJSProxy(handler, prototype); + DCHECK_LE(2, args.length()); + // thisArgument == receiver + CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); + CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, args.length() - 1); + Handle<String> trap_name = isolate->factory()->apply_string(); + // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + Handle<Object> handler(proxy->handler(), isolate); + // 2. If handler is null, throw a TypeError exception. + if (proxy->IsRevoked()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); + } + // 3. Assert: Type(handler) is Object. + DCHECK(handler->IsJSReceiver()); + // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. + Handle<JSReceiver> target(proxy->target(), isolate); + // 5. Let trap be ? GetMethod(handler, "apply"). + Handle<Object> trap; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, trap, + Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name)); + // 6. If trap is undefined, then + int const arguments_length = args.length() - 2; + if (trap->IsUndefined()) { + // 6.a. Return Call(target, thisArgument, argumentsList). + ScopedVector<Handle<Object>> argv(arguments_length); + for (int i = 0; i < arguments_length; ++i) { + argv[i] = args.at<Object>(i + 1); + } + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Execution::Call(isolate, target, receiver, + arguments_length, argv.start())); + return *result; + } + // 7. Let argArray be CreateArrayFromList(argumentsList). + Handle<JSArray> arg_array = isolate->factory()->NewJSArray( + FAST_ELEMENTS, arguments_length, arguments_length); + ElementsAccessor* accessor = arg_array->GetElementsAccessor(); + { + DisallowHeapAllocation no_gc; + FixedArrayBase* elements = arg_array->elements(); + for (int i = 0; i < arguments_length; i++) { + accessor->Set(elements, i, args[i + 1]); + } + } + // 8. Return Call(trap, handler, «target, thisArgument, argArray»). + Handle<Object> trap_result; + Handle<Object> trap_args[] = {target, receiver, arg_array}; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, trap_result, + Execution::Call(isolate, trap, handler, arraysize(trap_args), trap_args)); + return *trap_result; } -RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) { +// 9.5.14 [[Construct]] (argumentsList, newTarget) +RUNTIME_FUNCTION(Runtime_JSProxyConstruct) { HandleScope scope(isolate); - DCHECK(args.length() == 4); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, call_trap, 1); - RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy()); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2); - CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3); - if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); - return *isolate->factory()->NewJSFunctionProxy(handler, call_trap, - construct_trap, prototype); + DCHECK_LE(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, args.length() - 2); + CONVERT_ARG_HANDLE_CHECKED(Object, new_target, args.length() - 1); + Handle<String> trap_name = isolate->factory()->construct_string(); + + // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + Handle<Object> handler(proxy->handler(), isolate); + // 2. If handler is null, throw a TypeError exception. + if (proxy->IsRevoked()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); + } + // 3. Assert: Type(handler) is Object. + DCHECK(handler->IsJSReceiver()); + // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. + Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); + // 5. Let trap be ? GetMethod(handler, "construct"). + Handle<Object> trap; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, trap, + Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name)); + // 6. If trap is undefined, then + int const arguments_length = args.length() - 3; + if (trap->IsUndefined()) { + // 6.a. Assert: target has a [[Construct]] internal method. + DCHECK(target->IsConstructor()); + // 6.b. Return Construct(target, argumentsList, newTarget). + ScopedVector<Handle<Object>> argv(arguments_length); + for (int i = 0; i < arguments_length; ++i) { + argv[i] = args.at<Object>(i + 1); + } + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Execution::New(isolate, target, new_target, + arguments_length, argv.start())); + return *result; + } + // 7. Let argArray be CreateArrayFromList(argumentsList). + Handle<JSArray> arg_array = isolate->factory()->NewJSArray( + FAST_ELEMENTS, arguments_length, arguments_length); + ElementsAccessor* accessor = arg_array->GetElementsAccessor(); + { + DisallowHeapAllocation no_gc; + FixedArrayBase* elements = arg_array->elements(); + for (int i = 0; i < arguments_length; i++) { + accessor->Set(elements, i, args[i + 1]); + } + } + // 8. Let newObj be ? Call(trap, handler, «target, argArray, newTarget »). + Handle<Object> new_object; + Handle<Object> trap_args[] = {target, arg_array, new_target}; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, new_object, + Execution::Call(isolate, trap, handler, arraysize(trap_args), trap_args)); + // 9. If Type(newObj) is not Object, throw a TypeError exception. + if (!new_object->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kProxyConstructNonObject, new_object)); + } + // 10. Return newObj. + return *new_object; } @@ -43,15 +149,7 @@ RUNTIME_FUNCTION(Runtime_IsJSProxy) { } -RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); - return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy()); -} - - -RUNTIME_FUNCTION(Runtime_GetHandler) { +RUNTIME_FUNCTION(Runtime_JSProxyGetHandler) { SealHandleScope shs(isolate); DCHECK(args.length() == 1); CONVERT_ARG_CHECKED(JSProxy, proxy, 0); @@ -59,28 +157,21 @@ RUNTIME_FUNCTION(Runtime_GetHandler) { } -RUNTIME_FUNCTION(Runtime_GetCallTrap) { +RUNTIME_FUNCTION(Runtime_JSProxyGetTarget) { SealHandleScope shs(isolate); DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0); - return proxy->call_trap(); -} - - -RUNTIME_FUNCTION(Runtime_GetConstructTrap) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0); - return proxy->construct_trap(); + CONVERT_ARG_CHECKED(JSProxy, proxy, 0); + return proxy->target(); } -RUNTIME_FUNCTION(Runtime_Fix) { +RUNTIME_FUNCTION(Runtime_JSProxyRevoke) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0); - JSProxy::Fix(proxy); + JSProxy::Revoke(proxy); return isolate->heap()->undefined_value(); } + } // namespace internal } // namespace v8 |