Skip to content

RuntimeError: unreachable with virtual functions #1635

Closed

Description

@ColinEberhardt

I've hit this issue, but am struggling to create a compact reproduction - here's a brief summary.

See this PR ColinEberhardt/assemblyscript-regex#12

I'm hitting the following error at runtime:

    RuntimeError: unreachable
        at assembly/nfa/matcher/Matcher#matches@virtual (wasm-function[240]:1)
        at assembly/nfa/matcher/CharacterSetMatcher#matches~anonymous|0 (wasm-function[241]:19)
        at ~lib/array/Array<assembly/nfa/matcher/Matcher>#some (wasm-function[242]:85)
        at assembly/nfa/matcher/CharacterSetMatcher#matches (wasm-function[244]:21)
        at assembly/nfa/nfa/MatcherState<assembly/nfa/matcher/CharacterSetMatcher>#matches (wasm-function[245]:8)
        at assembly/nfa/nfa/State#matches@virtual (wasm-function[250]:58)
        at assembly/regexp/recursiveBacktrackingSearch (wasm-function[184]:121)
        at assembly/regexp/recursiveBacktrackingSearch@varargs (wasm-function[185]:56)
        at assembly/regexp/RegExp#exec (wasm-function[192]:307)

I've tried to recreate the issue, by creating a similar runtime state (replicating the various classes etc ...), but in doing so have stumbled on something odd. By adding the code outlined here:

https://github.com/ColinEberhardt/assemblyscript-regex/pull/12/files#diff-f350832f4859b9724e3ef59f756d2d201226fd81fd797207367fc269581115adR170-R178

Which basically creates a similar runtime state, the error goes away!

In other words - if I create a CharacterMatcher, CharacterSetMatcher, etc ... - execute their matches function, then throw the result away, everything wrks just fine. If not - I see the above runtime error later on in the code.

Activity

  1. dcodeIO commented on Jan 25, 2021

    @dcodeIO
    Member

    Hmm, an unreachable in a @virtual stub typically means that the class id of the this argument isn't handled by the stub, hence trapping. How this works currently is that the @virtual stub has essentially a br_table of class ids, switching over the ids of all the overloads before forwarding to the concrete overload.

    So what might happen there is that the stub is missing an id it should cover, or that an object incompatible with the stub slipped through even though it should have errored earlier.

  2. ColinEberhardt commented on Jan 25, 2021

    @ColinEberhardt
    ContributorAuthor

    Thanks for the info @dcodeIO - just to be clear, do you consider this to be an error in the compiler? or in my code? and is there something I could (or should) do to remove this error?

  3. dcodeIO commented on Jan 25, 2021

    @dcodeIO
    Member

    This may well be an error in the compiler, like missing an id while preparing virtual overloads. Or it may be a side-effect of something else that should have been caught earlier. If there is a simple way to reproduce the problem in a couple lines of code, that'd be ideal to investigate :)

  4. dcodeIO commented on Jan 28, 2021

    @dcodeIO
    Member

    Interesting, the fix is kinda a workaround for virtual tables, by implementing manually what they should do if they worked correctly. So yeah, that looks like a bug in the compiler.

    Reminds me that there are one or two changes in the upcoming 0.18 branch that may fix this.

  5. dcodeIO commented on Feb 3, 2021

    @dcodeIO
    Member

    There is a good chance that this problem has been implicitly fixed in 0.18.0. Can someone confirm?

  6. ColinEberhardt commented on Feb 4, 2021

    @ColinEberhardt
    ContributorAuthor

    Just for reference, this issue was fixed by @MaxGraey in this commit ColinEberhardt/assemblyscript-regex@6847db1 via the introduction of an explicit cast.

    It should be possible to checkout the commit prior to this change, update to 0.18, remove the workaround code and see if it all works.

    At the moment I'm waiting for an as-pect update before moving onto 0.18.

  7. dcodeIO commented on Feb 4, 2021

    @dcodeIO
    Member

    I see. So, I just took ColinEberhardt/assemblyscript-regex#26 and edited the relevant code section to be

    let _code: u32;
    
    export class CharacterSetMatcher extends Matcher {
      constructor(public matchers: Matcher[], public negated: bool) {
        super(MatcherType.CharacterSet);
      }
    
      matches(code: u32): bool {
        _code = code;
        let match = this.matchers.some((m) => m.matches(_code));
        return this.negated ? !match : match;
      }
    }

    again. That should have produced the issue, that correct? If so, I'm not seeing any test errors with 0.18, indicating that the issue may indeed have been fixed during bootstrapping.

  8. ColinEberhardt commented on Feb 4, 2021

    @ColinEberhardt
    ContributorAuthor

    Yes, I agree - that looks like the problem is fixed 👍

  9. jriehl commented on Feb 7, 2021

    @jriehl

    I'm still seeing something very much like this on 0.18.5:

    wasm://wasm/00054d42:1
    
    
    RuntimeError: unreachable
        at assembly/grammar/Grammar.GrammarVisitor#visitPrefix@virtual (<anonymous>:wasm-function[196]:0x50f1)
        at assembly/grammar/Grammar.Grammar#visit (<anonymous>:wasm-function[315]:0x8a69)
    ...
    

    Unfortunately the code isn't publicly available at present. Would it be worth any of my time trying to distill this down to a more generic test?

  10. github-actions commented on Jun 2, 2021

    @github-actions

    This issue has been automatically marked as stale because it has not had recent activity. It will be closed in one week if no further activity occurs. Thank you for your contributions!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      ⌂ Proxy