Nashorn can produce a ClassCastException when executing a plain JavaScript program.
The exception happens in a situation where the arguments variable is used in conjunction with call and apply. ## Observed behavior Code: ``` function F(SOME_PARAMETER) { Function.prototype.call.apply(G, arguments); } function G(){ this; F("SOME_ARGUMENT"); } G(); ``` Execution: ``` $ jjs -version test.js nashorn 1.8.0_101 Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.objects.NativeArguments to [Ljava.lang.Object; at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361) at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356) ... ``` ## Expected behavior Something else than a ClassCastException. Especially since the program is plain JavaScript. The minimal example will produce a 'RangeError: Maximum call stack size exceeded' and 'InternalError: too much recursion' on Chrome/Node and Firefox respectively. ## Thoughts The stack trace reveal that the arguments object is being cast to an array of objects, that seems wrong. According to ECMA262-5.1 for Function.prototype.apply, the numeric entries of the second argument should be iterated, if that argument is array-like. It looks like Nashorn just assumes it is an array already, and does the corresponding cast. The minimal example requires several surprising elements that should have no effect on the behavior of the program. But the ClassCastException disappear if one of them is removed. - the `this` variable in G - the unused `"SOME_ARGUMENT"` argument in G - the unused `SOME_PARAMETER` parameter name in F - the use use of `call.apply` in F, it should be rewritable to just `apply` ## Regression test The minimal example has been extended with a counter to avoid the stack overflow in other engines. ``` var i = 0; function F(SOME_PARAMETER) { if(i++ > 3){ return; } Function.prototype.call.apply(G, arguments); } function G(){ this; F("SOME_ARGUMENT"); } G(); ``` - Esben