Commit b7ff2bd5 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.

drive-by-fix: use IS_PROXY if possible in .js files.

BUG=v8:1543
LOG=n

Committed: https://crrev.com/8bfb7189a3472bc9d0820a1bd4534eaaf78ff847
Cr-Commit-Position: refs/heads/master@{#32985}

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

Cr-Commit-Position: refs/heads/master@{#33010}
parent b00d9e25
......@@ -8,11 +8,28 @@
// Used by the d8 shell to output results.
var stringifyDepthLimit = 4; // To avoid crashing on cyclic objects
// Hacky solution to circumvent forcing --allow-natives-syntax for d8
function isProxy(o) { return false };
function JSProxyGetTarget(proxy) { };
function JSProxyGetHandler(proxy) { };
try {
isProxy = Function(['object'], 'return %_IsJSProxy(object)');
JSProxyGetTarget = Function(['proxy'],
'return %JSProxyGetTarget(proxy)');
JSProxyGetHandler = Function(['proxy'],
'return %JSProxyGetHandler(proxy)');
} catch(e) {};
function Stringify(x, depth) {
if (depth === undefined)
depth = stringifyDepthLimit;
else if (depth === 0)
return "*";
return "...";
if (isProxy(x)) {
return StringifyProxy(x, depth);
}
switch (typeof x) {
case "undefined":
return "undefined";
......@@ -63,3 +80,12 @@ function Stringify(x, depth) {
return "[crazy non-standard value]";
}
}
function StringifyProxy(proxy, depth) {
var proxy_type = typeof proxy;
var info_object = {
target: JSProxyGetTarget(proxy),
handler: JSProxyGetHandler(proxy)
}
return '[' + proxy_type + ' Proxy ' + Stringify(info_object, 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));
......
......@@ -841,7 +841,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)};
}
// -------------------------------------------------------------------
......
......@@ -486,11 +486,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;
......@@ -524,7 +524,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) {
......@@ -747,7 +747,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);
......
......@@ -539,8 +539,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