| Index: src/collection.js
|
| diff --git a/src/collection.js b/src/collection.js
|
| deleted file mode 100644
|
| index 8bf6ec3515baf2c2ebd2b4ead4c300671ea8064e..0000000000000000000000000000000000000000
|
| --- a/src/collection.js
|
| +++ /dev/null
|
| @@ -1,504 +0,0 @@
|
| -// Copyright 2012 the V8 project authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -var $getHash;
|
| -var $getExistingHash;
|
| -
|
| -(function(global, utils) {
|
| -"use strict";
|
| -
|
| -%CheckIsBootstrapping();
|
| -
|
| -// -------------------------------------------------------------------
|
| -// Imports
|
| -
|
| -var GlobalMap = global.Map;
|
| -var GlobalObject = global.Object;
|
| -var GlobalSet = global.Set;
|
| -var hashCodeSymbol = utils.ImportNow("hash_code_symbol");
|
| -var IntRandom;
|
| -var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
|
| -
|
| -utils.Import(function(from) {
|
| - IntRandom = from.IntRandom;
|
| -});
|
| -
|
| -var NumberIsNaN;
|
| -
|
| -utils.Import(function(from) {
|
| - NumberIsNaN = from.NumberIsNaN;
|
| -});
|
| -
|
| -// -------------------------------------------------------------------
|
| -
|
| -function HashToEntry(table, hash, numBuckets) {
|
| - var bucket = ORDERED_HASH_TABLE_HASH_TO_BUCKET(hash, numBuckets);
|
| - return ORDERED_HASH_TABLE_BUCKET_AT(table, bucket);
|
| -}
|
| -%SetForceInlineFlag(HashToEntry);
|
| -
|
| -
|
| -function SetFindEntry(table, numBuckets, key, hash) {
|
| - var entry = HashToEntry(table, hash, numBuckets);
|
| - if (entry === NOT_FOUND) return entry;
|
| - var candidate = ORDERED_HASH_SET_KEY_AT(table, entry, numBuckets);
|
| - if (key === candidate) return entry;
|
| - var keyIsNaN = NumberIsNaN(key);
|
| - while (true) {
|
| - if (keyIsNaN && NumberIsNaN(candidate)) {
|
| - return entry;
|
| - }
|
| - entry = ORDERED_HASH_SET_CHAIN_AT(table, entry, numBuckets);
|
| - if (entry === NOT_FOUND) return entry;
|
| - candidate = ORDERED_HASH_SET_KEY_AT(table, entry, numBuckets);
|
| - if (key === candidate) return entry;
|
| - }
|
| - return NOT_FOUND;
|
| -}
|
| -%SetForceInlineFlag(SetFindEntry);
|
| -
|
| -
|
| -function MapFindEntry(table, numBuckets, key, hash) {
|
| - var entry = HashToEntry(table, hash, numBuckets);
|
| - if (entry === NOT_FOUND) return entry;
|
| - var candidate = ORDERED_HASH_MAP_KEY_AT(table, entry, numBuckets);
|
| - if (key === candidate) return entry;
|
| - var keyIsNaN = NumberIsNaN(key);
|
| - while (true) {
|
| - if (keyIsNaN && NumberIsNaN(candidate)) {
|
| - return entry;
|
| - }
|
| - entry = ORDERED_HASH_MAP_CHAIN_AT(table, entry, numBuckets);
|
| - if (entry === NOT_FOUND) return entry;
|
| - candidate = ORDERED_HASH_MAP_KEY_AT(table, entry, numBuckets);
|
| - if (key === candidate) return entry;
|
| - }
|
| - return NOT_FOUND;
|
| -}
|
| -%SetForceInlineFlag(MapFindEntry);
|
| -
|
| -
|
| -function ComputeIntegerHash(key, seed) {
|
| - var hash = key;
|
| - hash = hash ^ seed;
|
| - hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
|
| - hash = hash ^ (hash >>> 12);
|
| - hash = hash + (hash << 2);
|
| - hash = hash ^ (hash >>> 4);
|
| - hash = (hash * 2057) | 0; // hash = (hash + (hash << 3)) + (hash << 11);
|
| - hash = hash ^ (hash >>> 16);
|
| - return hash & 0x3fffffff;
|
| -}
|
| -%SetForceInlineFlag(ComputeIntegerHash);
|
| -
|
| -function GetExistingHash(key) {
|
| - if (%_IsSmi(key)) {
|
| - return ComputeIntegerHash(key, 0);
|
| - }
|
| - if (IS_STRING(key)) {
|
| - var field = %_StringGetRawHashField(key);
|
| - if ((field & 1 /* Name::kHashNotComputedMask */) === 0) {
|
| - return field >>> 2 /* Name::kHashShift */;
|
| - }
|
| - } else if (IS_SPEC_OBJECT(key) && !%_IsJSProxy(key) && !IS_GLOBAL(key)) {
|
| - var hash = GET_PRIVATE(key, hashCodeSymbol);
|
| - return hash;
|
| - }
|
| - return %GenericHash(key);
|
| -}
|
| -%SetForceInlineFlag(GetExistingHash);
|
| -
|
| -
|
| -function GetHash(key) {
|
| - var hash = GetExistingHash(key);
|
| - if (IS_UNDEFINED(hash)) {
|
| - hash = IntRandom() | 0;
|
| - if (hash === 0) hash = 1;
|
| - SET_PRIVATE(key, hashCodeSymbol, hash);
|
| - }
|
| - return hash;
|
| -}
|
| -%SetForceInlineFlag(GetHash);
|
| -
|
| -
|
| -// -------------------------------------------------------------------
|
| -// Harmony Set
|
| -
|
| -function SetConstructor(iterable) {
|
| - if (!%_IsConstructCall()) {
|
| - throw MakeTypeError(kConstructorNotFunction, "Set");
|
| - }
|
| -
|
| - %_SetInitialize(this);
|
| -
|
| - if (!IS_NULL_OR_UNDEFINED(iterable)) {
|
| - var adder = this.add;
|
| - if (!IS_CALLABLE(adder)) {
|
| - throw MakeTypeError(kPropertyNotFunction, 'add', this);
|
| - }
|
| -
|
| - for (var value of iterable) {
|
| - %_Call(adder, this, value);
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -function SetAdd(key) {
|
| - if (!IS_SET(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver, 'Set.prototype.add', this);
|
| - }
|
| - // Normalize -0 to +0 as required by the spec.
|
| - // Even though we use SameValueZero as the comparison for the keys we don't
|
| - // want to ever store -0 as the key since the key is directly exposed when
|
| - // doing iteration.
|
| - if (key === 0) {
|
| - key = 0;
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - var hash = GetHash(key);
|
| - if (SetFindEntry(table, numBuckets, key, hash) !== NOT_FOUND) return this;
|
| -
|
| - var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
|
| - var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
|
| - var capacity = numBuckets << 1;
|
| - if ((nof + nod) >= capacity) {
|
| - // Need to grow, bail out to runtime.
|
| - %SetGrow(this);
|
| - // Re-load state from the grown backing store.
|
| - table = %_JSCollectionGetTable(this);
|
| - numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
|
| - nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
|
| - }
|
| - var entry = nof + nod;
|
| - var index = ORDERED_HASH_SET_ENTRY_TO_INDEX(entry, numBuckets);
|
| - var bucket = ORDERED_HASH_TABLE_HASH_TO_BUCKET(hash, numBuckets);
|
| - var chainEntry = ORDERED_HASH_TABLE_BUCKET_AT(table, bucket);
|
| - ORDERED_HASH_TABLE_SET_BUCKET_AT(table, bucket, entry);
|
| - ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof + 1);
|
| - FIXED_ARRAY_SET(table, index, key);
|
| - FIXED_ARRAY_SET_SMI(table, index + 1, chainEntry);
|
| - return this;
|
| -}
|
| -
|
| -
|
| -function SetHas(key) {
|
| - if (!IS_SET(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver, 'Set.prototype.has', this);
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - var hash = GetExistingHash(key);
|
| - if (IS_UNDEFINED(hash)) return false;
|
| - return SetFindEntry(table, numBuckets, key, hash) !== NOT_FOUND;
|
| -}
|
| -
|
| -
|
| -function SetDelete(key) {
|
| - if (!IS_SET(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Set.prototype.delete', this);
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - var hash = GetExistingHash(key);
|
| - if (IS_UNDEFINED(hash)) return false;
|
| - var entry = SetFindEntry(table, numBuckets, key, hash);
|
| - if (entry === NOT_FOUND) return false;
|
| -
|
| - var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table) - 1;
|
| - var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table) + 1;
|
| - var index = ORDERED_HASH_SET_ENTRY_TO_INDEX(entry, numBuckets);
|
| - FIXED_ARRAY_SET(table, index, %_TheHole());
|
| - ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof);
|
| - ORDERED_HASH_TABLE_SET_DELETED_COUNT(table, nod);
|
| - if (nof < (numBuckets >>> 1)) %SetShrink(this);
|
| - return true;
|
| -}
|
| -
|
| -
|
| -function SetGetSize() {
|
| - if (!IS_SET(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Set.prototype.size', this);
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - return ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
|
| -}
|
| -
|
| -
|
| -function SetClearJS() {
|
| - if (!IS_SET(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Set.prototype.clear', this);
|
| - }
|
| - %_SetClear(this);
|
| -}
|
| -
|
| -
|
| -function SetForEach(f, receiver) {
|
| - if (!IS_SET(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Set.prototype.forEach', this);
|
| - }
|
| -
|
| - if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
|
| -
|
| - var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
|
| - var key;
|
| - var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
|
| - var value_array = [UNDEFINED];
|
| - while (%SetIteratorNext(iterator, value_array)) {
|
| - if (stepping) %DebugPrepareStepInIfStepping(f);
|
| - key = value_array[0];
|
| - %_Call(f, receiver, key, key, this);
|
| - }
|
| -}
|
| -
|
| -// -------------------------------------------------------------------
|
| -
|
| -%SetCode(GlobalSet, SetConstructor);
|
| -%FunctionSetLength(GlobalSet, 0);
|
| -%FunctionSetPrototype(GlobalSet, new GlobalObject());
|
| -%AddNamedProperty(GlobalSet.prototype, "constructor", GlobalSet, DONT_ENUM);
|
| -%AddNamedProperty(GlobalSet.prototype, toStringTagSymbol, "Set",
|
| - DONT_ENUM | READ_ONLY);
|
| -
|
| -%FunctionSetLength(SetForEach, 1);
|
| -
|
| -// Set up the non-enumerable functions on the Set prototype object.
|
| -utils.InstallGetter(GlobalSet.prototype, "size", SetGetSize);
|
| -utils.InstallFunctions(GlobalSet.prototype, DONT_ENUM, [
|
| - "add", SetAdd,
|
| - "has", SetHas,
|
| - "delete", SetDelete,
|
| - "clear", SetClearJS,
|
| - "forEach", SetForEach
|
| -]);
|
| -
|
| -
|
| -// -------------------------------------------------------------------
|
| -// Harmony Map
|
| -
|
| -function MapConstructor(iterable) {
|
| - if (!%_IsConstructCall()) {
|
| - throw MakeTypeError(kConstructorNotFunction, "Map");
|
| - }
|
| -
|
| - %_MapInitialize(this);
|
| -
|
| - if (!IS_NULL_OR_UNDEFINED(iterable)) {
|
| - var adder = this.set;
|
| - if (!IS_CALLABLE(adder)) {
|
| - throw MakeTypeError(kPropertyNotFunction, 'set', this);
|
| - }
|
| -
|
| - for (var nextItem of iterable) {
|
| - if (!IS_SPEC_OBJECT(nextItem)) {
|
| - throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
|
| - }
|
| - %_Call(adder, this, nextItem[0], nextItem[1]);
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -function MapGet(key) {
|
| - if (!IS_MAP(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Map.prototype.get', this);
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - var hash = GetExistingHash(key);
|
| - if (IS_UNDEFINED(hash)) return UNDEFINED;
|
| - var entry = MapFindEntry(table, numBuckets, key, hash);
|
| - if (entry === NOT_FOUND) return UNDEFINED;
|
| - return ORDERED_HASH_MAP_VALUE_AT(table, entry, numBuckets);
|
| -}
|
| -
|
| -
|
| -function MapSet(key, value) {
|
| - if (!IS_MAP(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Map.prototype.set', this);
|
| - }
|
| - // Normalize -0 to +0 as required by the spec.
|
| - // Even though we use SameValueZero as the comparison for the keys we don't
|
| - // want to ever store -0 as the key since the key is directly exposed when
|
| - // doing iteration.
|
| - if (key === 0) {
|
| - key = 0;
|
| - }
|
| -
|
| - var table = %_JSCollectionGetTable(this);
|
| - var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - var hash = GetHash(key);
|
| - var entry = MapFindEntry(table, numBuckets, key, hash);
|
| - if (entry !== NOT_FOUND) {
|
| - var existingIndex = ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets);
|
| - FIXED_ARRAY_SET(table, existingIndex + 1, value);
|
| - return this;
|
| - }
|
| -
|
| - var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
|
| - var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
|
| - var capacity = numBuckets << 1;
|
| - if ((nof + nod) >= capacity) {
|
| - // Need to grow, bail out to runtime.
|
| - %MapGrow(this);
|
| - // Re-load state from the grown backing store.
|
| - table = %_JSCollectionGetTable(this);
|
| - numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
|
| - nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
|
| - }
|
| - entry = nof + nod;
|
| - var index = ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets);
|
| - var bucket = ORDERED_HASH_TABLE_HASH_TO_BUCKET(hash, numBuckets);
|
| - var chainEntry = ORDERED_HASH_TABLE_BUCKET_AT(table, bucket);
|
| - ORDERED_HASH_TABLE_SET_BUCKET_AT(table, bucket, entry);
|
| - ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof + 1);
|
| - FIXED_ARRAY_SET(table, index, key);
|
| - FIXED_ARRAY_SET(table, index + 1, value);
|
| - FIXED_ARRAY_SET(table, index + 2, chainEntry);
|
| - return this;
|
| -}
|
| -
|
| -
|
| -function MapHas(key) {
|
| - if (!IS_MAP(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Map.prototype.has', this);
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - var hash = GetHash(key);
|
| - return MapFindEntry(table, numBuckets, key, hash) !== NOT_FOUND;
|
| -}
|
| -
|
| -
|
| -function MapDelete(key) {
|
| - if (!IS_MAP(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Map.prototype.delete', this);
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
|
| - var hash = GetHash(key);
|
| - var entry = MapFindEntry(table, numBuckets, key, hash);
|
| - if (entry === NOT_FOUND) return false;
|
| -
|
| - var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table) - 1;
|
| - var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table) + 1;
|
| - var index = ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets);
|
| - FIXED_ARRAY_SET(table, index, %_TheHole());
|
| - FIXED_ARRAY_SET(table, index + 1, %_TheHole());
|
| - ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof);
|
| - ORDERED_HASH_TABLE_SET_DELETED_COUNT(table, nod);
|
| - if (nof < (numBuckets >>> 1)) %MapShrink(this);
|
| - return true;
|
| -}
|
| -
|
| -
|
| -function MapGetSize() {
|
| - if (!IS_MAP(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Map.prototype.size', this);
|
| - }
|
| - var table = %_JSCollectionGetTable(this);
|
| - return ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
|
| -}
|
| -
|
| -
|
| -function MapClearJS() {
|
| - if (!IS_MAP(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Map.prototype.clear', this);
|
| - }
|
| - %_MapClear(this);
|
| -}
|
| -
|
| -
|
| -function MapForEach(f, receiver) {
|
| - if (!IS_MAP(this)) {
|
| - throw MakeTypeError(kIncompatibleMethodReceiver,
|
| - 'Map.prototype.forEach', this);
|
| - }
|
| -
|
| - if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
|
| -
|
| - var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
|
| - var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
|
| - var value_array = [UNDEFINED, UNDEFINED];
|
| - while (%MapIteratorNext(iterator, value_array)) {
|
| - if (stepping) %DebugPrepareStepInIfStepping(f);
|
| - %_Call(f, receiver, value_array[1], value_array[0], this);
|
| - }
|
| -}
|
| -
|
| -// -------------------------------------------------------------------
|
| -
|
| -%SetCode(GlobalMap, MapConstructor);
|
| -%FunctionSetLength(GlobalMap, 0);
|
| -%FunctionSetPrototype(GlobalMap, new GlobalObject());
|
| -%AddNamedProperty(GlobalMap.prototype, "constructor", GlobalMap, DONT_ENUM);
|
| -%AddNamedProperty(
|
| - GlobalMap.prototype, toStringTagSymbol, "Map", DONT_ENUM | READ_ONLY);
|
| -
|
| -%FunctionSetLength(MapForEach, 1);
|
| -
|
| -// Set up the non-enumerable functions on the Map prototype object.
|
| -utils.InstallGetter(GlobalMap.prototype, "size", MapGetSize);
|
| -utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
|
| - "get", MapGet,
|
| - "set", MapSet,
|
| - "has", MapHas,
|
| - "delete", MapDelete,
|
| - "clear", MapClearJS,
|
| - "forEach", MapForEach
|
| -]);
|
| -
|
| -// Expose to the global scope.
|
| -$getHash = GetHash;
|
| -$getExistingHash = GetExistingHash;
|
| -
|
| -function MapFromArray(array) {
|
| - var map = new GlobalMap;
|
| - var length = array.length;
|
| - for (var i = 0; i < length; i += 2) {
|
| - var key = array[i];
|
| - var value = array[i + 1];
|
| - %_Call(MapSet, map, key, value);
|
| - }
|
| - return map;
|
| -};
|
| -
|
| -function SetFromArray(array) {
|
| - var set = new GlobalSet;
|
| - var length = array.length;
|
| - for (var i = 0; i < length; ++i) {
|
| - %_Call(SetAdd, set, array[i]);
|
| - }
|
| - return set;
|
| -};
|
| -
|
| -// -----------------------------------------------------------------------
|
| -// Exports
|
| -
|
| -%InstallToContext([
|
| - "map_get", MapGet,
|
| - "map_set", MapSet,
|
| - "map_has", MapHas,
|
| - "map_delete", MapDelete,
|
| - "set_add", SetAdd,
|
| - "set_has", SetHas,
|
| - "set_delete", SetDelete,
|
| - "map_from_array", MapFromArray,
|
| - "set_from_array",SetFromArray,
|
| -]);
|
| -
|
| -})
|
|
|