From 685bc04a01853072bbdd04d1a4fc7e0a360bbd4d Mon Sep 17 00:00:00 2001 From: Andrey Adaikin Date: Mon, 17 Nov 2014 15:48:11 +0300 Subject: [PATCH] Expose internal properties of map/set iterators via mirrors. R=yangguo@chromium.org, vsevik LOG=Y Committed: https://code.google.com/p/v8/source/detail?r=d5f5d38f73f43eba9658d91ffbe511af8c340d78 Review URL: https://codereview.chromium.org/710273002 Cr-Commit-Position: refs/heads/master@{#25380} --- src/mirror-debugger.js | 16 ++++++++++++++++ src/runtime/runtime-collections.cc | 32 ++++++++++++++++++++++++++++++++ src/runtime/runtime.h | 2 ++ test/mjsunit/es6/mirror-iterators.js | 28 ++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js index c8d2461..6cec646 100644 --- a/src/mirror-debugger.js +++ b/src/mirror-debugger.js @@ -919,6 +919,22 @@ ObjectMirror.GetInternalProperties = function(value) { result.push(new InternalPropertyMirror("[[BoundArgs]]", boundArgs)); } return result; + } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) { + var details = IS_MAP_ITERATOR(value) ? %MapIteratorDetails(value) + : %SetIteratorDetails(value); + var kind; + switch (details[2]) { + case 1: kind = "keys"; break; + case 2: kind = "values"; break; + case 3: kind = "entries"; break; + } + var result = []; + result.push(new InternalPropertyMirror("[[IteratorHasMore]]", details[0])); + result.push(new InternalPropertyMirror("[[IteratorIndex]]", details[1])); + if (kind) { + result.push(new InternalPropertyMirror("[[IteratorKind]]", kind)); + } + return result; } else if (ObjectIsPromise(value)) { var result = []; result.push(new InternalPropertyMirror("[[PromiseStatus]]", diff --git a/src/runtime/runtime-collections.cc b/src/runtime/runtime-collections.cc index de1619e..e6a86d1 100644 --- a/src/runtime/runtime-collections.cc +++ b/src/runtime/runtime-collections.cc @@ -115,6 +115,22 @@ RUNTIME_FUNCTION(Runtime_SetIteratorNext) { } +// The array returned contains the following information: +// 0: HasMore flag +// 1: Iteration index +// 2: Iteration kind +RUNTIME_FUNCTION(Runtime_SetIteratorDetails) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); + Handle details = isolate->factory()->NewFixedArray(4); + details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); + details->set(1, holder->index()); + details->set(2, holder->kind()); + return *isolate->factory()->NewJSArrayWithElements(details); +} + + RUNTIME_FUNCTION(Runtime_MapInitialize) { HandleScope scope(isolate); DCHECK(args.length() == 1); @@ -225,6 +241,22 @@ RUNTIME_FUNCTION(Runtime_MapIteratorClone) { } +// The array returned contains the following information: +// 0: HasMore flag +// 1: Iteration index +// 2: Iteration kind +RUNTIME_FUNCTION(Runtime_MapIteratorDetails) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); + Handle details = isolate->factory()->NewFixedArray(4); + details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); + details->set(1, holder->index()); + details->set(2, holder->kind()); + return *isolate->factory()->NewJSArrayWithElements(details); +} + + RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { HandleScope scope(isolate); DCHECK(args.length() == 2); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index d353fda..4bc8fdf 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -313,6 +313,7 @@ namespace internal { F(SetIteratorInitialize, 3, 1) \ F(SetIteratorClone, 1, 1) \ F(SetIteratorNext, 2, 1) \ + F(SetIteratorDetails, 1, 1) \ \ /* Harmony maps */ \ F(MapInitialize, 1, 1) \ @@ -326,6 +327,7 @@ namespace internal { F(MapIteratorInitialize, 3, 1) \ F(MapIteratorClone, 1, 1) \ F(MapIteratorNext, 2, 1) \ + F(MapIteratorDetails, 1, 1) \ \ /* Harmony weak maps and sets */ \ F(WeakCollectionInitialize, 1, 1) \ diff --git a/test/mjsunit/es6/mirror-iterators.js b/test/mjsunit/es6/mirror-iterators.js index cc0b1e4..22ce424 100644 --- a/test/mjsunit/es6/mirror-iterators.js +++ b/test/mjsunit/es6/mirror-iterators.js @@ -23,6 +23,22 @@ function testIteratorMirror(iter, offset, expected, opt_limit) { assertArrayEquals(expected, values); } +function testIteratorInternalProperties(iter, offset, kind, index, has_more) { + while (offset-- > 0) iter.next(); + + var mirror = debug.MakeMirror(iter); + assertTrue(mirror.isIterator()); + + var properties = mirror.internalProperties(); + assertEquals(3, properties.length); + assertEquals("[[IteratorHasMore]]", properties[0].name()); + assertEquals(has_more, properties[0].value().value()); + assertEquals("[[IteratorIndex]]", properties[1].name()); + assertEquals(index, properties[1].value().value()); + assertEquals("[[IteratorKind]]", properties[2].name()); + assertEquals(kind, properties[2].value().value()); +} + var o1 = { foo: 1 }; var o2 = { foo: 2 }; @@ -47,6 +63,11 @@ testIteratorMirror(map.keys(), 0, [41], 1); testIteratorMirror(map.values(), 0, [42], 1); testIteratorMirror(map.entries(), 0, [[41, 42]], 1); +testIteratorInternalProperties(map.keys(), 0, "keys", 0, true); +testIteratorInternalProperties(map.values(), 1, "values", 1, true); +testIteratorInternalProperties(map.entries(), 2, "entries", 2, false); +testIteratorInternalProperties(map.keys(), 3, "keys", 2, false); + var set = new Set(); set.add(41); set.add(42); @@ -73,3 +94,10 @@ testIteratorMirror(set.entries(), 5, []); testIteratorMirror(set.keys(), 1, [42, o1], 2); testIteratorMirror(set.values(), 1, [42, o1], 2); testIteratorMirror(set.entries(), 1, [[42, 42], [o1, o1]], 2); + +testIteratorInternalProperties(set.keys(), 0, "values", 0, true); +testIteratorInternalProperties(set.values(), 1, "values", 1, true); +testIteratorInternalProperties(set.entries(), 2, "entries", 2, true); +testIteratorInternalProperties(set.keys(), 3, "values", 3, true); +testIteratorInternalProperties(set.values(), 4, "values", 4, false); +testIteratorInternalProperties(set.entries(), 5, "entries", 4, false); -- 2.7.4