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