Skip to content

Commit 3ff7a74

Browse files
committed
[GR-32016] Correction of Object/Array.prototype.toString(proxyObject).
PullRequest: js/2033
2 parents b5fbaf6 + 66677ad commit 3ff7a74

File tree

5 files changed

+66
-15
lines changed

5 files changed

+66
-15
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
6+
*/
7+
8+
/**
9+
* Tests of Object/Array.prototype.toString on proxy objects.
10+
*/
11+
12+
load('assert.js');
13+
14+
// Ensure that Array.prototype.toString invokes Object.prototype.toString
15+
delete Array.prototype.join;
16+
17+
[Object.prototype.toString, Array.prototype.toString].forEach(function (testedFunction) {
18+
// Proxy does not inherit [[ParameterMap]], [[ErrorData]], [[BooleanData]],
19+
// [[NumberData]], [[StringData]], [[DateValue]] and [[RegExpMatcher]] internal slots
20+
var argumentsObject = (function() { return arguments; })();
21+
assertSame('[object Object]', testedFunction.call(new Proxy(argumentsObject, {})));
22+
assertSame('[object Object]', testedFunction.call(new Proxy(new Error(), {})));
23+
assertSame('[object Object]', testedFunction.call(new Proxy(Object(true), {})));
24+
assertSame('[object Object]', testedFunction.call(new Proxy(Object(42), {})));
25+
assertSame('[object Object]', testedFunction.call(new Proxy(Object('foo'), {})));
26+
assertSame('[object Object]', testedFunction.call(new Proxy(new Date(), {})));
27+
assertSame('[object Object]', testedFunction.call(new Proxy(/a/, {})));
28+
29+
// Proxy inherits [[Call]] internal slot
30+
assertSame('[object Function]', testedFunction.call(new Proxy(function() {}, {})));
31+
32+
// There is an explicit handling of array Proxy targets in Object.prototype.toString
33+
assertSame('[object Array]', testedFunction.call(new Proxy([], {})));
34+
// revoked
35+
var revocable = Proxy.revocable([], {});
36+
revocable.revoke();
37+
assertThrows(function() {
38+
testedFunction.call(revocable.proxy);
39+
}, TypeError);
40+
// revoked too late (after builtinTag was determined)
41+
revocable = Proxy.revocable([], {
42+
get: function (target, key, receiver) {
43+
if (key === Symbol.toStringTag) {
44+
revocable.revoke();
45+
return undefined;
46+
} else {
47+
return Reflect.get(target, key, receiver);
48+
}
49+
},
50+
});
51+
assertSame('[object Array]', testedFunction.call(revocable.proxy));
52+
});

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/ObjectPrototypeBuiltins.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@
8585
import com.oracle.truffle.js.runtime.builtins.BuiltinEnum;
8686
import com.oracle.truffle.js.runtime.builtins.JSClass;
8787
import com.oracle.truffle.js.runtime.builtins.JSOrdinary;
88-
import com.oracle.truffle.js.runtime.builtins.JSProxy;
8988
import com.oracle.truffle.js.runtime.objects.JSLazyString;
9089
import com.oracle.truffle.js.runtime.objects.JSObject;
9190
import com.oracle.truffle.js.runtime.objects.Null;
@@ -309,12 +308,13 @@ protected String doJSObject(DynamicObject thisObj,
309308
@Specialization(guards = "isJSProxy(thisObj)")
310309
protected String doJSProxy(DynamicObject thisObj,
311310
@Shared("builtinTag") @Cached("create()") GetBuiltinToStringTagNode getBuiltinToStringTagNode) {
312-
Object target = JSProxy.getTargetNonProxy(thisObj);
313-
String toString = getToStringTag(thisObj);
314-
if (toString == null) {
315-
toString = getBuiltinToStringTagNode.execute(target);
311+
// builtinTag must be read before tag because the latter may revoke the proxy
312+
String builtinTag = getBuiltinToStringTagNode.execute(thisObj);
313+
String tag = getToStringTag(thisObj);
314+
if (tag == null) {
315+
tag = builtinTag;
316316
}
317-
return formatString(toString);
317+
return formatString(tag);
318318
}
319319

320320
@Specialization(guards = "isJSNull(thisObj)")

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/builtins/JSClass.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,13 @@ public String defaultToString(DynamicObject object) {
244244
}
245245

246246
protected String getToStringTag(DynamicObject object) {
247-
String result = null;
247+
String result = getBuiltinToStringTag(object);
248248
if (JSRuntime.isObject(object)) {
249249
Object toStringTag = JSObject.get(object, Symbol.SYMBOL_TO_STRING_TAG);
250250
if (JSRuntime.isString(toStringTag)) {
251251
result = JSRuntime.toStringIsString(toStringTag);
252252
}
253253
}
254-
if (result == null) {
255-
result = getBuiltinToStringTag(object);
256-
}
257254
return result;
258255
}
259256

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/builtins/JSProxy.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,13 @@ public boolean isExtensible(DynamicObject thisObj) {
548548
public String getBuiltinToStringTag(DynamicObject object) {
549549
Object targetNonProxy = getTargetNonProxy(object);
550550
if (JSDynamicObject.isJSDynamicObject(targetNonProxy)) {
551-
return JSObject.getJSClass((DynamicObject) targetNonProxy).getBuiltinToStringTag((DynamicObject) targetNonProxy);
551+
if (JSArray.isJSArray(targetNonProxy)) {
552+
return JSArray.CLASS_NAME;
553+
} else if (JSFunction.isJSFunction(targetNonProxy)) {
554+
return JSFunction.CLASS_NAME;
555+
} else {
556+
return "Object";
557+
}
552558
} else {
553559
return "Foreign";
554560
}

graal-js/test/test262.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
"filePath" : "annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js",
44
"status" : "FAIL",
55
"comment" : "new failures 2020-11-23"
6-
}, {
7-
"filePath" : "built-ins/Array/prototype/toString/non-callable-join-string-tag.js",
8-
"status" : "FAIL",
9-
"comment" : "new failures 2021-05-27"
106
}, {
117
"filePath" : "built-ins/Atomics/wait/bigint/no-spurious-wakeup-no-operation.js",
128
"status" : "PASS",

0 commit comments

Comments
 (0)