Skip to content

Is the JobQueue Port API a good abstraction? #1799

@akosthekiss

Description

@akosthekiss

TL;DR: Is there any other way to implement a Promise job queue than what's implemented in the default port? If not, should it not be merged into jerry-core?

Source of my confusion:

  • If Promises are available/enabled then those JS functions that are in thens or catches are to be executed after the main script completed. Until they get their turn, they are enqueued by jerry_port_jobqueue_enqueue.
  • Enqueued jobs must be executed, otherwise they keep references to their environment and memory will not be freed. (Just try to comment out jerry_port_default_jobqueue_run in main-unix.c, the debug-built jerry tool will assert out at cleanup when running a script with Promises, because heap does not get emptied.)
  • However, there is no general API to execute the enqueued jobs. The default port provides jerry_port_default_jobqueue_run, but it is specific to that port.
  • What's more, the default port implementation uses the engine's internal memory handling routines (jmem_heap_alloc_block, jmem_heap_free_block), which is quite a no-no IMHO.

I've taken a quick look at another VM (JavaScriptCore) and command line tool (jsc), how it handles Promises and enqueued jobs. Without digging too deep, it seems to me that there the VM has an API call to execute such jobs (called microtasks, if I'm not mistaken).
(vm.drainMicrotasks(); at https://trac.webkit.org/browser/webkit/trunk/Source/JavaScriptCore/jsc.cpp#L3522)

Wouldn't it be better for us, too, to integrate Promise job handling into the engine. E.g., something like

  • jerry_run_enqueued to run one enqueued job,
  • jerry_run_all_enqueued to run until the queue gets empty (replacement for jerry_port_default_jobqueue_run and analogous to JSC's vm.drainMicrotasks, I think).

Advantages:

  • the whole API needed to run a Promise-enabled engine is port-independent (in addition to the above discussed, jerry_init can do the queue initialization instead of jerry_port_default_jobqueue_init),
  • no API layering violation,
  • less burden on port implementers.

However, I'm not sure whether there are any use cases for which this approach would be inappropriate.

Feedbacks are welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ES2015Related to ES2015 featuresapiRelated to the public APIdiscussionOngoing discussion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions