Expose internal properties of map/set iterators via mirrors.
authorAndrey Adaikin <aandrey@chromium.org>
Mon, 17 Nov 2014 12:48:11 +0000 (15:48 +0300)
committerAndrey Adaikin <aandrey@chromium.org>
Mon, 17 Nov 2014 12:48:29 +0000 (12:48 +0000)
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
src/runtime/runtime-collections.cc
src/runtime/runtime.h
test/mjsunit/es6/mirror-iterators.js

index c8d2461..6cec646 100644 (file)
@@ -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]]",
index de1619e..e6a86d1 100644 (file)
@@ -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<FixedArray> 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<FixedArray> 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);
index d353fda..4bc8fdf 100644 (file)
@@ -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)                    \
index cc0b1e4..22ce424 100644 (file)
@@ -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);