weak-collection.js 5.08 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
var GlobalObject = global.Object;
var GlobalWeakMap = global.WeakMap;
var GlobalWeakSet = global.WeakSet;
14
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
15 16 17 18

// -------------------------------------------------------------------
// Harmony WeakMap

19 20
function WeakMapConstructor(iterable) {
  if (!%_IsConstructCall()) {
21
    throw MakeTypeError(kConstructorNotFunction, "WeakMap");
22
  }
23

24
  %WeakCollectionInitialize(this);
25 26

  if (!IS_NULL_OR_UNDEFINED(iterable)) {
27
    var adder = this.set;
28
    if (!IS_CALLABLE(adder)) {
29
      throw MakeTypeError(kPropertyNotFunction, 'set', this);
30
    }
31 32
    for (var nextItem of iterable) {
      if (!IS_SPEC_OBJECT(nextItem)) {
33
        throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
34
      }
35
      %_Call(adder, this, nextItem[0], nextItem[1]);
36 37
    }
  }
38 39 40 41 42
}


function WeakMapGet(key) {
  if (!IS_WEAKMAP(this)) {
43 44
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.get', this);
45
  }
46
  if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
47 48 49
  var hash = $getExistingHash(key);
  if (IS_UNDEFINED(hash)) return UNDEFINED;
  return %WeakCollectionGet(this, key, hash);
50 51 52 53 54
}


function WeakMapSet(key, value) {
  if (!IS_WEAKMAP(this)) {
55 56
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.set', this);
57
  }
58
  if (!IS_SPEC_OBJECT(key)) throw MakeTypeError(kInvalidWeakMapKey);
59
  return %WeakCollectionSet(this, key, value, $getHash(key));
60 61 62 63 64
}


function WeakMapHas(key) {
  if (!IS_WEAKMAP(this)) {
65 66
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.has', this);
67
  }
68
  if (!IS_SPEC_OBJECT(key)) return false;
69 70 71
  var hash = $getExistingHash(key);
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionHas(this, key, hash);
72 73 74 75 76
}


function WeakMapDelete(key) {
  if (!IS_WEAKMAP(this)) {
77 78
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakMap.prototype.delete', this);
79
  }
80
  if (!IS_SPEC_OBJECT(key)) return false;
81 82 83
  var hash = $getExistingHash(key);
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionDelete(this, key, hash);
84 85 86 87 88
}


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

89 90 91 92 93
%SetCode(GlobalWeakMap, WeakMapConstructor);
%FunctionSetLength(GlobalWeakMap, 0);
%FunctionSetPrototype(GlobalWeakMap, new GlobalObject());
%AddNamedProperty(GlobalWeakMap.prototype, "constructor", GlobalWeakMap,
                  DONT_ENUM);
94
%AddNamedProperty(GlobalWeakMap.prototype, toStringTagSymbol, "WeakMap",
95 96 97
                  DONT_ENUM | READ_ONLY);

// Set up the non-enumerable functions on the WeakMap prototype object.
98
utils.InstallFunctions(GlobalWeakMap.prototype, DONT_ENUM, [
99 100 101 102 103
  "get", WeakMapGet,
  "set", WeakMapSet,
  "has", WeakMapHas,
  "delete", WeakMapDelete
]);
104 105 106 107

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

108 109
function WeakSetConstructor(iterable) {
  if (!%_IsConstructCall()) {
110
    throw MakeTypeError(kConstructorNotFunction, "WeakSet");
111
  }
112

113
  %WeakCollectionInitialize(this);
114 115

  if (!IS_NULL_OR_UNDEFINED(iterable)) {
116
    var adder = this.add;
117
    if (!IS_CALLABLE(adder)) {
118
      throw MakeTypeError(kPropertyNotFunction, 'add', this);
119
    }
120
    for (var value of iterable) {
121
      %_Call(adder, this, value);
122 123
    }
  }
124 125 126 127 128
}


function WeakSetAdd(value) {
  if (!IS_WEAKSET(this)) {
129 130
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakSet.prototype.add', this);
131
  }
132
  if (!IS_SPEC_OBJECT(value)) throw MakeTypeError(kInvalidWeakSetValue);
133
  return %WeakCollectionSet(this, value, true, $getHash(value));
134 135 136 137 138
}


function WeakSetHas(value) {
  if (!IS_WEAKSET(this)) {
139 140
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakSet.prototype.has', this);
141
  }
142
  if (!IS_SPEC_OBJECT(value)) return false;
143 144 145
  var hash = $getExistingHash(value);
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionHas(this, value, hash);
146 147 148 149 150
}


function WeakSetDelete(value) {
  if (!IS_WEAKSET(this)) {
151 152
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        'WeakSet.prototype.delete', this);
153
  }
154
  if (!IS_SPEC_OBJECT(value)) return false;
155 156 157
  var hash = $getExistingHash(value);
  if (IS_UNDEFINED(hash)) return false;
  return %WeakCollectionDelete(this, value, hash);
158 159 160 161 162
}


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

163 164 165 166 167
%SetCode(GlobalWeakSet, WeakSetConstructor);
%FunctionSetLength(GlobalWeakSet, 0);
%FunctionSetPrototype(GlobalWeakSet, new GlobalObject());
%AddNamedProperty(GlobalWeakSet.prototype, "constructor", GlobalWeakSet,
                 DONT_ENUM);
168
%AddNamedProperty(GlobalWeakSet.prototype, toStringTagSymbol, "WeakSet",
169 170 171
                  DONT_ENUM | READ_ONLY);

// Set up the non-enumerable functions on the WeakSet prototype object.
172
utils.InstallFunctions(GlobalWeakSet.prototype, DONT_ENUM, [
173 174 175 176 177
  "add", WeakSetAdd,
  "has", WeakSetHas,
  "delete", WeakSetDelete
]);

178
})