weak-collection.js 5.33 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
(function(global, utils) {
6

7
"use strict";
8

9
%CheckIsBootstrapping();
10

11 12 13 14 15
// -------------------------------------------------------------------
// Imports

var GetExistingHash;
var GetHash;
16 17 18
var GlobalObject = global.Object;
var GlobalWeakMap = global.WeakMap;
var GlobalWeakSet = global.WeakSet;
19
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
20

21 22 23 24 25
utils.Import(function(from) {
  GetExistingHash = from.GetExistingHash;
  GetHash = from.GetHash;
});

26 27 28
// -------------------------------------------------------------------
// Harmony WeakMap

29
function 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 51 52
}


function WeakMapGet(key) {
  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 59
  if (IS_UNDEFINED(hash)) return UNDEFINED;
  return %WeakCollectionGet(this, key, hash);
60 61 62 63 64
}


function WeakMapSet(key, value) {
  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 73 74
}


function WeakMapHas(key) {
  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 81
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionHas(this, key, hash);
82 83 84 85 86
}


function WeakMapDelete(key) {
  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 93
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionDelete(this, key, hash);
94 95 96 97 98
}


// -------------------------------------------------------------------

99 100 101 102 103
%SetCode(GlobalWeakMap, WeakMapConstructor);
%FunctionSetLength(GlobalWeakMap, 0);
%FunctionSetPrototype(GlobalWeakMap, new GlobalObject());
%AddNamedProperty(GlobalWeakMap.prototype, "constructor", GlobalWeakMap,
                  DONT_ENUM);
104
%AddNamedProperty(GlobalWeakMap.prototype, toStringTagSymbol, "WeakMap",
105 106 107
                  DONT_ENUM | READ_ONLY);

// Set up the non-enumerable functions on the WeakMap prototype object.
108
utils.InstallFunctions(GlobalWeakMap.prototype, DONT_ENUM, [
109 110 111 112 113
  "get", WeakMapGet,
  "set", WeakMapSet,
  "has", WeakMapHas,
  "delete", WeakMapDelete
]);
114 115 116 117

// -------------------------------------------------------------------
// Harmony WeakSet

118
function 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 137 138
}


function WeakSetAdd(value) {
  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 147 148
}


function WeakSetHas(value) {
  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 155
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionHas(this, value, hash);
156 157 158 159 160
}


function WeakSetDelete(value) {
  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 167
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionDelete(this, value, hash);
168 169 170 171 172
}


// -------------------------------------------------------------------

173 174 175 176 177
%SetCode(GlobalWeakSet, WeakSetConstructor);
%FunctionSetLength(GlobalWeakSet, 0);
%FunctionSetPrototype(GlobalWeakSet, new GlobalObject());
%AddNamedProperty(GlobalWeakSet.prototype, "constructor", GlobalWeakSet,
                 DONT_ENUM);
178
%AddNamedProperty(GlobalWeakSet.prototype, toStringTagSymbol, "WeakSet",
179 180 181
                  DONT_ENUM | READ_ONLY);

// Set up the non-enumerable functions on the WeakSet prototype object.
182
utils.InstallFunctions(GlobalWeakSet.prototype, DONT_ENUM, [
183 184 185 186 187
  "add", WeakSetAdd,
  "has", WeakSetHas,
  "delete", WeakSetDelete
]);

188
})