Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated Java contains error for type-switching in debug mode #204

Closed
gmacon opened this issue Jul 12, 2017 · 1 comment · Fixed by kaitai-io/kaitai_struct_compiler#192
Milestone

Comments

@gmacon
Copy link

gmacon commented Jul 12, 2017

With a structure like this:

meta:
  id: foo
  endian: be
  ks-debug: true
seq:
- id: code
  type: u1
- id: data
  type:
    switch-on: code
    cases:
      1: one
      2: two
types:
  one:
    seq:
      - id: first
        type: u4
  two:
    seq:
      - id: second
        type: u4

Kaitai generates code which looks like this:

public class Foo extends KaitaiStruct {
    // ...
    public void _read() {
        _attrStart.put("code", this._io.pos());
        this.code = this._io.readU1();
        _attrEnd.put("code", this._io.pos());
        _attrStart.put("data", this._io.pos());
        switch (code()) {
        case 1: {
            this.data = new One(this._io, this, _root);
            this.data._read();
            break;
        }
        case 2: {
            this.data = new Two(this._io, this, _root);
            this.data._read();
            break;
        }
        }
        _attrEnd.put("data", this._io.pos());
    }
    // ...
    private int code;
    private KaitaiStruct data;
}

This gives the following compilation error:

[ERROR] Foo.java:[75,26] cannot find symbol
  symbol:   method _read()
  location: variable data of type io.kaitai.struct.KaitaiStruct
[ERROR] Foo.java:[80,26] cannot find symbol
  symbol:   method _read()
  location: variable data of type io.kaitai.struct.KaitaiStruct

since _read is not defined in KaitaiStruct. Since the variable is not always of type KaitaiStruct (I've seen some cases where it's Object instead, but haven't been able to come up with a simple example that exhibits that behavior), we cannot simply add _read as an abstract method.

If debug is disabled, the code is OK because the call to _read happens in the constructor instead of separately.

I've discovered a workaround, though: adding

repeat: expr
repeat-expr: 1

to the type-switched field causes the compiler to create a more specifically typed temporary variable on which _read is called. Perhaps the correct solution here is to change the compiler to always use a temporary in debug mode.

@GreyCat
Copy link
Member

GreyCat commented Jul 12, 2017

Thanks for the report and detailed explanation! I'll try to think of something to fix this. Anyway, hopefully _read() will be part of standard interface soon, i.e. as in this branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants