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 toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 20 21utils.Import(function(from) { 22 GetExistingHash = from.GetExistingHash; 23 GetHash = from.GetHash; 24}); 25 26// ------------------------------------------------------------------- 27// Harmony WeakMap 28 29function 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 51function 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 63function 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 73function 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 85function 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. 108utils.InstallFunctions(GlobalWeakMap.prototype, DONT_ENUM, [ 109 "get", WeakMapGet, 110 "set", WeakMapSet, 111 "has", WeakMapHas, 112 "delete", WeakMapDelete 113]); 114 115// ------------------------------------------------------------------- 116// Harmony WeakSet 117 118function 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 137function 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 147function 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 159function 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. 182utils.InstallFunctions(GlobalWeakSet.prototype, DONT_ENUM, [ 183 "add", WeakSetAdd, 184 "has", WeakSetHas, 185 "delete", WeakSetDelete 186]); 187 188}) 189