| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Flags: --harmony-proxies | 5 // Flags: --harmony-proxies --harmony-reflect |
| 6 | 6 |
| 7 var target = { target: 1 }; | 7 var target = { target: 1 }; |
| 8 target.__proto__ = {}; | 8 target.__proto__ = {}; |
| 9 var handler = { handler: 1 }; | 9 var handler = { handler: 1 }; |
| 10 var proxy = new Proxy(target, handler); | 10 var proxy = new Proxy(target, handler); |
| 11 | 11 |
| 12 assertSame(Object.getPrototypeOf(proxy), target.__proto__ ); | 12 assertSame(Object.getPrototypeOf(proxy), target.__proto__ ); |
| 13 | 13 |
| 14 |
| 14 assertThrows(function() { Object.setPrototypeOf(proxy, undefined) }, TypeError); | 15 assertThrows(function() { Object.setPrototypeOf(proxy, undefined) }, TypeError); |
| 15 assertThrows(function() { Object.setPrototypeOf(proxy, 1) }, TypeError); | 16 assertThrows(function() { Object.setPrototypeOf(proxy, 1) }, TypeError); |
| 16 | 17 |
| 17 var prototype = [1]; | 18 var prototype = [1]; |
| 18 assertSame(proxy, Object.setPrototypeOf(proxy, prototype)); | 19 assertSame(proxy, Object.setPrototypeOf(proxy, prototype)); |
| 19 assertSame(prototype, Object.getPrototypeOf(proxy)); | 20 assertSame(prototype, Object.getPrototypeOf(proxy)); |
| 20 assertSame(prototype, Object.getPrototypeOf(target)); | 21 assertSame(prototype, Object.getPrototypeOf(target)); |
| 21 | 22 |
| 23 var pair = Proxy.revocable(target, handler); |
| 24 assertSame(pair.proxy, Object.setPrototypeOf(pair.proxy, prototype)); |
| 25 assertSame(prototype, Object.getPrototypeOf(pair.proxy)); |
| 26 pair.revoke(); |
| 27 assertThrows('Object.setPrototypeOf(pair.proxy, prototype)', TypeError); |
| 28 |
| 22 handler.setPrototypeOf = function(target, proto) { | 29 handler.setPrototypeOf = function(target, proto) { |
| 23 return false; | 30 return false; |
| 24 }; | 31 }; |
| 25 assertThrows(function() { Object.setPrototypeOf(proxy, {a:1}) }, TypeError); | 32 assertThrows(function() { Object.setPrototypeOf(proxy, {a:1}) }, TypeError); |
| 26 | 33 |
| 27 handler.setPrototypeOf = function(target, proto) { | 34 handler.setPrototypeOf = function(target, proto) { |
| 28 return undefined; | 35 return undefined; |
| 29 }; | 36 }; |
| 30 assertThrows(function() { Object.setPrototypeOf(proxy, {a:2}) }, TypeError); | 37 assertThrows(function() { Object.setPrototypeOf(proxy, {a:2}) }, TypeError); |
| 31 | 38 |
| 32 handler.setPrototypeOf = function(proto) {}; | 39 handler.setPrototypeOf = function(proto) {}; |
| 33 assertThrows(function() { Object.setPrototypeOf(proxy, {a:3}) }, TypeError); | 40 assertThrows(function() { Object.setPrototypeOf(proxy, {a:3}) }, TypeError); |
| 34 | 41 |
| 35 handler.setPrototypeOf = function(target, proto) { | 42 handler.setPrototypeOf = function(target, proto) { |
| 36 throw Error(); | 43 throw Error(); |
| 37 }; | 44 }; |
| 38 assertThrows(function() { Object.setPrototypeOf(proxy, {a:4}) }, Error); | 45 assertThrows(function() { Object.setPrototypeOf(proxy, {a:4}) }, Error); |
| 39 | 46 |
| 40 var seen_prototype; | 47 var seen_prototype; |
| 41 var seen_target; | 48 var seen_target; |
| 42 handler.setPrototypeOf = function(target, proto) { | 49 handler.setPrototypeOf = function(target, proto) { |
| 43 seen_target = target; | 50 seen_target = target; |
| 44 seen_prototype = proto; | 51 seen_prototype = proto; |
| 45 return true; | 52 return true; |
| 46 } | 53 } |
| 47 assertSame(Object.setPrototypeOf(proxy, {a:5}), proxy); | 54 assertSame(Object.setPrototypeOf(proxy, {a:5}), proxy); |
| 48 assertSame(target, seen_target); | 55 assertSame(target, seen_target); |
| 49 assertEquals({a:5}, seen_prototype); | 56 assertEquals({a:5}, seen_prototype); |
| 50 | 57 |
| 51 // Target is a Proxy: | 58 (function setPrototypeProxyTarget() { |
| 52 var target2 = new Proxy(target, {}); | 59 var target = { target: 1 }; |
| 53 var proxy2 = new Proxy(target2, {}); | 60 target.__proto__ = {}; |
| 54 assertSame(Object.getPrototypeOf(proxy2), target.__proto__ ); | 61 var handler = {}; |
| 62 var handler2 = {}; |
| 63 var target2 = new Proxy(target, handler2); |
| 64 var proxy2 = new Proxy(target2, handler); |
| 65 assertSame(Object.getPrototypeOf(proxy2), target.__proto__ ); |
| 55 | 66 |
| 56 prototype = [2,3]; | 67 var prototype = [2,3]; |
| 57 assertSame(proxy2, Object.setPrototypeOf(proxy2, prototype)); | 68 assertSame(proxy2, Object.setPrototypeOf(proxy2, prototype)); |
| 58 assertSame(prototype, Object.getPrototypeOf(proxy2)); | 69 assertSame(prototype, Object.getPrototypeOf(proxy2)); |
| 59 assertSame(prototype, Object.getPrototypeOf(target)); | 70 assertSame(prototype, Object.getPrototypeOf(target)); |
| 71 })(); |
| 72 |
| 73 (function testProxyTrapInconsistent() { |
| 74 var target = { target: 1 }; |
| 75 target.__proto__ = {}; |
| 76 var handler = {}; |
| 77 var handler2 = { |
| 78 }; |
| 79 |
| 80 var target2 = new Proxy(target, handler); |
| 81 var proxy2 = new Proxy(target2, handler2); |
| 82 |
| 83 // If the final target is extensible we can set any prototype. |
| 84 var prototype = [1]; |
| 85 Reflect.setPrototypeOf(proxy2, prototype); |
| 86 assertSame(prototype, Reflect.getPrototypeOf(target)); |
| 87 |
| 88 handler2.setPrototypeOf = function(target, value) { |
| 89 Reflect.setPrototypeOf(target, value); |
| 90 return true; |
| 91 }; |
| 92 prototype = [2]; |
| 93 Reflect.setPrototypeOf(proxy2, prototype); |
| 94 assertSame(prototype, Reflect.getPrototypeOf(target)); |
| 95 |
| 96 // Prevent getting the target's prototype used to check the invariant. |
| 97 var gotPrototype = false; |
| 98 handler.getPrototypeOf = function() { |
| 99 gotPrototype = true; |
| 100 throw TypeError() |
| 101 }; |
| 102 // If the target is extensible we do not check the invariant. |
| 103 prototype = [3]; |
| 104 Reflect.setPrototypeOf(proxy2, prototype); |
| 105 assertFalse(gotPrototype); |
| 106 assertSame(prototype, Reflect.getPrototypeOf(target)); |
| 107 |
| 108 // Changing the prototype of a non-extensible target will trigger the |
| 109 // invariant-check and throw in the above handler. |
| 110 Reflect.preventExtensions(target); |
| 111 assertThrows(() => {Reflect.setPrototypeOf(proxy2, [4])}, TypeError); |
| 112 assertTrue(gotPrototype); |
| 113 assertEquals([3], Reflect.getPrototypeOf(target)); |
| 114 |
| 115 // Setting the prototype of a non-extensible target is fine if the prototype |
| 116 // doesn't change. |
| 117 delete handler.getPrototypeOf; |
| 118 Reflect.setPrototypeOf(proxy2, prototype); |
| 119 // Changing the prototype will throw. |
| 120 prototype = [5]; |
| 121 assertThrows(() => {Reflect.setPrototypeOf(proxy2, prototype)}, TypeError); |
| 122 })(); |
| OLD | NEW |