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