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