Skip to content

Calling interpreter.run() at wrong time in AsyncFunction does bad things. #204

@Webifi

Description

@Webifi

After an asynchronous call is completed in an AsyncFunction, you pass your result back to the interpreter using the supplied callback function, then you need to resume stepping the state stack somehow, often via interpreter.run() if you're not using an external stepper.

For example:

function nativeAsyncFunction(val, callback) {
  setTimeout(() => {
      callback(val)
      interpreter.run() // Continue stepping
    }, 0)
}

If, however, your AsyncFunction ends up not doing an asynchronous call for whatever reason and just executes the callback, if you mistakenly execute interpreter.run() again you'll throw things off, since the existing loop in interpreter.run() was never broken by the asynchronous call.

For example:

function nativeAsyncFunction(val, callback) {
  callback(val)
  interpreter.run() // This will do bad things
}

Sometimes it can be difficult to track whether your AsyncFunction actually did an asynchronous operation or not, especially if it's calling other functions in 3rd party libraries that may or may not end asynchronously.

It would be nice to have run() keep track of its run state. Perhaps by changing the run function to something that will block execution if it's already running, like:

Interpreter.prototype.run = function() {
  if (this.running_) return this.paused_
  this.running_ = true
  try {
    while (!this.paused_ && this.step()) {}
  } catch (e) {
    this.running_ = false
    throw e
  }
  this.running_ = false
  return this.paused_
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions