Graaljs: Unsupported materialization node type: class com.oracle.truffle.js.nodes.access.PrivateFieldGetNodeGen

Created on 30 Oct 2020  路  7Comments  路  Source: oracle/graaljs

hello
After trying to use the option ("js.ecmascript-version", "2021"), we got the issues with closing the context. Inside the code, we have private static fields inside js functions. Full stacktrace:
Caused by: org.graalvm.polyglot.PolyglotException: java.lang.IllegalStateException: should not reach here: Unsupported materialization node type: class com.oracle.truffle.js.nodes.access.PrivateFieldGetNodeGen
at com.oracle.truffle.js.runtime.Errors.shouldNotReachHere(Errors.java:600)
at com.oracle.truffle.js.nodes.instrumentation.JSMaterializedInvokeTargetableNode.createFor(JSMaterializedInvokeTargetableNode.java:88)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$InvokeNode.materializeInstrumentableNodes(JSFunctionCallNode.java:754)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:369)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:387)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$CallNode.materializeInstrumentableNodes(JSFunctionCallNode.java:552)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:369)
at com.oracle.truffle.js.nodes.access.WritePropertyNode.copyUninitialized(WritePropertyNode.java:300)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:372)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:387)
at com.oracle.truffle.js.nodes.control.VoidBlockNode.copyUninitialized(VoidBlockNode.java:67)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:372)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:387)
at com.oracle.truffle.js.nodes.control.ExprBlockNode.copyUninitialized(ExprBlockNode.java:111)
at com.oracle.truffle.js.nodes.JavaScriptNode.cloneUninitialized(JavaScriptNode.java:372)
at com.oracle.truffle.js.nodes.function.FunctionBodyNode.materializeInstrumentableNodes(FunctionBodyNode.java:86)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$AbstractNodeVisitor.materializeSyntaxNodes(InstrumentationHandler.java:1650)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$AbstractNodeVisitor.materialize(InstrumentationHandler.java:1555)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$AbstractNodeVisitor.visit(InstrumentationHandler.java:1516)
at org.graalvm.truffle/com.oracle.truffle.api.nodes.NodeUtil.forEachChild(NodeUtil.java:468)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$AbstractNodeVisitor.visit(InstrumentationHandler.java:1543)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.visitRoot(InstrumentationHandler.java:1186)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.visitRoots(InstrumentationHandler.java:747)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.addExecutionBinding(InstrumentationHandler.java:464)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.attachListener(InstrumentationHandler.java:1035)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler.access$2500(InstrumentationHandler.java:93)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.InstrumentationHandler$AbstractInstrumenter.attachExecutionEventListener(InstrumentationHandler.java:2132)
at org.graalvm.truffle/com.oracle.truffle.api.instrumentation.Instrumenter.attachExecutionEventListener(Instrumenter.java:88)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotEngineImpl$CancelHandler.enableCancel(PolyglotEngineImpl.java:1243)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotEngineImpl$CancelHandler.cancel(PolyglotEngineImpl.java:1227)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotContextImpl.close(PolyglotContextImpl.java:913)
at org.graalvm.sdk/org.graalvm.polyglot.Context.close(Context.java:645)

It was reproduced inside GraalVM 20.1. I tried to prepare code sample outside our project but didn't find the way how to reproduce that.
I found out that com.oracle.truffle.js.nodes.instrumentation.JSMaterializedInvokeTargetableNode has less classes inside switch than inside com.oracle.truffle.js.nodes.NodeFactory#createFunctionCall. Maybe it's the reason of issue?

bug

Most helpful comment

Ah, the corresponding instrument can be seen from your stack-trace. It happens when the execution is terminated from another thread (when the corresponding Context is closed). So, the issue can be reproduced using something like

Context context = Context.newBuilder("js").option("js.ecmascript-version", "2021").build();
new Thread(new Runnable() {
    public void run() {
        context.eval("js", "class C { #x = function() { while (true); }; m() { this.#x() } }; new C().m()");
    }
}).start();
Thread.sleep(5000);
context.close(true);

All 7 comments

Hi @antonliauchuk-tealium thanks for the report -- that looks like a bug on our side, but I don't think this has to do with ECMA 2021. We can have a look, but having a reproducer for the bug would be highly appreciated

Thank you for the report. I am able to reproduce this issue.

@eleinadani You can reproduce this issue by adding

    @Test
    public void github367()  {
        evalAllTags("class C { #x = function() {}; m() { this.#x() } }; new C().m()");
    }

somewhere into our instrumentation tests (into CallAccessTest, for example) and by running them in 2021 mode:

$ mx -J-Dpolyglot.js.ecmascript-version=2021 unittest --regex CallAccessTest
MxJUnitCore
JUnit version 4.12
..........E
github367(com.oracle.truffle.js.test.instrumentation.CallAccessTest)
org.graalvm.polyglot.PolyglotException: java.lang.IllegalStateException: should not reach here: Unsupported materialization node type: class com.oracle.truffle.js.nodes.access.PrivateFieldGetNodeGen
    at com.oracle.truffle.js.runtime.Errors.shouldNotReachHere(Errors.java:643)
    at com.oracle.truffle.js.nodes.instrumentation.JSMaterializedInvokeTargetableNode.createFor(JSMaterializedInvokeTargetableNode.java:88)
    at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$InvokeNode.materializeInstrumentableNodes(JSFunctionCallNode.java:753)

And yes, it is ECMAScript 2021 specific because the issue is about the materialization of PrivateFieldGetNode and private fields are not part of ECMAScript 2020 (they are not even part of ECMAScript 2021, but we have them enabled in this mode).

@antonliauchuk-tealium The issue seems to occur only when you use some truffle instrument than materializes nodes with all tags defined in JavaScriptLanguage (resp. when it materializes some specific JavaScript-specific tags that I doubt any available instrument enables specifically). Do you have an idea what instrument triggers this issue? If it is your private instrument then you may work around this issue by not materializing nodes with JSTags.FunctionCallTag, JSTags.ReadPropertyTag, JSTags.ReadElementTag, if possible.

Ah, the corresponding instrument can be seen from your stack-trace. It happens when the execution is terminated from another thread (when the corresponding Context is closed). So, the issue can be reproduced using something like

Context context = Context.newBuilder("js").option("js.ecmascript-version", "2021").build();
new Thread(new Runnable() {
    public void run() {
        context.eval("js", "class C { #x = function() { while (true); }; m() { this.#x() } }; new C().m()");
    }
}).start();
Thread.sleep(5000);
context.close(true);

@iamstolis , thanks for your answers and help
yes, in our case we have the logic for closing the context by timeout.

Thanks @iamstolis. I'll have a look

Fixed here.

Was this page helpful?
0 / 5 - 0 ratings