Home | History | Annotate | Download | only in harmony
      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