Commit 2c65b0be authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[Collections] Move size, clear, forEach to C++

Bug: v8:5717
Change-Id: I0e900b46a314a272206798aab8af5ccbb7f91fd3
Reviewed-on: https://chromium-review.googlesource.com/528315Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45907}
parent 814d08a6
......@@ -1173,6 +1173,7 @@ v8_source_set("v8_base") {
"src/builtins/builtins-boolean.cc",
"src/builtins/builtins-call.cc",
"src/builtins/builtins-callsite.cc",
"src/builtins/builtins-collections.cc",
"src/builtins/builtins-console.cc",
"src/builtins/builtins-constructor.h",
"src/builtins/builtins-dataview.cc",
......
......@@ -2957,6 +2957,11 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
InstallWithIntrinsicDefaultProto(isolate, map_has,
Context::MAP_HAS_METHOD_INDEX);
SimpleInstallFunction(prototype, "clear", Builtins::kMapClear, 0, true);
SimpleInstallFunction(prototype, "forEach", Builtins::kMapForEach, 1,
false);
SimpleInstallGetter(prototype, factory->InternalizeUtf8String("size"),
Builtins::kMapGetSize, false);
InstallSpeciesGetter(js_map_fun);
}
......@@ -2988,6 +2993,11 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleInstallFunction(prototype, "has", Builtins::kSetHas, 1, true);
InstallWithIntrinsicDefaultProto(isolate, set_has,
Context::SET_HAS_METHOD_INDEX);
SimpleInstallFunction(prototype, "clear", Builtins::kSetClear, 0, true);
SimpleInstallFunction(prototype, "forEach", Builtins::kSetForEach, 1,
false);
SimpleInstallGetter(prototype, factory->InternalizeUtf8String("size"),
Builtins::kSetGetSize, false);
InstallSpeciesGetter(js_set_fun);
}
......
// Copyright 2016 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.
#include "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
BUILTIN(MapGetSize) {
HandleScope scope(isolate);
const char* const kMethodName = "get Map.prototype.size";
CHECK_RECEIVER(JSMap, map, kMethodName);
Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
Handle<Object> size =
isolate->factory()->NewNumberFromInt(table->NumberOfElements());
return *size;
}
BUILTIN(MapClear) {
HandleScope scope(isolate);
const char* const kMethodName = "Map.prototype.clear";
CHECK_RECEIVER(JSMap, map, kMethodName);
JSMap::Clear(map);
return isolate->heap()->undefined_value();
}
BUILTIN(MapForEach) {
HandleScope scope(isolate);
const char* const kMethodName = "Map.prototype.forEach";
CHECK_RECEIVER(JSMap, map, kMethodName);
Handle<Object> callback_fn = args.atOrUndefined(isolate, 1);
if (!callback_fn->IsCallable()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kCalledNonCallable, callback_fn));
}
Handle<Object> receiver = args.atOrUndefined(isolate, 2);
Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
Handle<JSMapIterator> iterator = isolate->factory()->NewJSMapIterator();
iterator->set_table(*table);
iterator->set_index(Smi::kZero);
iterator->set_kind(Smi::FromInt(JSMapIterator::kKindEntries));
while (iterator->HasMore()) {
Handle<Object> key(iterator->CurrentKey(), isolate);
Handle<Object> value(iterator->CurrentValue(), isolate);
Handle<Object> argv[] = {value, key, map};
RETURN_FAILURE_ON_EXCEPTION(
isolate,
Execution::Call(isolate, callback_fn, receiver, arraysize(argv), argv));
iterator->MoveNext();
}
return isolate->heap()->undefined_value();
}
BUILTIN(SetGetSize) {
HandleScope scope(isolate);
const char* const kMethodName = "get Set.prototype.size";
CHECK_RECEIVER(JSSet, set, kMethodName);
Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
Handle<Object> size =
isolate->factory()->NewNumberFromInt(table->NumberOfElements());
return *size;
}
BUILTIN(SetClear) {
HandleScope scope(isolate);
const char* const kMethodName = "Set.prototype.clear";
CHECK_RECEIVER(JSSet, set, kMethodName);
JSSet::Clear(set);
return isolate->heap()->undefined_value();
}
BUILTIN(SetForEach) {
HandleScope scope(isolate);
const char* const kMethodName = "Set.prototype.forEach";
CHECK_RECEIVER(JSSet, set, kMethodName);
Handle<Object> callback_fn = args.atOrUndefined(isolate, 1);
if (!callback_fn->IsCallable()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kCalledNonCallable, callback_fn));
}
Handle<Object> receiver = args.atOrUndefined(isolate, 2);
Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
Handle<JSSetIterator> iterator = isolate->factory()->NewJSSetIterator();
iterator->set_table(*table);
iterator->set_index(Smi::kZero);
iterator->set_kind(Smi::FromInt(JSSetIterator::kKindValues));
while (iterator->HasMore()) {
Handle<Object> key(iterator->CurrentKey(), isolate);
Handle<Object> argv[] = {key, key, set};
RETURN_FAILURE_ON_EXCEPTION(
isolate,
Execution::Call(isolate, callback_fn, receiver, arraysize(argv), argv));
iterator->MoveNext();
}
return isolate->heap()->undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -579,6 +579,9 @@ namespace internal {
TFJ(MapConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(MapGet, 1, kKey) \
TFJ(MapHas, 1, kKey) \
CPP(MapGetSize) \
CPP(MapClear) \
CPP(MapForEach) \
\
/* Math */ \
/* ES6 #sec-math.abs */ \
......@@ -855,6 +858,9 @@ namespace internal {
/* Set */ \
TFJ(SetConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(SetHas, 1, kKey) \
CPP(SetGetSize) \
CPP(SetClear) \
CPP(SetForEach) \
\
/* SharedArrayBuffer */ \
CPP(SharedArrayBufferPrototypeGetByteLength) \
......
......@@ -535,6 +535,7 @@ bool BuiltinHasNoSideEffect(Builtins::Name id) {
// Map builtins.
case Builtins::kMapConstructor:
case Builtins::kMapGet:
case Builtins::kMapGetSize:
// Math builtins.
case Builtins::kMathAbs:
case Builtins::kMathAcos:
......@@ -586,6 +587,7 @@ bool BuiltinHasNoSideEffect(Builtins::Name id) {
case Builtins::kNumberPrototypeValueOf:
// Set builtins.
case Builtins::kSetConstructor:
case Builtins::kSetGetSize:
// String builtins. Strings are immutable.
case Builtins::kStringFromCharCode:
case Builtins::kStringFromCodePoint:
......
......@@ -181,54 +181,10 @@ function SetDelete(key) {
return true;
}
function SetGetSize() {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.size', this);
}
var table = %_JSCollectionGetTable(this);
return ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
}
function SetClearJS() {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.clear', this);
}
%_SetClear(this);
}
function SetForEach(f, receiver) {
if (!IS_SET(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Set.prototype.forEach', this);
}
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
var key;
var value_array = [UNDEFINED];
while (%SetIteratorNext(iterator, value_array)) {
key = value_array[0];
%_Call(f, receiver, key, key, this);
}
}
// -------------------------------------------------------------------
%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,
"delete", SetDelete,
"clear", SetClearJS,
"forEach", SetForEach
]);
......@@ -306,52 +262,10 @@ function MapDelete(key) {
return true;
}
function MapGetSize() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.size', this);
}
var table = %_JSCollectionGetTable(this);
return ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
}
function MapClearJS() {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.clear', this);
}
%_MapClear(this);
}
function MapForEach(f, receiver) {
if (!IS_MAP(this)) {
throw %make_type_error(kIncompatibleMethodReceiver,
'Map.prototype.forEach', this);
}
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
var value_array = [UNDEFINED, UNDEFINED];
while (%MapIteratorNext(iterator, value_array)) {
%_Call(f, receiver, value_array[1], value_array[0], this);
}
}
// -------------------------------------------------------------------
%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, [
"set", MapSet,
"delete", MapDelete,
"clear", MapClearJS,
"forEach", MapForEach
]);
// -----------------------------------------------------------------------
......
......@@ -885,11 +885,11 @@ class JSMapIterator
// populate the array differently.
inline void PopulateValueArray(FixedArray* array);
private:
// Returns the current value of the iterator. This should only be called when
// |HasMore| returns true.
inline Object* CurrentValue();
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
};
......
......@@ -75,7 +75,7 @@ RUNTIME_FUNCTION(Runtime_SetShrink) {
return isolate->heap()->undefined_value();
}
// TODO(gsathya): Remove this when we delete crankshaft.
RUNTIME_FUNCTION(Runtime_SetClear) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......@@ -159,7 +159,7 @@ RUNTIME_FUNCTION(Runtime_MapShrink) {
return isolate->heap()->undefined_value();
}
// TODO(gsathya): Remove this when we delete crankshaft.
RUNTIME_FUNCTION(Runtime_MapClear) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......
......@@ -633,6 +633,7 @@
'builtins/builtins-boolean.cc',
'builtins/builtins-call.cc',
'builtins/builtins-callsite.cc',
'builtins/builtins-collections.cc',
'builtins/builtins-console.cc',
'builtins/builtins-constructor.h',
'builtins/builtins-dataview.cc',
......
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