weak-collection.js 3.85 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
// -------------------------------------------------------------------
// Imports

14 15
var GlobalWeakMap = global.WeakMap;
var GlobalWeakSet = global.WeakSet;
16 17 18 19 20 21
var MathRandom = global.Math.random;

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

function GetExistingHash(key) {
  if (IS_RECEIVER(key) && !IS_PROXY(key) && !IS_GLOBAL(key)) {
22
    return %GetExistingHash(key);
23 24 25 26 27 28 29
  }
  return %GenericHash(key);
}
%SetForceInlineFlag(GetExistingHash);


function GetHash(key) {
30
  return %GenericHash(key);
31 32
}
%SetForceInlineFlag(GetHash);
33

34

35
// -------------------------------------------------------------------
36
// Harmony WeakMap
37

38
function WeakMapConstructor(iterable) {
39
  if (IS_UNDEFINED(new.target)) {
40
    throw %make_type_error(kConstructorNotFunction, "WeakMap");
41
  }
42

43
  %WeakCollectionInitialize(this);
44 45

  if (!IS_NULL_OR_UNDEFINED(iterable)) {
46
    var adder = this.set;
47
    if (!IS_CALLABLE(adder)) {
48
      throw %make_type_error(kPropertyNotFunction, adder, 'set', this);
49
    }
50
    for (var nextItem of iterable) {
51
      if (!IS_RECEIVER(nextItem)) {
52
        throw %make_type_error(kIteratorValueNotAnObject, nextItem);
53
      }
54
      %_Call(adder, this, nextItem[0], nextItem[1]);
55 56
    }
  }
57 58
}

59

60 61 62 63 64 65 66 67 68 69 70 71
// Set up the non-enumerable functions on the WeakMap prototype object.
DEFINE_METHODS(
  GlobalWeakMap.prototype,
  {
    set(key, value) {
      if (!IS_WEAKMAP(this)) {
        throw %make_type_error(kIncompatibleMethodReceiver,
                            'WeakMap.prototype.set', this);
      }
      if (!IS_RECEIVER(key)) throw %make_type_error(kInvalidWeakMapKey);
      return %WeakCollectionSet(this, key, value, GetHash(key));
    }
72

73 74 75 76 77 78 79 80 81 82
    delete(key) {
      if (!IS_WEAKMAP(this)) {
        throw %make_type_error(kIncompatibleMethodReceiver,
                            'WeakMap.prototype.delete', this);
      }
      if (!IS_RECEIVER(key)) return false;
      var hash = GetExistingHash(key);
      if (IS_UNDEFINED(hash)) return false;
      return %WeakCollectionDelete(this, key, hash);
    }
83
  }
84
);
85 86 87

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

88 89
%SetCode(GlobalWeakMap, WeakMapConstructor);
%FunctionSetLength(GlobalWeakMap, 0);
90 91

// -------------------------------------------------------------------
92
// Harmony WeakSet
93

94
function WeakSetConstructor(iterable) {
95
  if (IS_UNDEFINED(new.target)) {
96
    throw %make_type_error(kConstructorNotFunction, "WeakSet");
97
  }
98

99
  %WeakCollectionInitialize(this);
100 101

  if (!IS_NULL_OR_UNDEFINED(iterable)) {
102
    var adder = this.add;
103
    if (!IS_CALLABLE(adder)) {
104
      throw %make_type_error(kPropertyNotFunction, adder, 'add', this);
105
    }
106
    for (var value of iterable) {
107
      %_Call(adder, this, value);
108 109
    }
  }
110 111
}

112

113 114 115 116 117 118 119 120 121 122 123 124
// Set up the non-enumerable functions on the WeakSet prototype object.
DEFINE_METHODS(
  GlobalWeakSet.prototype,
  {
    add(value) {
      if (!IS_WEAKSET(this)) {
        throw %make_type_error(kIncompatibleMethodReceiver,
                            'WeakSet.prototype.add', this);
      }
      if (!IS_RECEIVER(value)) throw %make_type_error(kInvalidWeakSetValue);
      return %WeakCollectionSet(this, value, true, GetHash(value));
    }
125

126 127 128 129 130 131 132 133 134 135
    delete(value) {
      if (!IS_WEAKSET(this)) {
        throw %make_type_error(kIncompatibleMethodReceiver,
                            'WeakSet.prototype.delete', this);
      }
      if (!IS_RECEIVER(value)) return false;
      var hash = GetExistingHash(value);
      if (IS_UNDEFINED(hash)) return false;
      return %WeakCollectionDelete(this, value, hash);
    }
136
  }
137
);
138

139 140
// -------------------------------------------------------------------

141 142 143
%SetCode(GlobalWeakSet, WeakSetConstructor);
%FunctionSetLength(GlobalWeakSet, 0);

144
})