Skip to content

Commit 012aa85

Browse files
committed
[GR-28227] Backport: Java null should behave like null during Object creation.
PullRequest: js/1820
2 parents a91cf04 + fff3cca commit 012aa85

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2020, 2020, 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+
load('../assert.js');
9+
10+
var javaNull = java.lang.System.getProperty("iDontExist");
11+
12+
assertSame(Object.prototype, Object.getPrototypeOf(Object(javaNull)));
13+
assertSame(Object.prototype, Object.getPrototypeOf(new Object(javaNull)));
14+
assertSame(null, Object.getPrototypeOf(Object.create(javaNull)));
15+
16+
true;

graal-js/src/com.oracle.truffle.js.test/src/com/oracle/truffle/js/test/interop/ForeignBoxedObjectTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ public class ForeignBoxedObjectTest {
5757
public void testForeignNull() {
5858
try (Context context = JSTest.newContextBuilder().build()) {
5959
context.getBindings("js").putMember("obj", new ForeignNull());
60-
assertTrue(context.eval(ID, "try { Object(obj); false; } catch (e) { e instanceof TypeError }").asBoolean());
60+
assertTrue(context.eval(ID, "Object.getPrototypeOf(Object(obj)) === Object.prototype").asBoolean());
61+
assertTrue(context.eval(ID, "Object.getPrototypeOf(new Object(obj)) === Object.prototype").asBoolean());
62+
assertTrue(context.eval(ID, "Object.getPrototypeOf(Object.create(obj)) === null").asBoolean());
6163
assertTrue(context.eval(ID, "try { obj.foo; false; } catch (e) { e instanceof TypeError }").asBoolean());
6264
assertTrue(context.eval(ID, "try { obj.foo(); false; } catch (e) { e instanceof TypeError }").asBoolean());
6365
}

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,7 @@ protected DynamicObject getIntrinsicDefaultProto(JSRealm realm) {
13931393

13941394
}
13951395

1396+
@ImportStatic({JSConfig.class})
13961397
public abstract static class ConstructObjectNode extends ConstructWithNewTargetNode {
13971398
public ConstructObjectNode(JSContext context, JSBuiltin builtin, boolean isNewTargetCase) {
13981399
super(context, builtin, isNewTargetCase);
@@ -1403,6 +1404,10 @@ protected static boolean arg0NullOrUndefined(Object[] args) {
14031404
return (arg0 == Undefined.instance) || (arg0 == Null.instance);
14041405
}
14051406

1407+
protected static Object firstArgument(Object[] arguments) {
1408+
return (arguments.length == 0) ? Undefined.instance : arguments[0];
1409+
}
1410+
14061411
@Specialization(guards = {"isNewTargetCase"})
14071412
protected DynamicObject constructObjectNewTarget(DynamicObject newTarget, @SuppressWarnings("unused") Object[] arguments) {
14081413
return newObject(newTarget);
@@ -1413,10 +1418,17 @@ protected DynamicObject constructObject0(DynamicObject newTarget, @SuppressWarni
14131418
return newObject(newTarget);
14141419
}
14151420

1416-
@Specialization(guards = {"!isNewTargetCase", "arguments.length > 0", "!arg0NullOrUndefined(arguments)"})
1421+
@Specialization(guards = {"!isNewTargetCase", "arguments.length > 0", "!arg0NullOrUndefined(arguments)"}, limit = "InteropLibraryLimit")
14171422
protected Object constructObjectJSObject(@SuppressWarnings("unused") DynamicObject newTarget, Object[] arguments,
1418-
@Cached("createToObject(getContext())") JSToObjectNode toObjectNode) {
1419-
return toObjectNode.execute(arguments[0]);
1423+
@Cached("createToObject(getContext())") JSToObjectNode toObjectNode,
1424+
@CachedLibrary("firstArgument(arguments)") InteropLibrary interop,
1425+
@Cached("createBinaryProfile()") ConditionProfile isNull) {
1426+
Object arg0 = arguments[0];
1427+
if (isNull.profile(interop.isNull(arg0))) {
1428+
return newObject(Null.instance);
1429+
} else {
1430+
return toObjectNode.execute(arg0);
1431+
}
14201432
}
14211433

14221434
@Specialization(guards = {"arguments.length > 0", "arg0NullOrUndefined(arguments)"})

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ protected DynamicObject intlDefineProperties(DynamicObject obj, DynamicObject de
581581
}
582582
}
583583

584+
@ImportStatic({JSConfig.class})
584585
public abstract static class ObjectCreateNode extends ObjectDefineOperation {
585586
public ObjectCreateNode(JSContext context, JSBuiltin builtin) {
586587
super(context, builtin);
@@ -596,12 +597,16 @@ protected DynamicObject createPrototypeNull(Object prototype, Object properties)
596597
return objectDefineProperties(ret, properties);
597598
}
598599

599-
@TruffleBoundary
600-
@SuppressWarnings("unused")
601-
@Specialization(guards = {"!isJSNull(prototype)", "!isJSObject(prototype)"})
602-
protected DynamicObject createInvalidPrototype(Object prototype, Object properties) {
600+
@Specialization(guards = {"!isJSNull(prototype)", "!isJSObject(prototype)"}, limit = "InteropLibraryLimit")
601+
protected DynamicObject createForeignNullOrInvalidPrototype(Object prototype, Object properties,
602+
@CachedLibrary("prototype") InteropLibrary interop,
603+
@Cached("createBinaryProfile()") ConditionProfile isNull) {
603604
assert prototype != null;
604-
throw Errors.createTypeErrorInvalidPrototype(prototype);
605+
if (isNull.profile(prototype != Undefined.instance && interop.isNull(prototype))) {
606+
return createPrototypeNull(Null.instance, properties);
607+
} else {
608+
throw Errors.createTypeErrorInvalidPrototype(prototype);
609+
}
605610
}
606611

607612
@Specialization(guards = {"isJSObject(prototype)", "isJSObject(properties)"})

0 commit comments

Comments
 (0)