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 14var GetExistingHash; 15var GetHash; 16var GlobalObject = global.Object; 17var GlobalWeakMap = global.WeakMap; 18var GlobalWeakSet = global.WeakSet; 19var MakeTypeError; 20var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 21 22utils.Import(function(from) { 23 GetExistingHash = from.GetExistingHash; 24 GetHash = from.GetHash; 25 MakeTypeError = from.MakeTypeError; 26}); 27 28// ------------------------------------------------------------------- 29// Harmony WeakMap 30 31function 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 53function 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 65function 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 75function 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 87function 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. 110utils.InstallFunctions(GlobalWeakMap.prototype, DONT_ENUM, [ 111 "get", WeakMapGet, 112 "set", WeakMapSet, 113 "has", WeakMapHas, 114 "delete", WeakMapDelete 115]); 116 117// ------------------------------------------------------------------- 118// Harmony WeakSet 119 120function 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 139function 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 149function 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 161function 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. 184utils.InstallFunctions(GlobalWeakSet.prototype, DONT_ENUM, [ 185 "add", WeakSetAdd, 186 "has", WeakSetHas, 187 "delete", WeakSetDelete 188]); 189 190}) 191