Skip to content

jrubyc-compiled code with an array pattern fails to load (NullPointerException reading persisted IR) #9834

Open

Description

@sferik

A file compiled with jrubyc that uses an array pattern can't be loaded. Loading the .class file fails while reading the persisted IR:

# arr.rb
p([1] in [1])
$ jrubyc arr.rb
$ mkdir only && mv arr.class only/
$ jruby -e 'load "only/arr.class"'
Unhandled Java exception: java.lang.NullPointerException: Cannot invoke "org.jruby.ir.operands.OperandType.ordinal()" because "type" is null

The same file without the pattern, or with a hash pattern like {a: 1} in {a: 1}, loads and prints true. It fails the same way on 9.4.15.0, 10.1.2.0 and master. These all fail:

  • [1] in [1] and [1] in [Integer]
  • [1, 2] in [_, 2] and [1, *] in [1, *]
  • case [1]; in [x] then p x; end

With -Xir.reading.debug=true, the last operand read before the failure is a temporary variable that decodes to null, after which the reader is out of step with the data:

INSTR<copy
OP<temporary_variable
Decoding operand temporary_variable
>OP = null
OP<null

Array patterns use TemporaryIntVariables for the array's length, the rest count and element indexes (IRBuilder#intTemp). It's written with type INT, but TemporaryLocalVariable.decode has no case for INT, so it falls through to return null:

switch(type) {
    case CLOSURE: return TemporaryClosureVariable.decode(d);
    case CURRENT_MODULE: return TemporaryCurrentModuleVariable.decode(d);
    case FLOAT: return TemporaryFloatVariable.decode(d);
    case FIXNUM: return TemporaryFixnumVariable.decode(d);
    case BOOLEAN: return TemporaryBooleanVariable.decode(d);
    case LOCAL: return d.getCurrentScope().getManager().newTemporaryLocalVariable(d.decodeInt());
}
return null; // Should not reach here.

TemporaryIntVariable.decode already exists, so adding case INT: return TemporaryIntVariable.decode(d); should fix it.

I ran into this while writing a spec for #9831, where the persistence mode of spec/compiler/general_spec.rb fails the same way on [1] in [1].

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions