I'm currently getting an endless recursion when trying to evaluate
Polyglot.eval('squeaksmalltalk', 'Array')
in the RC15 polyglot shell.
"" + Polyglot.eval('squeaksmalltalk', 'Array')
on the other hand evaluates fine and prints something like this:
foreign {braceStream:: Metaclass (Array)>>braceStream:, new:: Metaclass (Array)>>new:, empty: Metaclass (Array)>>empty, ...
The JVM stack suggests that there could be a problem in JavaScriptLanguage#toString:
java.lang.Thread.State: RUNNABLE
at java.lang.StringCoding.decode(StringCoding.java:254)
at java.lang.String.<init>(String.java:546)
at java.lang.String.<init>(String.java:566)
at de.hpi.swa.graal.squeak.util.ArrayConversionUtils.bytesToString(ArrayConversionUtils.java:109)
at de.hpi.swa.graal.squeak.model.NativeObject.asString(NativeObject.java:232)
at de.hpi.swa.graal.squeak.model.NativeObject.toString(NativeObject.java:197)
at de.hpi.swa.graal.squeak.model.ClassObject.lambda$lookup$0(ClassObject.java:307)
at de.hpi.swa.graal.squeak.model.ClassObject$$Lambda$57/1632789609.test(Unknown Source)
at de.hpi.swa.graal.squeak.model.ClassObject.lookup(ClassObject.java:319)
at de.hpi.swa.graal.squeak.model.ClassObject.lookup(ClassObject.java:307)
at de.hpi.swa.graal.squeak.model.AbstractSqueakObject.readMember(AbstractSqueakObject.java:222)
at de.hpi.swa.graal.squeak.model.AbstractSqueakObjectGen$InteropLibraryExports$Uncached.readMember(AbstractSqueakObjectGen.java:386)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignObjectToString(JavaScriptLanguage.java:670)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:367)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignArrayToString(JavaScriptLanguage.java:643)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:349)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignObjectToString(JavaScriptLanguage.java:673)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:367)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignArrayToString(JavaScriptLanguage.java:643)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:349)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignObjectToString(JavaScriptLanguage.java:673)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:367)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignArrayToString(JavaScriptLanguage.java:643)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:349)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignObjectToString(JavaScriptLanguage.java:673)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:367)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignArrayToString(JavaScriptLanguage.java:643)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:349)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.foreignObjectToString(JavaScriptLanguage.java:673)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toStringForeignObject(JavaScriptLanguage.java:367)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:324)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:299)
at com.oracle.truffle.js.lang.JavaScriptLanguage.toString(JavaScriptLanguage.java:126)
at com.oracle.truffle.api.TruffleLanguage$Env.toStringIfVisible(TruffleLanguage.java:2219)
at com.oracle.truffle.api.TruffleLanguage$LanguageImpl.toStringIfVisible(TruffleLanguage.java:2632)
at com.oracle.truffle.polyglot.PolyglotContextImpl.printResult(PolyglotContextImpl.java:790)
at com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:768)
at org.graalvm.polyglot.Context.eval(Context.java:341)
at org.graalvm.launcher.MultiLanguageShell.readEvalPrint(MultiLanguageShell.java:197)
at org.graalvm.launcher.PolyglotLauncher.runShell(PolyglotLauncher.java:347)
at org.graalvm.launcher.PolyglotLauncher.launch(PolyglotLauncher.java:220)
at org.graalvm.launcher.PolyglotLauncher.main(PolyglotLauncher.java:357)
It's possible that this is an interop bug in our language implementation. But maybe Graal.js should deploy a failsafe and terminate toString() after a certain depth?
Hi @fniephaus
thanks for your report. This definitly looks like a bug in Graal.js. Some nesting and recursion is expected (depending on the nesting of your objects), but it should not be an infinite loop of course. I will investigate.
Best,
Christian
@wirthi The recursion is not infinite in theory, but it is too long to finish in practice. The root of the problem is that we allow the recursion up to 10th level, see JavaScriptLanguage.MAX_TOSTRING_DEPTH. This is too much for any object that may reference itself. Consider, for example,
Context context = Context.newBuilder("js").allowAllAccess(true).build();
context.getBindings("js").putMember("array", new ProxyArray() {
@Override
public Object get(long index) {
return this;
}
@Override
public void set(long index, Value arg1) {
}
@Override
public long getSize() {
return 10;
}
});
Source source = Source.newBuilder("js", "array", "noname").interactive(true).buildLiteral();
context.eval(source);
Hi @fniephaus
We have lowered the limit to show max 3 steps deep. This should solve the problem.
Best,
Christian
Great, thanks!