Home | History | Annotate | Download | only in src
      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 "use strict";
     29 
     30 var $Set = global.Set;
     31 var $Map = global.Map;
     32 var $WeakMap = global.WeakMap;
     33 
     34 //-------------------------------------------------------------------
     35 
     36 // Global sentinel to be used instead of undefined keys, which are not
     37 // supported internally but required for Harmony sets and maps.
     38 var undefined_sentinel = {};
     39 
     40 
     41 function SetConstructor() {
     42   if (%_IsConstructCall()) {
     43     %SetInitialize(this);
     44   } else {
     45     return new $Set();
     46   }
     47 }
     48 
     49 
     50 function SetAdd(key) {
     51   if (!IS_SET(this)) {
     52     throw MakeTypeError('incompatible_method_receiver',
     53                         ['Set.prototype.add', this]);
     54   }
     55   if (IS_UNDEFINED(key)) {
     56     key = undefined_sentinel;
     57   }
     58   return %SetAdd(this, key);
     59 }
     60 
     61 
     62 function SetHas(key) {
     63   if (!IS_SET(this)) {
     64     throw MakeTypeError('incompatible_method_receiver',
     65                         ['Set.prototype.has', this]);
     66   }
     67   if (IS_UNDEFINED(key)) {
     68     key = undefined_sentinel;
     69   }
     70   return %SetHas(this, key);
     71 }
     72 
     73 
     74 function SetDelete(key) {
     75   if (!IS_SET(this)) {
     76     throw MakeTypeError('incompatible_method_receiver',
     77                         ['Set.prototype.delete', this]);
     78   }
     79   if (IS_UNDEFINED(key)) {
     80     key = undefined_sentinel;
     81   }
     82   return %SetDelete(this, key);
     83 }
     84 
     85 
     86 function MapConstructor() {
     87   if (%_IsConstructCall()) {
     88     %MapInitialize(this);
     89   } else {
     90     return new $Map();
     91   }
     92 }
     93 
     94 
     95 function MapGet(key) {
     96   if (!IS_MAP(this)) {
     97     throw MakeTypeError('incompatible_method_receiver',
     98                         ['Map.prototype.get', this]);
     99   }
    100   if (IS_UNDEFINED(key)) {
    101     key = undefined_sentinel;
    102   }
    103   return %MapGet(this, key);
    104 }
    105 
    106 
    107 function MapSet(key, value) {
    108   if (!IS_MAP(this)) {
    109     throw MakeTypeError('incompatible_method_receiver',
    110                         ['Map.prototype.set', this]);
    111   }
    112   if (IS_UNDEFINED(key)) {
    113     key = undefined_sentinel;
    114   }
    115   return %MapSet(this, key, value);
    116 }
    117 
    118 
    119 function MapHas(key) {
    120   if (!IS_MAP(this)) {
    121     throw MakeTypeError('incompatible_method_receiver',
    122                         ['Map.prototype.has', this]);
    123   }
    124   if (IS_UNDEFINED(key)) {
    125     key = undefined_sentinel;
    126   }
    127   return !IS_UNDEFINED(%MapGet(this, key));
    128 }
    129 
    130 
    131 function MapDelete(key) {
    132   if (!IS_MAP(this)) {
    133     throw MakeTypeError('incompatible_method_receiver',
    134                         ['Map.prototype.delete', this]);
    135   }
    136   if (IS_UNDEFINED(key)) {
    137     key = undefined_sentinel;
    138   }
    139   if (!IS_UNDEFINED(%MapGet(this, key))) {
    140     %MapSet(this, key, void 0);
    141     return true;
    142   } else {
    143     return false;
    144   }
    145 }
    146 
    147 
    148 function WeakMapConstructor() {
    149   if (%_IsConstructCall()) {
    150     %WeakMapInitialize(this);
    151   } else {
    152     return new $WeakMap();
    153   }
    154 }
    155 
    156 
    157 function WeakMapGet(key) {
    158   if (!IS_WEAKMAP(this)) {
    159     throw MakeTypeError('incompatible_method_receiver',
    160                         ['WeakMap.prototype.get', this]);
    161   }
    162   if (!IS_SPEC_OBJECT(key)) {
    163     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
    164   }
    165   return %WeakMapGet(this, key);
    166 }
    167 
    168 
    169 function WeakMapSet(key, value) {
    170   if (!IS_WEAKMAP(this)) {
    171     throw MakeTypeError('incompatible_method_receiver',
    172                         ['WeakMap.prototype.set', this]);
    173   }
    174   if (!IS_SPEC_OBJECT(key)) {
    175     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
    176   }
    177   return %WeakMapSet(this, key, value);
    178 }
    179 
    180 
    181 function WeakMapHas(key) {
    182   if (!IS_WEAKMAP(this)) {
    183     throw MakeTypeError('incompatible_method_receiver',
    184                         ['WeakMap.prototype.has', this]);
    185   }
    186   if (!IS_SPEC_OBJECT(key)) {
    187     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
    188   }
    189   return !IS_UNDEFINED(%WeakMapGet(this, key));
    190 }
    191 
    192 
    193 function WeakMapDelete(key) {
    194   if (!IS_WEAKMAP(this)) {
    195     throw MakeTypeError('incompatible_method_receiver',
    196                         ['WeakMap.prototype.delete', this]);
    197   }
    198   if (!IS_SPEC_OBJECT(key)) {
    199     throw %MakeTypeError('invalid_weakmap_key', [this, key]);
    200   }
    201   if (!IS_UNDEFINED(%WeakMapGet(this, key))) {
    202     %WeakMapSet(this, key, void 0);
    203     return true;
    204   } else {
    205     return false;
    206   }
    207 }
    208 
    209 // -------------------------------------------------------------------
    210 
    211 (function () {
    212   %CheckIsBootstrapping();
    213 
    214   // Set up the Set and Map constructor function.
    215   %SetCode($Set, SetConstructor);
    216   %SetCode($Map, MapConstructor);
    217 
    218   // Set up the constructor property on the Set and Map prototype object.
    219   %SetProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
    220   %SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
    221 
    222   // Set up the non-enumerable functions on the Set prototype object.
    223   InstallFunctions($Set.prototype, DONT_ENUM, $Array(
    224     "add", SetAdd,
    225     "has", SetHas,
    226     "delete", SetDelete
    227   ));
    228 
    229   // Set up the non-enumerable functions on the Map prototype object.
    230   InstallFunctions($Map.prototype, DONT_ENUM, $Array(
    231     "get", MapGet,
    232     "set", MapSet,
    233     "has", MapHas,
    234     "delete", MapDelete
    235   ));
    236 
    237   // Set up the WeakMap constructor function.
    238   %SetCode($WeakMap, WeakMapConstructor);
    239 
    240   // Set up the constructor property on the WeakMap prototype object.
    241   %SetProperty($WeakMap.prototype, "constructor", $WeakMap, DONT_ENUM);
    242 
    243   // Set up the non-enumerable functions on the WeakMap prototype object.
    244   InstallFunctions($WeakMap.prototype, DONT_ENUM, $Array(
    245     "get", WeakMapGet,
    246     "set", WeakMapSet,
    247     "has", WeakMapHas,
    248     "delete", WeakMapDelete
    249   ));
    250 })();
    251