Why is my Kotlin/JS program failing with "RangeError: Maximum call stack size exceeded"?

211 Views Asked by At

I’ve written a Kotlin/JS program that is crashing on some JavaScript engines.

It’s crashing on GraalVM like this:

RangeError: Maximum call stack size exceeded
    at <js> 839(myprogram.js:394:1174923-1174934)
    at <js> e(myprogram.js:394:1175309-1175342)
    at <js> 724(myprogram.js:394:1174990-1174995)
    at <js> e(myprogram.js:394:1175309-1175342)
    at <js> :anonymous(myprogram.js:394:1175222-1175358)
    at <js> :program(myprogram.js:394:13041-1175382)
    at org.graalvm.polyglot.Context.eval(Context.java:345)

On Duktape it’s failing like this:

com.squareup.duktape.DuktapeException: RangeError: compiler recursion limit (line 1)
    at com.squareup.duktape.Duktape.evaluate(Native Method)
    at com.squareup.duktape.Duktape.evaluate(Duktape.java:60)

This crash was introduced by upgrading from Kotlin 1.4.10 to 1.6.21.

2

There are 2 best solutions below

0
Jesse Wilson On BEST ANSWER

Kotlin/JS uses a code shrinker in production builds. The code shrinker, Terser, produces very long statements that exceed the default limits of certain compilers.

To fix this problem, configure Terser to produce smaller lines. Create a file, subproject/webpack.config.d/myWebpackConfig.js where subproject is the Gradle module that produces the Kotlin/JS executable.

In that file, paste the following:

config.optimization = config.optimization || {};
const TerserPlugin = require("terser-webpack-plugin");
config.optimization.minimizer = [
    new TerserPlugin({
        terserOptions: {
            compress: {
                sequences: 10
            },
        },
    }),
];

Changing the value of the sequences option is the key. The default value, 200, fits 200 logical statements into each line. By scaling this down to 10 Terser emits smaller statements.

0
Christian Wirth On

You could try and start the Java VM with the -Xss and provide more stack to it, the default seems not to be enough for your usecase.

-Xss8m (or more)