From: yangguo@chromium.org Date: Wed, 23 Jul 2014 07:33:47 +0000 (+0000) Subject: Expose the content of Sets and WeakSets through SetMirror. X-Git-Tag: upstream/4.7.83~8104 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c3edd49265626fff8f923175d10b2dd2d3e8a2af;p=platform%2Fupstream%2Fv8.git Expose the content of Sets and WeakSets through SetMirror. BUG=v8:3093 LOG=Y R=aandrey@chromium.org, arv@chromium.org, yangguo@chromium.org Review URL: https://codereview.chromium.org/402423003 Patch from Alexandra Mikhaylova . git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22541 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js index e717f6e..35f34a9 100644 --- a/src/mirror-debugger.js +++ b/src/mirror-debugger.js @@ -83,6 +83,8 @@ function MakeMirror(value, opt_transient) { mirror = new ScriptMirror(value); } else if (IS_MAP(value) || IS_WEAKMAP(value)) { mirror = new MapMirror(value); + } else if (IS_SET(value) || IS_WEAKSET(value)) { + mirror = new SetMirror(value); } else if (ObjectIsPromise(value)) { mirror = new PromiseMirror(value); } else { @@ -158,6 +160,7 @@ var CONTEXT_TYPE = 'context'; var SCOPE_TYPE = 'scope'; var PROMISE_TYPE = 'promise'; var MAP_TYPE = 'map'; +var SET_TYPE = 'set'; // Maximum length when sending strings through the JSON protocol. var kMaxProtocolStringLength = 80; @@ -214,6 +217,7 @@ var ScopeType = { Global: 0, // - ErrorMirror // - PromiseMirror // - MapMirror +// - SetMirror // - PropertyMirror // - InternalPropertyMirror // - FrameMirror @@ -434,6 +438,15 @@ Mirror.prototype.isMap = function() { /** + * Check whether the mirror reflects a set. + * @returns {boolean} True if the mirror reflects a set + */ +Mirror.prototype.isSet = function() { + return this instanceof SetMirror; +}; + + +/** * Allocate a handle id for this object. */ Mirror.prototype.allocateHandle_ = function() { @@ -1304,6 +1317,33 @@ MapMirror.prototype.entries = function() { }; +function SetMirror(value) { + %_CallFunction(this, value, SET_TYPE, ObjectMirror); +} +inherits(SetMirror, ObjectMirror); + + +/** + * Returns an array of elements of a set. + * This will keep elements alive for WeakSets. + * + * @returns {Array.} Array of elements of a set. + */ +SetMirror.prototype.values = function() { + if (IS_WEAKSET(this.value_)) { + return %GetWeakSetValues(this.value_); + } + + var result = []; + var iter = %_CallFunction(this.value_, builtins.SetValues); + var next; + while (!(next = iter.next()).done) { + result.push(next.value); + } + return result; +}; + + /** * Base mirror object for properties. * @param {ObjectMirror} mirror The mirror object having this property diff --git a/src/runtime.cc b/src/runtime.cc index abf9c4e..61e1069 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1798,6 +1798,28 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { } +RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { + HandleScope scope(isolate); + ASSERT(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); + Handle table(ObjectHashTable::cast(holder->table())); + Handle values = + isolate->factory()->NewFixedArray(table->NumberOfElements()); + { + DisallowHeapAllocation no_gc; + int number_of_non_hole_elements = 0; + for (int i = 0; i < table->Capacity(); i++) { + Handle key(table->KeyAt(i), isolate); + if (table->IsKey(*key)) { + values->set(number_of_non_hole_elements++, *key); + } + } + ASSERT_EQ(table->NumberOfElements(), number_of_non_hole_elements); + } + return *isolate->factory()->NewJSArrayWithElements(values); +} + + RUNTIME_FUNCTION(Runtime_ClassOf) { SealHandleScope shs(isolate); ASSERT(args.length() == 1); diff --git a/src/runtime.h b/src/runtime.h index 791fdba..e6bdd15 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -298,6 +298,7 @@ namespace internal { F(WeakCollectionSet, 3, 1) \ \ F(GetWeakMapEntries, 1, 1) \ + F(GetWeakSetValues, 1, 1) \ \ /* Harmony events */ \ F(EnqueueMicrotask, 1, 1) \ diff --git a/test/mjsunit/harmony/mirror-collections.js b/test/mjsunit/harmony/mirror-collections.js index 9df5b68..271cf91 100644 --- a/test/mjsunit/harmony/mirror-collections.js +++ b/test/mjsunit/harmony/mirror-collections.js @@ -22,6 +22,24 @@ function testMapMirror(mirror) { assertEquals('map', fromJSON.type); } +function testSetMirror(mirror) { + // Create JSON representation. + var serializer = debug.MakeMirrorSerializer(); + var json = JSON.stringify(serializer.serializeValue(mirror)); + + // Check the mirror hierachy. + assertTrue(mirror instanceof debug.Mirror); + assertTrue(mirror instanceof debug.ValueMirror); + assertTrue(mirror instanceof debug.ObjectMirror); + assertTrue(mirror instanceof debug.SetMirror); + + assertTrue(mirror.isSet()); + + // Parse JSON representation and check. + var fromJSON = eval('(' + json + ')'); + assertEquals('set', fromJSON.type); +} + var o1 = new Object(); var o2 = new Object(); var o3 = new Object(); @@ -50,6 +68,19 @@ assertSame(o2, entries[1].value); assertEquals(undefined, entries[2].key); assertEquals(44, entries[2].value); +// Test the mirror object for Sets +var set = new Set(); +set.add(o1); +set.add(o2); +set.delete(o1); +set.add(undefined); +var setMirror = debug.MakeMirror(set); +testSetMirror(setMirror); +var values = setMirror.values(); +assertEquals(2, values.length); +assertSame(o2, values[0]); +assertEquals(undefined, values[1]); + // Test the mirror object for WeakMaps var weakMap = new WeakMap(); weakMap.set(o1, 11); @@ -80,3 +111,34 @@ function testWeakMapEntries(weakMapMirror) { } testWeakMapEntries(weakMapMirror); + +// Test the mirror object for WeakSets +var weakSet = new WeakSet(); +weakSet.add(o1); +weakSet.add(new Object()); +weakSet.add(o2); +weakSet.add(new Object()); +weakSet.add(new Object()); +weakSet.add(o3); +weakSet.delete(o2); +var weakSetMirror = debug.MakeMirror(weakSet); +testSetMirror(weakSetMirror); +assertTrue(weakSetMirror.values().length <= 5); +gc(); + +function testWeakSetValues(weakSetMirror) { + var values = weakSetMirror.values(); + assertEquals(2, values.length); + var found = 0; + for (var i = 0; i < values.length; i++) { + if (Object.is(values[i], o1)) { + found++; + } + if (Object.is(values[i], o3)) { + found++; + } + } + assertEquals(2, found); +} + +testWeakSetValues(weakSetMirror); diff --git a/test/mjsunit/runtime-gen/getweaksetvalues.js b/test/mjsunit/runtime-gen/getweaksetvalues.js new file mode 100644 index 0000000..e344723 --- /dev/null +++ b/test/mjsunit/runtime-gen/getweaksetvalues.js @@ -0,0 +1,5 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY +// Flags: --allow-natives-syntax --harmony +var _holder = new WeakMap(); +%GetWeakSetValues(_holder); diff --git a/tools/generate-runtime-tests.py b/tools/generate-runtime-tests.py index 6b99a47..dd32213 100755 --- a/tools/generate-runtime-tests.py +++ b/tools/generate-runtime-tests.py @@ -47,11 +47,11 @@ EXPAND_MACROS = [ # that the parser doesn't bit-rot. Change the values as needed when you add, # remove or change runtime functions, but make sure we don't lose our ability # to parse them! -EXPECTED_FUNCTION_COUNT = 419 -EXPECTED_FUZZABLE_COUNT = 334 +EXPECTED_FUNCTION_COUNT = 420 +EXPECTED_FUZZABLE_COUNT = 335 EXPECTED_CCTEST_COUNT = 8 EXPECTED_UNKNOWN_COUNT = 4 -EXPECTED_BUILTINS_COUNT = 812 +EXPECTED_BUILTINS_COUNT = 813 # Don't call these at all.