Commit 81a10167 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Expose promise status through promise mirror.

R=aandrey@chromium.org, rossberg@chromium.org, yurys@chromium.org
BUG=v8:3093
LOG=Y

Review URL: https://codereview.chromium.org/257803005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20988 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ce14ab97
...@@ -42,6 +42,18 @@ function ClearMirrorCache() { ...@@ -42,6 +42,18 @@ function ClearMirrorCache() {
} }
// Wrapper to check whether an object is a Promise. The call may not work
// if promises are not enabled.
// TODO(yangguo): remove this wrapper once promises are enabled by default.
function ObjectIsPromise(value) {
try {
return %IsPromise(value);
} catch (e) {
return false;
}
}
/** /**
* Returns the mirror for a specified value or object. * Returns the mirror for a specified value or object.
* *
...@@ -90,6 +102,8 @@ function MakeMirror(value, opt_transient) { ...@@ -90,6 +102,8 @@ function MakeMirror(value, opt_transient) {
mirror = new ErrorMirror(value); mirror = new ErrorMirror(value);
} else if (IS_SCRIPT(value)) { } else if (IS_SCRIPT(value)) {
mirror = new ScriptMirror(value); mirror = new ScriptMirror(value);
} else if (ObjectIsPromise(value)) {
mirror = new PromiseMirror(value);
} else { } else {
mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient); mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient);
} }
...@@ -159,6 +173,7 @@ var FRAME_TYPE = 'frame'; ...@@ -159,6 +173,7 @@ var FRAME_TYPE = 'frame';
var SCRIPT_TYPE = 'script'; var SCRIPT_TYPE = 'script';
var CONTEXT_TYPE = 'context'; var CONTEXT_TYPE = 'context';
var SCOPE_TYPE = 'scope'; var SCOPE_TYPE = 'scope';
var PROMISE_TYPE = 'promise';
// Maximum length when sending strings through the JSON protocol. // Maximum length when sending strings through the JSON protocol.
var kMaxProtocolStringLength = 80; var kMaxProtocolStringLength = 80;
...@@ -212,6 +227,7 @@ var ScopeType = { Global: 0, ...@@ -212,6 +227,7 @@ var ScopeType = { Global: 0,
// - DateMirror // - DateMirror
// - RegExpMirror // - RegExpMirror
// - ErrorMirror // - ErrorMirror
// - PromiseMirror
// - PropertyMirror // - PropertyMirror
// - InternalPropertyMirror // - InternalPropertyMirror
// - FrameMirror // - FrameMirror
...@@ -350,6 +366,15 @@ Mirror.prototype.isError = function() { ...@@ -350,6 +366,15 @@ Mirror.prototype.isError = function() {
}; };
/**
* Check whether the mirror reflects a promise.
* @returns {boolean} True if the mirror reflects a promise
*/
Mirror.prototype.isPromise = function() {
return this instanceof PromiseMirror;
};
/** /**
* Check whether the mirror reflects a property. * Check whether the mirror reflects a property.
* @returns {boolean} True if the mirror reflects a property * @returns {boolean} True if the mirror reflects a property
...@@ -637,9 +662,9 @@ ObjectMirror.prototype.propertyNames = function(kind, limit) { ...@@ -637,9 +662,9 @@ ObjectMirror.prototype.propertyNames = function(kind, limit) {
// Find all the named properties. // Find all the named properties.
if (kind & PropertyKind.Named) { if (kind & PropertyKind.Named) {
// Get all the local property names. // Get all the local property names except for private symbols.
propertyNames = propertyNames =
%GetLocalPropertyNames(this.value_, PROPERTY_ATTRIBUTES_NONE); %GetLocalPropertyNames(this.value_, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
total += propertyNames.length; total += propertyNames.length;
// Get names for named interceptor properties if any. // Get names for named interceptor properties if any.
...@@ -1171,6 +1196,26 @@ ErrorMirror.prototype.toText = function() { ...@@ -1171,6 +1196,26 @@ ErrorMirror.prototype.toText = function() {
}; };
/**
* Mirror object for a Promise object.
* @param {Object} data The Promise object
* @constructor
* @extends Mirror
*/
function PromiseMirror(value) {
%_CallFunction(this, value, PROMISE_TYPE, ObjectMirror);
}
inherits(PromiseMirror, ObjectMirror);
PromiseMirror.prototype.status = function() {
var status = %GetPromiseStatus(this.value_);
if (status == 0) return "pending";
if (status == 1) return "resolved";
return "rejected";
};
/** /**
* Base mirror object for properties. * Base mirror object for properties.
* @param {ObjectMirror} mirror The mirror object having this property * @param {ObjectMirror} mirror The mirror object having this property
...@@ -2350,6 +2395,7 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference, ...@@ -2350,6 +2395,7 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
case FUNCTION_TYPE: case FUNCTION_TYPE:
case ERROR_TYPE: case ERROR_TYPE:
case REGEXP_TYPE: case REGEXP_TYPE:
case PROMISE_TYPE:
// Add object representation. // Add object representation.
this.serializeObject_(mirror, content, details); this.serializeObject_(mirror, content, details);
break; break;
...@@ -2452,7 +2498,6 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, ...@@ -2452,7 +2498,6 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
content.indexedInterceptor = true; content.indexedInterceptor = true;
} }
// Add function specific properties.
if (mirror.isFunction()) { if (mirror.isFunction()) {
// Add function specific properties. // Add function specific properties.
content.name = mirror.name(); content.name = mirror.name();
...@@ -2480,12 +2525,16 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, ...@@ -2480,12 +2525,16 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
} }
} }
// Add date specific properties.
if (mirror.isDate()) { if (mirror.isDate()) {
// Add date specific properties. // Add date specific properties.
content.value = mirror.value(); content.value = mirror.value();
} }
if (mirror.isPromise()) {
// Add promise specific properties.
content.status = mirror.status();
}
// Add actual properties - named properties followed by indexed properties. // Add actual properties - named properties followed by indexed properties.
var propertyNames = mirror.propertyNames(PropertyKind.Named); var propertyNames = mirror.propertyNames(PropertyKind.Named);
var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed); var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
......
...@@ -338,3 +338,20 @@ function SetUpPromise() { ...@@ -338,3 +338,20 @@ function SetUpPromise() {
} }
SetUpPromise(); SetUpPromise();
// Functions to expose promise details to the debugger.
function GetPromiseStatus(promise) {
return GET_PRIVATE(promise, promiseStatus);
}
function GetPromiseOnResolve(promise) {
return GET_PRIVATE(promise, promiseOnResolve);
}
function GetPromiseOnReject(promise) {
return GET_PRIVATE(promise, promiseOnReject);
}
function GetPromiseValue(promise) {
return GET_PRIVATE(promise, promiseValue);
}
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-debug-as debug --harmony-promises
// Test the mirror object for promises.
function MirrorRefCache(json_refs) {
var tmp = eval('(' + json_refs + ')');
this.refs_ = [];
for (var i = 0; i < tmp.length; i++) {
this.refs_[tmp[i].handle] = tmp[i];
}
}
MirrorRefCache.prototype.lookup = function(handle) {
return this.refs_[handle];
}
function testPromiseMirror(promise, status) {
// Create mirror and JSON representation.
var mirror = debug.MakeMirror(promise);
var serializer = debug.MakeMirrorSerializer();
var json = JSON.stringify(serializer.serializeValue(mirror));
var refs = new MirrorRefCache(
JSON.stringify(serializer.serializeReferencedObjects()));
// Check the mirror hierachy.
assertTrue(mirror instanceof debug.Mirror);
assertTrue(mirror instanceof debug.ValueMirror);
assertTrue(mirror instanceof debug.ObjectMirror);
assertTrue(mirror instanceof debug.PromiseMirror);
// Check the mirror properties.
assertEquals(status, mirror.status());
assertTrue(mirror.isPromise());
assertEquals('promise', mirror.type());
assertFalse(mirror.isPrimitive());
assertEquals("Object", mirror.className());
assertEquals("#<Promise>", mirror.toText());
assertSame(promise, mirror.value());
// Parse JSON representation and check.
var fromJSON = eval('(' + json + ')');
assertEquals('promise', fromJSON.type);
assertEquals('Object', fromJSON.className);
assertEquals('function', refs.lookup(fromJSON.constructorFunction.ref).type);
assertEquals('Promise', refs.lookup(fromJSON.constructorFunction.ref).name);
assertEquals(status, fromJSON.status);
}
// Test a number of different promises.
var resolved = new Promise(function(resolve, reject) { resolve() });
var rejected = new Promise(function(resolve, reject) { reject() });
var pending = new Promise(function(resolve, reject) {});
testPromiseMirror(resolved, "resolved");
testPromiseMirror(rejected, "rejected");
testPromiseMirror(pending, "pending");
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