[proxies] Implement the Proxy constructor in C++ fully.

The main part of the Proxy constructor was already in C++, there's
actually no point in keeping a JavaScript wrapper.

R=cbruni@chromium.org
BUG=v8:1543
LOG=n

Review URL: https://codereview.chromium.org/1491893002

Cr-Commit-Position: refs/heads/master@{#32507}
This commit is contained in:
bmeurer 2015-12-02 04:29:50 -08:00 committed by Commit bot
parent 9cffd0d2ce
commit 2377170d07
6 changed files with 66 additions and 38 deletions

View File

@ -2149,13 +2149,15 @@ void Genesis::InitializeGlobal_harmony_proxies() {
Handle<JSGlobalObject> global(
JSGlobalObject::cast(native_context()->global_object()));
Isolate* isolate = global->GetIsolate();
Handle<JSFunction> proxy_fun =
InstallFunction(global, "Proxy", JS_PROXY_TYPE, JSProxy::kSize,
isolate->initial_object_prototype(), Builtins::kIllegal);
Handle<JSFunction> proxy_fun = InstallFunction(
global, "Proxy", JS_PROXY_TYPE, JSProxy::kSize,
isolate->initial_object_prototype(), Builtins::kProxyConstructor);
// TODO(verwaest): Set to null in InstallFunction.
proxy_fun->initial_map()->set_prototype(isolate->heap()->null_value());
proxy_fun->shared()->set_construct_stub(
*isolate->builtins()->JSBuiltinsConstructStub());
*isolate->builtins()->ProxyConstructor_ConstructStub());
proxy_fun->shared()->set_internal_formal_parameter_count(2);
proxy_fun->shared()->set_length(2);
native_context()->set_proxy_function(*proxy_fun);
}

View File

@ -1745,6 +1745,63 @@ BUILTIN(SymbolConstructor_ConstructStub) {
}
namespace {
// ES6 section 9.5.15 ProxyCreate (target, handler)
MaybeHandle<JSProxy> ProxyCreate(Isolate* isolate, Handle<Object> target,
Handle<Object> handler) {
if (!target->IsJSReceiver()) {
THROW_NEW_ERROR(
isolate, NewTypeError(MessageTemplate::kProxyTargetNonObject), JSProxy);
}
if (target->IsJSProxy() && JSProxy::cast(*target)->IsRevoked()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
JSProxy);
}
if (!handler->IsJSReceiver()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kProxyHandlerNonObject),
JSProxy);
}
if (handler->IsJSProxy() && JSProxy::cast(*handler)->IsRevoked()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked),
JSProxy);
}
return isolate->factory()->NewJSProxy(Handle<JSReceiver>::cast(target),
Handle<JSReceiver>::cast(handler));
}
} // namespace
// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Call]] case.
BUILTIN(ProxyConstructor) {
HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kConstructorNotFunction,
isolate->factory()->NewStringFromAsciiChecked("Proxy")));
}
// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Construct]] case.
BUILTIN(ProxyConstructor_ConstructStub) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
Handle<Object> target = args.at<Object>(1);
Handle<Object> handler = args.at<Object>(2);
// The ConstructStub is executed in the context of the caller, so we need
// to enter the callee context first before raising an exception.
isolate->set_context(args.target()->context());
Handle<JSProxy> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
ProxyCreate(isolate, target, handler));
return *result;
}
// -----------------------------------------------------------------------------
// Throwers for restricted function properties and strict arguments object
// properties

View File

@ -66,6 +66,9 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
\
V(DateToPrimitive, kNone) \
\
V(ProxyConstructor, kNone) \
V(ProxyConstructor_ConstructStub, kTarget) \
\
V(ReflectDefineProperty, kNone) \
V(ReflectDeleteProperty, kNone) \
V(ReflectGet, kNone) \

View File

@ -15,22 +15,13 @@ var GlobalProxy = global.Proxy;
var GlobalFunction = global.Function;
var GlobalObject = global.Object;
var MakeTypeError;
var ToNameArray;
utils.Import(function(from) {
MakeTypeError = from.MakeTypeError;
ToNameArray = from.ToNameArray;
});
//----------------------------------------------------------------------------
function ProxyCreate(target, handler) {
if (IS_UNDEFINED(new.target)) {
throw MakeTypeError(kConstructorNotFunction, "Proxy");
}
return %CreateJSProxy(target, handler);
}
function ProxyCreateFunction(handler, callTrap, constructTrap) {
if (!IS_SPEC_OBJECT(handler))
throw MakeTypeError(kProxyHandlerNonObject, "createFunction")
@ -150,7 +141,6 @@ function ProxyEnumerate(trap, handler, target) {
}
//-------------------------------------------------------------------
%SetCode(GlobalProxy, ProxyCreate);
//Set up non-enumerable properties of the Proxy object.
utils.InstallFunctions(GlobalProxy, DONT_ENUM, [

View File

@ -11,29 +11,6 @@
namespace v8 {
namespace internal {
RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, target, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, handler, 1);
if (!target->IsJSReceiver()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kProxyTargetNonObject));
}
if (!handler->IsJSReceiver()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kProxyHandlerNonObject));
}
if ((target->IsJSProxy() && JSProxy::cast(*target)->IsRevoked()) ||
(handler->IsJSProxy() && JSProxy::cast(*handler)->IsRevoked())) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kProxyHandlerOrTargetRevoked));
}
return *isolate->factory()->NewJSProxy(Handle<JSReceiver>::cast(target),
Handle<JSReceiver>::cast(handler));
}
RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
HandleScope scope(isolate);
DCHECK(args.length() == 5);

View File

@ -545,7 +545,6 @@ namespace internal {
F(BitwiseXor_Strong, 2, 1)
#define FOR_EACH_INTRINSIC_PROXY(F) \
F(CreateJSProxy, 2, 1) \
F(CreateJSFunctionProxy, 5, 1) \
F(IsJSProxy, 1, 1) \
F(IsJSFunctionProxy, 1, 1) \