• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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