collection.js revision c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9
1// Copyright 2011 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 29const $Set = global.Set; 30const $Map = global.Map; 31const $WeakMap = global.WeakMap; 32 33//------------------------------------------------------------------- 34 35// Global sentinel to be used instead of undefined keys, which are not 36// supported internally but required for Harmony sets and maps. 37var undefined_sentinel = {}; 38 39 40function SetConstructor() { 41 if (%_IsConstructCall()) { 42 %SetInitialize(this); 43 } else { 44 return new $Set(); 45 } 46} 47 48 49function SetAdd(key) { 50 if (!IS_SET(this)) { 51 throw MakeTypeError('incompatible_method_receiver', 52 ['Set.prototype.add', this]); 53 } 54 if (IS_UNDEFINED(key)) { 55 key = undefined_sentinel; 56 } 57 return %SetAdd(this, key); 58} 59 60 61function SetHas(key) { 62 if (!IS_SET(this)) { 63 throw MakeTypeError('incompatible_method_receiver', 64 ['Set.prototype.has', this]); 65 } 66 if (IS_UNDEFINED(key)) { 67 key = undefined_sentinel; 68 } 69 return %SetHas(this, key); 70} 71 72 73function SetDelete(key) { 74 if (!IS_SET(this)) { 75 throw MakeTypeError('incompatible_method_receiver', 76 ['Set.prototype.delete', this]); 77 } 78 if (IS_UNDEFINED(key)) { 79 key = undefined_sentinel; 80 } 81 return %SetDelete(this, key); 82} 83 84 85function MapConstructor() { 86 if (%_IsConstructCall()) { 87 %MapInitialize(this); 88 } else { 89 return new $Map(); 90 } 91} 92 93 94function MapGet(key) { 95 if (!IS_MAP(this)) { 96 throw MakeTypeError('incompatible_method_receiver', 97 ['Map.prototype.get', this]); 98 } 99 if (IS_UNDEFINED(key)) { 100 key = undefined_sentinel; 101 } 102 return %MapGet(this, key); 103} 104 105 106function MapSet(key, value) { 107 if (!IS_MAP(this)) { 108 throw MakeTypeError('incompatible_method_receiver', 109 ['Map.prototype.set', this]); 110 } 111 if (IS_UNDEFINED(key)) { 112 key = undefined_sentinel; 113 } 114 return %MapSet(this, key, value); 115} 116 117 118function MapHas(key) { 119 if (!IS_MAP(this)) { 120 throw MakeTypeError('incompatible_method_receiver', 121 ['Map.prototype.has', this]); 122 } 123 if (IS_UNDEFINED(key)) { 124 key = undefined_sentinel; 125 } 126 return !IS_UNDEFINED(%MapGet(this, key)); 127} 128 129 130function MapDelete(key) { 131 if (!IS_MAP(this)) { 132 throw MakeTypeError('incompatible_method_receiver', 133 ['Map.prototype.delete', this]); 134 } 135 if (IS_UNDEFINED(key)) { 136 key = undefined_sentinel; 137 } 138 if (!IS_UNDEFINED(%MapGet(this, key))) { 139 %MapSet(this, key, void 0); 140 return true; 141 } else { 142 return false; 143 } 144} 145 146 147function WeakMapConstructor() { 148 if (%_IsConstructCall()) { 149 %WeakMapInitialize(this); 150 } else { 151 return new $WeakMap(); 152 } 153} 154 155 156function WeakMapGet(key) { 157 if (!IS_WEAKMAP(this)) { 158 throw MakeTypeError('incompatible_method_receiver', 159 ['WeakMap.prototype.get', this]); 160 } 161 if (!IS_SPEC_OBJECT(key)) { 162 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 163 } 164 return %WeakMapGet(this, key); 165} 166 167 168function WeakMapSet(key, value) { 169 if (!IS_WEAKMAP(this)) { 170 throw MakeTypeError('incompatible_method_receiver', 171 ['WeakMap.prototype.set', this]); 172 } 173 if (!IS_SPEC_OBJECT(key)) { 174 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 175 } 176 return %WeakMapSet(this, key, value); 177} 178 179 180function WeakMapHas(key) { 181 if (!IS_WEAKMAP(this)) { 182 throw MakeTypeError('incompatible_method_receiver', 183 ['WeakMap.prototype.has', this]); 184 } 185 if (!IS_SPEC_OBJECT(key)) { 186 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 187 } 188 return !IS_UNDEFINED(%WeakMapGet(this, key)); 189} 190 191 192function WeakMapDelete(key) { 193 if (!IS_WEAKMAP(this)) { 194 throw MakeTypeError('incompatible_method_receiver', 195 ['WeakMap.prototype.delete', this]); 196 } 197 if (!IS_SPEC_OBJECT(key)) { 198 throw %MakeTypeError('invalid_weakmap_key', [this, key]); 199 } 200 if (!IS_UNDEFINED(%WeakMapGet(this, key))) { 201 %WeakMapSet(this, key, void 0); 202 return true; 203 } else { 204 return false; 205 } 206} 207 208// ------------------------------------------------------------------- 209 210(function () { 211 %CheckIsBootstrapping(); 212 213 // Set up the Set and Map constructor function. 214 %SetCode($Set, SetConstructor); 215 %SetCode($Map, MapConstructor); 216 217 // Set up the constructor property on the Set and Map prototype object. 218 %SetProperty($Set.prototype, "constructor", $Set, DONT_ENUM); 219 %SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM); 220 221 // Set up the non-enumerable functions on the Set prototype object. 222 InstallFunctions($Set.prototype, DONT_ENUM, $Array( 223 "add", SetAdd, 224 "has", SetHas, 225 "delete", SetDelete 226 )); 227 228 // Set up the non-enumerable functions on the Map prototype object. 229 InstallFunctions($Map.prototype, DONT_ENUM, $Array( 230 "get", MapGet, 231 "set", MapSet, 232 "has", MapHas, 233 "delete", MapDelete 234 )); 235 236 // Set up the WeakMap constructor function. 237 %SetCode($WeakMap, WeakMapConstructor); 238 239 // Set up the constructor property on the WeakMap prototype object. 240 %SetProperty($WeakMap.prototype, "constructor", $WeakMap, DONT_ENUM); 241 242 // Set up the non-enumerable functions on the WeakMap prototype object. 243 InstallFunctions($WeakMap.prototype, DONT_ENUM, $Array( 244 "get", WeakMapGet, 245 "set", WeakMapSet, 246 "has", WeakMapHas, 247 "delete", WeakMapDelete 248 )); 249})(); 250