JDK-8066231 : Fuzzing bug: Invalid symbol slot
  • Type: Sub-task
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u60
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2014-12-01
  • Updated: 2015-01-28
  • Resolved: 2015-01-28
Related Reports
Cloners :  
Cloners :  
Duplicate :  
Relates :  
Description
Four different programs seem to cause this failure

jjs> function f(){ try { Object; } catch(x if x >>>=0) { throw x2; } finally { } } f()
Exception in thread "main" java.lang.AssertionError
   at jdk.nashorn.internal.ir.Symbol.getSlot(Symbol.java:563)
   at jdk.nashorn.internal.codegen.MethodEmitter.load(MethodEmitter.java:953)
   at jdk.nashorn.internal.codegen.MethodEmitter.emitLocalVariableConversion(MethodEmitter.java:2519)
   at jdk.nashorn.internal.codegen.MethodEmitter.beforeJoinPoint(MethodEmitter.java:2492)
   at jdk.nashorn.internal.codegen.CodeGenerator.enterThrowNode(CodeGenerator.java:2981)
   at jdk.nashorn.internal.ir.ThrowNode.accept(ThrowNode.java:80)
   at jdk.nashorn.internal.ir.Node.accept(Node.java:265)
   at jdk.nashorn.internal.ir.Block.accept(Block.java:178)
   at jdk.nashorn.internal.ir.LexicalContextNode$Acceptor.accept(LexicalContextNode.java:57)
   at jdk.nashorn.internal.ir.Block.accept(Block.java:425)
   ...


jjs> function f(){ try { return; } catch(x) { return x ^= 0; } finally { throw 0; } } f()
Exception in thread "main" java.lang.AssertionError
   at jdk.nashorn.internal.ir.Symbol.getSlot(Symbol.java:555)
   at jdk.nashorn.internal.codegen.MethodEmitter.load(MethodEmitter.java:953)
   at jdk.nashorn.internal.codegen.MethodEmitter.emitLocalVariableConversion(MethodEmitter.java:2519)
   at jdk.nashorn.internal.codegen.MethodEmitter.beforeJoinPoint(MethodEmitter.java:2492)
   at jdk.nashorn.internal.codegen.CodeGenerator.enterThrowNode(CodeGenerator.java:2981)
   at jdk.nashorn.internal.ir.ThrowNode.accept(ThrowNode.java:80)
   at jdk.nashorn.internal.ir.Node.accept(Node.java:265)
   at jdk.nashorn.internal.ir.Block.accept(Block.java:178)
   at jdk.nashorn.internal.ir.LexicalContextNode$Acceptor.accept(LexicalContextNode.java:57)
   at jdk.nashorn.internal.ir.Block.accept(Block.java:425)
   ...


jjs> function f(){ try { return; } catch(x) { return x ^= Object; } finally { throw Object; } } f()
Exception in thread "main" java.lang.AssertionError
   at jdk.nashorn.internal.ir.Symbol.getSlot(Symbol.java:558)
   at jdk.nashorn.internal.codegen.MethodEmitter.load(MethodEmitter.java:953)
   at jdk.nashorn.internal.codegen.MethodEmitter.emitLocalVariableConversion(MethodEmitter.java:2519)
   at jdk.nashorn.internal.codegen.MethodEmitter.beforeJoinPoint(MethodEmitter.java:2492)
   at jdk.nashorn.internal.codegen.CodeGenerator.enterThrowNode(CodeGenerator.java:2981)
   at jdk.nashorn.internal.ir.ThrowNode.accept(ThrowNode.java:80)
   at jdk.nashorn.internal.ir.Node.accept(Node.java:265)
   at jdk.nashorn.internal.ir.Block.accept(Block.java:178)
   at jdk.nashorn.internal.ir.LexicalContextNode$Acceptor.accept(LexicalContextNode.java:57)
   at jdk.nashorn.internal.ir.Block.accept(Block.java:425)
   ...

Comments
Moved the last case into separate bug JDK-8071682 as it seems to be a separate issue.
27-01-2015

These are all related to throwing exceptions from finally blocks where there's a return statement in the try block. This is probably related to the fact that LocalVariableTypesCalculator uses node identity to gather information about the nodes, and inlining finally blocks creates a DAG out of a tree (nodes are reused), so different type information ends up being associated with the same node in the finally block, depending on what flow path it is reached through (normal vs. abrupt). E.g. in one of the above examples "function f(){ try { return; } catch(x) { return x ^= 0; } finally { throw 0; } } f()" the "throw 0" can be reached both with x being undefined, and with x having int type. Unfortunately, since we avoid copying nodes, we inline the same instance of the ThrowNode both in the normal and the abrupt flow. Seems like we'll have to abandon this concept and eagerly create deep copies of finally blocks when we inline them. This issue should likely be fixed together with JDK-8030198/JDK-8066231.
10-12-2014

This one is also broken: jjs> function f() { try { Object } catch(x) { (x=y); return; } finally { throw Object; } } f() Exception in thread "main" java.lang.AssertionError at jdk.nashorn.internal.ir.Symbol.getSlot(Symbol.java:558) at jdk.nashorn.internal.codegen.MethodEmitter.load(MethodEmitter.java:953) at jdk.nashorn.internal.codegen.MethodEmitter.emitLocalVariableConversion(MethodEmitter.java:2519) at jdk.nashorn.internal.codegen.MethodEmitter.beforeJoinPoint(MethodEmitter.java:2492) at jdk.nashorn.internal.codegen.CodeGenerator.enterThrowNode(CodeGenerator.java:2981) at jdk.nashorn.internal.ir.ThrowNode.accept(ThrowNode.java:80) at jdk.nashorn.internal.ir.Node.accept(Node.java:265) at jdk.nashorn.internal.ir.Block.accept(Block.java:178) at jdk.nashorn.internal.ir.LexicalContextNode$Acceptor.accept(LexicalContextNode.java:57) at jdk.nashorn.internal.ir.Block.accept(Block.java:425)
01-12-2014