Embedding
Embedding cookbook.
The preview API is synchronous, creator-thread-only and explicit about owned handles. These patterns show the intended host shape without inventing authority for files, networks or timers.
Evaluate and inspect failure
js_runtime *runtime = js_runtime_new();
js_value *result = NULL;
js_status status = js_eval(runtime, "throw new Error('boom')", &result);
if (status != JS_STATUS_OK) {
const char *message = js_runtime_error(runtime);
/* log or copy message before the next API operation */
js_runtime_clear_error(runtime);
}
js_value_free(runtime, result);
js_runtime_free(runtime);
Inject structured host data
js_value *config = js_object_new(runtime);
js_value *port = js_number_new(runtime, 8080);
js_object_set(runtime, config, "port", port);
js_runtime_set_global(runtime, "config", config);
js_value_free(runtime, port);
js_value_free(runtime, config);
Returned handles are owned and tied to one runtime. Inputs must be live handles from that runtime; values never outlive it.
Install a native callback
static js_status add(js_runtime *runtime,
js_value *receiver,
const js_value *const *args,
size_t argc,
void *host_data,
js_value **result) {
double left = 0, right = 0;
if (argc != 2 ||
js_value_get_number(runtime, args[0], &left) != JS_STATUS_OK ||
js_value_get_number(runtime, args[1], &right) != JS_STATUS_OK) {
return JS_STATUS_TYPE_ERROR;
}
*result = js_number_new(runtime, left + right);
return *result ? JS_STATUS_OK : JS_STATUS_OUT_OF_MEMORY;
}
Callback receiver and arguments are borrowed for the invocation. A successful callback transfers one owned result handle to the engine. Same-thread re-entry is supported; asynchronous and cross-thread callbacks are not.
Contain untrusted work and recover
js_runtime_set_instruction_limit(runtime, 10000);
js_runtime_set_call_stack_limit(runtime, 128);
js_runtime_set_allocation_limit(runtime, 4 * 1024 * 1024);
js_status status = js_eval(runtime, "while (true) {}", &result);
if (status == JS_STATUS_LIMIT_EXCEEDED) {
js_runtime_clear_error(runtime);
js_runtime_set_instruction_limit(runtime, 20000);
status = js_eval(runtime, "40 + 2", &result);
}
Containment is not a sandbox. JS++ grants no I/O authority itself, but a host callback can grant authority. Resource limits are deterministic synchronous execution controls, not process isolation or asynchronous cancellation.