weak-collection.js 5.34 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 MakeTypeError;
20
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
21

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

28 29 30
// -------------------------------------------------------------------
// Harmony WeakMap

31
function 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 53 54
}


function WeakMapGet(key) {
  if (!IS_WEAKMAP(this)) {
55 56
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.get', this);
57
  }
58
  if (!IS_RECEIVER(key)) return UNDEFINED;
59
  var hash = GetExistingHash(key);
60 61
  if (IS_UNDEFINED(hash)) return UNDEFINED;
  return %WeakCollectionGet(this, key, hash);
62 63 64 65 66
}


function WeakMapSet(key, value) {
  if (!IS_WEAKMAP(this)) {
67 68
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.set', this);
69
  }
70
  if (!IS_RECEIVER(key)) throw MakeTypeError(kInvalidWeakMapKey);
71
  return %WeakCollectionSet(this, key, value, GetHash(key));
72 73 74 75 76
}


function WeakMapHas(key) {
  if (!IS_WEAKMAP(this)) {
77 78
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.has', this);
79
  }
80
  if (!IS_RECEIVER(key)) return false;
81
  var hash = GetExistingHash(key);
82 83
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionHas(this, key, hash);
84 85 86 87 88
}


function WeakMapDelete(key) {
  if (!IS_WEAKMAP(this)) {
89 90
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.delete', this);
91
  }
92
  if (!IS_RECEIVER(key)) return false;
93
  var hash = GetExistingHash(key);
94 95
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionDelete(this, key, hash);
96 97 98 99 100
}


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

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

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

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

120
function 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 139 140
}


function WeakSetAdd(value) {
  if (!IS_WEAKSET(this)) {
141 142
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakSet.prototype.add', this);
143
  }
144
  if (!IS_RECEIVER(value)) throw MakeTypeError(kInvalidWeakSetValue);
145
  return %WeakCollectionSet(this, value, true, GetHash(value));
146 147 148 149 150
}


function WeakSetHas(value) {
  if (!IS_WEAKSET(this)) {
151 152
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakSet.prototype.has', this);
153
  }
154
  if (!IS_RECEIVER(value)) return false;
155
  var hash = GetExistingHash(value);
156 157
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionHas(this, value, hash);
158 159 160 161 162
}


function WeakSetDelete(value) {
  if (!IS_WEAKSET(this)) {
163 164
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakSet.prototype.delete', this);
165
  }
166
  if (!IS_RECEIVER(value)) return false;
167
  var hash = GetExistingHash(value);
168 169
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionDelete(this, value, hash);
170 171 172 173 174
}


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

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

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

190
})