Home | History | Annotate | Download | only in js
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 (function(global, utils) {
      6 
      7 "use strict";
      8 
      9 %CheckIsBootstrapping();
     10 
     11 // -------------------------------------------------------------------
     12 // Imports
     13 
     14 var GetExistingHash;
     15 var GetHash;
     16 var GlobalObject = global.Object;
     17 var GlobalWeakMap = global.WeakMap;
     18 var GlobalWeakSet = global.WeakSet;
     19 var MakeTypeError;
     20 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
     21 
     22 utils.Import(function(from) {
     23   GetExistingHash = from.GetExistingHash;
     24   GetHash = from.GetHash;
     25   MakeTypeError = from.MakeTypeError;
     26 });
     27 
     28 // -------------------------------------------------------------------
     29 // Harmony WeakMap
     30 
     31 function WeakMapConstructor(iterable) {
     32   if (IS_UNDEFINED(new.target)) {
     33     throw MakeTypeError(kConstructorNotFunction, "WeakMap");
     34   }
     35 
     36   %WeakCollectionInitialize(this);
     37 
     38   if (!IS_NULL_OR_UNDEFINED(iterable)) {
     39     var adder = this.set;
     40     if (!IS_CALLABLE(adder)) {
     41       throw MakeTypeError(kPropertyNotFunction, adder, 'set', this);
     42     }
     43     for (var nextItem of iterable) {
     44       if (!IS_RECEIVER(nextItem)) {
     45         throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
     46       }
     47       %_Call(adder, this, nextItem[0], nextItem[1]);
     48     }
     49   }
     50 }
     51 
     52 
     53 function WeakMapGet(key) {
     54   if (!IS_WEAKMAP(this)) {
     55     throw MakeTypeError(kIncompatibleMethodReceiver,
     56                         'WeakMap.prototype.get', this);
     57   }
     58   if (!IS_RECEIVER(key)) return UNDEFINED;
     59   var hash = GetExistingHash(key);
     60   if (IS_UNDEFINED(hash)) return UNDEFINED;
     61   return %WeakCollectionGet(this, key, hash);
     62 }
     63 
     64 
     65 function WeakMapSet(key, value) {
     66   if (!IS_WEAKMAP(this)) {
     67     throw MakeTypeError(kIncompatibleMethodReceiver,
     68                         'WeakMap.prototype.set', this);
     69   }
     70   if (!IS_RECEIVER(key)) throw MakeTypeError(kInvalidWeakMapKey);
     71   return %WeakCollectionSet(this, key, value, GetHash(key));
     72 }
     73 
     74 
     75 function WeakMapHas(key) {
     76   if (!IS_WEAKMAP(this)) {
     77     throw MakeTypeError(kIncompatibleMethodReceiver,
     78                         'WeakMap.prototype.has', this);
     79   }
     80   if (!IS_RECEIVER(key)) return false;
     81   var hash = GetExistingHash(key);
     82   if (IS_UNDEFINED(hash)) return false;
     83   return %WeakCollectionHas(this, key, hash);
     84 }
     85 
     86 
     87 function WeakMapDelete(key) {
     88   if (!IS_WEAKMAP(this)) {
     89     throw MakeTypeError(kIncompatibleMethodReceiver,
     90                         'WeakMap.prototype.delete', this);
     91   }
     92   if (!IS_RECEIVER(key)) return false;
     93   var hash = GetExistingHash(key);
     94   if (IS_UNDEFINED(hash)) return false;
     95   return %WeakCollectionDelete(this, key, hash);
     96 }
     97 
     98 
     99 // -------------------------------------------------------------------
    100 
    101 %SetCode(GlobalWeakMap, WeakMapConstructor);
    102 %FunctionSetLength(GlobalWeakMap, 0);
    103 %FunctionSetPrototype(GlobalWeakMap, new GlobalObject());
    104 %AddNamedProperty(GlobalWeakMap.prototype, "constructor", GlobalWeakMap,
    105                   DONT_ENUM);
    106 %AddNamedProperty(GlobalWeakMap.prototype, toStringTagSymbol, "WeakMap",
    107                   DONT_ENUM | READ_ONLY);
    108 
    109 // Set up the non-enumerable functions on the WeakMap prototype object.
    110 utils.InstallFunctions(GlobalWeakMap.prototype, DONT_ENUM, [
    111   "get", WeakMapGet,
    112   "set", WeakMapSet,
    113   "has", WeakMapHas,
    114   "delete", WeakMapDelete
    115 ]);
    116 
    117 // -------------------------------------------------------------------
    118 // Harmony WeakSet
    119 
    120 function WeakSetConstructor(iterable) {
    121   if (IS_UNDEFINED(new.target)) {
    122     throw MakeTypeError(kConstructorNotFunction, "WeakSet");
    123   }
    124 
    125   %WeakCollectionInitialize(this);
    126 
    127   if (!IS_NULL_OR_UNDEFINED(iterable)) {
    128     var adder = this.add;
    129     if (!IS_CALLABLE(adder)) {
    130       throw MakeTypeError(kPropertyNotFunction, adder, 'add', this);
    131     }
    132     for (var value of iterable) {
    133       %_Call(adder, this, value);
    134     }
    135   }
    136 }
    137 
    138 
    139 function WeakSetAdd(value) {
    140   if (!IS_WEAKSET(this)) {
    141     throw MakeTypeError(kIncompatibleMethodReceiver,
    142                         'WeakSet.prototype.add', this);
    143   }
    144   if (!IS_RECEIVER(value)) throw MakeTypeError(kInvalidWeakSetValue);
    145   return %WeakCollectionSet(this, value, true, GetHash(value));
    146 }
    147 
    148 
    149 function WeakSetHas(value) {
    150   if (!IS_WEAKSET(this)) {
    151     throw MakeTypeError(kIncompatibleMethodReceiver,
    152                         'WeakSet.prototype.has', this);
    153   }
    154   if (!IS_RECEIVER(value)) return false;
    155   var hash = GetExistingHash(value);
    156   if (IS_UNDEFINED(hash)) return false;
    157   return %WeakCollectionHas(this, value, hash);
    158 }
    159 
    160 
    161 function WeakSetDelete(value) {
    162   if (!IS_WEAKSET(this)) {
    163     throw MakeTypeError(kIncompatibleMethodReceiver,
    164                         'WeakSet.prototype.delete', this);
    165   }
    166   if (!IS_RECEIVER(value)) return false;
    167   var hash = GetExistingHash(value);
    168   if (IS_UNDEFINED(hash)) return false;
    169   return %WeakCollectionDelete(this, value, hash);
    170 }
    171 
    172 
    173 // -------------------------------------------------------------------
    174 
    175 %SetCode(GlobalWeakSet, WeakSetConstructor);
    176 %FunctionSetLength(GlobalWeakSet, 0);
    177 %FunctionSetPrototype(GlobalWeakSet, new GlobalObject());
    178 %AddNamedProperty(GlobalWeakSet.prototype, "constructor", GlobalWeakSet,
    179                  DONT_ENUM);
    180 %AddNamedProperty(GlobalWeakSet.prototype, toStringTagSymbol, "WeakSet",
    181                   DONT_ENUM | READ_ONLY);
    182 
    183 // Set up the non-enumerable functions on the WeakSet prototype object.
    184 utils.InstallFunctions(GlobalWeakSet.prototype, DONT_ENUM, [
    185   "add", WeakSetAdd,
    186   "has", WeakSetHas,
    187   "delete", WeakSetDelete
    188 ]);
    189 
    190 })
    191