• 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 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