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"use strict"; 6 7// This file relies on the fact that the following declaration has been made 8// in runtime.js: 9// var $Array = global.Array; 10 11var $WeakMap = global.WeakMap; 12var $WeakSet = global.WeakSet; 13 14 15// ------------------------------------------------------------------- 16// Harmony WeakMap 17 18function WeakMapConstructor(iterable) { 19 if (!%_IsConstructCall()) { 20 throw MakeTypeError('constructor_not_function', ['WeakMap']); 21 } 22 23 var iter, adder; 24 25 if (!IS_NULL_OR_UNDEFINED(iterable)) { 26 iter = GetIterator(ToObject(iterable)); 27 adder = this.set; 28 if (!IS_SPEC_FUNCTION(adder)) { 29 throw MakeTypeError('property_not_function', ['set', this]); 30 } 31 } 32 33 %WeakCollectionInitialize(this); 34 35 if (IS_UNDEFINED(iter)) return; 36 37 var next, done, nextItem; 38 while (!(next = iter.next()).done) { 39 if (!IS_SPEC_OBJECT(next)) { 40 throw MakeTypeError('iterator_result_not_an_object', [next]); 41 } 42 nextItem = next.value; 43 if (!IS_SPEC_OBJECT(nextItem)) { 44 throw MakeTypeError('iterator_value_not_an_object', [nextItem]); 45 } 46 %_CallFunction(this, nextItem[0], nextItem[1], adder); 47 } 48} 49 50 51function WeakMapGet(key) { 52 if (!IS_WEAKMAP(this)) { 53 throw MakeTypeError('incompatible_method_receiver', 54 ['WeakMap.prototype.get', this]); 55 } 56 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { 57 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 58 } 59 return %WeakCollectionGet(this, key); 60} 61 62 63function WeakMapSet(key, value) { 64 if (!IS_WEAKMAP(this)) { 65 throw MakeTypeError('incompatible_method_receiver', 66 ['WeakMap.prototype.set', this]); 67 } 68 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { 69 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 70 } 71 return %WeakCollectionSet(this, key, value); 72} 73 74 75function WeakMapHas(key) { 76 if (!IS_WEAKMAP(this)) { 77 throw MakeTypeError('incompatible_method_receiver', 78 ['WeakMap.prototype.has', this]); 79 } 80 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { 81 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 82 } 83 return %WeakCollectionHas(this, key); 84} 85 86 87function WeakMapDelete(key) { 88 if (!IS_WEAKMAP(this)) { 89 throw MakeTypeError('incompatible_method_receiver', 90 ['WeakMap.prototype.delete', this]); 91 } 92 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { 93 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 94 } 95 return %WeakCollectionDelete(this, key); 96} 97 98 99function WeakMapClear() { 100 if (!IS_WEAKMAP(this)) { 101 throw MakeTypeError('incompatible_method_receiver', 102 ['WeakMap.prototype.clear', this]); 103 } 104 // Replace the internal table with a new empty table. 105 %WeakCollectionInitialize(this); 106} 107 108 109// ------------------------------------------------------------------- 110 111function SetUpWeakMap() { 112 %CheckIsBootstrapping(); 113 114 %SetCode($WeakMap, WeakMapConstructor); 115 %FunctionSetPrototype($WeakMap, new $Object()); 116 %AddNamedProperty($WeakMap.prototype, "constructor", $WeakMap, DONT_ENUM); 117 118 // Set up the non-enumerable functions on the WeakMap prototype object. 119 InstallFunctions($WeakMap.prototype, DONT_ENUM, $Array( 120 "get", WeakMapGet, 121 "set", WeakMapSet, 122 "has", WeakMapHas, 123 "delete", WeakMapDelete, 124 "clear", WeakMapClear 125 )); 126} 127 128SetUpWeakMap(); 129 130 131// ------------------------------------------------------------------- 132// Harmony WeakSet 133 134function WeakSetConstructor(iterable) { 135 if (!%_IsConstructCall()) { 136 throw MakeTypeError('constructor_not_function', ['WeakSet']); 137 } 138 139 var iter, adder; 140 141 if (!IS_NULL_OR_UNDEFINED(iterable)) { 142 iter = GetIterator(ToObject(iterable)); 143 adder = this.add; 144 if (!IS_SPEC_FUNCTION(adder)) { 145 throw MakeTypeError('property_not_function', ['add', this]); 146 } 147 } 148 149 %WeakCollectionInitialize(this); 150 151 if (IS_UNDEFINED(iter)) return; 152 153 var next, done; 154 while (!(next = iter.next()).done) { 155 if (!IS_SPEC_OBJECT(next)) { 156 throw MakeTypeError('iterator_result_not_an_object', [next]); 157 } 158 %_CallFunction(this, next.value, adder); 159 } 160} 161 162 163function WeakSetAdd(value) { 164 if (!IS_WEAKSET(this)) { 165 throw MakeTypeError('incompatible_method_receiver', 166 ['WeakSet.prototype.add', this]); 167 } 168 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) { 169 throw %MakeTypeError('invalid_weakset_value', [this, value]); 170 } 171 return %WeakCollectionSet(this, value, true); 172} 173 174 175function WeakSetHas(value) { 176 if (!IS_WEAKSET(this)) { 177 throw MakeTypeError('incompatible_method_receiver', 178 ['WeakSet.prototype.has', this]); 179 } 180 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) { 181 throw %MakeTypeError('invalid_weakset_value', [this, value]); 182 } 183 return %WeakCollectionHas(this, value); 184} 185 186 187function WeakSetDelete(value) { 188 if (!IS_WEAKSET(this)) { 189 throw MakeTypeError('incompatible_method_receiver', 190 ['WeakSet.prototype.delete', this]); 191 } 192 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) { 193 throw %MakeTypeError('invalid_weakset_value', [this, value]); 194 } 195 return %WeakCollectionDelete(this, value); 196} 197 198 199function WeakSetClear() { 200 if (!IS_WEAKSET(this)) { 201 throw MakeTypeError('incompatible_method_receiver', 202 ['WeakSet.prototype.clear', this]); 203 } 204 // Replace the internal table with a new empty table. 205 %WeakCollectionInitialize(this); 206} 207 208 209// ------------------------------------------------------------------- 210 211function SetUpWeakSet() { 212 %CheckIsBootstrapping(); 213 214 %SetCode($WeakSet, WeakSetConstructor); 215 %FunctionSetPrototype($WeakSet, new $Object()); 216 %AddNamedProperty($WeakSet.prototype, "constructor", $WeakSet, DONT_ENUM); 217 218 // Set up the non-enumerable functions on the WeakSet prototype object. 219 InstallFunctions($WeakSet.prototype, DONT_ENUM, $Array( 220 "add", WeakSetAdd, 221 "has", WeakSetHas, 222 "delete", WeakSetDelete, 223 "clear", WeakSetClear 224 )); 225} 226 227SetUpWeakSet(); 228