Search code examples
kotlingradlesimulatorkotlin-coroutineskotlin-js

Uncaught TypeError: this.resultContinuation_0 is undefined when trying to run a suspend function in Kotlin JS Browser onclick


I'm working on a multi-platform RISC-V simulator in Kotlin and I've been stuck on a problem for more than a week now. I've tried everything that I could find online but I had no luck with it.

To give you a little context: I'm trying to bind this project (here you can download my code) to the VMB (virtual motherboard, here you can download the latest, not yet published version) via WebSockets. I've already done the communication part and also tested it on the JVM branch (I've also made another small Kotlin JS project with just the code for the communication part and it works fine, but for some reason when I put everything together it just doesn't work). It builds without any error and it even works fine (to an extend), until I try to connect to the VMB, then I get an error in the Browser's console saying Uncaught TypeError: this.resultContinuation_0 is undefined. I've lost so many hours on this problem and I'm pretty sure it's just something small (maybe even obvious) that I'm missing.

Steps to reproduce the problem:

  1. Download the projects (you will need both venus and VMB)
  2. Download and install grunt on your machine if you don't have it
  3. In the vmb folder double click on mother.exe and be sure to click on the power button (it works only on windows, sorry)
  4. Open the venus project in InteliJ and build it using gradle (IntelliJ usually recognizes the project as gradle automatically)
  5. After the build is completed, open a Powershell or cmd in the venus folder and run grut dist
  6. The results should now be in the out directory.
  7. You will probably need XAMPP to host the files on a server locally in case you get a CORS Error
  8. When you open the page go to the Simulator tab and then click on Assemble & Simulate from Editor button.
  9. You should now be able to see the error in the console.

Any help is highly appreciated as I've been stuck on this issue for days now. Thank you!

EDIT:

Upon further digging I noticed that the problem appears whenever I call a suspend function onclick.

For example: I made a function in Driver.kt:

    @JsName("connect")
    suspend fun connect() {
        sim.connectToMotherboard()
    }

Where connectToMotherboard() is a suspended function, that I call whenever a button is pressed.

HTML:

<button class="button is-primary" onclick="driver.connect()">Connect to Motherboard</button>

This gives me the same error as mentioned in the title. After I downloaded Firefox for developers I've got this message:

Uncaught TypeError: can't access property "context", this.resultContinuation_0 is undefined

Solution

  • Ok, the problem was that I called some @JSName functions in my HTML code. Something like this:

    @JsName("doSomething")
    suspend fun doSomething() {
        // some code...
    }
    

    And then in my HTML code I had some lines like this:

    <button id="someButton" class="button" onclick="doSomething()">Click Me</button>
    

    The key here is the suspend keyword. If you call a "normal" function from JS/HTML there's no problem, but a suspend function cannot be called from HTML. It has to be in a launch block or a Coroutine because otherwise the Continuation will be null. So I changed the kotlin code to something like this:

    val myButton = document.getElementById("someButton")
    simulatorRunButton!!.addEventListener("click", {
        launch(EmptyCoroutineContext) {
            doSomething()
        }
    })
    

    Of course, after doing that I had to erase the onclick part from my HTML object, something like this:

    <button id="someButton" class="button">Click Me</button>