Commit 8bfb7189 authored by cbruni's avatar cbruni Committed by Commit bot

[proxies] Better print for proxies in d8

Function proxies would not be printed so far since they ended up in Function.prototype.toString which only works with Function as a receiver but no Proxy. Additionally added support for more gracefully dealing with recursive __proto__ structures introduced by proxies.

BUG=v8:1543
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#32985}
parent dcac1f14
......@@ -13,6 +13,9 @@ function Stringify(x, depth) {
depth = stringifyDepthLimit;
else if (depth === 0)
return "*";
if (IS_PROXY(x)) {
return StringifyProxy(x, depth);
}
switch (typeof x) {
case "undefined":
return "undefined";
......@@ -26,40 +29,56 @@ function Stringify(x, depth) {
return x.toString();
case "object":
if (IS_NULL(x)) return "null";
if (x.constructor && x.constructor.name === "Array") {
var elems = [];
for (var i = 0; i < x.length; ++i) {
elems.push(
{}.hasOwnProperty.call(x, i) ? Stringify(x[i], depth - 1) : "");
}
return "[" + elems.join(", ") + "]";
}
try {
var string = String(x);
if (string && string !== "[object Object]") return string;
} catch(e) {}
var props = [];
var names = Object.getOwnPropertyNames(x);
names = names.concat(Object.getOwnPropertySymbols(x));
for (var i in names) {
var name = names[i];
var desc = Object.getOwnPropertyDescriptor(x, name);
if (IS_UNDEFINED(desc)) continue;
if (IS_SYMBOL(name)) name = "[" + Stringify(name) + "]";
if ("value" in desc) {
props.push(name + ": " + Stringify(desc.value, depth - 1));
}
if (desc.get) {
var getter = Stringify(desc.get);
props.push("get " + name + getter.slice(getter.indexOf('(')));
}
if (desc.set) {
var setter = Stringify(desc.set);
props.push("set " + name + setter.slice(setter.indexOf('(')));
}
return StringifyObject(x, depth);
} catch(RangeError) {
return "{*}"
}
return "{" + props.join(", ") + "}";
default:
return "[crazy non-standard value]";
}
}
function StringifyObject(x, depth) {
if (x.constructor && x.constructor.name === "Array") {
var elems = [];
for (var i = 0; i < x.length; ++i) {
elems.push(
{}.hasOwnProperty.call(x, i) ? Stringify(x[i], depth - 1) : "");
}
return "[" + elems.join(", ") + "]";
}
try {
var string = String(x);
if (string && string !== "[object Object]") return string;
} catch(e) {}
var props = [];
var names = Object.getOwnPropertyNames(x);
names = names.concat(Object.getOwnPropertySymbols(x));
for (var i in names) {
var name = names[i];
var desc = Object.getOwnPropertyDescriptor(x, name);
if (IS_UNDEFINED(desc)) continue;
if (IS_SYMBOL(name)) name = "[" + Stringify(name) + "]";
if ("value" in desc) {
props.push(name + ": " + Stringify(desc.value, depth - 1));
}
if (desc.get) {
var getter = Stringify(desc.get);
props.push("get " + name + getter.slice(getter.indexOf('(')));
}
if (desc.set) {
var setter = Stringify(desc.set);
props.push("set " + name + setter.slice(setter.indexOf('(')));
}
}
return "{" + props.join(", ") + "}";
}
function StringifyProxy(proxy, depth) {
var proxy_type = typeof proxy;
return '[' + proxy_type + ' Proxy ' + Stringify({
target: %JSProxyGetTarget(proxy),
handler: %JSProxyGetHandler(proxy)
}, depth-1) + ']';
}
......@@ -100,7 +100,7 @@ function GetExistingHash(key) {
if ((field & 1 /* Name::kHashNotComputedMask */) === 0) {
return field >>> 2 /* Name::kHashShift */;
}
} else if (IS_RECEIVER(key) && !%_IsJSProxy(key) && !IS_GLOBAL(key)) {
} else if (IS_RECEIVER(key) && !IS_PROXY(key) && !IS_GLOBAL(key)) {
var hash = GET_PRIVATE(key, hashCodeSymbol);
return hash;
}
......
......@@ -188,7 +188,7 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
function JSONStringify(value, replacer, space) {
if (%_ArgumentsLength() == 1 && !%_IsJSProxy(value)) {
if (%_ArgumentsLength() == 1 && !IS_PROXY(value)) {
return %BasicJSONStringify(value);
}
if (!IS_CALLABLE(replacer) && %is_arraylike(replacer)) {
......
......@@ -88,37 +88,38 @@ define STRING_TO_REGEXP_CACHE_ID = 0;
# Note: We have special support for typeof(foo) === 'bar' in the compiler.
# It will *not* generate a runtime typeof call for the most important
# values of 'bar'.
macro IS_NULL(arg) = (arg === null);
macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
macro IS_UNDEFINED(arg) = (arg === (void 0));
macro IS_NUMBER(arg) = (typeof(arg) === 'number');
macro IS_STRING(arg) = (typeof(arg) === 'string');
macro IS_BOOLEAN(arg) = (typeof(arg) === 'boolean');
macro IS_SYMBOL(arg) = (typeof(arg) === 'symbol');
macro IS_OBJECT(arg) = (typeof(arg) === 'object');
macro IS_ARRAY(arg) = (%_IsArray(arg));
macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === 'ArrayBuffer');
macro IS_BOOLEAN(arg) = (typeof(arg) === 'boolean');
macro IS_BOOLEAN_WRAPPER(arg) = (%_ClassOf(arg) === 'Boolean');
macro IS_DATAVIEW(arg) = (%_ClassOf(arg) === 'DataView');
macro IS_DATE(arg) = (%_IsDate(arg));
macro IS_ERROR(arg) = (%_ClassOf(arg) === 'Error');
macro IS_FUNCTION(arg) = (%_IsFunction(arg));
macro IS_REGEXP(arg) = (%_IsRegExp(arg));
macro IS_SIMD_VALUE(arg) = (%_IsSimdValue(arg));
macro IS_SET(arg) = (%_ClassOf(arg) === 'Set');
macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator');
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
macro IS_MAP(arg) = (%_ClassOf(arg) === 'Map');
macro IS_WEAKMAP(arg) = (%_ClassOf(arg) === 'WeakMap');
macro IS_WEAKSET(arg) = (%_ClassOf(arg) === 'WeakSet');
macro IS_MAP_ITERATOR(arg) = (%_ClassOf(arg) === 'Map Iterator');
macro IS_NULL(arg) = (arg === null);
macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
macro IS_NUMBER(arg) = (typeof(arg) === 'number');
macro IS_NUMBER_WRAPPER(arg) = (%_ClassOf(arg) === 'Number');
macro IS_STRING_WRAPPER(arg) = (%_ClassOf(arg) === 'String');
macro IS_SYMBOL_WRAPPER(arg) = (%_ClassOf(arg) === 'Symbol');
macro IS_BOOLEAN_WRAPPER(arg) = (%_ClassOf(arg) === 'Boolean');
macro IS_ERROR(arg) = (%_ClassOf(arg) === 'Error');
macro IS_OBJECT(arg) = (typeof(arg) === 'object');
macro IS_PROXY(arg) = (%_IsJSProxy(arg));
macro IS_REGEXP(arg) = (%_IsRegExp(arg));
macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script');
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === 'ArrayBuffer');
macro IS_DATAVIEW(arg) = (%_ClassOf(arg) === 'DataView');
macro IS_SHAREDARRAYBUFFER(arg) = (%_ClassOf(arg) === 'SharedArrayBuffer');
macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator');
macro IS_SET(arg) = (%_ClassOf(arg) === 'Set');
macro IS_SET_ITERATOR(arg) = (%_ClassOf(arg) === 'Set Iterator');
macro IS_MAP_ITERATOR(arg) = (%_ClassOf(arg) === 'Map Iterator');
macro IS_SHAREDARRAYBUFFER(arg) = (%_ClassOf(arg) === 'SharedArrayBuffer');
macro IS_SIMD_VALUE(arg) = (%_IsSimdValue(arg));
macro IS_STRING(arg) = (typeof(arg) === 'string');
macro IS_STRING_WRAPPER(arg) = (%_ClassOf(arg) === 'String');
macro IS_STRONG(arg) = (%IsStrong(arg));
macro IS_SYMBOL(arg) = (typeof(arg) === 'symbol');
macro IS_SYMBOL_WRAPPER(arg) = (%_ClassOf(arg) === 'Symbol');
macro IS_UNDEFINED(arg) = (arg === (void 0));
macro IS_WEAKMAP(arg) = (%_ClassOf(arg) === 'WeakMap');
macro IS_WEAKSET(arg) = (%_ClassOf(arg) === 'WeakSet');
# Macro for ES queries of the type: "Type(O) is Object."
macro IS_RECEIVER(arg) = (%_IsJSReceiver(arg));
......
......@@ -843,7 +843,7 @@ function FormatStackTrace(obj, raw_stack) {
function GetTypeName(receiver, requireConstructor) {
if (IS_NULL_OR_UNDEFINED(receiver)) return null;
if (%_IsJSProxy(receiver)) return "Proxy";
if (IS_PROXY(receiver)) return "Proxy";
var constructor = %GetDataProperty(TO_OBJECT(receiver), "constructor");
if (!IS_FUNCTION(constructor)) {
......
......@@ -192,7 +192,7 @@ function ObserverIsActive(observer, objectInfo) {
function ObjectInfoGetOrCreate(object) {
var objectInfo = ObjectInfoGet(object);
if (IS_UNDEFINED(objectInfo)) {
if (!%_IsJSProxy(object)) {
if (!IS_PROXY(object)) {
%SetIsObserved(object);
}
objectInfo = {
......
......@@ -22,7 +22,7 @@ utils.Import(function(from) {
function ProxyCreateRevocable(target, handler) {
var p = new GlobalProxy(target, handler);
return {proxy: p, revoke: () => %RevokeProxy(p)};
return {proxy: p, revoke: () => %JSProxyRevoke(p)};
}
// -------------------------------------------------------------------
......
......@@ -500,11 +500,11 @@ function CallTrap2(handler, name, defaultTrap, x, y) {
// ObjectGetOwnPropertyDescriptor and delete this.
function GetOwnPropertyJS(obj, v) {
var p = TO_NAME(v);
if (%_IsJSProxy(obj)) {
if (IS_PROXY(obj)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(v)) return UNDEFINED;
var handler = %GetHandler(obj);
var handler = %JSProxyGetHandler(obj);
var descriptor = CallTrap1(
handler, "getOwnPropertyDescriptor", UNDEFINED, p);
if (IS_UNDEFINED(descriptor)) return descriptor;
......@@ -538,7 +538,7 @@ function DefineProxyProperty(obj, p, attributes, should_throw) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(p)) return false;
var handler = %GetHandler(obj);
var handler = %JSProxyGetHandler(obj);
var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes);
if (!result) {
if (should_throw) {
......@@ -761,7 +761,7 @@ function DefineArrayProperty(obj, p, desc, should_throw) {
// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
function DefineOwnProperty(obj, p, desc, should_throw) {
if (%_IsJSProxy(obj)) {
if (IS_PROXY(obj)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(p)) return false;
......
......@@ -149,7 +149,7 @@ RUNTIME_FUNCTION(Runtime_IsJSProxy) {
}
RUNTIME_FUNCTION(Runtime_GetHandler) {
RUNTIME_FUNCTION(Runtime_JSProxyGetHandler) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
......@@ -157,7 +157,15 @@ RUNTIME_FUNCTION(Runtime_GetHandler) {
}
RUNTIME_FUNCTION(Runtime_RevokeProxy) {
RUNTIME_FUNCTION(Runtime_JSProxyGetTarget) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
return proxy->target();
}
RUNTIME_FUNCTION(Runtime_JSProxyRevoke) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
......
......@@ -543,8 +543,9 @@ namespace internal {
F(IsJSProxy, 1, 1) \
F(JSProxyCall, -1 /* >= 2 */, 1) \
F(JSProxyConstruct, -1 /* >= 3 */, 1) \
F(GetHandler, 1, 1) \
F(RevokeProxy, 1, 1)
F(JSProxyGetTarget, 1, 1) \
F(JSProxyGetHandler, 1, 1) \
F(JSProxyRevoke, 1, 1)
#define FOR_EACH_INTRINSIC_REGEXP(F) \
F(StringReplaceGlobalRegExpWithString, 4, 1) \
......
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