diff --git a/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/OptionalChainNode.java b/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/OptionalChainNode.java index e65410215a..ae59d7ff32 100644 --- a/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/OptionalChainNode.java +++ b/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/OptionalChainNode.java @@ -241,6 +241,10 @@ private boolean isNullish(Object targetValue) { return isNullish.profile(isNullOrUndefinedNode.executeBoolean(targetValue)); } + public JSTargetableNode getExpressionNode() { + return expressionNode; + } + @Override public JavaScriptNode getTarget() { return expressionNode.getTarget(); @@ -279,14 +283,14 @@ protected JavaScriptNode copyUninitialized(Set> materialize } @SuppressWarnings("serial") - private static final class ShortCircuitException extends ControlFlowException { + public static final class ShortCircuitException extends ControlFlowException { private static final ShortCircuitException INSTANCE = new ShortCircuitException(); private ShortCircuitException() { } - static ShortCircuitException instance() { + public static ShortCircuitException instance() { return INSTANCE; } } diff --git a/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/function/JSFunctionCallNode.java b/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/function/JSFunctionCallNode.java index dab887e1a8..f9d99db5c0 100644 --- a/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/function/JSFunctionCallNode.java +++ b/graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/function/JSFunctionCallNode.java @@ -81,6 +81,7 @@ import com.oracle.truffle.js.nodes.access.JSConstantNode.JSConstantUndefinedNode; import com.oracle.truffle.js.nodes.access.JSProxyCallNode; import com.oracle.truffle.js.nodes.access.JSTargetableNode; +import com.oracle.truffle.js.nodes.access.OptionalChainNode.ShortCircuitException; import com.oracle.truffle.js.nodes.access.OptionalChainNode.ShortCircuitTargetableNode; import com.oracle.truffle.js.nodes.access.PropertyGetNode; import com.oracle.truffle.js.nodes.access.PropertyNode; @@ -1596,6 +1597,11 @@ private Object fallback(Object receiver, Object[] arguments, Object[] callArgume } } errorBranch.enter(); + // There is no valid function to invoke. Do not throw if the invocation + // is optional, short-circuit instead. + if (getParent() instanceof InvokeNode invokeNode && invokeNode.getFunctionTargetDelegate() instanceof ShortCircuitTargetableNode) { + throw ShortCircuitException.instance(); + } throw Errors.createTypeErrorInteropException(receiver, ex != null ? ex : UnknownIdentifierException.create(Strings.toJavaString(functionName)), "invokeMember", functionName, this); }