[runtime] [proxy] implement [[Construct]]

LOG=N
BUG=v8:1543

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

Cr-Commit-Position: refs/heads/master@{#32718}
This commit is contained in:
cbruni 2015-12-09 06:55:00 -08:00 committed by Commit bot
parent 02320548a5
commit a2d5641bc4
14 changed files with 341 additions and 45 deletions

View File

@ -1749,8 +1749,14 @@ void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// the JSFunction on which new was invoked initially)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ Push(r1);
__ Push(r3);
// Include the pushed new_target, constructor and the receiver.
__ add(r0, r0, Operand(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
@ -1771,15 +1777,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
__ Jump(masm->isolate()->builtins()->ConstructFunction(),
RelocInfo::CODE_TARGET, eq);
__ cmp(r5, Operand(JS_PROXY_TYPE));
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq);
// Check if target has a [[Construct]] internal method.
__ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset));
__ tst(r2, Operand(1 << Map::kIsConstructor));
__ b(eq, &non_constructor);
// Only dispatch to proxies after checking whether they are constructors.
__ cmp(r5, Operand(JS_PROXY_TYPE));
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq);
// Called Construct on an exotic Object with a [[Construct]] internal method.
{
// Overwrite the original receiver with the (original) target.

View File

@ -1741,8 +1741,14 @@ void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// the JSFunction on which new was invoked initially)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ Push(x1);
__ Push(x3);
// Include the pushed new_target, constructor and the receiver.
__ Add(x0, x0, 3);
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
@ -1763,14 +1769,16 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE);
__ Jump(masm->isolate()->builtins()->ConstructFunction(),
RelocInfo::CODE_TARGET, eq);
__ Cmp(x5, JS_PROXY_TYPE);
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq);
// Check if target has a [[Construct]] internal method.
__ Ldrb(x2, FieldMemOperand(x4, Map::kBitFieldOffset));
__ TestAndBranchIfAllClear(x2, 1 << Map::kIsConstructor, &non_constructor);
// Only dispatch to proxies after checking whether they are constructors.
__ Cmp(x5, JS_PROXY_TYPE);
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq);
// Called Construct on an exotic Object with a [[Construct]] internal method.
{
// Overwrite the original receiver with the (original) target.

View File

@ -1603,13 +1603,21 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : the number of arguments (not including the receiver)
// -- edi : the constructor to call (checked to be a JSProxy)
// -- edx : the new target (either the same as the constructor or
// the JSFunction on which new was invoked initially)
// -- edi : the constructor to call (checked to be a JSProxy)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ PopReturnAddressTo(ecx);
__ Push(edi);
__ Push(edx);
__ PushReturnAddressFrom(ecx);
// Include the pushed new_target, constructor and the receiver.
__ add(eax, Immediate(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
@ -1630,14 +1638,16 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(equal, masm->isolate()->builtins()->ConstructFunction(),
RelocInfo::CODE_TARGET);
__ CmpInstanceType(ecx, JS_PROXY_TYPE);
__ j(equal, masm->isolate()->builtins()->ConstructProxy(),
RelocInfo::CODE_TARGET);
// Check if target has a [[Construct]] internal method.
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
__ j(zero, &non_constructor, Label::kNear);
// Only dispatch to proxies after checking whether they are constructors.
__ CmpInstanceType(ecx, JS_PROXY_TYPE);
__ j(equal, masm->isolate()->builtins()->ConstructProxy(),
RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method.
{
// Overwrite the original receiver with the (original) target.

View File

@ -208,6 +208,8 @@ class CallSite {
T(ProxyTargetNonObject, "Proxy target is non-object") \
T(ProxyTargetPropNotConfigurable, \
"Proxy target property '%' is not configurable") \
T(ProxyTrapConstructMustReturnObject, \
"Construct trap must return Object, but got ''%s'.") \
T(ProxyTrapFunctionExpected, \
"Proxy.createFunction called with non-function for '%' trap") \
T(ProxyTrapResultMustInclude, "Trap result must include %.") \

View File

@ -1761,8 +1761,14 @@ void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// the JSFunction on which new was invoked initially)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ Push(a1);
__ Push(a3);
// Include the pushed new_target, constructor and the receiver.
__ Addu(a0, a0, Operand(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
@ -1784,14 +1790,16 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset));
__ Jump(masm->isolate()->builtins()->ConstructFunction(),
RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq, t2, Operand(JS_PROXY_TYPE));
// Check if target has a [[Construct]] internal method.
__ lbu(t2, FieldMemOperand(t1, Map::kBitFieldOffset));
__ And(t2, t2, Operand(1 << Map::kIsCallable));
__ Branch(&non_constructor, eq, t2, Operand(zero_reg));
// Only dispatch to proxies after checking whether they are constructors.
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq, t2, Operand(JS_PROXY_TYPE));
// Called Construct on an exotic Object with a [[Construct]] internal method.
{
// Overwrite the original receiver with the (original) target.

View File

@ -1752,8 +1752,14 @@ void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// the JSFunction on which new was invoked initially)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ Push(a1);
__ Push(a3);
// Include the pushed new_target, constructor and the receiver.
__ Daddu(a0, a0, Operand(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
@ -1775,14 +1781,16 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset));
__ Jump(masm->isolate()->builtins()->ConstructFunction(),
RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq, t2, Operand(JS_PROXY_TYPE));
// Check if target has a [[Construct]] internal method.
__ lbu(t2, FieldMemOperand(t1, Map::kBitFieldOffset));
__ And(t2, t2, Operand(1 << Map::kIsCallable));
__ Branch(&non_constructor, eq, t2, Operand(zero_reg));
// Only dispatch to proxies after checking whether they are constructors.
__ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
eq, t2, Operand(JS_PROXY_TYPE));
// Called Construct on an exotic Object with a [[Construct]] internal method.
{
// Overwrite the original receiver with the (original) target.

View File

@ -1764,8 +1764,14 @@ void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// the JSFunction on which new was invoked initially)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ Push(r4);
__ Push(r6);
// Include the pushed new_target, constructor and the receiver.
__ addi(r3, r3, Operand(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}

View File

@ -73,6 +73,75 @@ RUNTIME_FUNCTION(Runtime_JSProxyCall) {
}
// 9.5.14 [[Construct]] (argumentsList, newTarget)
RUNTIME_FUNCTION(Runtime_JSProxyConstruct) {
HandleScope scope(isolate);
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::kProxyTrapConstructMustReturnObject,
new_object));
}
// 10. Return newObj.
return *new_object;
}
RUNTIME_FUNCTION(Runtime_IsJSProxy) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);

View File

@ -539,10 +539,11 @@ namespace internal {
F(BitwiseXor, 2, 1) \
F(BitwiseXor_Strong, 2, 1)
#define FOR_EACH_INTRINSIC_PROXY(F) \
F(IsJSProxy, 1, 1) \
F(JSProxyCall, -1 /* >= 2 */, 1) \
F(GetHandler, 1, 1) \
#define FOR_EACH_INTRINSIC_PROXY(F) \
F(IsJSProxy, 1, 1) \
F(JSProxyCall, -1 /* >= 2 */, 1) \
F(JSProxyConstruct, -1 /* >= 3 */, 1) \
F(GetHandler, 1, 1) \
F(RevokeProxy, 1, 1)
#define FOR_EACH_INTRINSIC_REGEXP(F) \

View File

@ -1807,13 +1807,20 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : the number of arguments (not including the receiver)
// -- rdi : the constructor to call (checked to be a JSProxy)
// -- rdx : the new target (either the same as the constructor or
// the JSFunction on which new was invoked initially)
// -- rdi : the constructor to call (checked to be a JSProxy)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ PopReturnAddressTo(kScratchRegister);
__ Push(rdi);
__ Push(rdx);
__ PushReturnAddressFrom(kScratchRegister);
// Include the pushed new_target, constructor and the receiver.
__ addp(rax, Immediate(3));
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()), 1);
}
@ -1835,15 +1842,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
__ j(equal, masm->isolate()->builtins()->ConstructFunction(),
RelocInfo::CODE_TARGET);
__ CmpInstanceType(rcx, JS_PROXY_TYPE);
__ j(equal, masm->isolate()->builtins()->ConstructProxy(),
RelocInfo::CODE_TARGET);
// Check if target has a [[Construct]] internal method.
__ testb(FieldOperand(rcx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsConstructor));
__ j(zero, &non_constructor, Label::kNear);
// Only dispatch to proxies after checking whether they are constructors.
__ CmpInstanceType(rcx, JS_PROXY_TYPE);
__ j(equal, masm->isolate()->builtins()->ConstructProxy(),
RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method.
{
// Overwrite the original receiver with the (original) target.

View File

@ -1603,13 +1603,21 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : the number of arguments (not including the receiver)
// -- edi : the constructor to call (checked to be a JSProxy)
// -- edx : the new target (either the same as the constructor or
// the JSFunction on which new was invoked initially)
// -- edi : the constructor to call (checked to be a JSProxy)
// -----------------------------------
// TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
// Call into the Runtime for Proxy [[Construct]].
__ PopReturnAddressTo(ecx);
__ Push(edi);
__ Push(edx);
__ PushReturnAddressFrom(ecx);
// Include the pushed new_target, constructor and the receiver.
__ add(eax, Immediate(3));
// Tail-call to the runtime.
__ JumpToExternalReference(
ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
}
@ -1617,9 +1625,9 @@ void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
void Builtins::Generate_Construct(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : the number of arguments (not including the receiver)
// -- edi : the constructor to call (can be any Object)
// -- edx : the new target (either the same as the constructor or
// the JSFunction on which new was invoked initially)
// -- edi : the constructor to call (can be any Object)
// -----------------------------------
// Check if target is a Smi.
@ -1630,14 +1638,16 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(equal, masm->isolate()->builtins()->ConstructFunction(),
RelocInfo::CODE_TARGET);
__ CmpInstanceType(ecx, JS_PROXY_TYPE);
__ j(equal, masm->isolate()->builtins()->ConstructProxy(),
RelocInfo::CODE_TARGET);
// Check if target has a [[Construct]] internal method.
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
__ j(zero, &non_constructor, Label::kNear);
// Only dispatch to proxies after checking whether they are constructors.
__ CmpInstanceType(ecx, JS_PROXY_TYPE);
__ j(equal, masm->isolate()->builtins()->ConstructProxy(),
RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method.
{
// Overwrite the original receiver with the (original) target.

View File

@ -5,7 +5,7 @@
// Flags: --allow-natives-syntax --harmony-proxies --harmony-reflect
function CreateConstructableProxy(handler) {
return Proxy.createFunction(handler, function() {}, function() {});
return new Proxy(function(){}, handler);
}
(function() {

View File

@ -0,0 +1,158 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-proxies --harmony-reflect
(function testNonConstructable() {
var proxy = new Proxy({},{});
assertThrows(function(){ new proxy() }, TypeError);
var proxy2 = new Proxy(proxy, {});
assertThrows(function(){ proxy2() }, TypeError);
})();
(function testFailingConstructRevoked() {
var pair = Proxy.revocable(Array, {});
var instance = new pair.proxy();
pair.revoke();
assertThrows(function(){ new pair.proxy() }, TypeError);
})();
(function testFailingGetTrap() {
var handler = {
get() {
throw TypeError();
}
}
var proxy = new Proxy({},{});
var proxy2 = new Proxy({}, proxy);
assertThrows(function(){ new proxy2() }, TypeError);
})();
(function testConstructFallback() {
var called = false;
function Target() {
called = true;
this.property1 = 'value1';
};
Target.prototype = {};
var proxy = new Proxy(Target, {});
assertFalse(called);
var instance = new proxy();
assertTrue(called);
assertEquals('value1', instance.property1);
assertSame(Target.prototype, Reflect.getPrototypeOf(instance));
var proxy2 = new Proxy(proxy, {});
called = false;
var instance2 = new proxy2();
assertTrue(called);
assertEquals('value1', instance2.property1);
assertSame(Target.prototype, Reflect.getPrototypeOf(instance));
})();
(function testConstructTrapDirectReturn() {
function Target(a, b) {
this.sum = a + b;
};
var handler = {
construct(t, c, args) {
return { sum: 42 };
}
};
var proxy = new Proxy(Target, handler);
assertEquals(42, (new proxy(1, 2)).sum);
})();
(function testConstructTrap() {
function Target(arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
}
var seen_target, seen_arguments, seen_new_target;
var handler = {
construct(target, args, new_target) {
seen_target = target;
seen_arguments = args;
seen_new_target = new_target;
return Reflect.construct(target, args, new_target);
}
}
var proxy = new Proxy(Target, handler);
var instance = new proxy('a', 'b');
assertEquals(Target, seen_target);
assertEquals(['a','b'], seen_arguments);
assertEquals(proxy, seen_new_target);
assertEquals('a', instance.arg1);
assertEquals('b', instance.arg2);
var instance2 = Reflect.construct(proxy, ['a1', 'b1'], Array);
assertEquals(Target, seen_target);
assertEquals(['a1', 'b1'], seen_arguments);
assertEquals(Array, seen_new_target);
assertEquals('a1', instance2.arg1);
assertEquals('b1', instance2.arg2);
})();
(function testConstructCrossRealm() {
var realm1 = Realm.create();
var handler = {
construct(target, args, new_target) {
return args;
}
};
var OtherProxy = Realm.eval(realm1, "Proxy");
var otherArrayPrototype = Realm.eval(realm1, 'Array.prototype');
// Proxy and handler are from this realm.
var proxy = new Proxy(Array, handler);
var result = new proxy();
assertSame(Array.prototype, Reflect.getPrototypeOf(result));
// Proxy is from this realm, handler is from realm1.
var otherProxy = new OtherProxy(Array, handler);
var otherResult = new otherProxy();
assertSame(Array.prototype, Reflect.getPrototypeOf(otherResult));
// Proxy and handler are from realm1.
var otherProxy2 = Realm.eval(realm1, 'new Proxy('+
'Array, { construct(target, args, new_target) { return args }} )');
var otherResult2 = new otherProxy2();
assertSame(Array.prototype, Reflect.getPrototypeOf(otherResult2));
})();
(function testReflectConstructCrossReal() {
var realm1 = Realm.create();
var realm2 = Realm.create();
var realm3 = Realm.create();
var realm4 = Realm.create();
var argsRealm1 = Realm.eval(realm1, '[]');
var ProxyRealm2 = Realm.eval(realm2, 'Proxy');
var constructorRealm3 = Realm.eval(realm3, '(function(){})');
var handlerRealm4 = Realm.eval(realm4,
'({ construct(target, args, new_target) {return args} })');
var proxy = new ProxyRealm2(constructorRealm3, handlerRealm4);
// Check that the arguments array returned by handlerRealm4 is created in the
// realm of the Reflect.construct function.
var result = Reflect.construct(proxy, argsRealm1);
assertSame(Array.prototype, Reflect.getPrototypeOf(result));
var ReflectConstructRealm1 = Realm.eval(realm1, 'Reflect.construct');
var result2 = ReflectConstructRealm1(proxy, argsRealm1);
assertSame(Realm.eval(realm1, 'Array.prototype'),
Reflect.getPrototypeOf(result2));
var result3 = ReflectConstructRealm1(proxy, []);
assertSame(Realm.eval(realm1, 'Array.prototype'),
Reflect.getPrototypeOf(result3));
var ReflectConstructRealm2 = Realm.eval(realm2, 'Reflect.construct');
var result4 = ReflectConstructRealm2(proxy, argsRealm1);
assertSame(Realm.eval(realm2, 'Array.prototype'),
Reflect.getPrototypeOf(result4));
})();

View File

@ -87,7 +87,6 @@
# Proxy tests rely on non ES6 version of Proxies
# TODO(neis,cbruni): figure out which Proxy tests can be reused
'es6/classes-proxy' : [SKIP],
'es6/regress/regress-cr493566': [SKIP],
'for-in-opt': [SKIP],
'harmony/proxies-example-membrane': [SKIP],