Commit 9e5e3aff authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[runtime] Cleanup native methods creation in js/collection.js and js/collection-iterator.js.

This CL replaces usages of utils.InstallFunctions and utils.InstallGetter()
with the DEFINE_METHOD* macros that ensure that the native function is
created in proper form from the beginning. Thus the function will not
require further reconfiguring like adding a computed name or removing of
'prototype' property.

This CL is one of a series of cleanup CL which are the preliminary steps for
improving function closures creation.

Bug: v8:6459

fox

Change-Id: I0d95cd28511a84ff2c0a6e4dbf7274f73a0629f4
Reviewed-on: https://chromium-review.googlesource.com/548155
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46286}
parent a1503030
......@@ -25,65 +25,66 @@ function SetIteratorConstructor(set, kind) {
}
function SetIteratorNextJS() {
if (!IS_SET_ITERATOR(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set Iterator.prototype.next', this);
DEFINE_METHOD(
SetIterator.prototype,
next() {
if (!IS_SET_ITERATOR(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set Iterator.prototype.next', this);
}
var value_array = [UNDEFINED, UNDEFINED];
var result = %_CreateIterResultObject(value_array, false);
switch (%SetIteratorNext(this, value_array)) {
case 0:
result.value = UNDEFINED;
result.done = true;
break;
case ITERATOR_KIND_VALUES:
result.value = value_array[0];
break;
case ITERATOR_KIND_ENTRIES:
value_array[1] = value_array[0];
break;
}
return result;
}
var value_array = [UNDEFINED, UNDEFINED];
var result = %_CreateIterResultObject(value_array, false);
switch (%SetIteratorNext(this, value_array)) {
case 0:
result.value = UNDEFINED;
result.done = true;
break;
case ITERATOR_KIND_VALUES:
result.value = value_array[0];
break;
case ITERATOR_KIND_ENTRIES:
value_array[1] = value_array[0];
break;
}
return result;
}
function SetEntries() {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.entries', this);
);
DEFINE_METHODS(
GlobalSet.prototype,
{
entries() {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.entries', this);
}
return new SetIterator(this, ITERATOR_KIND_ENTRIES);
}
values() {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.values', this);
}
return new SetIterator(this, ITERATOR_KIND_VALUES);
}
}
return new SetIterator(this, ITERATOR_KIND_ENTRIES);
}
function SetValues() {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.values', this);
}
return new SetIterator(this, ITERATOR_KIND_VALUES);
}
);
// -------------------------------------------------------------------
%SetCode(SetIterator, SetIteratorConstructor);
%FunctionSetInstanceClassName(SetIterator, 'Set Iterator');
utils.InstallFunctions(SetIterator.prototype, DONT_ENUM, [
'next', SetIteratorNextJS
]);
var SetIteratorNext = SetIterator.prototype.next;
%AddNamedProperty(SetIterator.prototype, toStringTagSymbol,
"Set Iterator", READ_ONLY | DONT_ENUM);
utils.InstallFunctions(GlobalSet.prototype, DONT_ENUM, [
'entries', SetEntries,
'keys', SetValues,
'values', SetValues
]);
var SetValues = GlobalSet.prototype.values;
%AddNamedProperty(GlobalSet.prototype, "keys", SetValues, DONT_ENUM);
%AddNamedProperty(GlobalSet.prototype, iteratorSymbol, SetValues, DONT_ENUM);
// -------------------------------------------------------------------
......@@ -93,76 +94,77 @@ function MapIteratorConstructor(map, kind) {
}
function MapIteratorNextJS() {
if (!IS_MAP_ITERATOR(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map Iterator.prototype.next', this);
DEFINE_METHOD(
MapIterator.prototype,
next() {
if (!IS_MAP_ITERATOR(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map Iterator.prototype.next', this);
}
var value_array = [UNDEFINED, UNDEFINED];
var result = %_CreateIterResultObject(value_array, false);
switch (%MapIteratorNext(this, value_array)) {
case 0:
result.value = UNDEFINED;
result.done = true;
break;
case ITERATOR_KIND_KEYS:
result.value = value_array[0];
break;
case ITERATOR_KIND_VALUES:
result.value = value_array[1];
break;
// ITERATOR_KIND_ENTRIES does not need any processing.
}
return result;
}
var value_array = [UNDEFINED, UNDEFINED];
var result = %_CreateIterResultObject(value_array, false);
switch (%MapIteratorNext(this, value_array)) {
case 0:
result.value = UNDEFINED;
result.done = true;
break;
case ITERATOR_KIND_KEYS:
result.value = value_array[0];
break;
case ITERATOR_KIND_VALUES:
result.value = value_array[1];
break;
// ITERATOR_KIND_ENTRIES does not need any processing.
);
DEFINE_METHODS(
GlobalMap.prototype,
{
entries() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.entries', this);
}
return new MapIterator(this, ITERATOR_KIND_ENTRIES);
}
keys() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.keys', this);
}
return new MapIterator(this, ITERATOR_KIND_KEYS);
}
values() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.values', this);
}
return new MapIterator(this, ITERATOR_KIND_VALUES);
}
}
);
return result;
}
function MapEntries() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.entries', this);
}
return new MapIterator(this, ITERATOR_KIND_ENTRIES);
}
function MapKeys() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.keys', this);
}
return new MapIterator(this, ITERATOR_KIND_KEYS);
}
function MapValues() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.values', this);
}
return new MapIterator(this, ITERATOR_KIND_VALUES);
}
// -------------------------------------------------------------------
%SetCode(MapIterator, MapIteratorConstructor);
%FunctionSetInstanceClassName(MapIterator, 'Map Iterator');
utils.InstallFunctions(MapIterator.prototype, DONT_ENUM, [
'next', MapIteratorNextJS
]);
var MapIteratorNext = MapIterator.prototype.next;
%AddNamedProperty(MapIterator.prototype, toStringTagSymbol,
"Map Iterator", READ_ONLY | DONT_ENUM);
utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
'entries', MapEntries,
'keys', MapKeys,
'values', MapValues
]);
var MapEntries = GlobalMap.prototype.entries;
%AddNamedProperty(GlobalMap.prototype, iteratorSymbol, MapEntries, DONT_ENUM);
// -------------------------------------------------------------------
......@@ -170,8 +172,8 @@ utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
utils.Export(function(to) {
to.MapEntries = MapEntries;
to.MapIteratorNext = MapIteratorNextJS;
to.SetIteratorNext = SetIteratorNextJS;
to.MapIteratorNext = MapIteratorNext;
to.SetIteratorNext = SetIteratorNext;
to.SetValues = SetValues;
});
......
......@@ -120,163 +120,158 @@ function GetHash(key) {
// -------------------------------------------------------------------
// Harmony Set
function SetAdd(key) {
if (!IS_SET(this)) {
throw %make_type_error(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;
}
//Set up the non-enumerable functions on the Set prototype object.
DEFINE_METHODS(
GlobalSet.prototype,
{
add(key) {
if (!IS_SET(this)) {
throw %make_type_error(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 SetDelete(key) {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.delete', this);
delete(key) {
if (!IS_SET(this)) {
throw %make_type_error(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;
}
}
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;
}
// Set up the non-enumerable functions on the Set prototype object.
utils.InstallFunctions(GlobalSet.prototype, DONT_ENUM, [
"add", SetAdd,
"delete", SetDelete,
]);
);
// -------------------------------------------------------------------
// Harmony Map
//Set up the non-enumerable functions on the Map prototype object.
DEFINE_METHODS(
GlobalMap.prototype,
{
set(key, value) {
if (!IS_MAP(this)) {
throw %make_type_error(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 MapSet(key, value) {
if (!IS_MAP(this)) {
throw %make_type_error(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 MapDelete(key) {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.delete', this);
delete(key) {
if (!IS_MAP(this)) {
throw %make_type_error(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;
}
}
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;
}
// Set up the non-enumerable functions on the Map prototype object.
utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
"set", MapSet,
"delete", MapDelete,
]);
);
// -----------------------------------------------------------------------
// Exports
%InstallToContext([
"map_set", MapSet,
"map_delete", MapDelete,
"set_add", SetAdd,
"set_delete", SetDelete,
"map_set", GlobalMap.prototype.set,
"map_delete", GlobalMap.prototype.delete,
"set_add", GlobalSet.prototype.add,
"set_delete", GlobalSet.prototype.delete,
]);
utils.Export(function(to) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment