Skip to content

niso_engine.h: the engine interface

Generated from bindings/js/niso_engine.h when the site was built at 7aa23e2.

From bindings/js/niso_engine.h, a header of its own outside niso_runtime.h.

Functions: niso_js_host_count, niso_js_host_at, niso_js_note_error, niso_js_interrupted, niso_js_wall_clock, niso_js_module_url, niso_js_load, niso_js_script_hash, qe_new, qe_free, qe_eval, qe_eval_module, qe_eval_args, qe_run_microtasks, qe_gc, qe_hook, qe_argc, qe_num, qe_bool, qe_null, qe_str, qe_len, qe_item_is_str, qe_item_num, qe_item_str, qe_is_str, qe_bytes, qe_ret_num, qe_ret_bool, qe_ret_str, qe_ret_nums, qe_ret_strs, qe_ret_bytes, qe_can_alias, qe_ret_alias, qe_detach, qe_ret_list, qe_push_num, qe_push_bytes, qe_push_str, qe_throw

The engine interface: what a JS engine implements so the shared binding (glue.js plus the generated host functions) runs on it. It is host functions taking and returning numbers, booleans, strings and arrays of them, calls from C into the glue’s hooks, microtasks, and a GC. Weak refs and finalizers are the engine’s own WeakRef and FinalizationRegistry.

Every function here runs on the DOM thread. Strings an engine hands to a host function stay valid until that host function returns.

typedef struct qe_engine qe_engine;
typedef struct qe_args qe_args;

Hooks the glue returns, called by name.

enum qe_hook {
QE_HOOK_INVOKE, /* (callback type, callback id, args...) */
QE_HOOK_DROP, /* (callback id) */
QE_HOOK_STRENGTH, /* (connected, wrapper ids...) */
QE_HOOK_TASKS, /* () -> whether the glue's own task sources ran any */
QE_HOOK_SCRIPT, /* (script element id or 0, parser inserted) */
QE_HOOK_MICROTASK, /* () queues a microtask that notifies mutation observers */
QE_HOOK_MODULE, /* (module, call, event, status): see niso_dom_set_module_hook */
QE_HOOK_WASM_CALL, /* (callback, memories moved, args...) -> 0, or 1 if the host function threw */
QE_HOOK_WASM_TASK, /* (job) runs a WebAssembly task */
QE_HOOK_WORKER, /* () runs a worker's script, in the worker's engine */
QE_HOOK_MESSAGE, /* (MessageEvent id) -> 1 once its data is deserialized */
QE_HOOK_EVALUATE, /* () before the embedder runs a classic script */
QE_HOOK_HANDLER, /* (target, element, name, source) -> callback id of the compiled event handler, or 0 */
QE_HOOK_COUNT,
};
extern const char* const qe_hook_names[QE_HOOK_COUNT];
typedef void (*niso_js_host_fn)(niso_js* js, qe_args* a);
typedef struct niso_js_host {
const char* name;
niso_js_host_fn fn;
} niso_js_host;

Provided by the binding core.

extern const char niso_js_glue[];
extern const size_t niso_js_glue_len;
size_t niso_js_host_count(void);
const niso_js_host* niso_js_host_at(size_t i);
void niso_js_note_error(niso_js* js);

Whether the worker the engine runs was terminated: the engine aborts the script that runs, as soon as it can, when this becomes true.

bool niso_js_interrupted(niso_js* js);

Milliseconds since the Unix epoch on the DOM’s clock (niso_dom_wall_clock), which skips ahead with virtual time. Date.now() and new Date() should read it; an engine that lets an embedder set its Date’s clock sets it to this.

double niso_js_wall_clock(niso_js* js);

The absolute URL a module specifier imported from base names, malloc’ed and NUL-terminated, or NULL when it names none (a bare specifier).

char* niso_js_module_url(niso_js* js, const char* specifier, const char* base);

The source at url from the DOM’s loader, malloc’ed and NUL-terminated, or NULL when it cannot load.

char* niso_js_load(niso_js* js, const char* url, size_t* len);

FNV-1a over a script’s bytes: how an ahead-of-time engine finds a script it was built with.

uint64_t niso_js_script_hash(const char* src, size_t len);

Implemented by the engine. qe_runs_workers says whether niso_js runs dedicated workers on threads of its own, with an engine per thread; an engine whose host starts the threads (Node-API’s, through the core’s worker host) or that has no engine per thread (Porffor’s) says false. qe_new evaluates the glue, calls it with an object holding every host function and the global object, and keeps the hooks it returns.

extern const bool qe_runs_workers;
qe_engine* qe_new(niso_js* js);
void qe_free(qe_engine* e);

0 on success; an uncaught exception is reported and counted. When result is non-null, a successful eval stores the completion value converted to a string there, malloc’ed and NUL-terminated, with its length in result_len.

int qe_eval(qe_engine* e, const char* src, size_t len, const char* name, char** result, size_t* result_len);

Runs a module script at url and the module graph it imports, which loads through niso_js_module_url and niso_js_load. Errors, including a top-level await that rejects later, are reported as unhandled rejections.

void qe_eval_module(qe_engine* e, const char* src, size_t len, const char* url);

From a host function: runs a classic script, whose exception propagates to the host function’s caller instead of being reported (importScripts). With compile_only it only parses the script, and a parse error is not thrown. 0 on success, 1 when it threw, 2 when it does not parse.

int qe_eval_args(qe_args* a, const char* src, size_t len, const char* name, bool compile_only);

Runs microtasks, then reports the promises rejected with no handler.

void qe_run_microtasks(qe_engine* e);
void qe_gc(qe_engine* e);

Calls a hook with numeric arguments. Exceptions are reported; the result is NaN then, or when the hook returns a non-number.

double qe_hook(qe_engine* e, enum qe_hook hook, const double* args, size_t n);
size_t qe_argc(qe_args* a);
double qe_num(qe_args* a, size_t i);
bool qe_bool(qe_args* a, size_t i);

True for null, undefined, or a missing argument.

bool qe_null(qe_args* a, size_t i);
const char* qe_str(qe_args* a, size_t i, size_t* len);
size_t qe_len(qe_args* a, size_t i);
bool qe_item_is_str(qe_args* a, size_t i, size_t j);
double qe_item_num(qe_args* a, size_t i, size_t j);
const char* qe_item_str(qe_args* a, size_t i, size_t j, size_t* len);
bool qe_is_str(qe_args* a, size_t i);

The bytes of an ArrayBuffer, typed array or DataView argument, valid until the host function returns; NULL with *len 0 for anything else.

const uint8_t* qe_bytes(qe_args* a, size_t i, size_t* len);
void qe_ret_num(qe_args* a, double v);
void qe_ret_bool(qe_args* a, bool v);

A NULL ptr returns null.

void qe_ret_str(qe_args* a, const char* ptr, size_t len);
void qe_ret_nums(qe_args* a, const double* v, size_t n);
void qe_ret_strs(qe_args* a, const niso_str* v, size_t n);

Returns a new ArrayBuffer holding a copy of the bytes.

void qe_ret_bytes(qe_args* a, const uint8_t* ptr, size_t len);

Whether the engine can return an ArrayBuffer over bytes it does not own, which a WebAssembly.Memory’s buffer is.

bool qe_can_alias(void);

Returns an ArrayBuffer over len bytes at ptr, not a copy. The caller keeps them alive and unmoved until it detaches the buffer with qe_detach.

void qe_ret_alias(qe_args* a, uint8_t* ptr, size_t len);

Detaches the ArrayBuffer argument i; false if it is not one.

bool qe_detach(qe_args* a, size_t i);

Returns an empty array that qe_push_num, qe_push_str and qe_push_bytes append to.

void qe_ret_list(qe_args* a);
void qe_push_num(qe_args* a, double v);
void qe_push_bytes(qe_args* a, const uint8_t* ptr, size_t len);

A NULL ptr pushes null.

void qe_push_str(qe_args* a, const char* ptr, size_t len);

Throws the glue’s error for a niso_status code.

void qe_throw(qe_args* a, int32_t code, const char* msg, size_t len);