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 33function 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 42function TestWithGet(handler) { 43 TestWithProxies(TestWithGet2, handler) 44} 45 46var c = "global" 47var key = "" 48 49function 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 68TestWithGet({ 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 76TestWithGet({ 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 85TestWithGet({ 86 getPropertyDescriptor: function(k) { 87 key = k; 88 return k === "a" ? {value: "onproxy", configurable: true} : undefined 89 } 90}) 91 92TestWithGet({ 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 100TestWithGet({ 101 getPropertyDescriptor: function(k) { 102 key = k; 103 return k === "a" ? 104 {get value() { return "onproxy" }, configurable: true} : undefined 105 } 106}) 107 108TestWithGet({ 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 120function TestWithGetCall(handler) { 121 TestWithProxies(TestWithGetCall2, handler) 122} 123 124var receiver = null 125var c = function() { return "global" } 126 127function 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 150function onproxy() { receiver = this; return "onproxy" } 151 152TestWithGetCall({ 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 160TestWithGetCall({ 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 169TestWithGetCall({ 170 getPropertyDescriptor: function(k) { 171 key = k; 172 return k === "a" ? {value: onproxy, configurable: true} : undefined 173 } 174}) 175 176TestWithGetCall({ 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 184TestWithGetCall({ 185 getPropertyDescriptor: function(k) { 186 key = k; 187 return k === "a" ? 188 {get value() { return onproxy }, configurable: true} : undefined 189 } 190}) 191 192TestWithGetCall({ 193 get: undefined, 194 getPropertyDescriptor: function(k) { 195 key = k; 196 return k === "a" ? {value: onproxy, configurable: true} : undefined 197 } 198}) 199 200 201function TestWithGetCallThrow(handler) { 202 TestWithProxies(TestWithGetCallThrow2, handler) 203} 204 205function 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 224function onproxythrow() { throw "myexn" } 225 226TestWithGetCallThrow({ 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 234TestWithGetCallThrow({ 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 243TestWithGetCallThrow({ 244 getPropertyDescriptor: function(k) { 245 key = k; 246 return k === "a" ? {value: onproxythrow, configurable: true} : undefined 247 } 248}) 249 250TestWithGetCallThrow({ 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 258TestWithGetCallThrow({ 259 getPropertyDescriptor: function(k) { 260 key = k; 261 return k === "a" ? 262 {get value() { return onproxythrow }, configurable: true} : undefined 263 } 264}) 265 266TestWithGetCallThrow({ 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 278var key 279var val 280 281function TestWithSet(handler, hasSetter) { 282 TestWithProxies(TestWithSet2, handler, hasSetter) 283} 284 285var c = "global" 286 287function 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 323TestWithSet({ 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 330TestWithSet({ 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 338TestWithSet({ 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 348TestWithSet({ 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 360TestWithSet({ 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 371TestWithSet({ 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 381TestWithSet({ 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 392TestWithSet({ 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 401function TestWithSetThrow(handler, hasSetter) { 402 TestWithProxies(TestWithSetThrow2, handler, hasSetter) 403} 404 405function 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 423TestWithSetThrow({ 424 set: function(r, k, v) { throw "myexn" }, 425 getPropertyDescriptor: function(k) { 426 return k === "a" ? {writable: true, configurable: true} : undefined 427 } 428}) 429 430TestWithSetThrow({ 431 getPropertyDescriptor: function(k) { throw "myexn" }, 432}) 433 434TestWithSetThrow({ 435 getPropertyDescriptor: function(k) { 436 return k === "a" ? {writable: true, configurable: true} : undefined 437 }, 438 defineProperty: function(k, desc) { throw "myexn" } 439}) 440 441TestWithSetThrow({ 442 getPropertyDescriptor: function(k) { 443 return k === "a" ? 444 {set: function() { throw "myexn" }, configurable: true} : undefined 445 } 446}, true) 447