| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index 55eddf5be59d6de613053afb537b4641b7a8c4c7..8c878b178a19ffe66b5d54428af94f7bbce5b796 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -7140,15 +7140,14 @@ Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
|
| return Just(result->IsTrue(isolate));
|
| }
|
|
|
| -
|
| -Local<Array> Map::AsArray() const {
|
| - i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
|
| - i::Isolate* isolate = obj->GetIsolate();
|
| +namespace {
|
| +i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
|
| + int offset, int kind) {
|
| i::Factory* factory = isolate->factory();
|
| - LOG_API(isolate, Map, AsArray);
|
| - ENTER_V8(isolate);
|
| - i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(obj->table()));
|
| - int length = table->NumberOfElements() * 2;
|
| + i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj));
|
| + if (offset >= table->NumberOfElements()) return factory->NewJSArray(0);
|
| + int length = (table->NumberOfElements() - offset) *
|
| + (kind == i::JSMapIterator::kKindEntries ? 2 : 1);
|
| i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
|
| int result_index = 0;
|
| {
|
| @@ -7158,15 +7157,30 @@ Local<Array> Map::AsArray() const {
|
| for (int i = 0; i < capacity; ++i) {
|
| i::Object* key = table->KeyAt(i);
|
| if (key == the_hole) continue;
|
| - result->set(result_index++, key);
|
| - result->set(result_index++, table->ValueAt(i));
|
| + if (offset-- > 0) continue;
|
| + if (kind == i::JSMapIterator::kKindEntries ||
|
| + kind == i::JSMapIterator::kKindKeys) {
|
| + result->set(result_index++, key);
|
| + }
|
| + if (kind == i::JSMapIterator::kKindEntries ||
|
| + kind == i::JSMapIterator::kKindValues) {
|
| + result->set(result_index++, table->ValueAt(i));
|
| + }
|
| }
|
| }
|
| DCHECK_EQ(result_index, result->length());
|
| DCHECK_EQ(result_index, length);
|
| - i::Handle<i::JSArray> result_array =
|
| - factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
|
| - return Utils::ToLocal(result_array);
|
| + return factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
|
| +}
|
| +} // namespace
|
| +
|
| +Local<Array> Map::AsArray() const {
|
| + i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
|
| + i::Isolate* isolate = obj->GetIsolate();
|
| + LOG_API(isolate, Map, AsArray);
|
| + ENTER_V8(isolate);
|
| + return Utils::ToLocal(
|
| + MapAsArray(isolate, obj->table(), 0, i::JSMapIterator::kKindEntries));
|
| }
|
|
|
|
|
| @@ -7232,15 +7246,13 @@ Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
|
| return Just(result->IsTrue(isolate));
|
| }
|
|
|
| -
|
| -Local<Array> Set::AsArray() const {
|
| - i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
|
| - i::Isolate* isolate = obj->GetIsolate();
|
| +namespace {
|
| +i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object* table_obj,
|
| + int offset) {
|
| i::Factory* factory = isolate->factory();
|
| - LOG_API(isolate, Set, AsArray);
|
| - ENTER_V8(isolate);
|
| - i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(obj->table()));
|
| - int length = table->NumberOfElements();
|
| + i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj));
|
| + int length = table->NumberOfElements() - offset;
|
| + if (length <= 0) return factory->NewJSArray(0);
|
| i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
|
| int result_index = 0;
|
| {
|
| @@ -7250,14 +7262,22 @@ Local<Array> Set::AsArray() const {
|
| for (int i = 0; i < capacity; ++i) {
|
| i::Object* key = table->KeyAt(i);
|
| if (key == the_hole) continue;
|
| + if (offset-- > 0) continue;
|
| result->set(result_index++, key);
|
| }
|
| }
|
| DCHECK_EQ(result_index, result->length());
|
| DCHECK_EQ(result_index, length);
|
| - i::Handle<i::JSArray> result_array =
|
| - factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
|
| - return Utils::ToLocal(result_array);
|
| + return factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
|
| +}
|
| +} // namespace
|
| +
|
| +Local<Array> Set::AsArray() const {
|
| + i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
|
| + i::Isolate* isolate = obj->GetIsolate();
|
| + LOG_API(isolate, Set, AsArray);
|
| + ENTER_V8(isolate);
|
| + return Utils::ToLocal(SetAsArray(isolate, obj->table(), 0));
|
| }
|
|
|
|
|
| @@ -9354,6 +9374,46 @@ int debug::EstimatedValueSize(Isolate* v8_isolate, v8::Local<v8::Value> value) {
|
| return i::Handle<i::HeapObject>::cast(object)->Size();
|
| }
|
|
|
| +v8::MaybeLocal<v8::Array> debug::EntriesPreview(Isolate* v8_isolate,
|
| + v8::Local<v8::Value> value,
|
| + bool* is_key_value) {
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| + ENTER_V8(isolate);
|
| + if (value->IsMap()) {
|
| + *is_key_value = true;
|
| + return value.As<Map>()->AsArray();
|
| + }
|
| + if (value->IsSet()) {
|
| + *is_key_value = false;
|
| + return value.As<Set>()->AsArray();
|
| + }
|
| +
|
| + i::Handle<i::Object> object = Utils::OpenHandle(*value);
|
| + if (object->IsJSWeakCollection()) {
|
| + *is_key_value = object->IsJSWeakMap();
|
| + return Utils::ToLocal(i::JSWeakCollection::GetEntries(
|
| + i::Handle<i::JSWeakCollection>::cast(object), 0));
|
| + }
|
| + if (object->IsJSMapIterator()) {
|
| + i::Handle<i::JSMapIterator> iterator =
|
| + i::Handle<i::JSMapIterator>::cast(object);
|
| + int iterator_kind = i::Smi::cast(iterator->kind())->value();
|
| + *is_key_value = iterator_kind == i::JSMapIterator::kKindEntries;
|
| + if (!iterator->HasMore()) return v8::Array::New(v8_isolate);
|
| + return Utils::ToLocal(MapAsArray(isolate, iterator->table(),
|
| + i::Smi::cast(iterator->index())->value(),
|
| + iterator_kind));
|
| + }
|
| + if (object->IsJSSetIterator()) {
|
| + i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
|
| + *is_key_value = false;
|
| + if (!it->HasMore()) return v8::Array::New(v8_isolate);
|
| + return Utils::ToLocal(
|
| + SetAsArray(isolate, it->table(), i::Smi::cast(it->index())->value()));
|
| + }
|
| + return v8::MaybeLocal<v8::Array>();
|
| +}
|
| +
|
| Local<String> CpuProfileNode::GetFunctionName() const {
|
| const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
|
| i::Isolate* isolate = node->isolate();
|
|
|