Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 // Flags: --harmony-proxies | 28 // Flags: --harmony-proxies |
| 29 | 29 |
| 30 | 30 |
| 31 // Helper. | 31 // Helper. |
| 32 | 32 |
|
Lasse Reichstein
2011/10/17 12:38:39
I'll undo the manual semicolon insertions so you w
| |
| 33 function CreateFrozen(handler, callTrap, constructTrap) { | 33 function CreateFrozen(handler, callTrap, constructTrap) { |
| 34 if (handler.fix === undefined) handler.fix = function() { return {} } | 34 if (handler.fix === undefined) { |
| 35 handler.fix = function() { return { length: { value: 2 } }; }; | |
|
rossberg
2011/10/17 11:49:08
This shouldn't be necessary, because Object.freeze
Lasse Reichstein
2011/10/17 12:38:39
Ok, removing fix for fix.
| |
| 36 } | |
| 35 var f = Proxy.createFunction(handler, callTrap, constructTrap) | 37 var f = Proxy.createFunction(handler, callTrap, constructTrap) |
| 36 Object.freeze(f) | 38 Object.freeze(f) |
| 37 return f | 39 return f |
| 38 } | 40 } |
| 39 | 41 |
| 40 | 42 |
| 41 // Calling (call, Function.prototype.call, Function.prototype.apply, | 43 // Calling (call, Function.prototype.call, Function.prototype.apply, |
| 42 // Function.prototype.bind). | 44 // Function.prototype.bind). |
| 43 | 45 |
| 44 var global_object = this | 46 var global_object = this; |
| 45 var receiver | 47 var receiver; |
| 48 | |
| 49 // Ensures that checking the "length" property of a function proxy doesn't | |
| 50 // crash due to lack of a [[Get]] method. | |
| 51 var handler = { | |
|
rossberg
2011/10/17 11:49:08
Could you move this up to the helpers section?
Lasse Reichstein
2011/10/17 12:38:39
Done.
| |
| 52 get : function(r, n) { return n == "length" ? 2 : undefined; } | |
| 53 }; | |
| 54 | |
| 46 | 55 |
| 47 function TestCall(isStrict, callTrap) { | 56 function TestCall(isStrict, callTrap) { |
| 48 assertEquals(42, callTrap(5, 37)) | 57 assertEquals(42, callTrap(5, 37)); |
| 49 assertEquals(isStrict ? undefined : global_object, receiver) | 58 assertEquals(isStrict ? undefined : global_object, receiver); |
| 50 | 59 |
| 51 var handler = { | 60 var handler = { |
| 52 get: function(r, k) { | 61 get: function(r, k) { |
| 53 return k == "length" ? 2 : Function.prototype[k] | 62 return k == "length" ? 2 : Function.prototype[k]; |
| 54 } | 63 } |
| 55 } | 64 }; |
| 56 var f = Proxy.createFunction(handler, callTrap) | 65 var f = Proxy.createFunction(handler, callTrap); |
| 57 | 66 |
| 58 receiver = 333 | 67 receiver = 333; |
| 59 assertEquals(42, f(11, 31)) | 68 assertEquals(42, f(11, 31)); |
| 60 assertEquals(isStrict ? undefined : global_object, receiver) | 69 assertEquals(isStrict ? undefined : global_object, receiver); |
| 61 var o = {f: f} | 70 var o = {f: f}; |
| 62 receiver = 333 | 71 receiver = 333; |
| 63 assertEquals(42, o.f(10, 32)) | 72 assertEquals(42, o.f(10, 32)); |
| 64 assertSame(o, receiver) | 73 assertSame(o, receiver); |
| 65 receiver = 333 | 74 receiver = 333; |
| 66 assertEquals(42, o["f"](9, 33)) | 75 assertEquals(42, o["f"](9, 33)); |
| 67 assertSame(o, receiver) | 76 assertSame(o, receiver); |
| 68 receiver = 333 | 77 receiver = 333; |
| 69 assertEquals(42, (1, o).f(8, 34)) | 78 assertEquals(42, (1, o).f(8, 34)); |
| 70 assertSame(o, receiver) | 79 assertSame(o, receiver); |
| 71 receiver = 333 | 80 receiver = 333; |
| 72 assertEquals(42, (1, o)["f"](7, 35)) | 81 assertEquals(42, (1, o)["f"](7, 35)); |
| 73 assertSame(o, receiver) | 82 assertSame(o, receiver); |
| 74 receiver = 333 | 83 receiver = 333; |
| 75 assertEquals(42, f.call(o, 32, 10)) | 84 assertEquals(42, f.call(o, 32, 10)); |
| 76 assertSame(o, receiver) | 85 assertSame(o, receiver); |
| 77 receiver = 333 | 86 receiver = 333; |
| 78 assertEquals(42, f.call(null, 33, 9)) | 87 assertEquals(42, f.call(null, 33, 9)); |
| 79 assertSame(isStrict ? null : global_object, receiver) | 88 assertSame(isStrict ? null : global_object, receiver); |
| 80 receiver = 333 | 89 receiver = 333; |
| 81 assertEquals(44, f.call(2, 21, 23)) | 90 assertEquals(44, f.call(2, 21, 23)); |
| 82 assertSame(2, receiver.valueOf()) | 91 assertSame(2, receiver.valueOf()); |
| 83 receiver = 333 | 92 receiver = 333; |
| 84 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) | 93 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)); |
| 85 assertSame(o, receiver) | 94 assertSame(o, receiver); |
| 86 receiver = 333 | 95 receiver = 333; |
| 87 assertEquals(43, Function.prototype.call.call(f, null, 20, 23)) | 96 assertEquals(43, Function.prototype.call.call(f, null, 20, 23)); |
| 88 assertSame(isStrict ? null : global_object, receiver) | 97 assertSame(isStrict ? null : global_object, receiver); |
| 89 assertEquals(44, Function.prototype.call.call(f, 2, 21, 23)) | 98 assertEquals(44, Function.prototype.call.call(f, 2, 21, 23)); |
| 90 assertEquals(2, receiver.valueOf()) | 99 assertEquals(2, receiver.valueOf()); |
| 91 receiver = 333 | 100 receiver = 333; |
| 92 assertEquals(32, f.apply(o, [16, 16])) | 101 assertEquals(32, f.apply(o, [16, 16])); |
| 93 assertSame(o, receiver) | 102 assertSame(o, receiver); |
| 94 receiver = 333 | 103 receiver = 333; |
| 95 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) | 104 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])); |
| 96 assertSame(o, receiver) | 105 assertSame(o, receiver); |
| 97 | 106 |
| 98 var ff = Function.prototype.bind.call(f, o, 12) | 107 var ff = Function.prototype.bind.call(f, o, 12); |
| 99 assertTrue(ff.length <= 1) // TODO(rossberg): Not spec'ed yet, be lax. | 108 assertTrue(ff.length <= 1); // TODO(rossberg): Not spec'ed yet, be lax. |
| 100 receiver = 333 | 109 receiver = 333; |
| 101 assertEquals(42, ff(30)) | 110 assertEquals(42, ff(30)); |
| 102 assertSame(o, receiver) | 111 assertSame(o, receiver); |
| 103 receiver = 333 | 112 receiver = 333; |
| 104 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) | 113 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])); |
| 105 assertSame(o, receiver) | 114 assertSame(o, receiver); |
| 106 | 115 |
| 107 var fff = Function.prototype.bind.call(ff, o, 30) | 116 var fff = Function.prototype.bind.call(ff, o, 30); |
| 108 assertEquals(0, fff.length) | 117 assertEquals(0, fff.length); |
| 109 receiver = 333 | 118 receiver = 333; |
| 110 assertEquals(42, fff()) | 119 assertEquals(42, fff()); |
| 111 assertSame(o, receiver) | 120 assertSame(o, receiver); |
| 112 receiver = 333 | 121 receiver = 333; |
| 113 assertEquals(42, Function.prototype.call.call(fff, {})) | 122 assertEquals(42, Function.prototype.call.call(fff, {})); |
| 114 assertSame(o, receiver) | 123 assertSame(o, receiver); |
| 115 | 124 |
| 116 var f = CreateFrozen({}, callTrap) | 125 var f = CreateFrozen({}, callTrap); |
| 117 receiver = 333 | 126 receiver = 333; |
| 118 assertEquals(42, f(11, 31)) | 127 assertEquals(42, f(11, 31)); |
| 119 assertSame(isStrict ? undefined : global_object, receiver) | 128 assertSame(isStrict ? undefined : global_object, receiver); |
| 120 var o = {f: f} | 129 var o = {f: f}; |
| 121 receiver = 333 | 130 receiver = 333; |
| 122 assertEquals(42, o.f(10, 32)) | 131 assertEquals(42, o.f(10, 32)); |
| 123 assertSame(o, receiver) | 132 assertSame(o, receiver); |
| 124 receiver = 333 | 133 receiver = 333; |
| 125 assertEquals(42, o["f"](9, 33)) | 134 assertEquals(42, o["f"](9, 33)); |
| 126 assertSame(o, receiver) | 135 assertSame(o, receiver); |
| 127 receiver = 333 | 136 receiver = 333; |
| 128 assertEquals(42, (1, o).f(8, 34)) | 137 assertEquals(42, (1, o).f(8, 34)); |
| 129 assertSame(o, receiver) | 138 assertSame(o, receiver); |
| 130 receiver = 333 | 139 receiver = 333; |
| 131 assertEquals(42, (1, o)["f"](7, 35)) | 140 assertEquals(42, (1, o)["f"](7, 35)); |
| 132 assertSame(o, receiver) | 141 assertSame(o, receiver); |
| 133 receiver = 333 | 142 receiver = 333; |
| 134 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) | 143 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)); |
| 135 assertSame(o, receiver) | 144 assertSame(o, receiver); |
| 136 receiver = 333 | 145 receiver = 333; |
| 137 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) | 146 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])); |
| 138 assertSame(o, receiver) | 147 assertSame(o, receiver); |
| 139 receiver = 333 | 148 receiver = 333; |
| 140 assertEquals(42, ff(30)) | 149 assertEquals(42, ff(30)); |
| 141 assertSame(o, receiver) | 150 assertSame(o, receiver); |
| 142 receiver = 333 | 151 receiver = 333; |
| 143 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) | 152 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])); |
| 144 assertSame(o, receiver) | 153 assertSame(o, receiver); |
| 145 } | 154 } |
| 146 | 155 |
| 147 TestCall(false, function(x, y) { | 156 TestCall(false, function(x, y) { |
| 148 receiver = this; return x + y | 157 receiver = this; |
| 149 }) | 158 return x + y; |
| 159 }); | |
| 150 | 160 |
| 151 TestCall(true, function(x, y) { | 161 TestCall(true, function(x, y) { |
| 152 "use strict"; | 162 "use strict"; |
| 153 receiver = this; return x + y | 163 receiver = this; |
| 164 return x + y; | |
| 165 }); | |
| 166 | |
| 167 TestCall(false, function() { | |
| 168 receiver = this; return arguments[0] + arguments[1]; | |
| 154 }) | 169 }) |
| 155 | 170 |
| 156 TestCall(false, function() { | 171 TestCall(false, Proxy.createFunction(handler, function(x, y) { |
| 157 receiver = this; return arguments[0] + arguments[1] | 172 receiver = this; |
| 158 }) | 173 return x + y; |
| 174 })); | |
| 159 | 175 |
| 160 TestCall(false, Proxy.createFunction({}, function(x, y) { | 176 TestCall(true, Proxy.createFunction(handler, function(x, y) { |
| 161 receiver = this; return x + y | 177 "use strict"; |
| 162 })) | 178 receiver = this; |
| 179 return x + y; | |
| 180 })); | |
| 163 | 181 |
| 164 TestCall(true, Proxy.createFunction({}, function(x, y) { | 182 TestCall(false, CreateFrozen(handler, function(x, y) { |
| 165 "use strict"; | 183 receiver = this; |
| 166 receiver = this; return x + y | 184 return x + y; |
| 167 })) | 185 })); |
| 168 | |
| 169 TestCall(false, CreateFrozen({}, function(x, y) { | |
| 170 receiver = this; return x + y | |
| 171 })) | |
| 172 | 186 |
| 173 | 187 |
| 174 | 188 |
| 175 // Using intrinsics as call traps. | 189 // Using intrinsics as call traps. |
| 176 | 190 |
| 177 function TestCallIntrinsic(type, callTrap) { | 191 function TestCallIntrinsic(type, callTrap) { |
| 178 var f = Proxy.createFunction({}, callTrap) | 192 var f = Proxy.createFunction({}, callTrap) |
| 179 var x = f() | 193 var x = f() |
| 180 assertTrue(typeof x == type) | 194 assertTrue(typeof x == type) |
| 181 } | 195 } |
| 182 | 196 |
| 183 TestCallIntrinsic("boolean", Boolean) | 197 TestCallIntrinsic("boolean", Boolean) |
| 184 TestCallIntrinsic("number", Number) | 198 TestCallIntrinsic("number", Number) |
| 185 TestCallIntrinsic("string", String) | 199 TestCallIntrinsic("string", String) |
| 186 TestCallIntrinsic("object", Object) | 200 TestCallIntrinsic("object", Object) |
| 187 TestCallIntrinsic("function", Function) | 201 TestCallIntrinsic("function", Function) |
| 188 | 202 |
| 189 | 203 |
| 190 | 204 |
| 191 // Throwing from call trap. | 205 // Throwing from call trap. |
| 192 | 206 |
| 193 function TestCallThrow(callTrap) { | 207 function TestCallThrow(callTrap) { |
| 194 var f = Proxy.createFunction({}, callTrap) | 208 var f = Proxy.createFunction(handler, callTrap); |
|
rossberg
2011/10/17 11:49:08
None of this should actually need the length prope
Lasse Reichstein
2011/10/17 12:38:39
Right, no call to bind here. Undoing.
| |
| 195 assertThrows(function(){ f(11) }, "myexn") | 209 assertThrows(function(){ f(11) }, "myexn"); |
| 196 assertThrows(function(){ ({x: f}).x(11) }, "myexn") | 210 assertThrows(function(){ ({x: f}).x(11) }, "myexn"); |
| 197 assertThrows(function(){ ({x: f})["x"](11) }, "myexn") | 211 assertThrows(function(){ ({x: f})["x"](11) }, "myexn"); |
| 198 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn") | 212 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn"); |
| 199 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") | 213 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") ; |
| 200 | 214 |
| 201 var f = CreateFrozen({}, callTrap) | 215 var f = CreateFrozen(handler, callTrap); |
| 202 assertThrows(function(){ f(11) }, "myexn") | 216 assertThrows(function(){ f(11) }, "myexn"); |
| 203 assertThrows(function(){ ({x: f}).x(11) }, "myexn") | 217 assertThrows(function(){ ({x: f}).x(11) }, "myexn"); |
| 204 assertThrows(function(){ ({x: f})["x"](11) }, "myexn") | 218 assertThrows(function(){ ({x: f})["x"](11) }, "myexn"); |
| 205 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn") | 219 assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn"); |
| 206 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") | 220 assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") ; |
| 207 } | 221 } |
| 208 | 222 |
| 209 TestCallThrow(function() { throw "myexn" }) | 223 TestCallThrow(function() { throw "myexn"; }); |
| 210 TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" })) | 224 TestCallThrow(Proxy.createFunction(handler, function() { throw "myexn"; })); |
| 211 TestCallThrow(CreateFrozen({}, function() { throw "myexn" })) | 225 TestCallThrow(CreateFrozen(handler, function() { throw "myexn"; })); |
| 212 | 226 |
| 213 | 227 |
| 214 | 228 |
| 215 // Construction (new). | 229 // Construction (new). |
| 216 | 230 |
| 217 var prototype = {} | 231 var prototype = {}; |
| 218 var receiver | 232 var receiver; |
| 219 | 233 |
| 220 var handlerWithPrototype = { | 234 var handlerWithPrototype = { |
| 221 fix: function() { return {prototype: prototype} }, | 235 fix: function() { |
| 222 get: function(r, n) { assertEquals("prototype", n); return prototype } | 236 return { length: {value: 2}, |
| 237 prototype: { value: prototype } } | |
| 238 }, | |
| 239 get: function(r, n) { | |
| 240 if (n == "length") return 2; | |
| 241 assertEquals("prototype", n); | |
| 242 return prototype; | |
| 243 } | |
| 244 }; | |
| 245 | |
| 246 var handlerSansPrototype = { | |
| 247 fix: function() { return { length: { value: 2 } }; }, | |
|
Lasse Reichstein
2011/10/17 12:38:39
Removing length from fix here too.
| |
| 248 get: function(r, n) { | |
| 249 if (n == "length") return 2; | |
| 250 assertEquals("prototype", n); | |
| 251 return undefined; | |
| 252 } | |
| 253 }; | |
| 254 | |
| 255 function ReturnUndef(x, y) { | |
| 256 "use strict"; | |
| 257 receiver = this; | |
| 258 this.sum = x + y; | |
| 223 } | 259 } |
| 224 | 260 |
| 225 var handlerSansPrototype = { | 261 function ReturnThis(x, y) { |
| 226 fix: function() { return {} }, | 262 "use strict"; |
| 227 get: function(r, n) { assertEquals("prototype", n); return undefined } | 263 receiver = this; |
| 264 this.sum = x + y; | |
| 265 return this; | |
| 228 } | 266 } |
| 229 | 267 |
| 230 function ReturnUndef(x, y) { "use strict"; receiver = this; this.sum = x + y } | 268 function ReturnNew(x, y) { |
| 231 function ReturnThis(x, y) { "use strict"; receiver = this; this.sum = x + y; ret urn this } | 269 "use strict"; |
| 232 function ReturnNew(x, y) { "use strict"; receiver = this; return {sum: x + y} } | 270 receiver = this; |
| 271 return {sum: x + y}; | |
| 272 } | |
| 273 | |
| 233 function ReturnNewWithProto(x, y) { | 274 function ReturnNewWithProto(x, y) { |
| 234 "use strict"; | 275 "use strict"; |
| 235 receiver = this; | 276 receiver = this; |
| 236 var result = Object.create(prototype) | 277 var result = Object.create(prototype) |
| 237 result.sum = x + y | 278 result.sum = x + y |
| 238 return result | 279 return result |
| 239 } | 280 } |
| 240 | 281 |
| 241 function TestConstruct(proto, constructTrap) { | 282 function TestConstruct(proto, constructTrap) { |
| 242 TestConstruct2(proto, constructTrap, handlerWithPrototype) | 283 TestConstruct2(proto, constructTrap, handlerWithPrototype); |
| 243 TestConstruct2(proto, constructTrap, handlerSansPrototype) | 284 TestConstruct2(proto, constructTrap, handlerSansPrototype); |
| 244 } | 285 } |
| 245 | 286 |
| 246 function TestConstruct2(proto, constructTrap, handler) { | 287 function TestConstruct2(proto, constructTrap, handler) { |
| 247 var f = Proxy.createFunction(handler, function() {}, constructTrap) | 288 var f = Proxy.createFunction(handler, function() {}, constructTrap); |
| 248 var o = new f(11, 31) | 289 var o = new f(11, 31); |
| 249 assertEquals(undefined, receiver) | 290 assertEquals(undefined, receiver); |
| 250 assertEquals(42, o.sum) | 291 assertEquals(42, o.sum); |
| 251 assertSame(proto, Object.getPrototypeOf(o)) | 292 assertSame(proto, Object.getPrototypeOf(o)); |
| 252 | 293 |
| 253 // TODO(rossberg): does not work yet. | 294 // TODO(rossberg): does not work yet. |
| 254 // var ff = Function.prototype.bind.call(f, o, 10) | 295 // var ff = Function.prototype.bind.call(f, o, 10) |
| 255 // var o = new ff(32) | 296 // var o = new ff(32) |
| 256 // assertEquals(undefined, receiver) | 297 // assertEquals(undefined, receiver) |
| 257 // assertEquals(42, o.sum) | 298 // assertEquals(42, o.sum) |
| 258 // assertSame(proto, Object.getPrototypeOf(o)) | 299 // assertSame(proto, Object.getPrototypeOf(o)) |
| 259 | 300 |
| 260 var f = CreateFrozen(handler, function() {}, constructTrap) | 301 var f = CreateFrozen(handler, function() {}, constructTrap); |
| 261 var o = new f(11, 32) | 302 var o = new f(11, 32); |
| 262 assertEquals(undefined, receiver) | 303 assertEquals(undefined, receiver); |
| 263 assertEquals(43, o.sum) | 304 assertEquals(43, o.sum); |
| 264 assertSame(proto, Object.getPrototypeOf(o)) | 305 assertSame(proto, Object.getPrototypeOf(o)); |
| 265 | 306 |
| 266 var ff = Function.prototype.bind.call(f, o, 10) | 307 var ff = Function.prototype.bind.call(f, o, 10); |
| 267 var o = new ff(32) | 308 var o = new ff(32); |
| 268 assertEquals(undefined, receiver) | 309 assertEquals(undefined, receiver); |
| 269 assertEquals(42, o.sum) | 310 assertEquals(42, o.sum); |
| 270 assertSame(proto, Object.getPrototypeOf(o)) | 311 assertSame(proto, Object.getPrototypeOf(o)); |
| 271 } | 312 } |
| 272 | 313 |
| 273 TestConstruct(Object.prototype, ReturnNew) | 314 TestConstruct(Object.prototype, ReturnNew); |
| 274 TestConstruct(prototype, ReturnNewWithProto) | 315 TestConstruct(prototype, ReturnNewWithProto); |
| 275 | 316 |
| 276 TestConstruct(Object.prototype, Proxy.createFunction({}, ReturnNew)) | 317 TestConstruct(Object.prototype, Proxy.createFunction(handler, ReturnNew)); |
| 277 TestConstruct(prototype, Proxy.createFunction({}, ReturnNewWithProto)) | 318 TestConstruct(prototype, Proxy.createFunction(handler, ReturnNewWithProto)); |
| 278 | 319 |
| 279 TestConstruct(Object.prototype, CreateFrozen({}, ReturnNew)) | 320 TestConstruct(Object.prototype, CreateFrozen(handler, ReturnNew)); |
| 280 TestConstruct(prototype, CreateFrozen({}, ReturnNewWithProto)) | 321 TestConstruct(prototype, CreateFrozen(handler, ReturnNewWithProto)); |
| 281 | 322 |
| 282 | 323 |
| 283 | 324 |
| 284 // Construction with derived construct trap. | 325 // Construction with derived construct trap. |
| 285 | 326 |
| 286 function TestConstructFromCall(proto, returnsThis, callTrap) { | 327 function TestConstructFromCall(proto, returnsThis, callTrap) { |
| 287 TestConstructFromCall2(proto, returnsThis, callTrap, handlerWithPrototype) | 328 TestConstructFromCall2(proto, returnsThis, callTrap, handlerWithPrototype); |
| 288 TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype) | 329 TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype); |
| 289 } | 330 } |
| 290 | 331 |
| 291 function TestConstructFromCall2(proto, returnsThis, callTrap, handler) { | 332 function TestConstructFromCall2(proto, returnsThis, callTrap, handler) { |
| 292 var f = Proxy.createFunction(handler, callTrap) | 333 var f = Proxy.createFunction(handler, callTrap); |
| 293 var o = new f(11, 31) | 334 var o = new f(11, 31); |
| 294 if (returnsThis) assertEquals(o, receiver) | 335 if (returnsThis) assertEquals(o, receiver); |
| 295 assertEquals(42, o.sum) | 336 assertEquals(42, o.sum); |
| 296 assertSame(proto, Object.getPrototypeOf(o)) | 337 assertSame(proto, Object.getPrototypeOf(o)); |
| 297 | 338 |
| 298 // TODO(rossberg): does not work yet. | 339 // TODO(rossberg): does not work yet. |
| 299 // var ff = Function.prototype.bind.call(f, o, 10) | 340 // var ff = Function.prototype.bind.call(f, o, 10) |
| 300 // var o = new ff(32) | 341 // var o = new ff(32) |
| 301 // assertEquals(undefined, receiver) | 342 // assertEquals(undefined, receiver) |
| 302 // assertEquals(42, o.sum) | 343 // assertEquals(42, o.sum) |
| 303 // assertSame(proto, Object.getPrototypeOf(o)) | 344 // assertSame(proto, Object.getPrototypeOf(o)) |
| 304 | 345 |
| 305 var f = CreateFrozen(handler, callTrap) | 346 var f = CreateFrozen(handler, callTrap); |
| 306 var o = new f(11, 32) | 347 var o = new f(11, 32); |
| 307 if (returnsThis) assertEquals(o, receiver) | 348 if (returnsThis) assertEquals(o, receiver); |
| 308 assertEquals(43, o.sum) | 349 assertEquals(43, o.sum); |
| 309 assertSame(proto, Object.getPrototypeOf(o)) | 350 assertSame(proto, Object.getPrototypeOf(o)); |
| 310 | 351 |
| 311 // TODO(rossberg): does not work yet. | 352 // TODO(rossberg): does not work yet. |
| 312 // var ff = Function.prototype.bind.call(f, o, 10) | 353 // var ff = Function.prototype.bind.call(f, o, 10) |
| 313 // var o = new ff(32) | 354 // var o = new ff(32) |
| 314 // assertEquals(undefined, receiver) | 355 // assertEquals(undefined, receiver) |
| 315 // assertEquals(42, o.sum) | 356 // assertEquals(42, o.sum) |
| 316 // assertSame(proto, Object.getPrototypeOf(o)) | 357 // assertSame(proto, Object.getPrototypeOf(o)) |
| 317 } | 358 } |
| 318 | 359 |
| 319 TestConstructFromCall(Object.prototype, true, ReturnUndef) | 360 TestConstructFromCall(Object.prototype, true, ReturnUndef); |
| 320 TestConstructFromCall(Object.prototype, true, ReturnThis) | 361 TestConstructFromCall(Object.prototype, true, ReturnThis); |
| 321 TestConstructFromCall(Object.prototype, false, ReturnNew) | 362 TestConstructFromCall(Object.prototype, false, ReturnNew); |
| 322 TestConstructFromCall(prototype, false, ReturnNewWithProto) | 363 TestConstructFromCall(prototype, false, ReturnNewWithProto); |
| 323 | 364 |
| 324 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnUnd ef)) | 365 TestConstructFromCall(Object.prototype, true, |
| 325 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnThi s)) | 366 Proxy.createFunction(handler, ReturnUndef)); |
| 326 TestConstructFromCall(Object.prototype, false, Proxy.createFunction({}, ReturnNe w)) | 367 TestConstructFromCall(Object.prototype, true, |
| 327 TestConstructFromCall(prototype, false, Proxy.createFunction({}, ReturnNewWithPr oto)) | 368 Proxy.createFunction(handler, ReturnThis)); |
| 369 TestConstructFromCall(Object.prototype, false, | |
| 370 Proxy.createFunction(handler, ReturnNew)); | |
| 371 TestConstructFromCall(prototype, false, | |
| 372 Proxy.createFunction(handler, ReturnNewWithProto)); | |
| 328 | 373 |
| 329 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef)) | 374 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef)); |
| 330 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis)) | 375 TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis)); |
| 331 TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew)) | 376 TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew)); |
| 332 TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto)) | 377 TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto)); |
| 333 | 378 |
| 334 ReturnUndef.prototype = prototype | 379 ReturnUndef.prototype = prototype; |
| 335 ReturnThis.prototype = prototype | 380 ReturnThis.prototype = prototype; |
| 336 ReturnNew.prototype = prototype | 381 ReturnNew.prototype = prototype; |
| 337 ReturnNewWithProto.prototype = prototype | 382 ReturnNewWithProto.prototype = prototype; |
| 338 | 383 |
| 339 TestConstructFromCall(prototype, true, ReturnUndef) | 384 TestConstructFromCall(prototype, true, ReturnUndef); |
| 340 TestConstructFromCall(prototype, true, ReturnThis) | 385 TestConstructFromCall(prototype, true, ReturnThis); |
| 341 TestConstructFromCall(Object.prototype, false, ReturnNew) | 386 TestConstructFromCall(Object.prototype, false, ReturnNew); |
| 342 TestConstructFromCall(prototype, false, ReturnNewWithProto) | 387 TestConstructFromCall(prototype, false, ReturnNewWithProto); |
| 343 | 388 |
| 344 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnUnd ef)) | 389 TestConstructFromCall(Object.prototype, true, |
| 345 TestConstructFromCall(Object.prototype, true, Proxy.createFunction({}, ReturnThi s)) | 390 Proxy.createFunction(handler, ReturnUndef)); |
| 346 TestConstructFromCall(Object.prototype, false, Proxy.createFunction({}, ReturnNe w)) | 391 TestConstructFromCall(Object.prototype, true, |
| 347 TestConstructFromCall(prototype, false, Proxy.createFunction({}, ReturnNewWithPr oto)) | 392 Proxy.createFunction(handler, ReturnThis)); |
| 393 TestConstructFromCall(Object.prototype, false, | |
| 394 Proxy.createFunction(handler, ReturnNew)); | |
| 395 TestConstructFromCall(prototype, false, | |
| 396 Proxy.createFunction(handler, ReturnNewWithProto)); | |
| 348 | 397 |
| 349 TestConstructFromCall(prototype, true, Proxy.createFunction(handlerWithPrototype , ReturnUndef)) | 398 TestConstructFromCall(prototype, true, |
| 350 TestConstructFromCall(prototype, true, Proxy.createFunction(handlerWithPrototype , ReturnThis)) | 399 Proxy.createFunction(handlerWithPrototype, ReturnUndef)); |
| 351 TestConstructFromCall(Object.prototype, false, Proxy.createFunction(handlerWithP rototype, ReturnNew)) | 400 TestConstructFromCall(prototype, true, |
| 352 TestConstructFromCall(prototype, false, Proxy.createFunction(handlerWithPrototyp e, ReturnNewWithProto)) | 401 Proxy.createFunction(handlerWithPrototype, ReturnThis)); |
| 402 TestConstructFromCall(Object.prototype, false, | |
| 403 Proxy.createFunction(handlerWithPrototype, ReturnNew)); | |
| 404 TestConstructFromCall(prototype, false, | |
| 405 Proxy.createFunction(handlerWithPrototype, | |
| 406 ReturnNewWithProto)); | |
| 353 | 407 |
| 354 TestConstructFromCall(prototype, true, CreateFrozen(handlerWithPrototype, Return Undef)) | 408 TestConstructFromCall(prototype, true, |
| 355 TestConstructFromCall(prototype, true, CreateFrozen(handlerWithPrototype, Return This)) | 409 CreateFrozen(handlerWithPrototype, ReturnUndef)); |
| 356 TestConstructFromCall(Object.prototype, false, CreateFrozen(handlerWithPrototype , ReturnNew)) | 410 TestConstructFromCall(prototype, true, |
| 357 TestConstructFromCall(prototype, false, CreateFrozen(handlerWithPrototype, Retur nNewWithProto)) | 411 CreateFrozen(handlerWithPrototype, ReturnThis)); |
| 412 TestConstructFromCall(Object.prototype, false, | |
| 413 CreateFrozen(handlerWithPrototype, ReturnNew)); | |
| 414 TestConstructFromCall(prototype, false, | |
| 415 CreateFrozen(handlerWithPrototype, ReturnNewWithProto)); | |
| 358 | 416 |
| 359 | 417 |
| 360 | 418 |
| 361 // Throwing from the construct trap. | 419 // Throwing from the construct trap. |
| 362 | 420 |
| 363 function TestConstructThrow(trap) { | 421 function TestConstructThrow(trap) { |
| 364 TestConstructThrow2(Proxy.createFunction({fix: function() {return {}}}, trap)) | 422 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} }, |
| 365 TestConstructThrow2(Proxy.createFunction({fix: function() {return {}}}, | 423 trap)); |
| 366 function() {}, trap)) | 424 TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} }, |
| 425 function() {}, | |
| 426 trap)); | |
| 367 } | 427 } |
| 368 | 428 |
| 369 function TestConstructThrow2(f) { | 429 function TestConstructThrow2(f) { |
| 370 assertThrows(function(){ new f(11) }, "myexn") | 430 assertThrows(function(){ new f(11) }, "myexn"); |
| 371 Object.freeze(f) | 431 Object.freeze(f); |
| 372 assertThrows(function(){ new f(11) }, "myexn") | 432 assertThrows(function(){ new f(11) }, "myexn"); |
| 373 } | 433 } |
| 374 | 434 |
| 375 TestConstructThrow(function() { throw "myexn" }) | 435 TestConstructThrow(function() { throw "myexn"; }); |
| 376 TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn" })) | 436 TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn"; })); |
| 377 TestConstructThrow(CreateFrozen({}, function() { throw "myexn" })) | 437 TestConstructThrow(CreateFrozen({}, function() { throw "myexn"; })); |
| 378 | 438 |
| 379 | 439 |
| 380 | 440 |
| 381 // Using function proxies as getters and setters. | 441 // Using function proxies as getters and setters. |
| 382 | 442 |
| 383 var value | 443 var value; |
| 384 var receiver | 444 var receiver; |
| 385 | 445 |
| 386 function TestAccessorCall(getterCallTrap, setterCallTrap) { | 446 function TestAccessorCall(getterCallTrap, setterCallTrap) { |
| 387 var handler = {fix: function() { return {} }} | 447 var handler = { fix: function() { return {}; } }; |
| 388 var pgetter = Proxy.createFunction(handler, getterCallTrap) | 448 var pgetter = Proxy.createFunction(handler, getterCallTrap); |
| 389 var psetter = Proxy.createFunction(handler, setterCallTrap) | 449 var psetter = Proxy.createFunction(handler, setterCallTrap); |
| 390 | 450 |
| 391 var o = {} | 451 var o = {}; |
| 392 var oo = Object.create(o) | 452 var oo = Object.create(o); |
| 393 Object.defineProperty(o, "a", {get: pgetter, set: psetter}) | 453 Object.defineProperty(o, "a", {get: pgetter, set: psetter}); |
| 394 Object.defineProperty(o, "b", {get: pgetter}) | 454 Object.defineProperty(o, "b", {get: pgetter}); |
| 395 Object.defineProperty(o, "c", {set: psetter}) | 455 Object.defineProperty(o, "c", {set: psetter}); |
| 396 Object.defineProperty(o, "3", {get: pgetter, set: psetter}) | 456 Object.defineProperty(o, "3", {get: pgetter, set: psetter}); |
| 397 Object.defineProperty(oo, "a", {value: 43}) | 457 Object.defineProperty(oo, "a", {value: 43}); |
| 398 | 458 |
| 399 receiver = "" | 459 receiver = ""; |
| 400 assertEquals(42, o.a) | 460 assertEquals(42, o.a); |
| 401 assertSame(o, receiver) | 461 assertSame(o, receiver); |
| 402 receiver = "" | 462 receiver = ""; |
| 403 assertEquals(42, o.b) | 463 assertEquals(42, o.b); |
| 404 assertSame(o, receiver) | 464 assertSame(o, receiver); |
| 405 receiver = "" | 465 receiver = ""; |
| 406 assertEquals(undefined, o.c) | 466 assertEquals(undefined, o.c); |
| 407 assertEquals("", receiver) | 467 assertEquals("", receiver); |
| 408 receiver = "" | 468 receiver = ""; |
| 409 assertEquals(42, o["a"]) | 469 assertEquals(42, o["a"]); |
| 410 assertSame(o, receiver) | 470 assertSame(o, receiver); |
| 411 receiver = "" | 471 receiver = ""; |
| 412 assertEquals(42, o[3]) | 472 assertEquals(42, o[3]); |
| 413 assertSame(o, receiver) | 473 assertSame(o, receiver); |
| 414 | 474 |
| 415 receiver = "" | 475 receiver = ""; |
| 416 assertEquals(43, oo.a) | 476 assertEquals(43, oo.a); |
| 417 assertEquals("", receiver) | 477 assertEquals("", receiver); |
| 418 receiver = "" | 478 receiver = ""; |
| 419 assertEquals(42, oo.b) | 479 assertEquals(42, oo.b); |
| 420 assertSame(o, receiver) | 480 assertSame(o, receiver); |
| 421 receiver = "" | 481 receiver = ""; |
| 422 assertEquals(undefined, oo.c) | 482 assertEquals(undefined, oo.c); |
| 423 assertEquals("", receiver) | 483 assertEquals("", receiver); |
| 424 receiver = "" | 484 receiver = ""; |
| 425 assertEquals(43, oo["a"]) | 485 assertEquals(43, oo["a"]); |
| 426 assertEquals("", receiver) | 486 assertEquals("", receiver); |
| 427 receiver = "" | 487 receiver = ""; |
| 428 assertEquals(42, oo[3]) | 488 assertEquals(42, oo[3]); |
| 429 assertSame(o, receiver) | 489 assertSame(o, receiver); |
| 430 | 490 |
| 431 receiver = "" | 491 receiver = ""; |
| 432 assertEquals(50, o.a = 50) | 492 assertEquals(50, o.a = 50); |
| 433 assertSame(o, receiver) | 493 assertSame(o, receiver); |
| 434 assertEquals(50, value) | 494 assertEquals(50, value); |
| 435 receiver = "" | 495 receiver = ""; |
| 436 assertEquals(51, o.b = 51) | 496 assertEquals(51, o.b = 51); |
| 437 assertEquals("", receiver) | 497 assertEquals("", receiver); |
| 438 assertEquals(50, value) // no setter | 498 assertEquals(50, value); // no setter |
| 439 assertThrows(function() { "use strict"; o.b = 51 }, TypeError) | 499 assertThrows(function() { "use strict"; o.b = 51 }, TypeError); |
| 440 receiver = "" | 500 receiver = ""; |
| 441 assertEquals(52, o.c = 52) | 501 assertEquals(52, o.c = 52); |
| 442 assertSame(o, receiver) | 502 assertSame(o, receiver); |
| 443 assertEquals(52, value) | 503 assertEquals(52, value); |
| 444 receiver = "" | 504 receiver = ""; |
| 445 assertEquals(53, o["a"] = 53) | 505 assertEquals(53, o["a"] = 53); |
| 446 assertSame(o, receiver) | 506 assertSame(o, receiver); |
| 447 assertEquals(53, value) | 507 assertEquals(53, value); |
| 448 receiver = "" | 508 receiver = ""; |
| 449 assertEquals(54, o[3] = 54) | 509 assertEquals(54, o[3] = 54); |
| 450 assertSame(o, receiver) | 510 assertSame(o, receiver); |
| 451 assertEquals(54, value) | 511 assertEquals(54, value); |
| 452 | 512 |
| 453 value = 0 | 513 value = 0; |
| 454 receiver = "" | 514 receiver = ""; |
| 455 assertEquals(60, oo.a = 60) | 515 assertEquals(60, oo.a = 60); |
| 456 assertEquals("", receiver) | 516 assertEquals("", receiver); |
| 457 assertEquals(0, value) // oo has own 'a' | 517 assertEquals(0, value); // oo has own 'a' |
| 458 assertEquals(61, oo.b = 61) | 518 assertEquals(61, oo.b = 61); |
| 459 assertSame("", receiver) | 519 assertSame("", receiver); |
| 460 assertEquals(0, value) // no setter | 520 assertEquals(0, value); // no setter |
| 461 assertThrows(function() { "use strict"; oo.b = 61 }, TypeError) | 521 assertThrows(function() { "use strict"; oo.b = 61; }, TypeError); |
| 462 receiver = "" | 522 receiver = ""; |
| 463 assertEquals(62, oo.c = 62) | 523 assertEquals(62, oo.c = 62); |
| 464 assertSame(oo, receiver) | 524 assertSame(oo, receiver); |
| 465 assertEquals(62, value) | 525 assertEquals(62, value); |
| 466 receiver = "" | 526 receiver = ""; |
| 467 assertEquals(63, oo["c"] = 63) | 527 assertEquals(63, oo["c"] = 63); |
| 468 assertSame(oo, receiver) | 528 assertSame(oo, receiver); |
| 469 assertEquals(63, value) | 529 assertEquals(63, value); |
| 470 receiver = "" | 530 receiver = ""; |
| 471 assertEquals(64, oo[3] = 64) | 531 assertEquals(64, oo[3] = 64); |
| 472 assertSame(oo, receiver) | 532 assertSame(oo, receiver); |
| 473 assertEquals(64, value) | 533 assertEquals(64, value); |
| 474 } | 534 } |
| 475 | 535 |
| 476 TestAccessorCall( | 536 TestAccessorCall( |
| 477 function() { receiver = this; return 42 }, | 537 function() { receiver = this; return 42; }, |
| 478 function(x) { receiver = this; value = x } | 538 function(x) { receiver = this; value = x; } |
| 479 ) | 539 ); |
| 480 | 540 |
| 481 TestAccessorCall( | 541 TestAccessorCall( |
| 482 function() { "use strict"; receiver = this; return 42 }, | 542 function() { "use strict"; receiver = this; return 42; }, |
| 483 function(x) { "use strict"; receiver = this; value = x } | 543 function(x) { "use strict"; receiver = this; value = x; } |
| 484 ) | 544 ); |
| 485 | 545 |
| 486 TestAccessorCall( | 546 TestAccessorCall( |
| 487 Proxy.createFunction({}, function() { receiver = this; return 42 }), | 547 Proxy.createFunction({}, function() { receiver = this; return 42; }), |
| 488 Proxy.createFunction({}, function(x) { receiver = this; value = x }) | 548 Proxy.createFunction({}, function(x) { receiver = this; value = x; }) |
| 489 ) | 549 ); |
| 490 | 550 |
| 491 TestAccessorCall( | 551 TestAccessorCall( |
| 492 CreateFrozen({}, function() { receiver = this; return 42 }), | 552 CreateFrozen({}, function() { receiver = this; return 42; }), |
| 493 CreateFrozen({}, function(x) { receiver = this; value = x }) | 553 CreateFrozen({}, function(x) { receiver = this; value = x; }) |
| 494 ) | 554 ); |
| OLD | NEW |