Commit c3edd492 authored by yangguo@chromium.org's avatar yangguo@chromium.org

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 <amikhaylova@google.com>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22541 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ed04566c
......@@ -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
......@@ -433,6 +437,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.
*/
......@@ -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.<Object>} 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
......
......@@ -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<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
Handle<FixedArray> 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<Object> 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);
......
......@@ -298,6 +298,7 @@ namespace internal {
F(WeakCollectionSet, 3, 1) \
\
F(GetWeakMapEntries, 1, 1) \
F(GetWeakSetValues, 1, 1) \
\
/* Harmony events */ \
F(EnqueueMicrotask, 1, 1) \
......
......@@ -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);
// 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);
......@@ -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.
......
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