1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 27 28 // Flags: --harmony-proxies 29 30 31 // Helper. 32 33 function TestWithProxies(test, x, y, z) { 34 test(Proxy.create, x, y, z) 35 test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z) 36 } 37 38 39 40 // Getting. 41 42 function TestWithGet(handler) { 43 TestWithProxies(TestWithGet2, handler) 44 } 45 46 var c = "global" 47 var key = "" 48 49 function TestWithGet2(create, handler) { 50 var b = "local" 51 52 var p = create(handler) 53 with (p) { 54 assertEquals("onproxy", a) 55 assertEquals("local", b) 56 assertEquals("global", c) 57 } 58 59 var o = Object.create(p, {d: {value: "own"}}) 60 with (o) { 61 assertEquals("onproxy", a) 62 assertEquals("local", b) 63 assertEquals("global", c) 64 assertEquals("own", d) 65 } 66 } 67 68 TestWithGet({ 69 get: function(r, k) { key = k; return k === "a" ? "onproxy" : undefined }, 70 getPropertyDescriptor: function(k) { 71 key = k; 72 return k === "a" ? {value: "onproxy", configurable: true} : undefined 73 } 74 }) 75 76 TestWithGet({ 77 get: function(r, k) { return this.get2(r, k) }, 78 get2: function(r, k) { key = k; return k === "a" ? "onproxy" : undefined }, 79 getPropertyDescriptor: function(k) { 80 key = k; 81 return k === "a" ? {value: "onproxy", configurable: true} : undefined 82 } 83 }) 84 85 TestWithGet({ 86 getPropertyDescriptor: function(k) { 87 key = k; 88 return k === "a" ? {value: "onproxy", configurable: true} : undefined 89 } 90 }) 91 92 TestWithGet({ 93 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) }, 94 getPropertyDescriptor2: function(k) { 95 key = k; 96 return k === "a" ? {value: "onproxy", configurable: true} : undefined 97 } 98 }) 99 100 TestWithGet({ 101 getPropertyDescriptor: function(k) { 102 key = k; 103 return k === "a" ? 104 {get value() { return "onproxy" }, configurable: true} : undefined 105 } 106 }) 107 108 TestWithGet({ 109 get: undefined, 110 getPropertyDescriptor: function(k) { 111 key = k; 112 return k === "a" ? {value: "onproxy", configurable: true} : undefined 113 } 114 }) 115 116 117 118 // Invoking. 119 120 function TestWithGetCall(handler) { 121 TestWithProxies(TestWithGetCall2, handler) 122 } 123 124 var receiver = null 125 var c = function() { return "global" } 126 127 function TestWithGetCall2(create, handler) { 128 var b = function() { return "local" } 129 130 var p = create(handler) 131 with (p) { 132 receiver = null 133 assertEquals("onproxy", a()) 134 assertSame(p, receiver) 135 assertEquals("local", b()) 136 assertEquals("global", c()) 137 } 138 139 var o = Object.create(p, {d: {value: function() { return "own" }}}) 140 with (o) { 141 receiver = null 142 assertEquals("onproxy", a()) 143 assertSame(o, receiver) 144 assertEquals("local", b()) 145 assertEquals("global", c()) 146 assertEquals("own", d()) 147 } 148 } 149 150 function onproxy() { receiver = this; return "onproxy" } 151 152 TestWithGetCall({ 153 get: function(r, k) { key = k; return k === "a" ? onproxy : undefined }, 154 getPropertyDescriptor: function(k) { 155 key = k; 156 return k === "a" ? {value: onproxy, configurable: true} : undefined 157 } 158 }) 159 160 TestWithGetCall({ 161 get: function(r, k) { return this.get2(r, k) }, 162 get2: function(r, k) { key = k; return k === "a" ? onproxy : undefined }, 163 getPropertyDescriptor: function(k) { 164 key = k; 165 return k === "a" ? {value: onproxy, configurable: true} : undefined 166 } 167 }) 168 169 TestWithGetCall({ 170 getPropertyDescriptor: function(k) { 171 key = k; 172 return k === "a" ? {value: onproxy, configurable: true} : undefined 173 } 174 }) 175 176 TestWithGetCall({ 177 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) }, 178 getPropertyDescriptor2: function(k) { 179 key = k; 180 return k === "a" ? {value: onproxy, configurable: true} : undefined 181 } 182 }) 183 184 TestWithGetCall({ 185 getPropertyDescriptor: function(k) { 186 key = k; 187 return k === "a" ? 188 {get value() { return onproxy }, configurable: true} : undefined 189 } 190 }) 191 192 TestWithGetCall({ 193 get: undefined, 194 getPropertyDescriptor: function(k) { 195 key = k; 196 return k === "a" ? {value: onproxy, configurable: true} : undefined 197 } 198 }) 199 200 201 function TestWithGetCallThrow(handler) { 202 TestWithProxies(TestWithGetCallThrow2, handler) 203 } 204 205 function TestWithGetCallThrow2(create, handler) { 206 var b = function() { return "local" } 207 208 var p = create(handler) 209 with (p) { 210 assertThrows(function(){ a() }, "myexn") 211 assertEquals("local", b()) 212 assertEquals("global", c()) 213 } 214 215 var o = Object.create(p, {d: {value: function() { return "own" }}}) 216 with (o) { 217 assertThrows(function(){ a() }, "myexn") 218 assertEquals("local", b()) 219 assertEquals("global", c()) 220 assertEquals("own", d()) 221 } 222 } 223 224 function onproxythrow() { throw "myexn" } 225 226 TestWithGetCallThrow({ 227 get: function(r, k) { key = k; return k === "a" ? onproxythrow : undefined }, 228 getPropertyDescriptor: function(k) { 229 key = k; 230 return k === "a" ? {value: onproxythrow, configurable: true} : undefined 231 } 232 }) 233 234 TestWithGetCallThrow({ 235 get: function(r, k) { return this.get2(r, k) }, 236 get2: function(r, k) { key = k; return k === "a" ? onproxythrow : undefined }, 237 getPropertyDescriptor: function(k) { 238 key = k; 239 return k === "a" ? {value: onproxythrow, configurable: true} : undefined 240 } 241 }) 242 243 TestWithGetCallThrow({ 244 getPropertyDescriptor: function(k) { 245 key = k; 246 return k === "a" ? {value: onproxythrow, configurable: true} : undefined 247 } 248 }) 249 250 TestWithGetCallThrow({ 251 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) }, 252 getPropertyDescriptor2: function(k) { 253 key = k; 254 return k === "a" ? {value: onproxythrow, configurable: true} : undefined 255 } 256 }) 257 258 TestWithGetCallThrow({ 259 getPropertyDescriptor: function(k) { 260 key = k; 261 return k === "a" ? 262 {get value() { return onproxythrow }, configurable: true} : undefined 263 } 264 }) 265 266 TestWithGetCallThrow({ 267 get: undefined, 268 getPropertyDescriptor: function(k) { 269 key = k; 270 return k === "a" ? {value: onproxythrow, configurable: true} : undefined 271 } 272 }) 273 274 275 276 // Setting. 277 278 var key 279 var val 280 281 function TestWithSet(handler, hasSetter) { 282 TestWithProxies(TestWithSet2, handler, hasSetter) 283 } 284 285 var c = "global" 286 287 function TestWithSet2(create, handler, hasSetter) { 288 var b = "local" 289 290 var p = create(handler) 291 key = val = undefined 292 with (p) { 293 a = "set" 294 assertEquals("a", key) 295 assertEquals("set", val) 296 assertEquals("local", b) 297 assertEquals("global", c) 298 b = "local" 299 c = "global" 300 assertEquals("a", key) 301 assertEquals("set", val) 302 } 303 304 if (!hasSetter) return 305 306 var o = Object.create(p, {d: {value: "own"}}) 307 key = val = undefined 308 with (o) { 309 a = "set" 310 assertEquals("a", key) 311 assertEquals("set", val) 312 assertEquals("local", b) 313 assertEquals("global", c) 314 assertEquals("own", d) 315 b = "local" 316 c = "global" 317 d = "own" 318 assertEquals("a", key) 319 assertEquals("set", val) 320 } 321 } 322 323 TestWithSet({ 324 set: function(r, k, v) { key = k; val = v; return true }, 325 getPropertyDescriptor: function(k) { 326 return k === "a" ? {writable: true, configurable: true} : undefined 327 } 328 }) 329 330 TestWithSet({ 331 set: function(r, k, v) { return this.set2(r, k, v) }, 332 set2: function(r, k, v) { key = k; val = v; return true }, 333 getPropertyDescriptor: function(k) { 334 return k === "a" ? {writable: true, configurable: true} : undefined 335 } 336 }) 337 338 TestWithSet({ 339 getPropertyDescriptor: function(k) { 340 return this.getOwnPropertyDescriptor(k) 341 }, 342 getOwnPropertyDescriptor: function(k) { 343 return k === "a" ? {writable: true, configurable: true} : undefined 344 }, 345 defineProperty: function(k, desc) { key = k; val = desc.value } 346 }) 347 348 TestWithSet({ 349 getOwnPropertyDescriptor: function(k) { 350 return this.getPropertyDescriptor2(k) 351 }, 352 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) }, 353 getPropertyDescriptor2: function(k) { 354 return k === "a" ? {writable: true, configurable: true} : undefined 355 }, 356 defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, 357 defineProperty2: function(k, desc) { key = k; val = desc.value } 358 }) 359 360 TestWithSet({ 361 getOwnPropertyDescriptor: function(k) { 362 return this.getPropertyDescriptor(k) 363 }, 364 getPropertyDescriptor: function(k) { 365 return k === "a" ? 366 {get writable() { return true }, configurable: true} : undefined 367 }, 368 defineProperty: function(k, desc) { key = k; val = desc.value } 369 }) 370 371 TestWithSet({ 372 getOwnPropertyDescriptor: function(k) { 373 return this.getPropertyDescriptor(k) 374 }, 375 getPropertyDescriptor: function(k) { 376 return k === "a" ? 377 {set: function(v) { key = k; val = v }, configurable: true} : undefined 378 } 379 }, true) 380 381 TestWithSet({ 382 getOwnPropertyDescriptor: function(k) { 383 return this.getPropertyDescriptor(k) 384 }, 385 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) }, 386 getPropertyDescriptor2: function(k) { 387 return k === "a" ? 388 {set: function(v) { key = k; val = v }, configurable: true} : undefined 389 } 390 }, true) 391 392 TestWithSet({ 393 getOwnPropertyDescriptor: function(k) { return null }, 394 getPropertyDescriptor: function(k) { 395 return k === "a" ? {writable: true, configurable: true} : undefined 396 }, 397 defineProperty: function(k, desc) { key = k; val = desc.value } 398 }) 399 400 401 function TestWithSetThrow(handler, hasSetter) { 402 TestWithProxies(TestWithSetThrow2, handler, hasSetter) 403 } 404 405 function TestWithSetThrow2(create, handler, hasSetter) { 406 var p = create(handler) 407 assertThrows(function(){ 408 with (p) { 409 a = 1 410 } 411 }, "myexn") 412 413 if (!hasSetter) return 414 415 var o = Object.create(p, {}) 416 assertThrows(function(){ 417 with (o) { 418 a = 1 419 } 420 }, "myexn") 421 } 422 423 TestWithSetThrow({ 424 set: function(r, k, v) { throw "myexn" }, 425 getPropertyDescriptor: function(k) { 426 return k === "a" ? {writable: true, configurable: true} : undefined 427 } 428 }) 429 430 TestWithSetThrow({ 431 getPropertyDescriptor: function(k) { throw "myexn" }, 432 }) 433 434 TestWithSetThrow({ 435 getPropertyDescriptor: function(k) { 436 return k === "a" ? {writable: true, configurable: true} : undefined 437 }, 438 defineProperty: function(k, desc) { throw "myexn" } 439 }) 440 441 TestWithSetThrow({ 442 getPropertyDescriptor: function(k) { 443 return k === "a" ? 444 {set: function() { throw "myexn" }, configurable: true} : undefined 445 } 446 }, true) 447