blob: 8b590e5c1c1e1be6415d2c10a0c24c85c033dff8 [file]
// Generated by src/wasm/idl/generate.py from bindings.py. Do not edit.
//
// rive_module_imports.mjs, the lane modules, rive_parallel.mjs and
// rive_script_runner.mjs as one script.
// Link it into an emscripten build of librive with --pre-js and the
// script runner installs itself as Module.riveScripting.
(function () {
// Generated by src/wasm/idl/generate.py from bindings.py. Do not edit.
// The runtime import object for script modules executing on the
// browser engine. Scalars forward straight into the host call
// table; str/buf/pod params stage through the host heap because
// the host cannot dereference module memory. `addr` params pass
// through as module addresses, which the host reads through its
// own memory seam.
//
// host contract:
// calls per-op host entry points (native-pointer convention)
// heapU8() Uint8Array over the host heap (refresh per call)
// stackSave() -> mark
// stackAlloc(size) -> host heap ptr valid until its mark is restored
// stackRestore(mark)
// malloc(size) -> host heap ptr, free(ptr)
// counters optional bridge tallies, counted while counters.on
// Staging nests: a host op may call back into the module, whose
// imports stage again above the outer call. Buffers too big for the
// host stack stage on its heap instead.
// moduleMemory: late-bound accessor for the script module memory,
// set after instantiation.
// only: the one namespace to build, as a lane needs, or null for all.
//
// Names that cross to wasm are quoted so a closure compiled host
// cannot rename them.
function createRiveModuleImports(host, moduleMemory, only = null) {
const want = (module) => only === null || only === module;
const calls = host.calls;
const stackSave = host.stackSave;
const stackRestore = host.stackRestore;
const kStackStageLimit = 4096;
const counters = host.counters ?? { on: false };
// Rebuilt only when the module memory grows.
let moduleBytes = null;
const moduleU8 = () => {
const buffer = moduleMemory().buffer;
if (moduleBytes === null || moduleBytes.buffer !== buffer) {
moduleBytes = new Uint8Array(buffer);
}
return moduleBytes;
};
// Checked first: a range the module lacks throws before the alloc.
// Module addresses and lengths arrive as signed i32s.
const stageOut = (ptr, len) => {
if (len < 0 || (ptr >>> 0) + len > moduleU8().length) {
throw new RangeError('module range out of bounds');
}
const dst =
len > kStackStageLimit ? host.malloc(len) : host.stackAlloc(len);
if (dst === 0) {
throw new Error(`could not stage ${len} bytes for the host`);
}
return dst;
};
const stageIn = (ptr, len) => {
const dst = stageOut(ptr, len);
ptr >>>= 0;
host.heapU8().set(moduleBytes.subarray(ptr, ptr + len), dst);
if (counters.on) counters.bytesStaged += len;
return dst;
};
const unstage = (dst, len) => {
if (dst !== 0 && len > kStackStageLimit) {
host.free(dst);
}
};
const copyOut = (src, ptr, len) => {
if (len === 0) {
return;
}
moduleU8().set(host.heapU8().subarray(src, src + len), ptr >>> 0);
if (counters.on) counters.bytesCopiedOut += len;
};
// The elements a size answer wrote: all of them when they fit.
const fitted = (size, capacity) =>
size >>> 0 <= capacity ? size >>> 0 : 0;
// Stages the managed string at text for fn(staged, byteLength). Null
// reads as empty and the rest outside module memory traps, as on WAMR.
const stageManaged = (text, fn) => {
const length = managedLength(moduleMemory().buffer, text);
const mark = stackSave();
let text_p = 0;
try {
text_p = stageIn(text, length);
fn(text_p, length);
} finally {
unstage(text_p, length);
stackRestore(mark);
}
};
// The std console, under the method codes rive_web_console takes.
const consoleCall = (method) => (text) =>
stageManaged(text, (text_p, length) =>
calls.rive_console(method, text_p, length)
);
return {
// Imported only by scripts that call Math.random, trace or console.
'env': {
'seed': () => Date.now() * Math.random(),
// Where modules baked before rive_rt_v1.now read the clocks.
'emscripten_get_now': () => performance.now(),
'emscripten_date_now': () => Date.now(),
'trace': (message, n, a0, a1, a2, a3, a4) =>
stageManaged(message, (text_p, length) =>
calls.rive_trace(text_p, length, n, a0, a1, a2, a3, a4)
),
'console.log': consoleCall(0),
'console.debug': consoleCall(0),
'console.info': consoleCall(0),
'console.warn': consoleCall(0),
'console.error': consoleCall(0),
'console.time': consoleCall(1),
'console.timeLog': consoleCall(2),
'console.timeEnd': consoleCall(3),
},
'rive_rt_v1': want('rive_rt_v1') && {
'log': (level, message, length) => {
const mark = stackSave();
let message_p = 0;
try {
message_p = stageIn(message, length);
calls.rive_rt_log(level, message_p, length);
} finally {
unstage(message_p, length);
stackRestore(mark);
}
},
'mark_needs_update': calls.rive_rt_mark_needs_update,
'budget_exceeded': calls.rive_rt_budget_exceeded,
'error': (message, length) => {
const mark = stackSave();
let message_p = 0;
try {
message_p = stageIn(message, length);
calls.rive_rt_error(message_p, length);
} finally {
unstage(message_p, length);
stackRestore(mark);
}
},
'now': () => performance.now(),
'date_now': () => Date.now(),
'debug_enter': calls.rive_rt_debug_enter,
'debug_line': calls.rive_rt_debug_line,
'debug_leave': calls.rive_rt_debug_leave,
'utc_offset': calls.rive_rt_utc_offset,
'is_dst': calls.rive_rt_is_dst,
'zone_name': (epochSeconds, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_rt_zone_name(epochSeconds, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
},
'rive_data_v1': want('rive_data_v1') && {
'view_model': calls.rive_data_view_model,
'root_view_model': calls.rive_data_root_view_model,
'global_view_model': (object, name, nameLength) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, nameLength);
return calls.rive_data_global_view_model(object, name_p, nameLength);
} finally {
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'global_view_model_names': (object, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_data_global_view_model_names(object, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'context': calls.rive_data_context,
'context_parent': calls.rive_data_context_parent,
'context_view_model': calls.rive_data_context_view_model,
'context_release': calls.rive_data_context_release,
'has_view_model': (name, nameLength) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, nameLength);
return calls.rive_data_has_view_model(name_p, nameLength);
} finally {
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'new_view_model': (name, nameLength, templateName, templateLength) => {
const mark = stackSave();
let name_p = 0;
let templateName_p = 0;
try {
name_p = stageIn(name, nameLength);
templateName_p = stageIn(templateName, templateLength);
return calls.rive_data_new_view_model(name_p, nameLength, templateName_p, templateLength);
} finally {
unstage(templateName_p, templateLength);
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'vmi_release': calls.rive_data_vmi_release,
'vmi_number': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_number(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_boolean': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_boolean(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_string': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_string(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_trigger': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_trigger(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_color': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_color(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_view_model': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_view_model(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_property': (vmi, name, length, kindOut, kindCount) => {
const mark = stackSave();
let name_p = 0;
let kindOut_p = 0;
try {
name_p = stageIn(name, length);
kindOut_p = stageIn(kindOut, kindCount * 4);
const ret = calls.rive_data_vmi_property(vmi, name_p, length, kindOut_p, kindCount);
copyOut(kindOut_p, kindOut, kindCount * 4);
return ret;
} finally {
unstage(kindOut_p, kindCount * 4);
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_instance': (vmi, name, nameLength) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, nameLength);
return calls.rive_data_vmi_instance(vmi, name_p, nameLength);
} finally {
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'vmi_symbol_index': calls.rive_data_vmi_symbol_index,
'vmi_equal': calls.rive_data_vmi_equal,
'view_model_get': calls.rive_data_view_model_get,
'vmi_list': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_list(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_enum': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_enum(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_image': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_image(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_font': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_font(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_blob': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_blob(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'vmi_artboard': (vmi, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_data_vmi_artboard(vmi, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'image_get': calls.rive_data_image_get,
'image_set': calls.rive_data_image_set,
'font_get': calls.rive_data_font_get,
'font_set': calls.rive_data_font_set,
'font_release': calls.rive_data_font_release,
'blob_present': calls.rive_data_blob_present,
'blob_get': (property, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_data_blob_get(property, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'blob_name': (property, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_data_blob_name(property, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'blob_set': (property, bytes, byteCount) => {
const mark = stackSave();
let bytes_p = 0;
try {
bytes_p = stageIn(bytes, byteCount);
calls.rive_data_blob_set(property, bytes_p, byteCount);
} finally {
unstage(bytes_p, byteCount);
stackRestore(mark);
}
},
'blob_clear': calls.rive_data_blob_clear,
'artboard_get': calls.rive_data_artboard_get,
'artboard_set': calls.rive_data_artboard_set,
'enum_get': (property, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_data_enum_get(property, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'enum_set': (property, value, length) => {
const mark = stackSave();
let value_p = 0;
try {
value_p = stageIn(value, length);
calls.rive_data_enum_set(property, value_p, length);
} finally {
unstage(value_p, length);
stackRestore(mark);
}
},
'enum_values': (property, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_data_enum_values(property, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'prop_release': calls.rive_data_prop_release,
'trigger_fire': calls.rive_data_trigger_fire,
'list_length': calls.rive_data_list_length,
'list_push': calls.rive_data_list_push,
'list_pop': calls.rive_data_list_pop,
'list_shift': calls.rive_data_list_shift,
'list_clear': calls.rive_data_list_clear,
'list_swap': calls.rive_data_list_swap,
'list_insert': calls.rive_data_list_insert,
'list_remove': calls.rive_data_list_remove,
'list_remove_at': calls.rive_data_list_remove_at,
'list_remove_all_of': calls.rive_data_list_remove_all_of,
'list_get': calls.rive_data_list_get,
'view_model_set': calls.rive_data_view_model_set,
'color_get': calls.rive_data_color_get,
'color_set': calls.rive_data_color_set,
'number_get': calls.rive_data_number_get,
'number_set': calls.rive_data_number_set,
'boolean_get': calls.rive_data_boolean_get,
'boolean_set': calls.rive_data_boolean_set,
'string_get': (property, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_data_string_get(property, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'string_changed': calls.rive_data_string_changed,
'string_set': (property, value, length) => {
const mark = stackSave();
let value_p = 0;
try {
value_p = stageIn(value, length);
calls.rive_data_string_set(property, value_p, length);
} finally {
unstage(value_p, length);
stackRestore(mark);
}
},
'watch': calls.rive_data_watch,
'unwatch': calls.rive_data_unwatch,
'convert_result': (kind, number, booleanValue, color, value, length) => {
const mark = stackSave();
let value_p = 0;
try {
value_p = stageIn(value, length);
calls.rive_data_convert_result(kind, number, booleanValue, color, value_p, length);
} finally {
unstage(value_p, length);
stackRestore(mark);
}
},
},
'rive_artboard_v1': want('rive_artboard_v1') && {
'release': calls.rive_artboard_release,
'advance': calls.rive_artboard_advance,
'draw': calls.rive_artboard_draw,
'instance': calls.rive_artboard_instance,
'data': calls.rive_artboard_data,
'width': calls.rive_artboard_width,
'height': calls.rive_artboard_height,
'set_width': calls.rive_artboard_set_width,
'set_height': calls.rive_artboard_set_height,
'frame_origin': calls.rive_artboard_frame_origin,
'set_frame_origin': calls.rive_artboard_set_frame_origin,
'bounds': (artboard, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_artboard_bounds(artboard, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'pointer_event': calls.rive_artboard_pointer_event,
'scroll_event': calls.rive_artboard_scroll_event,
'gamepad_event': (artboard, payload, byteCount) => {
const mark = stackSave();
let payload_p = 0;
try {
payload_p = stageIn(payload, byteCount);
return calls.rive_artboard_gamepad_event(artboard, payload_p, byteCount);
} finally {
unstage(payload_p, byteCount);
stackRestore(mark);
}
},
'animation': (artboard, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_artboard_animation(artboard, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'animation_release': calls.rive_artboard_animation_release,
'animation_duration': calls.rive_artboard_animation_duration,
'animation_advance': calls.rive_artboard_animation_advance,
'animation_set_time': calls.rive_artboard_animation_set_time,
'add_to_path': calls.rive_artboard_add_to_path,
'node': (artboard, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_artboard_node(artboard, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'node_release': calls.rive_artboard_node_release,
'node_transform': (node, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_artboard_node_transform(node, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'node_set': calls.rive_artboard_node_set,
'node_world_transform': (node, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_artboard_node_world_transform(node, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'node_set_world_transform': (node, values, floatCount) => {
const mark = stackSave();
let values_p = 0;
try {
values_p = stageIn(values, floatCount * 4);
calls.rive_artboard_node_set_world_transform(node, values_p, floatCount);
} finally {
unstage(values_p, floatCount * 4);
stackRestore(mark);
}
},
'node_decompose': (node, values, floatCount) => {
const mark = stackSave();
let values_p = 0;
try {
values_p = stageIn(values, floatCount * 4);
calls.rive_artboard_node_decompose(node, values_p, floatCount);
} finally {
unstage(values_p, floatCount * 4);
stackRestore(mark);
}
},
'node_path_verbs': (node, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount);
const ret = calls.rive_artboard_node_path_verbs(node, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
stackRestore(mark);
}
},
'node_path_points': (node, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_artboard_node_path_points(node, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'node_paint': (node, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_artboard_node_paint(node, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'node_children': (node, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_artboard_node_children(node, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'node_parent': calls.rive_artboard_node_parent,
'property_key': (artboard, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_artboard_property_key(artboard, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'draw_visit': calls.rive_artboard_draw_visit,
'draw_modulated': calls.rive_artboard_draw_modulated,
'drawable_draw': calls.rive_artboard_drawable_draw,
'drawable_value': (drawable, key, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_artboard_drawable_value(drawable, key, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'drawable_string': (drawable, key, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount);
const ret = calls.rive_artboard_drawable_string(drawable, key, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
stackRestore(mark);
}
},
'drawable_properties': (drawable, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount);
const ret = calls.rive_artboard_drawable_properties(drawable, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
stackRestore(mark);
}
},
},
'rive_audio_v1': want('rive_audio_v1') && {
'source': (object, name, nameLength) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, nameLength);
return calls.rive_audio_source(object, name_p, nameLength);
} finally {
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'source_release': calls.rive_audio_source_release,
'source_duration': calls.rive_audio_source_duration,
'source_sample_rate': calls.rive_audio_source_sample_rate,
'source_channels': calls.rive_audio_source_channels,
'source_to_blob': calls.rive_audio_source_to_blob,
'stream': calls.rive_audio_stream,
'stream_ring': calls.rive_audio_stream_ring,
'stream_seeks': calls.rive_audio_stream_seeks,
'stream_channels': calls.rive_audio_stream_channels,
'stream_sample_rate': calls.rive_audio_stream_sample_rate,
'stream_seek_frame': calls.rive_audio_stream_seek_frame,
'stream_set_loop': calls.rive_audio_stream_set_loop,
'stream_ended': calls.rive_audio_stream_ended,
'stream_release': calls.rive_audio_stream_release,
'play': calls.rive_audio_play,
'play_at_time': calls.rive_audio_play_at_time,
'play_in_time': calls.rive_audio_play_in_time,
'play_at_frame': calls.rive_audio_play_at_frame,
'play_in_frame': calls.rive_audio_play_in_frame,
'time': calls.rive_audio_time,
'time_frame': calls.rive_audio_time_frame,
'sample_rate': calls.rive_audio_sample_rate,
'processor_sample_rate': calls.rive_audio_processor_sample_rate,
'processor_channels': calls.rive_audio_processor_channels,
'sound_release': calls.rive_audio_sound_release,
'sound_play': calls.rive_audio_sound_play,
'sound_pause': calls.rive_audio_sound_pause,
'sound_resume': calls.rive_audio_sound_resume,
'sound_stop': calls.rive_audio_sound_stop,
'sound_seek': calls.rive_audio_sound_seek,
'sound_seek_frame': calls.rive_audio_sound_seek_frame,
'sound_completed': calls.rive_audio_sound_completed,
'sound_time': calls.rive_audio_sound_time,
'sound_time_frame': calls.rive_audio_sound_time_frame,
'sound_volume': calls.rive_audio_sound_volume,
'sound_set_volume': calls.rive_audio_sound_set_volume,
},
'rive_path_v1': want('rive_path_v1') && {
'new': calls.rive_path_new,
'update': (path, verbs, verbCount, points, floatCount, fillRule) => {
const mark = stackSave();
let verbs_p = 0;
let points_p = 0;
try {
verbs_p = stageIn(verbs, verbCount);
points_p = stageIn(points, floatCount * 4);
calls.rive_path_update(path, verbs_p, verbCount, points_p, floatCount, fillRule);
} finally {
unstage(points_p, floatCount * 4);
unstage(verbs_p, verbCount);
stackRestore(mark);
}
},
'release': calls.rive_path_release,
'add': calls.rive_path_add,
'verbs': (path, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount);
const ret = calls.rive_path_verbs(path, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
stackRestore(mark);
}
},
'points': (path, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_path_points(path, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'effect_result': (verbs, verbCount, points, floatCount) => {
const mark = stackSave();
let verbs_p = 0;
let points_p = 0;
try {
verbs_p = stageIn(verbs, verbCount);
points_p = stageIn(points, floatCount * 4);
calls.rive_path_effect_result(verbs_p, verbCount, points_p, floatCount);
} finally {
unstage(points_p, floatCount * 4);
unstage(verbs_p, verbCount);
stackRestore(mark);
}
},
},
'rive_measure_v1': want('rive_measure_v1') && {
'path_new': (verbs, verbCount, points, floatCount) => {
const mark = stackSave();
let verbs_p = 0;
let points_p = 0;
try {
verbs_p = stageIn(verbs, verbCount);
points_p = stageIn(points, floatCount * 4);
return calls.rive_measure_path_new(verbs_p, verbCount, points_p, floatCount);
} finally {
unstage(points_p, floatCount * 4);
unstage(verbs_p, verbCount);
stackRestore(mark);
}
},
'contours_new': (verbs, verbCount, points, floatCount) => {
const mark = stackSave();
let verbs_p = 0;
let points_p = 0;
try {
verbs_p = stageIn(verbs, verbCount);
points_p = stageIn(points, floatCount * 4);
return calls.rive_measure_contours_new(verbs_p, verbCount, points_p, floatCount);
} finally {
unstage(points_p, floatCount * 4);
unstage(verbs_p, verbCount);
stackRestore(mark);
}
},
'contour_next': calls.rive_measure_contour_next,
'length': calls.rive_measure_length,
'is_closed': calls.rive_measure_is_closed,
'pos_tan': (measure, distance, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_measure_pos_tan(measure, distance, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'warp': (measure, x, y, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_measure_warp(measure, x, y, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'extract': calls.rive_measure_extract,
'extract_read': (measure, verbs, verbCount, points, floatCount) => {
const mark = stackSave();
let verbs_p = 0;
let points_p = 0;
try {
verbs_p = stageIn(verbs, verbCount);
points_p = stageIn(points, floatCount * 4);
const ret = calls.rive_measure_extract_read(measure, verbs_p, verbCount, points_p, floatCount);
copyOut(verbs_p, verbs, verbCount);
copyOut(points_p, points, floatCount * 4);
return ret;
} finally {
unstage(points_p, floatCount * 4);
unstage(verbs_p, verbCount);
stackRestore(mark);
}
},
'release': calls.rive_measure_release,
},
'rive_paint_v1': want('rive_paint_v1') && {
'new': calls.rive_paint_new,
'release': calls.rive_paint_release,
'style': calls.rive_paint_style,
'color': calls.rive_paint_color,
'thickness': calls.rive_paint_thickness,
'join': calls.rive_paint_join,
'cap': calls.rive_paint_cap,
'blend_mode': calls.rive_paint_blend_mode,
'feather': calls.rive_paint_feather,
'shader': calls.rive_paint_shader,
'shader_transform': (paint, values, floatCount) => {
const mark = stackSave();
let values_p = 0;
try {
values_p = stageIn(values, floatCount * 4);
calls.rive_paint_shader_transform(paint, values_p, floatCount);
} finally {
unstage(values_p, floatCount * 4);
stackRestore(mark);
}
},
},
'rive_canvas_v1': want('rive_canvas_v1') && {
'new': calls.rive_canvas_new,
'release': calls.rive_canvas_release,
'width': calls.rive_canvas_width,
'height': calls.rive_canvas_height,
'resize': calls.rive_canvas_resize,
'image': calls.rive_canvas_image,
'begin_frame': calls.rive_canvas_begin_frame,
'end_frame': calls.rive_canvas_end_frame,
},
'rive_gpu_v1': want('rive_gpu_v1') && {
'features': (out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_gpu_features(out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'canvas_new': calls.rive_gpu_canvas_new,
'canvas_release': calls.rive_gpu_canvas_release,
'canvas_color_view': (canvas, props, propCount) => {
const mark = stackSave();
let props_p = 0;
try {
props_p = stageIn(props, propCount * 4);
const ret = calls.rive_gpu_canvas_color_view(canvas, props_p, propCount);
copyOut(props_p, props, propCount * 4);
return ret;
} finally {
unstage(props_p, propCount * 4);
stackRestore(mark);
}
},
'canvas_image': calls.rive_gpu_canvas_image,
'canvas_resize': (canvas, width, height, props, propCount) => {
const mark = stackSave();
let props_p = 0;
try {
props_p = stageIn(props, propCount * 4);
const ret = calls.rive_gpu_canvas_resize(canvas, width, height, props_p, propCount);
copyOut(props_p, props, propCount * 4);
return ret;
} finally {
unstage(props_p, propCount * 4);
stackRestore(mark);
}
},
'target_view': (current, props, propCount) => {
const mark = stackSave();
let props_p = 0;
try {
props_p = stageIn(props, propCount * 4);
const ret = calls.rive_gpu_target_view(current, props_p, propCount);
copyOut(props_p, props, propCount * 4);
return ret;
} finally {
unstage(props_p, propCount * 4);
stackRestore(mark);
}
},
'pass_begin': (desc, descByteCount, blob, blobCount) => {
const mark = stackSave();
let desc_p = 0;
let blob_p = 0;
try {
desc_p = stageIn(desc, descByteCount);
blob_p = stageIn(blob, blobCount);
return calls.rive_gpu_pass_begin(desc_p, descByteCount, blob_p, blobCount);
} finally {
unstage(blob_p, blobCount);
unstage(desc_p, descByteCount);
stackRestore(mark);
}
},
'pass_set_pipeline': calls.rive_gpu_pass_set_pipeline,
'pass_set_vertex_buffer': calls.rive_gpu_pass_set_vertex_buffer,
'pass_set_index_buffer': calls.rive_gpu_pass_set_index_buffer,
'pass_set_bind_group': (pass, groupIndex, bindGroup, dynamicOffsets, dynamicOffsetByteCount) => {
const mark = stackSave();
let dynamicOffsets_p = 0;
try {
dynamicOffsets_p = stageIn(dynamicOffsets, dynamicOffsetByteCount);
calls.rive_gpu_pass_set_bind_group(pass, groupIndex, bindGroup, dynamicOffsets_p, dynamicOffsetByteCount);
} finally {
unstage(dynamicOffsets_p, dynamicOffsetByteCount);
stackRestore(mark);
}
},
'pass_set_viewport': calls.rive_gpu_pass_set_viewport,
'pass_set_scissor': calls.rive_gpu_pass_set_scissor,
'pass_set_stencil_reference': calls.rive_gpu_pass_set_stencil_reference,
'pass_set_blend_color': calls.rive_gpu_pass_set_blend_color,
'pass_draw': calls.rive_gpu_pass_draw,
'pass_draw_indexed': calls.rive_gpu_pass_draw_indexed,
'pass_finish': calls.rive_gpu_pass_finish,
'pass_release': calls.rive_gpu_pass_release,
'image_view': calls.rive_gpu_image_view,
'buffer_new': (usage, sizeInBytes, immutable, data, dataCount) => {
const mark = stackSave();
let data_p = 0;
try {
data_p = stageIn(data, dataCount);
return calls.rive_gpu_buffer_new(usage, sizeInBytes, immutable, data_p, dataCount);
} finally {
unstage(data_p, dataCount);
stackRestore(mark);
}
},
'buffer_update': (buffer, dstOffset, data, dataCount) => {
const mark = stackSave();
let data_p = 0;
try {
data_p = stageIn(data, dataCount);
calls.rive_gpu_buffer_update(buffer, dstOffset, data_p, dataCount);
} finally {
unstage(data_p, dataCount);
stackRestore(mark);
}
},
'buffer_update_blob': calls.rive_gpu_buffer_update_blob,
'buffer_new_blob': calls.rive_gpu_buffer_new_blob,
'buffer_release': calls.rive_gpu_buffer_release,
'texture_new': (desc, descByteCount) => {
const mark = stackSave();
let desc_p = 0;
try {
desc_p = stageIn(desc, descByteCount);
return calls.rive_gpu_texture_new(desc_p, descByteCount);
} finally {
unstage(desc_p, descByteCount);
stackRestore(mark);
}
},
'texture_upload': (texture, region, regionByteCount, data, dataCount) => {
const mark = stackSave();
let region_p = 0;
let data_p = 0;
try {
region_p = stageIn(region, regionByteCount);
data_p = stageIn(data, dataCount);
calls.rive_gpu_texture_upload(texture, region_p, regionByteCount, data_p, dataCount);
} finally {
unstage(data_p, dataCount);
unstage(region_p, regionByteCount);
stackRestore(mark);
}
},
'texture_release': calls.rive_gpu_texture_release,
'sampler_new': (desc, descByteCount) => {
const mark = stackSave();
let desc_p = 0;
try {
desc_p = stageIn(desc, descByteCount);
return calls.rive_gpu_sampler_new(desc_p, descByteCount);
} finally {
unstage(desc_p, descByteCount);
stackRestore(mark);
}
},
'sampler_release': calls.rive_gpu_sampler_release,
'texture_view_new': (texture, desc, descByteCount) => {
const mark = stackSave();
let desc_p = 0;
try {
desc_p = stageIn(desc, descByteCount);
return calls.rive_gpu_texture_view_new(texture, desc_p, descByteCount);
} finally {
unstage(desc_p, descByteCount);
stackRestore(mark);
}
},
'texture_view_release': calls.rive_gpu_texture_view_release,
'shader_target': calls.rive_gpu_shader_target,
'shader_asset_bytes': (object, name, nameLength, out, outCount) => {
const mark = stackSave();
let name_p = 0;
let out_p = 0;
try {
name_p = stageIn(name, nameLength);
out_p = stageIn(out, outCount);
const ret = calls.rive_gpu_shader_asset_bytes(object, name_p, nameLength, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'shader_asset_id': (object, name, nameLength) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, nameLength);
return calls.rive_gpu_shader_asset_id(object, name_p, nameLength);
} finally {
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'shader_module_from_asset': (object, name, nameLength, entry) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, nameLength);
return calls.rive_gpu_shader_module_from_asset(object, name_p, nameLength, entry);
} finally {
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'shader_module_from_rstb': (rstb, rstbCount, assetId, entry) => {
const mark = stackSave();
let rstb_p = 0;
try {
rstb_p = stageIn(rstb, rstbCount);
return calls.rive_gpu_shader_module_from_rstb(rstb_p, rstbCount, assetId, entry);
} finally {
unstage(rstb_p, rstbCount);
stackRestore(mark);
}
},
'shader_module_release': calls.rive_gpu_shader_module_release,
'bind_group_layout_new': (groupIndex, entries, entryByteCount) => {
const mark = stackSave();
let entries_p = 0;
try {
entries_p = stageIn(entries, entryByteCount);
return calls.rive_gpu_bind_group_layout_new(groupIndex, entries_p, entryByteCount);
} finally {
unstage(entries_p, entryByteCount);
stackRestore(mark);
}
},
'bind_group_layout_release': calls.rive_gpu_bind_group_layout_release,
'bind_group_layout_from_shader': (shaderModule, groupIndex, dynamicUBOs, dynamicUBOCount) => {
const mark = stackSave();
let dynamicUBOs_p = 0;
try {
dynamicUBOs_p = stageIn(dynamicUBOs, dynamicUBOCount * 4);
return calls.rive_gpu_bind_group_layout_from_shader(shaderModule, groupIndex, dynamicUBOs_p, dynamicUBOCount);
} finally {
unstage(dynamicUBOs_p, dynamicUBOCount * 4);
stackRestore(mark);
}
},
'bind_group_layout_from_shaders': (vertexModule, fragmentModule, groupIndex, dynamicUBOs, dynamicUBOCount) => {
const mark = stackSave();
let dynamicUBOs_p = 0;
try {
dynamicUBOs_p = stageIn(dynamicUBOs, dynamicUBOCount * 4);
return calls.rive_gpu_bind_group_layout_from_shaders(vertexModule, fragmentModule, groupIndex, dynamicUBOs_p, dynamicUBOCount);
} finally {
unstage(dynamicUBOs_p, dynamicUBOCount * 4);
stackRestore(mark);
}
},
'bind_group_layout_from_entries': (vertexModule, vertexEntry, vertexEntryLength, fragmentModule, fragmentEntry, fragmentEntryLength, groupIndex) => {
const mark = stackSave();
let vertexEntry_p = 0;
let fragmentEntry_p = 0;
try {
vertexEntry_p = stageIn(vertexEntry, vertexEntryLength);
fragmentEntry_p = stageIn(fragmentEntry, fragmentEntryLength);
return calls.rive_gpu_bind_group_layout_from_entries(vertexModule, vertexEntry_p, vertexEntryLength, fragmentModule, fragmentEntry_p, fragmentEntryLength, groupIndex);
} finally {
unstage(fragmentEntry_p, fragmentEntryLength);
unstage(vertexEntry_p, vertexEntryLength);
stackRestore(mark);
}
},
'bind_group_new': (layout, ubos, uboByteCount, textures, textureByteCount, samplers, samplerByteCount) => {
const mark = stackSave();
let ubos_p = 0;
let textures_p = 0;
let samplers_p = 0;
try {
ubos_p = stageIn(ubos, uboByteCount);
textures_p = stageIn(textures, textureByteCount);
samplers_p = stageIn(samplers, samplerByteCount);
return calls.rive_gpu_bind_group_new(layout, ubos_p, uboByteCount, textures_p, textureByteCount, samplers_p, samplerByteCount);
} finally {
unstage(samplers_p, samplerByteCount);
unstage(textures_p, textureByteCount);
unstage(ubos_p, uboByteCount);
stackRestore(mark);
}
},
'bind_group_release': calls.rive_gpu_bind_group_release,
'pipeline_new': (desc, descByteCount, blob, blobCount) => {
const mark = stackSave();
let desc_p = 0;
let blob_p = 0;
try {
desc_p = stageIn(desc, descByteCount);
blob_p = stageIn(blob, blobCount);
return calls.rive_gpu_pipeline_new(desc_p, descByteCount, blob_p, blobCount);
} finally {
unstage(blob_p, blobCount);
unstage(desc_p, descByteCount);
stackRestore(mark);
}
},
'pipeline_release': calls.rive_gpu_pipeline_release,
},
'rive_mat4_v1': want('rive_mat4_v1') && {
'multiply': (out, outBytes, a, aBytes, b, bBytes) => {
const mark = stackSave();
let out_p = 0;
let a_p = 0;
let b_p = 0;
try {
out_p = stageIn(out, outBytes);
a_p = stageIn(a, aBytes);
b_p = stageIn(b, bBytes);
calls.rive_mat4_multiply(out_p, outBytes, a_p, aBytes, b_p, bBytes);
copyOut(out_p, out, outBytes);
} finally {
unstage(b_p, bBytes);
unstage(a_p, aBytes);
unstage(out_p, outBytes);
stackRestore(mark);
}
},
'invert': (out, outBytes, src, srcBytes) => {
const mark = stackSave();
let out_p = 0;
let src_p = 0;
try {
out_p = stageIn(out, outBytes);
src_p = stageIn(src, srcBytes);
const ret = calls.rive_mat4_invert(out_p, outBytes, src_p, srcBytes);
copyOut(out_p, out, outBytes);
return ret;
} finally {
unstage(src_p, srcBytes);
unstage(out_p, outBytes);
stackRestore(mark);
}
},
},
'rive_buffer_v1': want('rive_buffer_v1') && {
'new': calls.rive_buffer_new,
'update': (buffer, bytes, byteCount) => {
const mark = stackSave();
let bytes_p = 0;
try {
bytes_p = stageIn(bytes, byteCount);
calls.rive_buffer_update(buffer, bytes_p, byteCount);
} finally {
unstage(bytes_p, byteCount);
stackRestore(mark);
}
},
'release': calls.rive_buffer_release,
},
'rive_mesh_instances_v1': want('rive_mesh_instances_v1') && {
'new': calls.rive_mesh_instances_new,
'resize': calls.rive_mesh_instances_resize,
'update': (instances, first, bytes, byteCount) => {
const mark = stackSave();
let bytes_p = 0;
try {
bytes_p = stageIn(bytes, byteCount);
calls.rive_mesh_instances_update(instances, first, bytes_p, byteCount);
} finally {
unstage(bytes_p, byteCount);
stackRestore(mark);
}
},
'release': calls.rive_mesh_instances_release,
},
'rive_blob_v1': want('rive_blob_v1') && {
'asset_bytes': (object, name, nameLength, out, outCount) => {
const mark = stackSave();
let name_p = 0;
let out_p = 0;
try {
name_p = stageIn(name, nameLength);
out_p = stageIn(out, outCount);
const ret = calls.rive_blob_asset_bytes(object, name_p, nameLength, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
unstage(name_p, nameLength);
stackRestore(mark);
}
},
},
'rive_image_v1': want('rive_image_v1') && {
'from_asset': (object, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_image_from_asset(object, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'width': calls.rive_image_width,
'height': calls.rive_image_height,
'release': calls.rive_image_release,
'decode': (bytes, byteCount, token) => {
const mark = stackSave();
let bytes_p = 0;
try {
bytes_p = stageIn(bytes, byteCount);
return calls.rive_image_decode(bytes_p, byteCount, token);
} finally {
unstage(bytes_p, byteCount);
stackRestore(mark);
}
},
'decode_cancel': calls.rive_image_decode_cancel,
},
'rive_font_v1': want('rive_font_v1') && {
'from_asset': (object, name, length) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, length);
return calls.rive_font_from_asset(object, name_p, length);
} finally {
unstage(name_p, length);
stackRestore(mark);
}
},
'decode': (bytes, byteCount) => {
const mark = stackSave();
let bytes_p = 0;
try {
bytes_p = stageIn(bytes, byteCount);
return calls.rive_font_decode(bytes_p, byteCount);
} finally {
unstage(bytes_p, byteCount);
stackRestore(mark);
}
},
'release': calls.rive_font_release,
'metrics': (font, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_font_metrics(font, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'weight': calls.rive_font_weight,
'is_italic': calls.rive_font_is_italic,
'axis_count': calls.rive_font_axis_count,
'axis': (font, index, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_font_axis(font, index, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'axis_value': calls.rive_font_axis_value,
'features': (font, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_font_features(font, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'has_glyph': calls.rive_font_has_glyph,
'with_options': (font, coords, coordCount, features, featureCount) => {
const mark = stackSave();
let coords_p = 0;
let features_p = 0;
try {
coords_p = stageIn(coords, coordCount * 4);
features_p = stageIn(features, featureCount * 4);
return calls.rive_font_with_options(font, coords_p, coordCount, features_p, featureCount);
} finally {
unstage(features_p, featureCount * 4);
unstage(coords_p, coordCount * 4);
stackRestore(mark);
}
},
'glyph_verbs': (font, glyph, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount);
const ret = calls.rive_font_glyph_verbs(font, glyph, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
stackRestore(mark);
}
},
'glyph_points': (font, glyph, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_font_glyph_points(font, glyph, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
},
'rive_text_v1': want('rive_text_v1') && {
'new': calls.rive_text_new,
'release': calls.rive_text_release,
'append': (text, chars, length, font, paint, size, lineHeight, letterSpacing, foreground) => {
const mark = stackSave();
let chars_p = 0;
try {
chars_p = stageIn(chars, length);
calls.rive_text_append(text, chars_p, length, font, paint, size, lineHeight, letterSpacing, foreground);
} finally {
unstage(chars_p, length);
stackRestore(mark);
}
},
'clear': calls.rive_text_clear,
'layout': (text, desc, descByteCount) => {
const mark = stackSave();
let desc_p = 0;
try {
desc_p = stageIn(desc, descByteCount);
calls.rive_text_layout(text, desc_p, descByteCount);
} finally {
unstage(desc_p, descByteCount);
stackRestore(mark);
}
},
'draw': calls.rive_text_draw,
'bounds': (text, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
calls.rive_text_bounds(text, out_p, outCount);
copyOut(out_p, out, outCount * 4);
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'length': calls.rive_text_length,
'lines': (text, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_text_lines(text, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'runs': (text, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_text_runs(text, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'glyphs': (text, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_text_glyphs(text, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'hit_test': calls.rive_text_hit_test,
'caret': (text, index, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_text_caret(text, index, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
'selection_rects': (text, from, to, out, outCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageIn(out, outCount * 4);
const ret = calls.rive_text_selection_rects(text, from, to, out_p, outCount);
copyOut(out_p, out, outCount * 4);
return ret;
} finally {
unstage(out_p, outCount * 4);
stackRestore(mark);
}
},
},
'rive_shader_v1': want('rive_shader_v1') && {
'linear': calls.rive_shader_linear,
'radial': calls.rive_shader_radial,
'release': calls.rive_shader_release,
},
'rive_test_v1': want('rive_test_v1') && {
'blob': (name, nameLength, out, outCount) => {
const mark = stackSave();
let name_p = 0;
let out_p = 0;
try {
name_p = stageIn(name, nameLength);
out_p = stageIn(out, outCount);
const ret = calls.rive_test_blob(name_p, nameLength, out_p, outCount);
copyOut(out_p, out, outCount);
return ret;
} finally {
unstage(out_p, outCount);
unstage(name_p, nameLength);
stackRestore(mark);
}
},
},
'rive_transition_v1': want('rive_transition_v1') && {
'child_draw': calls.rive_transition_child_draw,
'child_width': calls.rive_transition_child_width,
'child_height': calls.rive_transition_child_height,
},
'rive_renderer_v1': want('rive_renderer_v1') && {
'save': calls.rive_renderer_save,
'restore': calls.rive_renderer_restore,
'transform': calls.rive_renderer_transform,
'draw_path': calls.rive_renderer_draw_path,
'clip_path': calls.rive_renderer_clip_path,
'modulate_opacity': calls.rive_renderer_modulate_opacity,
'modulate_color': calls.rive_renderer_modulate_color,
'draw_image': calls.rive_renderer_draw_image,
'draw_image_mesh': calls.rive_renderer_draw_image_mesh,
'draw_image_mesh_instanced': calls.rive_renderer_draw_image_mesh_instanced,
},
'rive_net_v1': want('rive_net_v1') && {
'fetch': (request, requestCount, token) => {
const mark = stackSave();
let request_p = 0;
try {
request_p = stageIn(request, requestCount);
return calls.rive_net_fetch(request_p, requestCount, token);
} finally {
unstage(request_p, requestCount);
stackRestore(mark);
}
},
'fetch_cancel': calls.rive_net_fetch_cancel,
},
'rive_file_v1': want('rive_file_v1') && {
'decode': (bytes, byteCount, statusOut, statusCount) => {
const mark = stackSave();
let bytes_p = 0;
let statusOut_p = 0;
try {
bytes_p = stageIn(bytes, byteCount);
statusOut_p = stageIn(statusOut, statusCount * 4);
const ret = calls.rive_file_decode(bytes_p, byteCount, statusOut_p, statusCount);
copyOut(statusOut_p, statusOut, statusCount * 4);
return ret;
} finally {
unstage(statusOut_p, statusCount * 4);
unstage(bytes_p, byteCount);
stackRestore(mark);
}
},
'release': calls.rive_file_release,
'artboard_count': calls.rive_file_artboard_count,
'artboard_name': (file, index, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_file_artboard_name(file, index, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'bindable': (file, name, nameLength, useDefault) => {
const mark = stackSave();
let name_p = 0;
try {
name_p = stageIn(name, nameLength);
return calls.rive_file_bindable(file, name_p, nameLength, useDefault);
} finally {
unstage(name_p, nameLength);
stackRestore(mark);
}
},
'bindable_release': calls.rive_file_bindable_release,
'bindable_name': (bindable, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageIn(buffer, capacity);
const ret = calls.rive_file_bindable_name(bindable, buffer_p, capacity);
copyOut(buffer_p, buffer, capacity);
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'bindable_data': calls.rive_file_bindable_data,
'bindable_equal': calls.rive_file_bindable_equal,
},
'rive_lanes_v1': want('rive_lanes_v1') && {
'start': (kind, entry, input, inputByteCount, holds, holdCount) => {
const mark = stackSave();
let input_p = 0;
let holds_p = 0;
try {
input_p = stageIn(input, inputByteCount);
holds_p = stageIn(holds, holdCount * 4);
return calls.rive_lanes_start(kind, entry, input_p, inputByteCount, holds_p, holdCount);
} finally {
unstage(holds_p, holdCount * 4);
unstage(input_p, inputByteCount);
stackRestore(mark);
}
},
'state': calls.rive_lanes_state,
'failed': (lane, buffer, capacity) => {
const mark = stackSave();
let buffer_p = 0;
try {
buffer_p = stageOut(buffer, capacity);
const ret = calls.rive_lanes_failed(lane, buffer_p, capacity);
copyOut(buffer_p, buffer, fitted(ret, capacity));
return ret;
} finally {
unstage(buffer_p, capacity);
stackRestore(mark);
}
},
'stop': calls.rive_lanes_stop,
'release': calls.rive_lanes_release,
'result': calls.rive_lanes_result,
'watch': calls.rive_lanes_watch,
'wait': calls.rive_lanes_wait,
'cancel_wait': calls.rive_lanes_cancel_wait,
'wait_within': calls.rive_lanes_wait_within,
},
'rive_jobs_v1': want('rive_jobs_v1') && {
'threads': calls.rive_jobs_threads,
'join': calls.rive_jobs_join,
'join_any': (jobs, count, timeoutSeconds) => {
const mark = stackSave();
let jobs_p = 0;
try {
jobs_p = stageIn(jobs, count * 4);
return calls.rive_jobs_join_any(jobs_p, count, timeoutSeconds);
} finally {
unstage(jobs_p, count * 4);
stackRestore(mark);
}
},
},
'rive_parallel_v1': want('rive_parallel_v1') && {
'size': calls.rive_parallel_size,
'run': calls.rive_parallel_run,
'waiting': () => undefined,
},
'rive_shared_v1': want('rive_shared_v1') && {
'region_create': calls.rive_shared_region_create,
'region_size': calls.rive_shared_region_size,
'region_lock': calls.rive_shared_region_lock,
'region_unlock': calls.rive_shared_region_unlock,
'region_read': (region, offset, out, outByteCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageOut(out, outByteCount);
const ret = calls.rive_shared_region_read(region, offset, out_p, outByteCount);
copyOut(out_p, out, ret !== 0 ? outByteCount : 0);
return ret;
} finally {
unstage(out_p, outByteCount);
stackRestore(mark);
}
},
'region_write': (region, offset, data, dataByteCount) => {
const mark = stackSave();
let data_p = 0;
try {
data_p = stageIn(data, dataByteCount);
return calls.rive_shared_region_write(region, offset, data_p, dataByteCount);
} finally {
unstage(data_p, dataByteCount);
stackRestore(mark);
}
},
'region_poisoned': calls.rive_shared_region_poisoned,
'atomic_load': calls.rive_shared_atomic_load,
'atomic_store': calls.rive_shared_atomic_store,
'atomic_add': calls.rive_shared_atomic_add,
'atomic_cas': calls.rive_shared_atomic_cas,
'ring_create': calls.rive_shared_ring_create,
'ring_write': (ring, data, dataByteCount, holds, holdCount) => {
const mark = stackSave();
let data_p = 0;
let holds_p = 0;
try {
data_p = stageIn(data, dataByteCount);
holds_p = stageIn(holds, holdCount * 4);
return calls.rive_shared_ring_write(ring, data_p, dataByteCount, holds_p, holdCount);
} finally {
unstage(holds_p, holdCount * 4);
unstage(data_p, dataByteCount);
stackRestore(mark);
}
},
'ring_read': (ring, out, outByteCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageOut(out, outByteCount);
const ret = calls.rive_shared_ring_read(ring, out_p, outByteCount);
copyOut(out_p, out, fitted(ret - 1, outByteCount));
return ret;
} finally {
unstage(out_p, outByteCount);
stackRestore(mark);
}
},
'ring_drop': calls.rive_shared_ring_drop,
'ring_used': calls.rive_shared_ring_used,
'ring_signal': calls.rive_shared_ring_signal,
'snapshot_create': calls.rive_shared_snapshot_create,
'snapshot_publish': (snapshot, data, dataByteCount, holds, holdCount) => {
const mark = stackSave();
let data_p = 0;
let holds_p = 0;
try {
data_p = stageIn(data, dataByteCount);
holds_p = stageIn(holds, holdCount * 4);
return calls.rive_shared_snapshot_publish(snapshot, data_p, dataByteCount, holds_p, holdCount);
} finally {
unstage(holds_p, holdCount * 4);
unstage(data_p, dataByteCount);
stackRestore(mark);
}
},
'snapshot_read': (snapshot, out, outByteCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageOut(out, outByteCount);
const ret = calls.rive_shared_snapshot_read(snapshot, out_p, outByteCount);
copyOut(out_p, out, fitted(ret - 1, outByteCount));
return ret;
} finally {
unstage(out_p, outByteCount);
stackRestore(mark);
}
},
'snapshot_seq': calls.rive_shared_snapshot_seq,
'read_done': calls.rive_shared_read_done,
'signal_create': calls.rive_shared_signal_create,
'signal_notify': calls.rive_shared_signal_notify,
'signal_seq': calls.rive_shared_signal_seq,
'blob_create': (data, dataByteCount) => {
const mark = stackSave();
let data_p = 0;
try {
data_p = stageIn(data, dataByteCount);
return calls.rive_shared_blob_create(data_p, dataByteCount);
} finally {
unstage(data_p, dataByteCount);
stackRestore(mark);
}
},
'blob_size': calls.rive_shared_blob_size,
'blob_read': (blob, offset, out, outByteCount) => {
const mark = stackSave();
let out_p = 0;
try {
out_p = stageOut(out, outByteCount);
const ret = calls.rive_shared_blob_read(blob, offset, out_p, outByteCount);
copyOut(out_p, out, fitted(ret, outByteCount));
return ret;
} finally {
unstage(out_p, outByteCount);
stackRestore(mark);
}
},
'retain': calls.rive_shared_retain,
'release': calls.rive_shared_release,
},
};
}
// host.calls for one VM. hostCall(index) is the librive function at
// that index of its kRiveWebCalls table, undefined for a missing op.
// ctx.vm is the VM
// handle, zeroed when the VM goes away while its module is still
// instantiating. ctx.raised holds a raiseModuleError message: it is
// thrown once the host call has returned, so only module frames
// unwind. Anything thrown from inside librive unwound its frames
// without their destructors, so ctx.hostFault marks the VM done for.
// ctx.counters, when given, tallies the calls into librive.
// A fault in a nested script call unwinds the outer module frames too.
// only binds just that namespace's calls, as in createRiveModuleImports.
function bindRiveHostCalls(hostCall, ctx, only = null) {
const want = (module) => only === null || only === module;
const counters = ctx.counters ?? { on: false };
const raise = () => {
const error = new Error(ctx.raised);
ctx.raised = null;
throw error;
};
const fault = (error) => {
ctx.hostFault = true;
throw error;
};
const nestedFault = () => {
throw new Error('librive faulted in a nested script call');
};
const released = () => {
throw new Error('script VM was released');
};
return {
rive_rt_log: want('rive_rt_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(0)),
rive_rt_mark_needs_update: want('rive_rt_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(1)),
rive_rt_budget_exceeded: want('rive_rt_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(2)),
rive_rt_error: want('rive_rt_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(3)),
rive_rt_debug_enter: want('rive_rt_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(4)),
rive_rt_debug_line: want('rive_rt_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(5)),
rive_rt_debug_leave: want('rive_rt_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(6)),
rive_rt_utc_offset: want('rive_rt_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(7)),
rive_rt_is_dst: want('rive_rt_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(8)),
rive_rt_zone_name: want('rive_rt_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(9)),
rive_data_view_model: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(10)),
rive_data_root_view_model: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(11)),
rive_data_global_view_model: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(12)),
rive_data_global_view_model_names: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(13)),
rive_data_context: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(14)),
rive_data_context_parent: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(15)),
rive_data_context_view_model: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(16)),
rive_data_context_release: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(17)),
rive_data_has_view_model: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(18)),
rive_data_new_view_model: want('rive_data_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(19)),
rive_data_vmi_release: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(20)),
rive_data_vmi_number: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(21)),
rive_data_vmi_boolean: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(22)),
rive_data_vmi_string: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(23)),
rive_data_vmi_trigger: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(24)),
rive_data_vmi_color: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(25)),
rive_data_vmi_view_model: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(26)),
rive_data_vmi_property: want('rive_data_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(27)),
rive_data_vmi_instance: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(28)),
rive_data_vmi_symbol_index: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(29)),
rive_data_vmi_equal: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(30)),
rive_data_view_model_get: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(31)),
rive_data_vmi_list: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(32)),
rive_data_vmi_enum: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(33)),
rive_data_vmi_image: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(34)),
rive_data_vmi_font: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(35)),
rive_data_vmi_blob: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(36)),
rive_data_vmi_artboard: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(37)),
rive_data_image_get: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(38)),
rive_data_image_set: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(39)),
rive_data_font_get: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(40)),
rive_data_font_set: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(41)),
rive_data_font_release: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(42)),
rive_data_blob_present: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(43)),
rive_data_blob_get: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(44)),
rive_data_blob_name: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(45)),
rive_data_blob_set: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(46)),
rive_data_blob_clear: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(47)),
rive_data_artboard_get: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(48)),
rive_data_artboard_set: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(49)),
rive_data_enum_get: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(50)),
rive_data_enum_set: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(51)),
rive_data_enum_values: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(52)),
rive_data_prop_release: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(53)),
rive_data_trigger_fire: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(54)),
rive_data_list_length: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(55)),
rive_data_list_push: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(56)),
rive_data_list_pop: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(57)),
rive_data_list_shift: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(58)),
rive_data_list_clear: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(59)),
rive_data_list_swap: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(60)),
rive_data_list_insert: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(61)),
rive_data_list_remove: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(62)),
rive_data_list_remove_at: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(63)),
rive_data_list_remove_all_of: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(64)),
rive_data_list_get: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(65)),
rive_data_view_model_set: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(66)),
rive_data_color_get: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(67)),
rive_data_color_set: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(68)),
rive_data_number_get: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(69)),
rive_data_number_set: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(70)),
rive_data_boolean_get: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(71)),
rive_data_boolean_set: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(72)),
rive_data_string_get: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(73)),
rive_data_string_changed: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(74)),
rive_data_string_set: want('rive_data_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(75)),
rive_data_watch: want('rive_data_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(76)),
rive_data_unwatch: want('rive_data_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(77)),
rive_data_convert_result: want('rive_data_v1') && ((fn) => (a0, a1, a2, a3, a4, a5) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(78)),
rive_artboard_release: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(79)),
rive_artboard_advance: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(80)),
rive_artboard_draw: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(81)),
rive_artboard_instance: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(82)),
rive_artboard_data: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(83)),
rive_artboard_width: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(84)),
rive_artboard_height: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(85)),
rive_artboard_set_width: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(86)),
rive_artboard_set_height: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(87)),
rive_artboard_frame_origin: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(88)),
rive_artboard_set_frame_origin: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(89)),
rive_artboard_bounds: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(90)),
rive_artboard_pointer_event: want('rive_artboard_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(91)),
rive_artboard_scroll_event: want('rive_artboard_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6, a7, a8) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6, a7, a8); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(92)),
rive_artboard_gamepad_event: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(93)),
rive_artboard_animation: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(94)),
rive_artboard_animation_release: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(95)),
rive_artboard_animation_duration: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(96)),
rive_artboard_animation_advance: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(97)),
rive_artboard_animation_set_time: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(98)),
rive_artboard_add_to_path: want('rive_artboard_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6, a7) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6, a7); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(99)),
rive_artboard_node: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(100)),
rive_artboard_node_release: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(101)),
rive_artboard_node_transform: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(102)),
rive_artboard_node_set: want('rive_artboard_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(103)),
rive_artboard_node_world_transform: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(104)),
rive_artboard_node_set_world_transform: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(105)),
rive_artboard_node_decompose: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(106)),
rive_artboard_node_path_verbs: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(107)),
rive_artboard_node_path_points: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(108)),
rive_artboard_node_paint: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(109)),
rive_artboard_node_children: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(110)),
rive_artboard_node_parent: want('rive_artboard_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(111)),
rive_artboard_property_key: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(112)),
rive_artboard_draw_visit: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(113)),
rive_artboard_draw_modulated: want('rive_artboard_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(114)),
rive_artboard_drawable_draw: want('rive_artboard_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(115)),
rive_artboard_drawable_value: want('rive_artboard_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(116)),
rive_artboard_drawable_string: want('rive_artboard_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(117)),
rive_artboard_drawable_properties: want('rive_artboard_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_artboard_v1', 'drawable_properties') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(118)),
rive_audio_source: want('rive_audio_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(119)),
rive_audio_source_release: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(120)),
rive_audio_source_duration: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(121)),
rive_audio_source_sample_rate: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(122)),
rive_audio_source_channels: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(123)),
rive_audio_source_to_blob: want('rive_audio_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(124)),
rive_audio_stream: want('rive_audio_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(125)),
rive_audio_stream_ring: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(126)),
rive_audio_stream_seeks: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(127)),
rive_audio_stream_channels: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(128)),
rive_audio_stream_sample_rate: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(129)),
rive_audio_stream_seek_frame: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(130)),
rive_audio_stream_set_loop: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(131)),
rive_audio_stream_ended: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(132)),
rive_audio_stream_release: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(133)),
rive_audio_play: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(134)),
rive_audio_play_at_time: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(135)),
rive_audio_play_in_time: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(136)),
rive_audio_play_at_frame: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(137)),
rive_audio_play_in_frame: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(138)),
rive_audio_time: want('rive_audio_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(139)),
rive_audio_time_frame: want('rive_audio_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(140)),
rive_audio_sample_rate: want('rive_audio_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(141)),
rive_audio_processor_sample_rate: want('rive_audio_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(142)),
rive_audio_processor_channels: want('rive_audio_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(143)),
rive_audio_sound_release: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(144)),
rive_audio_sound_play: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(145)),
rive_audio_sound_pause: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(146)),
rive_audio_sound_resume: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(147)),
rive_audio_sound_stop: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(148)),
rive_audio_sound_seek: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(149)),
rive_audio_sound_seek_frame: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(150)),
rive_audio_sound_completed: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(151)),
rive_audio_sound_time: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(152)),
rive_audio_sound_time_frame: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(153)),
rive_audio_sound_volume: want('rive_audio_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(154)),
rive_audio_sound_set_volume: want('rive_audio_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(155)),
rive_path_new: want('rive_path_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(156)),
rive_path_update: want('rive_path_v1') && ((fn) => (a0, a1, a2, a3, a4, a5) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(157)),
rive_path_release: want('rive_path_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(158)),
rive_path_add: want('rive_path_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6, a7) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6, a7); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(159)),
rive_path_verbs: want('rive_path_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(160)),
rive_path_points: want('rive_path_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(161)),
rive_path_effect_result: want('rive_path_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(162)),
rive_measure_path_new: want('rive_measure_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(163)),
rive_measure_contours_new: want('rive_measure_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(164)),
rive_measure_contour_next: want('rive_measure_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(165)),
rive_measure_length: want('rive_measure_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(166)),
rive_measure_is_closed: want('rive_measure_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(167)),
rive_measure_pos_tan: want('rive_measure_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(168)),
rive_measure_warp: want('rive_measure_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(169)),
rive_measure_extract: want('rive_measure_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(170)),
rive_measure_extract_read: want('rive_measure_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(171)),
rive_measure_release: want('rive_measure_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(172)),
rive_paint_new: want('rive_paint_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(173)),
rive_paint_release: want('rive_paint_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(174)),
rive_paint_style: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(175)),
rive_paint_color: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(176)),
rive_paint_thickness: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(177)),
rive_paint_join: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(178)),
rive_paint_cap: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(179)),
rive_paint_blend_mode: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(180)),
rive_paint_feather: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(181)),
rive_paint_shader: want('rive_paint_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(182)),
rive_paint_shader_transform: want('rive_paint_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(183)),
rive_canvas_new: want('rive_canvas_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(184)),
rive_canvas_release: want('rive_canvas_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(185)),
rive_canvas_width: want('rive_canvas_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(186)),
rive_canvas_height: want('rive_canvas_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(187)),
rive_canvas_resize: want('rive_canvas_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(188)),
rive_canvas_image: want('rive_canvas_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(189)),
rive_canvas_begin_frame: want('rive_canvas_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(190)),
rive_canvas_end_frame: want('rive_canvas_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(191)),
rive_gpu_features: want('rive_gpu_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(192)),
rive_gpu_canvas_new: want('rive_gpu_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(193)),
rive_gpu_canvas_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(194)),
rive_gpu_canvas_color_view: want('rive_gpu_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(195)),
rive_gpu_canvas_image: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(196)),
rive_gpu_canvas_resize: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(197)),
rive_gpu_target_view: want('rive_gpu_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(198)),
rive_gpu_pass_begin: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(199)),
rive_gpu_pass_set_pipeline: want('rive_gpu_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(200)),
rive_gpu_pass_set_vertex_buffer: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(201)),
rive_gpu_pass_set_index_buffer: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(202)),
rive_gpu_pass_set_bind_group: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(203)),
rive_gpu_pass_set_viewport: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(204)),
rive_gpu_pass_set_scissor: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(205)),
rive_gpu_pass_set_stencil_reference: want('rive_gpu_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(206)),
rive_gpu_pass_set_blend_color: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(207)),
rive_gpu_pass_draw: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(208)),
rive_gpu_pass_draw_indexed: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4, a5) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(209)),
rive_gpu_pass_finish: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(210)),
rive_gpu_pass_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(211)),
rive_gpu_image_view: want('rive_gpu_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(212)),
rive_gpu_buffer_new: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(213)),
rive_gpu_buffer_update: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(214)),
rive_gpu_buffer_update_blob: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(215)),
rive_gpu_buffer_new_blob: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(216)),
rive_gpu_buffer_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(217)),
rive_gpu_texture_new: want('rive_gpu_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(218)),
rive_gpu_texture_upload: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(219)),
rive_gpu_texture_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(220)),
rive_gpu_sampler_new: want('rive_gpu_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(221)),
rive_gpu_sampler_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(222)),
rive_gpu_texture_view_new: want('rive_gpu_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(223)),
rive_gpu_texture_view_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(224)),
rive_gpu_shader_target: want('rive_gpu_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(225)),
rive_gpu_shader_asset_bytes: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(226)),
rive_gpu_shader_asset_id: want('rive_gpu_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(227)),
rive_gpu_shader_module_from_asset: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(228)),
rive_gpu_shader_module_from_rstb: want('rive_gpu_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_gpu_v1', 'shader_module_from_rstb') : (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(229)),
rive_gpu_shader_module_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(230)),
rive_gpu_bind_group_layout_new: want('rive_gpu_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(231)),
rive_gpu_bind_group_layout_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(232)),
rive_gpu_bind_group_layout_from_shader: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(233)),
rive_gpu_bind_group_layout_from_shaders: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(234)),
rive_gpu_bind_group_layout_from_entries: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(235)),
rive_gpu_bind_group_new: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(236)),
rive_gpu_bind_group_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(237)),
rive_gpu_pipeline_new: want('rive_gpu_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(238)),
rive_gpu_pipeline_release: want('rive_gpu_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(239)),
rive_mat4_multiply: want('rive_mat4_v1') && ((fn) => (a0, a1, a2, a3, a4, a5) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(240)),
rive_mat4_invert: want('rive_mat4_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(241)),
rive_buffer_new: want('rive_buffer_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(242)),
rive_buffer_update: want('rive_buffer_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(243)),
rive_buffer_release: want('rive_buffer_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(244)),
rive_mesh_instances_new: want('rive_mesh_instances_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(245)),
rive_mesh_instances_resize: want('rive_mesh_instances_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(246)),
rive_mesh_instances_update: want('rive_mesh_instances_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(247)),
rive_mesh_instances_release: want('rive_mesh_instances_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(248)),
rive_blob_asset_bytes: want('rive_blob_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(249)),
rive_image_from_asset: want('rive_image_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(250)),
rive_image_width: want('rive_image_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(251)),
rive_image_height: want('rive_image_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(252)),
rive_image_release: want('rive_image_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(253)),
rive_image_decode: want('rive_image_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(254)),
rive_image_decode_cancel: want('rive_image_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(255)),
rive_font_from_asset: want('rive_font_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(256)),
rive_font_decode: want('rive_font_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_font_v1', 'decode') : (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(257)),
rive_font_release: want('rive_font_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(258)),
rive_font_metrics: want('rive_font_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(259)),
rive_font_weight: want('rive_font_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(260)),
rive_font_is_italic: want('rive_font_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(261)),
rive_font_axis_count: want('rive_font_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(262)),
rive_font_axis: want('rive_font_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(263)),
rive_font_axis_value: want('rive_font_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(264)),
rive_font_features: want('rive_font_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(265)),
rive_font_has_glyph: want('rive_font_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(266)),
rive_font_with_options: want('rive_font_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(267)),
rive_font_glyph_verbs: want('rive_font_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_font_v1', 'glyph_verbs') : (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(268)),
rive_font_glyph_points: want('rive_font_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_font_v1', 'glyph_points') : (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(269)),
rive_text_new: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'new') : () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(270)),
rive_text_release: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'release') : (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(271)),
rive_text_append: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'append') : (a0, a1, a2, a3, a4, a5, a6, a7, a8) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6, a7, a8); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(272)),
rive_text_clear: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'clear') : (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(273)),
rive_text_layout: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'layout') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(274)),
rive_text_draw: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'draw') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(275)),
rive_text_bounds: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'bounds') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(276)),
rive_text_length: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'length') : (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(277)),
rive_text_lines: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'lines') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(278)),
rive_text_runs: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'runs') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(279)),
rive_text_glyphs: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'glyphs') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(280)),
rive_text_hit_test: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'hit_test') : (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(281)),
rive_text_caret: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'caret') : (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(282)),
rive_text_selection_rects: want('rive_text_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_text_v1', 'selection_rects') : (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(283)),
rive_shader_linear: want('rive_shader_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(284)),
rive_shader_radial: want('rive_shader_v1') && ((fn) => (a0, a1, a2, a3, a4, a5) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4, a5); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(285)),
rive_shader_release: want('rive_shader_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(286)),
rive_test_blob: want('rive_test_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(287)),
rive_transition_child_draw: want('rive_transition_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(288)),
rive_transition_child_width: want('rive_transition_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(289)),
rive_transition_child_height: want('rive_transition_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(290)),
rive_renderer_save: want('rive_renderer_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(291)),
rive_renderer_restore: want('rive_renderer_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(292)),
rive_renderer_transform: want('rive_renderer_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(293)),
rive_renderer_draw_path: want('rive_renderer_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(294)),
rive_renderer_clip_path: want('rive_renderer_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(295)),
rive_renderer_modulate_opacity: want('rive_renderer_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(296)),
rive_renderer_modulate_color: want('rive_renderer_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(297)),
rive_renderer_draw_image: want('rive_renderer_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(298)),
rive_renderer_draw_image_mesh: want('rive_renderer_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6, a7) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6, a7); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(299)),
rive_renderer_draw_image_mesh_instanced: want('rive_renderer_v1') && ((fn) => (a0, a1, a2, a3, a4, a5, a6) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(300)),
rive_net_fetch: want('rive_net_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(301)),
rive_net_fetch_cancel: want('rive_net_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(302)),
rive_file_decode: want('rive_file_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(303)),
rive_file_release: want('rive_file_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(304)),
rive_file_artboard_count: want('rive_file_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(305)),
rive_file_artboard_name: want('rive_file_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(306)),
rive_file_bindable: want('rive_file_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(307)),
rive_file_bindable_release: want('rive_file_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(308)),
rive_file_bindable_name: want('rive_file_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(309)),
rive_file_bindable_data: want('rive_file_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(310)),
rive_file_bindable_equal: want('rive_file_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(311)),
rive_lanes_start: want('rive_lanes_v1') && ((fn) => (a0, a1, a2, a3, a4, a5) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4, a5); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(312)),
rive_lanes_state: want('rive_lanes_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(313)),
rive_lanes_failed: want('rive_lanes_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(314)),
rive_lanes_stop: want('rive_lanes_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(315)),
rive_lanes_release: want('rive_lanes_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(316)),
rive_lanes_result: want('rive_lanes_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(317)),
rive_lanes_watch: want('rive_lanes_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(318)),
rive_lanes_wait: want('rive_lanes_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(319)),
rive_lanes_cancel_wait: want('rive_lanes_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(320)),
rive_lanes_wait_within: want('rive_lanes_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(321)),
rive_jobs_threads: want('rive_jobs_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(322)),
rive_jobs_join: want('rive_jobs_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(323)),
rive_jobs_join_any: want('rive_jobs_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(324)),
rive_parallel_size: want('rive_parallel_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(325)),
rive_parallel_run: want('rive_parallel_v1') && ((fn) => fn === undefined ? unlinkedImport('rive_parallel_v1', 'run') : (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(326)),
rive_shared_region_create: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(327)),
rive_shared_region_size: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(328)),
rive_shared_region_lock: want('rive_shared_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(329)),
rive_shared_region_unlock: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(330)),
rive_shared_region_read: want('rive_shared_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(331)),
rive_shared_region_write: want('rive_shared_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(332)),
rive_shared_region_poisoned: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(333)),
rive_shared_atomic_load: want('rive_shared_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(334)),
rive_shared_atomic_store: want('rive_shared_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(335)),
rive_shared_atomic_add: want('rive_shared_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(336)),
rive_shared_atomic_cas: want('rive_shared_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(337)),
rive_shared_ring_create: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(338)),
rive_shared_ring_write: want('rive_shared_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(339)),
rive_shared_ring_read: want('rive_shared_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(340)),
rive_shared_ring_drop: want('rive_shared_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(341)),
rive_shared_ring_used: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(342)),
rive_shared_ring_signal: want('rive_shared_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(343)),
rive_shared_snapshot_create: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(344)),
rive_shared_snapshot_publish: want('rive_shared_v1') && ((fn) => (a0, a1, a2, a3, a4) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3, a4); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(345)),
rive_shared_snapshot_read: want('rive_shared_v1') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(346)),
rive_shared_snapshot_seq: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(347)),
rive_shared_read_done: want('rive_shared_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(348)),
rive_shared_signal_create: want('rive_shared_v1') && ((fn) => () => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(349)),
rive_shared_signal_notify: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(350)),
rive_shared_signal_seq: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(351)),
rive_shared_blob_create: want('rive_shared_v1') && ((fn) => (a0, a1) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(352)),
rive_shared_blob_size: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(353)),
rive_shared_blob_read: want('rive_shared_v1') && ((fn) => (a0, a1, a2, a3) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0, a1, a2, a3); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(354)),
rive_shared_retain: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
let ret;
try { ret = fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
return ret;
})(hostCall(355)),
rive_shared_release: want('rive_shared_v1') && ((fn) => (a0) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(356)),
rive_console: want('env') && ((fn) => (a0, a1, a2) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(357)),
rive_trace: want('env') && ((fn) => (a0, a1, a2, a3, a4, a5, a6, a7) => {
if (ctx.vm === 0) released();
if (counters.on) counters.hostCalls++;
try { fn(ctx.vm, a0, a1, a2, a3, a4, a5, a6, a7); } catch (error) { fault(error); }
if (ctx.hostFault) nestedFault();
if (ctx.raised !== null) raise();
})(hostCall(358)),
};
}
// Stands in for an import the host lacks, so the module still links
// and only a call to it traps, as on WAMR.
function unlinkedImport(module, name) {
return () => {
throw new Error(
'failed to call unlinked import function ' + module + '.' + name
);
};
}
// Generated by src/wasm/idl/generate.py from bindings.py and
// lane_layout.py. Do not edit.
//
// What each kind of lane module may import, which the page runner
// checks it against, and the numbers lanes and the page agree on.
// The console imports every lane gets.
const kLaneConsole = [
'console.log',
'console.debug',
'console.info',
'console.warn',
'console.error',
];
// [module, name or null for all of it, kinds, refusal or null], the
// first match deciding.
const kLaneImportRules = [
['rive_rt_v1', 'now', ['job', 'worker'], null],
['rive_lanes_v1', 'wait_within', [], 'blocks on a signal, which only the main lane may; a worker awaits Signal.next or Port.receive instead'],
['rive_shared_v1', 'region_lock', ['job', 'worker'], 'locks a shared region, which the audio thread may not wait on; share through atomics, rings and snapshots instead'],
['rive_shared_v1', 'read_done', [], null],
['rive_shared_v1', null, ['job', 'worker', 'processor'], null],
['rive_lane_v1', null, ['job', 'worker', 'processor'], null],
['rive_job_v1', null, ['job'], null],
['rive_worker_v1', null, ['worker'], null],
['env', 'console.log', ['job', 'worker', 'processor'], null],
['env', 'console.debug', ['job', 'worker', 'processor'], null],
['env', 'console.info', ['job', 'worker', 'processor'], null],
['env', 'console.warn', ['job', 'worker', 'processor'], null],
['env', 'console.error', ['job', 'worker', 'processor'], null],
['env', 'console.time', ['job', 'worker'], null],
['env', 'console.timeLog', ['job', 'worker'], null],
['env', 'console.timeEnd', ['job', 'worker'], null],
];
// Why a lane module of kind ('job', 'worker' or 'processor') may not
// import module.name: null when it may, else the end of "<kind> code ...",
// empty when no rule says why.
function laneImportRefusal(kind, module, name) {
for (const [ruleModule, ruleName, kinds, refusal] of kLaneImportRules) {
if (module === ruleModule && (ruleName === null || name === ruleName)) {
return kinds.includes(kind) ? null : refusal ?? '';
}
}
return '';
}
// [section, kind] for each lane kind, in rive_lanes_v1's order.
const kLaneSections = [
['rive.jobs', 'job'],
['rive.workers', 'worker'],
['rive.audio', 'processor'],
];
// The prefix each kind's entries export under, before their number.
const kLaneEntryPrefixes = {
'job': '__rive_job_',
'worker': '__rive_worker_',
'processor': '__rive_processor_',
};
// The rive_lanes_v1 states every lane moves through.
const kLaneStates = {
'starting': 0,
'running': 1,
'done': 2,
'failed': 3,
'stopped': 4,
};
// What a processor event carries for a console line, in place of a state.
const kProcessorEventLog = 0xffffffff;
// The most 64 KiB pages a job instance's memory may have grown to for another
// job to reuse it, as memory never shrinks.
const kReuseMaxPages = 256;
// How long a processor's init may run in milliseconds, natively per step and in
// a worklet as a whole, far longer than a block as it may build tables.
const kProcessorInitMs = 1000;
// Where a parallel call's control block keeps each word, in bytes from its
// start. The words its parts race on sit 128 bytes apart, each alone on a cache
// line, Apple's included. The claim takes 8 bytes, so no grain can wrap it.
const kParallelThunk = 0;
const kParallelArgs = 4;
const kParallelParts = 8;
const kParallelCount = 12;
const kParallelAtOnce = 16;
const kParallelCallerParks = 20;
const kParallelGeneration = 128;
const kParallelArrived = 256;
const kParallelSleepers = 384;
const kParallelClaim = 512;
const kParallelStop = 640;
// The exports a lane module may carry besides its entries.
const kLaneAllocExport = '__rive_lane_alloc';
const kLaneFreeExport = '__rive_lane_free';
const kWorkerWakeExport = '__rive_worker_wake';
const kProcessorProcessExport = '__rive_processor_process';
const kFrameMinorExport = '__riveFrameMinor';
const kLiftedStartExport = '__riveLiftedStart';
const kLaneResetExport = '__riveLaneReset';
// What lanes report the same way on every host.
const kProcessorHolds =
'a processor cannot pass shared objects through rings or snapshots, as the audio thread may ' +
'not hold or give them back; pass them in Audio.start\'s argument';
const kProcessorOverran = 'processor overran its block budget';
const kProcessorInitOverran = 'processor init overran its budget';
const kProcessorNode = 'rive-processors';
// A processor block's budget in milliseconds, first for its first block; 0 for none.
function processorBlockBudgetMs(hardBlocks, frames, sampleRate, first) {
return hardBlocks === 0 ? 0.0 : Math.max(first ? 100.0 : 1.0, Math.ceil(hardBlocks * 1000.0 * frames / sampleRate));
}
// Why a lane module that imports module.name cannot load.
function laneImportError(module, name) {
return 'lane module imports ' + module + '.' + name + ', which it cannot reach';
}
// Generated by src/wasm/idl/generate.py from shared_layout.py. Do not edit.
//
// The shared memory words librive and rive_shared_lane.mjs both read,
// as byte offsets into librive's heap.
// What a block holds, its first word.
const kKindRegion = 0;
const kKindRing = 1;
const kKindSnapshot = 2;
const kKindSignal = 3;
const kKindBlob = 4;
// Every block starts with these words.
const kHeaderKind = 0;
const kHeaderLock = 4;
const kHeaderCapacity = 8;
// A region after its header.
const kRegionPoisoned = 16;
const kRegionData = 32;
// A ring after its header; signals are registry ids.
const kRingHead = 16;
const kRingUsed = 20;
const kRingDataSignal = 24;
const kRingSpaceSignal = 28;
const kRingData = 32;
// A snapshot after its header: copies of capacity bytes each, a version per
// copy that is odd while a publish writes it.
const kSnapshotLatest = 16;
const kSnapshotSeq = 24;
const kSnapshotSeqHigh = 28;
const kSnapshotVersions = 32;
const kSnapshotSizes = 40;
const kSnapshotData = 48;
const kSnapshotCopies = 2;
// A ring record's length word or a snapshot copy's size. With the holds bit
// set, the bytes end in the shared ids the value holds and then their count.
const kRecordHolds = 0x80000000;
// A signal after its header; watchers point at wake words.
const kSignalWatcherCount = 16;
const kSignalSeq = 24;
const kSignalSeqHigh = 28;
const kSignalWatchers = 32;
// A blob after its header: bytes fixed once made.
const kBlobData = 16;
// The futex word a watcher parks on.
const kWakeWordWord = 0;
// The registry, at SharedRegistry::table().
const kTableLanes = 16;
const kTableTokens = 144;
const kTableChunks = 148;
// A registry slot. Its state packs the generation in the low bits, a live bit,
// then the pins librive holds.
const kSlotState = 0;
const kSlotBlock = 4;
const kSlotOwner = 16;
const kSlotOwnerHigh = 20;
const kSlotSize = 24;
const kSlotLive = 4096;
const kSlotPin = 8192;
// Slots come in chunks that never move once made.
const kChunkShift = 10;
const kChunkSlots = 1024;
// An id: the top bit, its slot, the generation's low bits.
const kIdBit = 0x80000000;
const kIdSlotShift = 12;
const kIdGenerationMask = 4095;
// Lanes without librive.
const kLaneCount = 32;
const kLaneIdle = 1;
const kLaneFirstToken = 2;
// What ring_write answers.
const kRingWriteFull = 0;
const kRingWriteWritten = 1;
const kRingWriteNeverFits = 2;
// What region_lock answers.
const kRegionLockGone = 0;
// Words of the counter an NRDP page shares with its worklet thread, so it can
// free what the thread held when it ends it.
const kHoldBlocks = 0;
const kHoldStarting = 1;
const kHoldToken = 2;
const kHoldLock = 3;
const kHoldWords = 4;
// The rive_shared_v1 natives for a lane without librive, such as an audio
// worklet, through Atomics on librive's heap; like librive's, none ever waits.
// Traps as WAMR does when byteLength bytes at ptr leave a module's memory.
function checkBounds(buffer, ptr, byteLength) {
if (ptr + byteLength > buffer.byteLength) {
throw new Error('out of bounds memory access');
}
}
// The byte length of the std string at ptr, which the word before it holds.
// Null reads as empty. Addresses and lengths arrive from wasm as signed i32s.
function managedLength(buffer, ptr) {
ptr >>>= 0;
if (ptr < 4) {
return 0;
}
checkBounds(buffer, ptr, 0);
const length = new DataView(buffer).getUint32(ptr - 4, true);
checkBounds(buffer, ptr, length);
return length;
}
// UTF-16 text in a module's memory. Audio worklet scopes may have no
// TextDecoder.
function utf16Text(buffer, ptr, byteLength) {
ptr >>>= 0;
byteLength >>>= 0;
checkBounds(buffer, ptr, byteLength);
if (typeof TextDecoder !== 'undefined') {
return new TextDecoder('utf-16le', { ignoreBOM: true }).decode(
new Uint8Array(buffer, ptr, byteLength)
);
}
// A Uint16Array cannot start at an odd address, so text there is copied.
const units =
ptr % 2 === 0
? new Uint16Array(buffer, ptr, byteLength >> 1)
: new Uint16Array(buffer.slice(ptr, ptr + byteLength - (byteLength % 2)));
let text = '';
for (let i = 0; i < units.length; i += 4096) {
text += String.fromCharCode.apply(null, units.subarray(i, i + 4096));
}
return text;
}
// Each thread's lane word and lock token, per table. Past the table's lane
// words a lane pins through the slot's count, which no page can free.
const laneClaims = new Map();
const kOverflowToken = kLaneFirstToken + kLaneCount;
function claimLane(i32, table) {
let claim = laneClaims.get(table);
if (claim === undefined) {
for (let i = 0; i < kLaneCount && claim === undefined; i++) {
const word = (table + kTableLanes + i * 4) >>> 2;
if (Atomics.compareExchange(i32, word, 0, kLaneIdle) === 0) {
claim = { word, token: kLaneFirstToken + i };
}
}
// Still a token of its own, so its locks tell from librive's and
// other lanes'.
claim ??= {
word: -1,
token: kOverflowToken + Atomics.add(i32, (table + kTableTokens) >>> 2, 1),
};
laneClaims.set(table, claim);
}
return claim;
}
// The id names the slot's live object.
const slotNames = (state, id) =>
(state & kSlotLive) !== 0 && ((state ^ id) & kIdGenerationMask) === 0;
// heap() answers librive's heap buffer, table is SharedRegistry::table() and
// owner the VM whose objects the lane reaches; the lane records its token and
// lock in holds, for a page to free them.
function createSharedLaneImports(heap, table, owner, moduleMemory, holds = null, fail = () => {}) {
table >>>= 0;
const ownerLow = owner % 0x100000000;
const ownerHigh = Math.floor(owner / 0x100000000);
// Views over the heap and the lane's memory, rebuilt only when growth
// replaces a buffer, so no call allocates on the audio thread.
let buffer = null;
let u8 = null;
let i32 = null;
let u32 = null;
let moduleBuffer = null;
let moduleU8 = null;
const views = () => {
const current = heap();
if (current !== buffer) {
buffer = current;
u8 = new Uint8Array(buffer);
i32 = new Int32Array(buffer);
u32 = new Uint32Array(buffer);
}
};
views();
const claim = claimLane(i32, table);
if (holds !== null) {
Atomics.store(holds, kHoldToken, claim.token);
}
// The lane's bytes when [ptr, ptr + length) lies in its memory, checked
// before any lock is taken; null otherwise, as WAMR would trap.
const moduleRange = (ptr, length) => {
const current = moduleMemory().buffer;
if (current !== moduleBuffer) {
moduleBuffer = current;
moduleU8 = new Uint8Array(current);
}
return ptr + length <= moduleU8.length ? moduleU8 : null;
};
const copy = (to, toAt, from, fromAt, size) => {
for (let i = 0; i < size; i++) {
to[toAt + i] = from[fromAt + i];
}
};
// Recorded before the swap, so whichever way an ended thread stopped,
// the word holds this token only if the lane took it.
const lock = (address) => {
if (holds !== null) {
Atomics.store(holds, kHoldLock, address);
}
while (Atomics.compareExchange(i32, address >>> 2, 0, claim.token) !== 0) {}
};
const unlock = (address) => {
Atomics.store(i32, address >>> 2, 0);
if (holds !== null) {
Atomics.store(holds, kHoldLock, 0);
}
};
// The block an id names, pinned so librive cannot free it until unpin;
// 0 when the id is stale, another VM's or of another kind. A lane pins
// one at a time.
let pinned = 0;
const pin = (id, kind) => {
views();
id >>>= 0;
if ((id & kIdBit) === 0) {
return 0;
}
const index = (id & ~kIdBit) >>> kIdSlotShift;
const chunk = Atomics.load(u32, (table + kTableChunks + (index >>> kChunkShift) * 4) >>> 2);
if (chunk === 0) {
return 0;
}
const slot = chunk + (index & (kChunkSlots - 1)) * kSlotSize;
const stateAt = (slot + kSlotState) >>> 2;
if (claim.word >= 0) {
// Stored before the state is checked, as librive retires a slot
// before scanning the lane words: one of the two sees the other.
Atomics.store(u32, claim.word, slot);
if (!slotNames(Atomics.load(u32, stateAt), id)) {
Atomics.store(u32, claim.word, kLaneIdle);
return 0;
}
} else {
for (;;) {
const state = Atomics.load(u32, stateAt);
if (!slotNames(state, id)) {
return 0;
}
if (Atomics.compareExchange(u32, stateAt, state, state + kSlotPin) === state) {
break;
}
}
}
pinned = slot;
const block = Atomics.load(u32, (slot + kSlotBlock) >>> 2);
if (
u32[(block + kHeaderKind) >>> 2] !== kind ||
u32[(slot + kSlotOwner) >>> 2] !== ownerLow ||
u32[(slot + kSlotOwnerHigh) >>> 2] !== ownerHigh
) {
unpin();
return 0;
}
return block;
};
const unpin = () => {
if (claim.word >= 0) {
Atomics.store(u32, claim.word, kLaneIdle);
} else {
Atomics.sub(u32, (pinned + kSlotState) >>> 2, kSlotPin);
}
};
const capacityOf = (block) => u32[(block + kHeaderCapacity) >>> 2];
// A sequence is a low and a high word, as a 64 bit atomic allocates here.
const bumpSeq = (low, high) => {
if (Atomics.add(u32, low >>> 2, 1) === 0xffffffff) {
Atomics.add(u32, high >>> 2, 1);
}
};
// High first, so a read during a carry answers less, never more.
const readSeq = (low, high) => {
const top = Atomics.load(u32, high >>> 2);
return top * 0x100000000 + Atomics.load(u32, low >>> 2);
};
const notify = (signal) => {
const block = pin(signal, kKindSignal);
if (block === 0) {
return;
}
bumpSeq(block + kSignalSeq, block + kSignalSeqHigh);
lock(block + kHeaderLock);
try {
const count = u32[(block + kSignalWatcherCount) >>> 2];
const watchers = u32[(block + kSignalWatchers) >>> 2] >>> 2;
for (let i = 0; i < count; i++) {
// A watcher's wake word: a futex word librive's threads wait on.
const word = (u32[watchers + i] + kWakeWordWord) >>> 2;
Atomics.add(i32, word, 1);
Atomics.notify(i32, word);
}
} finally {
unlock(block + kHeaderLock);
unpin();
}
};
// Ring bytes wrap around the block's data.
const ringCopyIn = (block, at, from, fromAt, size) => {
const capacity = capacityOf(block);
const first = Math.min(size, capacity - at);
copy(u8, block + kRingData + at, from, fromAt, first);
copy(u8, block + kRingData, from, fromAt + first, size - first);
};
const ringCopyOut = (block, at, to, toAt, size) => {
const capacity = capacityOf(block);
at %= capacity;
const first = Math.min(size, capacity - at);
copy(to, toAt, u8, block + kRingData + at, first);
copy(to, toAt + first, u8, block + kRingData, size - first);
};
// A record's length, four bytes little endian.
const sizeBytes = new Uint8Array(4);
const sizeWord = new Uint32Array(sizeBytes.buffer);
const refuseHolds = () => {
fail(kProcessorHolds);
return 0;
};
// Pops the head record into to at out if it fits capacity, or with to null drops it if it
// does not, and notifies space. Answers its size plus one, 0 when empty or a drop keeps it.
const pop = (ring, to, out, capacity) => {
const block = pin(ring, kKindRing);
if (block === 0) {
return 0;
}
let signal = 0;
let size = 0;
lock(block + kHeaderLock);
try {
const used = u32[(block + kRingUsed) >>> 2];
if (used === 0) {
return 0;
}
const head = u32[(block + kRingHead) >>> 2];
ringCopyOut(block, head, sizeBytes, 0, 4);
size = sizeWord[0];
if ((size & kRecordHolds) !== 0) {
return refuseHolds();
}
if (to === null) {
if (size <= capacity) {
return 0;
}
} else if (out === 0 || size > capacity) {
return size + 1;
} else {
ringCopyOut(block, head + 4, to, out, size);
}
u32[(block + kRingHead) >>> 2] = (head + 4 + size) % capacityOf(block);
u32[(block + kRingUsed) >>> 2] = used - 4 - size;
signal = u32[(block + kRingSpaceSignal) >>> 2];
} finally {
unlock(block + kHeaderLock);
unpin();
}
notify(signal);
return size + 1;
};
// A region word's index, or -1 outside the region.
const word = (block, offset) => {
offset >>>= 0;
if ((offset & 3) !== 0 || offset + 4 > capacityOf(block)) {
return -1;
}
return (block + kRegionData + offset) >>> 2;
};
// -1 outside the region or once it is gone, which the std throws for.
const atomic = (region, offset, use) => {
const block = pin(region, kKindRegion);
if (block === 0) {
return -1;
}
try {
const at = word(block, offset);
return at < 0 ? -1 : use(at) >>> 0;
} finally {
unpin();
}
};
return {
'region_create': () => 0,
'region_size': (region) => {
const block = pin(region, kKindRegion);
if (block === 0) {
return 0;
}
const size = capacityOf(block);
unpin();
return size;
},
'region_lock': () => kRegionLockGone,
'region_unlock': () => {},
'region_read': () => 0,
'region_write': () => 0,
'region_poisoned': (region) => {
const block = pin(region, kKindRegion);
if (block === 0) {
return 0;
}
const poisoned = u32[(block + kRegionPoisoned) >>> 2] !== 0 ? 1 : 0;
unpin();
return poisoned;
},
'atomic_load': (region, offset) => atomic(region, offset, (at) => Atomics.load(i32, at)),
'atomic_store': (region, offset, value) =>
atomic(region, offset, (at) => {
Atomics.store(i32, at, value | 0);
return 0;
}),
'atomic_add': (region, offset, value) =>
atomic(region, offset, (at) => Atomics.add(i32, at, value | 0)),
'atomic_cas': (region, offset, expected, desired) =>
atomic(region, offset, (at) =>
Atomics.compareExchange(i32, at, expected | 0, desired | 0)
),
'ring_create': () => 0,
'ring_write': (ring, data, dataByteCount, holds, holdCount) => {
data >>>= 0;
dataByteCount >>>= 0;
const from = moduleRange(data, dataByteCount);
const block = from !== null ? pin(ring, kKindRing) : 0;
if (block === 0) {
return kRingWriteFull;
}
if (holdCount !== 0) {
unpin();
return refuseHolds();
}
let signal = 0;
lock(block + kHeaderLock);
try {
const capacity = capacityOf(block);
if (4 + dataByteCount > capacity) {
return kRingWriteNeverFits;
}
const used = u32[(block + kRingUsed) >>> 2];
if (used + 4 + dataByteCount > capacity) {
return kRingWriteFull;
}
const head = u32[(block + kRingHead) >>> 2];
sizeWord[0] = dataByteCount;
ringCopyIn(block, (head + used) % capacity, sizeBytes, 0, 4);
ringCopyIn(block, (head + used + 4) % capacity, from, data, dataByteCount);
u32[(block + kRingUsed) >>> 2] = used + 4 + dataByteCount;
signal = u32[(block + kRingDataSignal) >>> 2];
} finally {
unlock(block + kHeaderLock);
unpin();
}
notify(signal);
return kRingWriteWritten;
},
'ring_read': (ring, out, outByteCount) => {
out >>>= 0;
outByteCount >>>= 0;
const to = moduleRange(out, outByteCount);
return to !== null ? pop(ring, to, out, outByteCount) : 0;
},
'ring_drop': (ring, capacity) => pop(ring, null, 0, capacity >>> 0),
'ring_used': (ring) => {
const block = pin(ring, kKindRing);
if (block === 0) {
return 0;
}
lock(block + kHeaderLock);
const used = u32[(block + kRingUsed) >>> 2];
unlock(block + kHeaderLock);
unpin();
return used;
},
'ring_signal': (ring, space) => {
const block = pin(ring, kKindRing);
if (block === 0) {
return 0;
}
const signal = u32[(block + (space !== 0 ? kRingSpaceSignal : kRingDataSignal)) >>> 2];
unpin();
return signal;
},
'snapshot_create': () => 0,
// As SharedSnapshot::publish: publishers take turns writing the copy
// readers are not on.
'snapshot_publish': (snapshot, data, dataByteCount, holds, holdCount) => {
data >>>= 0;
dataByteCount >>>= 0;
const from = moduleRange(data, dataByteCount);
const block = from !== null ? pin(snapshot, kKindSnapshot) : 0;
if (block === 0) {
return 0;
}
try {
const capacity = capacityOf(block);
if (holdCount !== 0) {
return refuseHolds();
}
if (dataByteCount > capacity) {
return 0;
}
lock(block + kHeaderLock);
try {
const latestAt = (block + kSnapshotLatest) >>> 2;
const latest = Atomics.load(u32, latestAt);
const sizesAt = (block + kSnapshotSizes) >>> 2;
const replaced = latest !== 0 ? Atomics.load(u32, sizesAt + latest - 1) : 0;
// Nothing here could give back the replaced value's holds.
if ((replaced & kRecordHolds) !== 0) {
return refuseHolds();
}
const index = latest % kSnapshotCopies;
const versionAt = ((block + kSnapshotVersions) >>> 2) + index;
const version = Atomics.load(u32, versionAt) | 1;
Atomics.store(u32, versionAt, version);
// A load after the store keeps the bytes from landing
// before the odd version, as JS has no fence.
Atomics.load(u32, versionAt);
copy(u8, block + kSnapshotData + index * capacity, from, data, dataByteCount);
Atomics.store(u32, sizesAt + index, dataByteCount);
Atomics.store(u32, versionAt, version + 1);
Atomics.store(u32, latestAt, index + 1);
bumpSeq(block + kSnapshotSeq, block + kSnapshotSeqHigh);
} finally {
unlock(block + kHeaderLock);
}
return 1;
} finally {
unpin();
}
},
// As SharedSnapshot::read, without the lock.
'snapshot_read': (snapshot, out, outByteCount) => {
out >>>= 0;
outByteCount >>>= 0;
const to = moduleRange(out, outByteCount);
const block = to !== null ? pin(snapshot, kKindSnapshot) : 0;
if (block === 0) {
return 0;
}
try {
for (;;) {
const latest = Atomics.load(u32, (block + kSnapshotLatest) >>> 2);
if (latest === 0) {
return 0;
}
const index = latest - 1;
const versionAt = ((block + kSnapshotVersions) >>> 2) + index;
const version = Atomics.load(u32, versionAt);
if ((version & 1) !== 0) {
continue;
}
const word = Atomics.load(u32, ((block + kSnapshotSizes) >>> 2) + index);
const capacity = capacityOf(block);
const at = block + kSnapshotData + index * capacity;
const refused = (word & kRecordHolds) !== 0;
// A torn read answers what the version check discards.
const size = Math.min(word, capacity);
if (!refused && out !== 0 && size <= outByteCount) {
copy(to, out, u8, at, size);
}
// An exchange rather than a load keeps the copy from
// reading past the check.
if (Atomics.compareExchange(u32, versionAt, version, version) === version) {
return refused ? refuseHolds() : size + 1;
}
}
} finally {
unpin();
}
},
'snapshot_seq': (snapshot) => {
const block = pin(snapshot, kKindSnapshot);
if (block === 0) {
return 0;
}
const seq = readSeq(block + kSnapshotSeq, block + kSnapshotSeqHigh);
unpin();
return seq;
},
'signal_create': () => 0,
'signal_notify': (signal) => notify(signal),
'signal_seq': (signal) => {
const block = pin(signal, kKindSignal);
if (block === 0) {
return 0;
}
const seq = readSeq(block + kSignalSeq, block + kSignalSeqHigh);
unpin();
return seq;
},
'blob_create': () => 0,
'blob_size': (blob) => {
const block = pin(blob, kKindBlob);
if (block === 0) {
return 0;
}
const size = capacityOf(block);
unpin();
return size;
},
// A blob never changes, so the copy takes no lock.
'blob_read': (blob, offset, out, outByteCount) => {
offset >>>= 0;
out >>>= 0;
outByteCount >>>= 0;
const to = moduleRange(out, outByteCount);
const block = to !== null ? pin(blob, kKindBlob) : 0;
if (block === 0) {
return 0;
}
const size = capacityOf(block);
const count = offset < size ? Math.min(outByteCount, size - offset) : 0;
copy(to, out, u8, block + kBlobData + offset, count);
unpin();
return count;
},
'retain': () => 0,
'release': () => {},
};
}
// Frees the lock word and lane word a lane left held, for a page that ended
// its thread, once that thread is surely gone.
function releaseSharedLane(heap, table, holds) {
const token = Atomics.load(holds, kHoldToken);
if (token < kLaneFirstToken) {
return;
}
const i32 = new Int32Array(heap());
const lockAt = Atomics.load(holds, kHoldLock);
if (lockAt !== 0) {
Atomics.compareExchange(i32, lockAt >>> 2, token, 0);
}
// Last: the slot it pinned keeps the locked block alive until here.
if (token < kOverflowToken) {
Atomics.store(i32, (((table >>> 0) + kTableLanes) >>> 2) + token - kLaneFirstToken, 0);
}
}
// Instances of the lane modules a script module carries, started the same way
// by the page runner and, through createProcessorMixer, by the audio worklets.
function errorText(error) {
return String(error?.message ?? error);
}
// Chrome's worklet scope has no performance; Date's milliseconds still catch a
// block of several.
const monotonicNow =
globalThis.performance !== undefined ? () => globalThis.performance.now() : Date.now;
// The console imports: each line is a std string, its byte length before it.
// Only jobs and workers import the timers.
function laneConsole(memory, log, timers = new Map()) {
const text = (ptr) => {
const buffer = memory().buffer;
return utf16Text(buffer, ptr, managedLength(buffer, ptr));
};
const env = {};
for (const name of kLaneConsole) {
env[name] = (ptr) => log(text(ptr));
}
const report = (end) => (ptr) => {
const label = text(ptr);
const started = timers.get(label);
if (started === undefined) {
log(`Timer '${label}' does not exist`);
return;
}
if (end) {
timers.delete(label);
}
log(`${label}: ${(monotonicNow() - started).toFixed(3)}ms`);
};
env['console.time'] = (ptr) => timers.set(text(ptr), monotonicNow());
env['console.timeLog'] = report(false);
env['console.timeEnd'] = report(true);
return env;
}
const noFuelCheck = () => {};
// An instance of lane.module whose imports reach the lane's own natives, log,
// timers, clock and fuel check. Returns { exports, memory, failure } or
// { error }.
function instantiateLane(lane) {
let memory = null;
let thrown = null;
const failure = (error) => thrown ?? errorText(error);
const imports = {
'env': laneConsole(() => memory, lane.log, lane.timers),
'rive_shared_v1': lane.shared(() => memory),
'rive_rt_v1': { 'now': lane.now ?? monotonicNow },
'rive_lane_v1': {
'error': (ptr, byteLength) => {
thrown = utf16Text(memory.buffer, ptr, byteLength);
lane.onThrow?.(thrown);
},
'fuel_check': lane.fuel ?? noFuelCheck,
},
};
if (lane.natives !== undefined) {
imports[lane.natives] = lane.own(() => memory);
}
try {
const exports = new WebAssembly.Instance(lane.module, imports).exports;
memory = exports['memory'];
return { exports, memory, failure };
} catch (error) {
return { error: failure(error) };
}
}
// Runs the instance's start, or its reset when a job ran in it before, then
// prefix + entry with a copy of input and args, freeing the copy after when
// lane.free. Returns { result } or { error }.
function enterLane(instance, lane, reset = false) {
try {
const exports = instance.exports;
exports[reset ? kLaneResetExport : kLiftedStartExport]?.();
const input = lane.input;
const at = exports[kLaneAllocExport](input.length) >>> 0;
new Uint8Array(instance.memory.buffer, at, input.length).set(input);
const result = exports[lane.prefix + lane.entry](
at,
input.length,
...(lane.args ?? [])
);
if (lane.free) {
exports[kLaneFreeExport](at);
}
return { result };
} catch (error) {
return { error: instance.failure(error) };
}
}
// A new instance, entered. Returns { exports, memory, result, failure } or
// { error }.
function startLane(lane) {
const instance = instantiateLane(lane);
const entered = instance.error === undefined ? enterLane(instance, lane) : instance;
return entered.error === undefined ? { ...instance, result: entered.result } : entered;
}
// One script audio processor, whose init may take kProcessorInitMs. Returns
// { lane } or { error }; shared(memory, fail) answers its shared imports.
function startProcessorLane(module, entry, input, format, shared, log) {
// As natively, a native that fails the processor lets the block finish.
let failed = null;
const fail = (text) => {
failed ??= text;
};
// When its fuel checks end it and why, made once so a block allocates
// nothing on the audio thread.
const bounds = { until: monotonicNow() + kProcessorInitMs, reason: kProcessorInitOverran };
const started = startLane({
module,
shared: (memory) => shared(memory, fail),
log,
fuel: () => {
if (monotonicNow() > bounds.until) {
throw bounds.reason;
}
},
prefix: kLaneEntryPrefixes['processor'],
entry,
input,
args: [format.sampleRate, format.maxFrames, format.channels],
free: true,
});
if (started.error !== undefined || failed !== null) {
return { error: started.error ?? failed };
}
bounds.until = Infinity;
bounds.reason = kProcessorOverran;
const exports = started.exports;
const memory = started.memory;
// Rebuilt only when the block moves or memory grows, so a block
// allocates nothing on the audio thread.
let view = null;
return {
lane: {
// Ends the block past budget ms, if any; sink gets its samples
// before a collection can move them. Null, or why it failed.
render(frames, startFrame, sink, budget = 0) {
if (budget > 0) {
bounds.until = monotonicNow() + budget;
}
try {
const at = exports[kProcessorProcessExport](frames, startFrame) >>> 0;
if (failed !== null) {
return failed;
}
const length = frames * format.channels;
if (
view === null ||
view.buffer !== memory.buffer ||
view.byteOffset !== at ||
view.length !== length
) {
view = new Float32Array(memory.buffer, at, length);
}
sink(view);
exports[kFrameMinorExport]?.();
return null;
} catch (error) {
return started.failure(error);
} finally {
bounds.until = Infinity;
}
},
},
};
}
// Every processor a real time output runs, as the page's messages say, with
// answers through post. It counts blocks and starts in holds, the Hold words.
function createProcessorMixer(heap, table, post, holds) {
const lanes = new Map();
// What render walks, rebuilt only when lanes change, so a block does not
// allocate an iterator.
let order = [];
const relist = () => {
order = [...lanes.entries()];
};
// Null while compiling, then the module or the compile's error text,
// until the page forgets it.
const modules = new Map();
// Starts not yet run, behind one whose module still compiles.
const waiting = [];
// The output's add and where in its block a chunk goes, set as render
// walks, so sinks allocate nothing.
let add = null;
let offset = 0;
let frame = -1;
const fail = (id, text) => {
lanes.delete(id);
relist();
post({ id, kind: 'failed', text });
};
const start = (message) => {
const id = message.id;
const module = modules.get(message.moduleId);
if (typeof module === 'string') {
post({ id, kind: 'failed', text: module });
return;
}
const format = message.format;
const started = startProcessorLane(
module,
message.entry,
message.input,
format,
(moduleMemory, fail) =>
createSharedLaneImports(heap, table, message.sharedOwner, moduleMemory, holds, fail),
(text) => post({ id, kind: 'log', text })
);
if (started.error !== undefined) {
post({ id, kind: 'failed', text: started.error });
return;
}
const channels = format.channels;
lanes.set(id, {
lane: started.lane,
maxFrames: format.maxFrames,
// A block past its hard limit, where there is one, ends at its
// next fuel check, or without fuel once it returns.
hardBlocks: message.hardBlocks,
sampleRate: format.sampleRate,
warm: false,
sink: (block) => add(block, channels, offset),
});
relist();
post({ id, kind: 'running' });
};
// Starts in arrival order, up to the first whose module still compiles.
const drain = () => {
while (waiting.length > 0 && modules.get(waiting[0].moduleId) !== null) {
start(waiting.shift());
// Each start gets the page's whole start limit, and the checks it
// took must not count under the shorter limit after it.
Atomics.add(holds, kHoldBlocks, 1);
}
if (waiting.length === 0) {
Atomics.store(holds, kHoldStarting, 0);
}
};
return {
receive(message) {
if (message.kind === 'forget') {
modules.delete(message.moduleId);
return;
}
if (message.kind === 'stop') {
// A stop beats the start it follows when that still waits.
const at = waiting.findIndex((queued) => queued.id === message.id);
if (at >= 0) {
waiting.splice(at, 1);
drain();
} else {
lanes.delete(message.id);
relist();
}
return;
}
if (message.kind === 'end') {
// The page gave up on this output and failed what it ran.
lanes.clear();
relist();
waiting.length = 0;
return;
}
const moduleId = message.moduleId;
if (!modules.has(moduleId) && message.bytes === null) {
// A fresh worklet lacks modules the page sent the one before.
post({ id: message.id, kind: 'resend' });
return;
}
if (!modules.has(moduleId)) {
// Compiling on the audio thread would stall every processor.
modules.set(moduleId, null);
const settle = (value) => {
if (modules.has(moduleId)) {
modules.set(moduleId, value);
}
};
WebAssembly.compile(message.bytes)
.then(settle, (error) => settle(errorText(error)))
.then(drain);
}
Atomics.store(holds, kHoldStarting, 1);
waiting.push(message);
drain();
},
// Hands into(block, channels, offset) each processor's interleaved
// samples, in chunks of at most its block, offset frames in.
render(frames, firstFrame, into) {
if (frame < 0) {
frame = firstFrame;
}
add = into;
// A failure relists, which must not shift the rest of this pass.
const list = order;
for (let i = 0; i < list.length; i++) {
const [id, entry] = list[i];
for (offset = 0; offset < frames; offset += entry.maxFrames) {
const chunk = Math.min(entry.maxFrames, frames - offset);
const budget = processorBlockBudgetMs(
entry.hardBlocks,
chunk,
entry.sampleRate,
!entry.warm
);
const began = monotonicNow();
let error = entry.lane.render(chunk, frame + offset, entry.sink, budget);
if (error === null && budget > 0 && monotonicNow() - began > budget) {
error = kProcessorOverran;
}
entry.warm = true;
if (error !== null) {
fail(id, error);
break;
}
}
}
frame += frames;
Atomics.add(holds, kHoldBlocks, 1);
},
// The output went away: every processor it ran ends with text.
failAll(text) {
for (const id of [...lanes.keys()]) {
fail(id, text);
}
for (const message of waiting.splice(0)) {
post({ id: message.id, kind: 'failed', text });
}
},
};
}
// Parallel calls on a page with threads. A team of pool threads runs a
// module's parts on members: instances of the module that share its memory,
// made without its start or its data, which would undo what the page's own
// instance already did to that memory. A call hands its parts to the team
// through words in shared memory, and the page's thread runs its own part
// while the members run theirs. The page's thread cannot wait, so it spins.
// Team threads spin a while after each call, then park in a way that still
// lets them take the memory of a module loaded later.
// The team's words, by Int32 index. Words that threads race on sit on cache
// lines of their own.
const kTeamCall = 0;
const kTeamParked = 16;
const kTeamThreads = 32;
const kTeamVm = 33;
const kTeamControl = 34;
const kTeamGlobals = 35;
const kTeamFailed = 48;
const kTeamFailKind = 49;
const kTeamFailAt = 50;
const kTeamFailLength = 51;
const kTeamFailMs = 52;
const kTeamFailBytes = 53;
const kTeamWaits = 54;
// Each thread's line: the call it last finished, the call the page assigned
// it until the thread takes its part, its part in that call, and the last
// call it saw. The page writes an assignment before the call starts, so a
// thread that wakes late never takes a later call's part as its own, and
// clears one the thread never took, so it never runs it after the call ends.
const kTeamDone = 128;
const kTeamAssigned = 1;
const kTeamPart = 2;
const kTeamSeen = 3;
// As many as a native call's team.
const kTeamMax = 63;
// The most parts a call gets by default, one per core up to this.
const kDefaultParts = 8;
const kTeamTextAt = (kTeamDone + 16 * kTeamMax) * 4;
const kTeamTextBytes = 512;
const kFailTrap = 1;
const kFailThrow = 2;
const kFailBudget = 3;
const kWaitAsync = 1;
const kWaitTimed = 2;
// How long a team thread polls for the next call before it parks, as the
// native team does, so a frame's next stage starts without a wake.
const kSpinMs = 0.05;
// A parked thread without Atomics.waitAsync looks for messages this often.
const kTimedWaitMs = 2;
// How long a call waits for a thread to take its part before it wakes the
// team again, and before it gives up on the thread.
const kRewakeMs = 1;
const kTakeMs = 1000;
// How long preparing a module waits for its members.
const kReadyMs = 10000;
// As each native member's spill zone, which fills the frame collector's
// 64 KiB raw block after its header.
const kSpillBytes = 65536 - 16;
const textOf = (error) => String(error?.message ?? error);
// Polls done until it holds or about ms pass, reading the clock only now and
// then since a read costs more than a poll.
function spinFor(done, ms) {
const until = performance.now() + ms;
for (let polls = 1; ; polls++) {
if (done()) {
return true;
}
if ((polls & 63) === 0 && performance.now() >= until) {
return false;
}
}
}
// One event loop turn, so a parked thread takes its messages.
function nextTurn() {
const channel = new MessageChannel();
return new Promise((resolve) => {
channel.port1.onmessage = () => {
channel.port1.close();
resolve();
};
channel.port2.postMessage(0);
});
}
// What a member may import: the clock, aligned to the page's so a deadline
// the page set means the same here, the throw and budget reports a part's
// failure carries, debug probes, which only matter where a debugger runs
// everything on the page's thread, and the check in only part 0 makes.
// Anything else the build refused.
function memberImports(module, memory, state, offset) {
const imports = {};
const stopped = () => state.view !== null && Atomics.load(state.view, state.stop) !== 0;
const known = {
'rive_rt_v1': {
'now': () => {
// A fuel check reads the clock, so a stopped call ends there.
if (stopped()) {
throw new Error('stopped by another part');
}
return performance.now() + offset;
},
'budget_exceeded': (ms) => {
state.budgetMs = ms;
throw new Error('execution exceeded timeout');
},
'error': (at, length) => {
state.thrown = [at, length];
},
'debug_enter': () => {},
'debug_line': () => 0,
'debug_leave': () => {},
},
'rive_parallel_v1': {
'waiting': () => {},
},
};
for (const wanted of WebAssembly.Module.imports(module)) {
const space = (imports[wanted['module']] ??= {});
if (wanted['kind'] === 'memory') {
space[wanted['name']] = memory;
} else if (wanted['kind'] === 'function') {
space[wanted['name']] =
known[wanted['module']]?.[wanted['name']] ??
(() => {
throw new Error(
`parallel code called the host through ${wanted['module']}.${wanted['name']}`
);
});
}
}
return imports;
}
// The team thread's side: its members, by module, and its loop.
function teamThread() {
const members = new Map();
let words = null;
let index = -1;
function addMember(data) {
const ready = new Int32Array(data['ready']);
const state = { thrown: null, budgetMs: -1, view: null, stop: 0 };
try {
// Each thread compiles its own, as threads that lazily compile
// one shared module at once have crashed the engine.
const module = new WebAssembly.Module(data['bytes']);
const memory = data['memory'];
const offset = performance.timeOrigin - data['origin'];
const instance = new WebAssembly.Instance(
module,
memberImports(module, memory, state, offset)
);
const exports = instance.exports;
// A module whose code never spills exports no spill floor.
const spill = exports['__riveSpillFloor'] === undefined ? 0 : data['spill'];
if (spill !== 0) {
exports['__riveSpillFloor'].value = spill;
}
members.set(data['key'], { exports, memory, state, spill, buffer: null, view: null });
Atomics.store(ready, index, 1);
} catch (error) {
Atomics.store(ready, index, 2);
}
Atomics.notify(ready, index);
}
// The first failure of the call wins; it stops the other parts at their
// next check or sync.
function fail(participant, member, error) {
if (Atomics.compareExchange(words, kTeamFailed, -1, participant) !== -1) {
return;
}
const state = member.state;
if (state.thrown !== null) {
words[kTeamFailKind] = kFailThrow;
words[kTeamFailAt] = state.thrown[0];
words[kTeamFailLength] = state.thrown[1];
} else if (state.budgetMs >= 0) {
words[kTeamFailKind] = kFailBudget;
words[kTeamFailMs] = state.budgetMs;
} else {
words[kTeamFailKind] = kFailTrap;
const text = new TextEncoder().encode(textOf(error)).subarray(0, kTeamTextBytes);
new Uint8Array(words.buffer, kTeamTextAt, text.length).set(text);
words[kTeamFailBytes] = text.length;
}
Atomics.store(member.view, member.state.stop, 1);
}
function runShare(generation) {
const line = kTeamDone + 16 * index;
if (Atomics.compareExchange(words, line + kTeamAssigned, generation, 0) !== generation) {
return false;
}
const participant = words[line + kTeamPart];
const threads = words[kTeamThreads];
const member = members.get(words[kTeamVm]);
if (member === undefined) {
return true;
}
// The page grows the memory only between calls.
const buffer = member.memory.buffer;
if (member.buffer !== buffer) {
member.buffer = buffer;
member.view = new Int32Array(buffer);
}
const view = member.view;
const control = words[kTeamControl] >>> 0;
const state = member.state;
state.thrown = null;
state.budgetMs = -1;
state.view = view;
state.stop = (control + kParallelStop) >>> 2;
const exports = member.exports;
// A trap skips the epilogues that give back spill space.
if (member.spill !== 0) {
exports['__riveCallSpill'].value = member.spill + kSpillBytes;
}
try {
exports['__riveLoadGlobals'](words[kTeamGlobals]);
} catch (error) {
fail(participant, member, error);
return true;
}
const count = view[(control + kParallelCount) >>> 2];
const thunk = view[(control + kParallelThunk) >>> 2];
const args = view[(control + kParallelArgs) >>> 2];
const parts = view[(control + kParallelParts) >>> 2] >>> 2;
const call = exports['__riveParallelCall'];
for (let part = participant; part < count; part += threads) {
if (Atomics.load(view, state.stop) !== 0) {
break;
}
try {
call(thunk, view[parts + part], args);
} catch (error) {
fail(participant, member, error);
break;
}
}
return true;
}
async function loop() {
// Tests under node keep a thread from taking parts with
// RIVE_PARALLEL_DEAF_THREAD, as one whose wake was lost would.
if (String(index) === globalThis.process?.['env']?.['RIVE_PARALLEL_DEAF_THREAD']) {
return;
}
let seen = Atomics.load(words, kTeamCall);
const moved = () => Atomics.load(words, kTeamCall) !== seen;
// WebKit can lose the wake of an async wait, which stalls a call
// until it gives up on the thread. Tests under node take the timed
// path with RIVE_PARALLEL_TIMED_WAITS.
const userAgent = globalThis.navigator?.userAgent ?? '';
const waitAsync =
typeof Atomics.waitAsync === 'function' &&
!(userAgent.includes('AppleWebKit/') && !userAgent.includes('Chrome/')) &&
globalThis.process?.['env']?.['RIVE_PARALLEL_TIMED_WAITS'] === undefined;
Atomics.store(words, kTeamWaits, waitAsync ? kWaitAsync : kWaitTimed);
let turned = performance.now();
for (;;) {
if (!spinFor(moved, kSpinMs)) {
Atomics.add(words, kTeamParked, 1);
if (waitAsync) {
const waited = Atomics.waitAsync(words, kTeamCall, seen);
if (waited.async) {
await waited.value;
}
} else if (performance.now() - turned >= kTimedWaitMs) {
// Messages get a turn in place of a sleep, so a woken
// call never waits on one.
await nextTurn();
turned = performance.now();
} else {
Atomics.wait(words, kTeamCall, seen, kTimedWaitMs);
}
Atomics.sub(words, kTeamParked, 1);
continue;
}
seen = Atomics.load(words, kTeamCall);
Atomics.store(words, kTeamDone + 16 * index + kTeamSeen, seen);
if (runShare(seen)) {
Atomics.store(words, kTeamDone + 16 * index, seen);
}
}
}
return {
// The page's messages to this thread; false for any other.
message(data) {
const team = data?.['riveParallelTeam'];
if (team !== undefined) {
words = new Int32Array(team['words']);
index = team['index'];
loop();
return true;
}
const vm = data?.['riveParallelVm'];
if (vm !== undefined) {
addMember(vm);
return true;
}
const drop = data?.['riveParallelDrop'];
if (drop !== undefined) {
members.delete(drop);
return true;
}
return false;
},
};
}
// The page's side: the team, which every module on the page shares, one call
// at a time, and each module's members on it. threads.start() starts a team
// thread and answers its worker, or null where there are no threads.
function createParallel(threads) {
let team = null;
let nextKey = 1;
const thread = teamThread();
// The call the page's thread is in.
let current = null;
// Team threads to size - 1, started once and kept.
function teamOf(size) {
team ??= {
words: new Int32Array(
new SharedArrayBuffer(kTeamTextAt + kTeamTextBytes)
),
workers: [],
// By thread, the last call it saw when a call gave up on it, or
// undefined; it sits out calls until it sees another.
lost: [],
};
while (team.workers.length + 1 < Math.min(size, kTeamMax + 1)) {
const index = team.workers.length;
const worker = threads.start();
if (worker === null) {
break;
}
worker.postMessage({ 'riveParallelTeam': { 'words': team.words.buffer, 'index': index } });
team.workers.push(worker);
}
return team;
}
// Members on the team for a module whose memory is shared, once its own
// instance has started, from the bytes each member compiles. Null when
// there is no team to run them.
function setUp(entry, bytes, size) {
const exports = entry.instance.exports;
if (
size <= 1 ||
!threads.can() ||
exports['__riveParallelCall'] === undefined ||
exports['__riveSaveGlobals'] === undefined ||
exports['__riveRawAlloc'] === undefined
) {
return null;
}
const { workers } = teamOf(size);
if (workers.length === 0) {
return null;
}
// The allocator traps once the memory cannot grow. As natively, the
// members made before then stay, and without any a call runs alone.
const alloc = (bytes) => {
try {
return exports['__riveRawAlloc'](bytes) >>> 0;
} catch {
return 0;
}
};
const globals = alloc(Math.max(exports['__riveGlobalBytes'].value, 4));
if (globals === 0) {
return null;
}
const parallel = {
key: nextKey++,
globals,
ready: new Int32Array(new SharedArrayBuffer(4 * workers.length)),
running: false,
};
workers.forEach((worker, index) => {
const spill = alloc(kSpillBytes);
if (spill === 0) {
Atomics.store(parallel.ready, index, 2);
return;
}
worker.postMessage({
'riveParallelVm': {
'key': parallel.key,
'bytes': bytes,
'memory': entry.memory,
'spill': spill,
'ready': parallel.ready.buffer,
'origin': performance.timeOrigin,
},
});
});
return parallel;
}
// Settles once every member of the module started or failed to, or a
// team thread that never answers is left out. It polls on timers, as a
// pending waitAsync would not keep node running.
async function ready(parallel) {
const until = performance.now() + kReadyMs;
while (parallel.ready.some((state) => state === 0) && performance.now() < until) {
await new Promise((done) => setTimeout(done, 1));
}
}
function release(parallel) {
for (const worker of team?.workers ?? []) {
worker.postMessage({ 'riveParallelDrop': parallel.key });
}
}
// Whether a thread a call gave up on has since seen another call, as one
// that only woke late has.
function present(index) {
const lost = team.lost[index];
if (lost === undefined) {
return true;
}
if (Atomics.load(team.words, kTeamDone + 16 * index + kTeamSeen) === lost) {
return false;
}
team.lost[index] = undefined;
return true;
}
// For a member that has not taken its part: once the call fails, the
// page takes the part back. Until then the page wakes the team again,
// since the member may have missed its wake, and fails the call once the
// member is too late.
function nudge(call, index, now) {
const words = team.words;
const line = kTeamDone + 16 * index;
if (Atomics.load(words, line + kTeamAssigned) !== call.generation) {
return;
}
if (Atomics.load(call.view, call.stop) === 0 && now - call.began >= kTakeMs) {
call.fail(new Error(
`a thread of the page's team did not start its part of a parallel call within ${kTakeMs} ms`
));
}
if (Atomics.load(call.view, call.stop) !== 0) {
if (Atomics.compareExchange(words, line + kTeamAssigned, call.generation, 0) === call.generation) {
team.lost[index] = Atomics.load(words, line + kTeamSeen);
call.taken.add(index);
}
} else if (now - call.woke >= kRewakeMs) {
call.woke = now;
Atomics.notify(words, kTeamCall);
}
}
// Waits for each member to finish its part, or for the page to take it
// back. A call past its budget fails here too.
function join(call, fuelCheck) {
const words = team.words;
for (const index of call.members) {
const line = kTeamDone + 16 * index;
for (let polls = 1; Atomics.load(words, line) !== call.generation; polls++) {
if ((polls & 1023) !== 0) {
continue;
}
if (call.taken.has(index)) {
break;
}
if (Atomics.load(call.view, call.stop) === 0 && fuelCheck !== undefined) {
try {
fuelCheck();
} catch (error) {
call.fail(error);
}
}
nudge(call, index, performance.now());
}
}
}
// Part 0 checking in from a sync, where the page's thread waits inside
// the module and the join cannot run.
function waiting() {
const call = current;
if (call === null) {
return;
}
const now = performance.now();
for (const index of call.members) {
nudge(call, index, now);
}
}
// Runs the call whose control block is at control, one part per thread
// it gets when the call asks for every part at once, and answers the
// threads that ran parts. report raises a member's throw or budget
// failure as the page's own instance would.
function run(entry, parallel, control, report) {
if (parallel?.running) {
throw new Error('parallel calls cannot nest');
}
// A word an atomic reads must be aligned.
if ((control & 3) !== 0) {
throw new Error('parallel call control block is not aligned');
}
// The page grows the memory only between calls.
const buffer = entry.memory.buffer;
if (entry.view32?.buffer !== buffer) {
entry.view32 = new Int32Array(buffer);
}
const view = entry.view32;
const word = (offset) => (control + offset) >>> 2;
let count = view[word(kParallelCount)];
const members = [];
for (let index = 0; index < (parallel?.ready.length ?? 0) && members.length + 1 < count; index++) {
if (Atomics.load(parallel.ready, index) === 1 && present(index)) {
members.push(index);
}
}
const threads = members.length + 1;
if (view[word(kParallelAtOnce)] !== 0) {
count = threads;
view[word(kParallelCount)] = count;
}
view[word(kParallelAtOnce)] = threads >= count ? 1 : 0;
// The claim takes two words, and the page's thread may not park.
for (const offset of [
kParallelGeneration,
kParallelArrived,
kParallelSleepers,
kParallelClaim,
kParallelClaim + 4,
kParallelStop,
kParallelCallerParks,
]) {
Atomics.store(view, word(offset), 0);
}
const exports = entry.instance.exports;
const call = exports['__riveParallelCall'];
const thunk = view[word(kParallelThunk)];
const args = view[word(kParallelArgs)];
const parts = view[word(kParallelParts)] >>> 2;
if (threads === 1) {
for (let part = 0; part < count; part++) {
call(thunk, view[parts + part], args);
}
return 1;
}
const words = team.words;
parallel.running = true;
try {
exports['__riveSaveGlobals'](parallel.globals);
words[kTeamThreads] = threads;
words[kTeamVm] = parallel.key;
words[kTeamControl] = control;
words[kTeamGlobals] = parallel.globals;
Atomics.store(words, kTeamFailed, -1);
// An assignment of 0 is none.
const generation = ((Atomics.load(words, kTeamCall) + 1) | 0) || 1;
members.forEach((index, j) => {
const line = kTeamDone + 16 * index;
words[line + kTeamPart] = j + 1;
Atomics.store(words, line + kTeamAssigned, generation);
});
Atomics.store(words, kTeamCall, generation);
if (Atomics.load(words, kTeamParked) !== 0) {
Atomics.notify(words, kTeamCall);
}
let thrown = null;
const began = performance.now();
current = {
members,
generation,
view,
stop: word(kParallelStop),
began,
woke: began,
// Members whose parts the page took back.
taken: new Set(),
// The page's own failure, which stops the other parts unless
// a member failed first.
fail(error) {
thrown ??= error;
if (Atomics.compareExchange(words, kTeamFailed, -1, 0) === -1) {
Atomics.store(view, word(kParallelStop), 1);
}
},
};
for (let part = 0; part < count; part += threads) {
if (Atomics.load(view, word(kParallelStop)) !== 0) {
break;
}
try {
call(thunk, view[parts + part], args);
} catch (error) {
current.fail(error);
break;
}
}
join(current, exports['__riveFuelCheck']);
const failed = Atomics.load(words, kTeamFailed);
if (failed > 0) {
const kind = words[kTeamFailKind];
if (kind === kFailThrow) {
report.thrown(words[kTeamFailAt], words[kTeamFailLength]);
} else if (kind === kFailBudget) {
report.budget(words[kTeamFailMs]);
if (thrown !== null) {
throw thrown;
}
}
const text = new Uint8Array(words[kTeamFailBytes]);
text.set(new Uint8Array(words.buffer, kTeamTextAt, text.length));
throw new Error(
kind === kFailTrap ? new TextDecoder().decode(text) : 'parallel part trapped'
);
}
if (thrown !== null) {
throw thrown;
}
return threads;
} finally {
parallel.running = false;
current = null;
}
}
return {
setUp,
ready,
release,
run,
waiting,
message: thread.message,
// The parts a call gets: chosen, where the host chose a number, else
// the page's default.
parts(chosen) {
const parts = Math.trunc(chosen ?? NaN);
return Number.isFinite(parts)
? Math.min(Math.max(parts, 1), kTeamMax + 1)
: Math.min(globalThis.navigator?.hardwareConcurrency ?? 1, kDefaultParts);
},
// How the team waits when parked, for tests to report.
state() {
const waits = team === null ? 0 : Atomics.load(team.words, kTeamWaits);
return {
'team': team?.workers.length ?? 0,
'waits': waits === kWaitAsync ? 'async' : waits === kWaitTimed ? 'timed' : 'none',
};
},
};
}
// The JS half of the browser scripting lane. Script modules run on the
// browser's own wasm engine; librive reaches them through the EM_JS calls in
// browser_scripting_vm.cpp, which forward to the runner installed here.
//
// Loading a file is two steps. File::import makes each script VM and
// registers its module bytes here, without instantiating. The host then
// awaits prepare(), which compiles and instantiates every registered module
// asynchronously, and only then asks librive to start the file's scripts.
// A host that skips prepare() still works where the browser allows
// synchronous compilation on the calling thread: start() instantiates inline.
//
// Hosts link rive_scripting_pre.js, generated from this file, into their
// emscripten build with --pre-js. It installs the runner by itself, so a
// host only does:
// ... import a file ...
// await Module.riveScripting.prepare();
// ... start the file's scripts ...
// WasmScriptingVM::CallOutcome, then the browser's own host fault.
const kOk = 0;
const kMissing = 1;
const kTrapped = 2;
const kHostFault = 3;
// One function returning v128.const zero, then one returning the relaxed
// swizzle of two: the smallest modules each SIMD flavor needs.
const kV128Zero = [0xfd, 0x0c, ...new Array(16).fill(0)];
const kSimdProbe = probeModule([...kV128Zero]);
const kRelaxedSimdProbe = probeModule([
...kV128Zero,
...kV128Zero,
0xfd,
0x80,
0x02,
]);
function probeModule(body) {
const code = [0, ...body, 0x0b];
return new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 1, 0, 0, 0,
// One type, () -> v128, and one function of it.
1, 5, 1, 0x60, 0, 1, 0x7b,
3, 2, 1, 0,
10, code.length + 2, 1, code.length, ...code,
]);
}
// Index immediates of the 0xfc ops by sub-opcode: none for the saturating
// truncations, then memory.init through table.fill.
const kBulkIndices = [0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1];
// The ops past the variable accesses that take one LEB.
const kOneLebOps = [0x0c, 0x0d, 0x10, 0x12, 0x3f, 0x40, 0x41, 0x42, 0xd0, 0xd2];
// The SIMD a module's types and code need: 2 for relaxed, 1 for plain, 0 for
// none, or -1 when they hold what this walk does not read.
function simdNeeded(bytes) {
let needed = 0;
let at = 8;
const need = (flavor) => {
needed = Math.max(needed, flavor);
};
const next = () => {
const [value, end] = readLeb(bytes, at);
at = end;
return value;
};
const memarg = () => {
if (next() & 0x40) {
next();
}
next();
};
// False for a reference type with a heap type, which takes more bytes.
const valueType = () => {
const type = bytes[at++];
if (type === 0x7b) {
need(1);
}
return type !== 0x63 && type !== 0x64;
};
const instruction = () => {
const op = bytes[at++];
if (op === 0xfd) {
const sub = next();
need(sub >= 0x100 && sub <= 0x113 ? 2 : 1);
if (sub <= 0x0b || sub === 0x5c || sub === 0x5d) {
memarg();
} else if (sub === 0x0c || sub === 0x0d) {
at += 16;
} else if (sub >= 0x15 && sub <= 0x22) {
at += 1;
} else if (sub >= 0x54 && sub <= 0x5b) {
memarg();
at += 1;
}
} else if (op === 0xfc) {
const sub = next();
if (sub >= kBulkIndices.length) {
return false;
}
for (let i = 0; i < kBulkIndices[sub]; i++) {
next();
}
} else if (op === 0xfe) {
// atomic.fence takes a byte, the other atomics a memarg.
if (next() === 3) {
at += 1;
} else {
memarg();
}
} else if (op >= 0x28 && op <= 0x3e) {
memarg();
} else if (op >= 0x02 && op <= 0x04) {
// A block type: one byte, or a type index.
if (bytes[at] === 0x7b) {
need(1);
}
next();
} else if (op === 0x0e) {
for (let labels = next(); labels >= 0 && at < bytes.length; labels--) {
next();
}
} else if (op === 0x1c) {
for (let types = next(); types > 0 && at < bytes.length; types--) {
if (!valueType()) {
return false;
}
}
} else if (op === 0x11 || op === 0x13) {
next();
next();
} else if (op === 0x43 || op === 0x44) {
at += op === 0x43 ? 4 : 8;
} else if ((op >= 0x20 && op <= 0x26) || kOneLebOps.includes(op)) {
next();
} else if (!(op <= 0x01 || op === 0x05 || op === 0x0b || op === 0x0f ||
op === 0x1a || op === 0x1b || op === 0xd1 ||
(op >= 0x45 && op <= 0xc4))) {
return false;
}
return true;
};
while (at < bytes.length) {
const id = bytes[at];
const [size, body] = readLeb(bytes, at + 1);
at = body;
if (id === 1) {
for (let types = next(); types > 0 && at < bytes.length; types--) {
// Function types only: params, then results.
if (bytes[at++] !== 0x60) {
return -1;
}
for (let list = 0; list < 2; list++) {
for (let n = next(); n > 0 && at < bytes.length; n--) {
if (!valueType()) {
return -1;
}
}
}
}
} else if (id === 10) {
for (let bodies = next(); bodies > 0 && at < bytes.length; bodies--) {
const end = Math.min(next() + at, bytes.length);
for (let locals = next(); locals > 0 && at < end; locals--) {
next();
if (!valueType()) {
return -1;
}
}
while (at < end) {
if (!instruction()) {
return -1;
}
}
}
}
at = body + size;
}
return needed;
}
function readLeb(bytes, at) {
let value = 0;
let shift = 0;
let byte;
do {
byte = bytes[at++];
value |= (byte & 0x7f) << shift;
shift += 7;
} while (byte & 0x80);
return [value >>> 0, at];
}
function leb(value) {
const out = [];
do {
const byte = value & 0x7f;
value >>>= 7;
out.push(value ? byte | 0x80 : byte);
} while (value);
return out;
}
// Each section of a module: its id, where it starts, its body and its end.
function sectionsOf(bytes) {
const sections = [];
for (let at = 8; at < bytes.length; ) {
const [size, body] = readLeb(bytes, at + 1);
sections.push({ id: bytes[at], at, body, end: body + size });
at = body + size;
}
return sections;
}
const kLaneSectionNames = kLaneSections.map(([name]) =>
Array.from(name, (c) => c.charCodeAt(0))
);
// The lane modules a script module carries in its custom sections.
function laneModulesOf(bytes) {
const lanes = [];
for (const section of sectionsOf(bytes)) {
if (section.id !== 0) {
continue;
}
const [length, name] = readLeb(bytes, section.body);
const named = (wanted) =>
wanted.length === length && wanted.every((c, i) => bytes[name + i] === c);
if (kLaneSectionNames.some(named)) {
lanes.push(bytes.subarray(name + length, section.end));
}
}
return lanes;
}
// rasc runs every script's top level in the module's start function, and a
// top level can pass memory to the host. The module's memory is an export,
// which the page cannot reach until start has returned. So the start section
// is dropped and its function exported, for the runner to call once the
// instance and its memory exist. Modules without one come back untouched.
// Lane modules are cached by these bytes, so they must match wasm_lane.cpp's.
function liftStart(bytes) {
const all = sectionsOf(bytes);
const start = all.find((section) => section.id === 8);
const sections = all.filter((section) => section !== start);
if (start === undefined || !sections.some((section) => section.id === 7)) {
return bytes;
}
const startFunction = readLeb(bytes, start.body)[0];
const parts = [bytes.subarray(0, 8)];
for (const section of sections) {
let body = bytes.subarray(section.body, section.end);
if (section.id === 7) {
const [count, first] = readLeb(bytes, section.body);
const name = Array.from(kLiftedStartExport, (c) => c.charCodeAt(0));
body = Uint8Array.from([
...leb(count + 1),
...bytes.subarray(first, section.end),
...leb(name.length),
...name,
0,
...leb(startFunction),
]);
}
parts.push(Uint8Array.from([section.id, ...leb(body.length)]), body);
}
const out = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
let at = 0;
for (const part of parts) {
out.set(part, at);
at += part.length;
}
return out;
}
// A parallel module declares a shared memory up to wasm32's limit, which a
// browser would set aside whole and which needs cross origin isolation. Its
// memory moves to an import instead, so the runner picks the memory to give
// it: shared up to what the device can set aside, else unshared, where its
// parts run one at a time. Every other module comes back untouched.
const kMemoryImport = ['rive_parallel_v1', 'memory'];
const kSharedTryPages = 32768;
function importMemory(bytes) {
const all = sectionsOf(bytes);
const memory = all.find((section) => section.id === 5);
const imports = all.find((section) => section.id === 2);
if (memory === undefined || imports === undefined) {
return { bytes, memory: null };
}
let [count, at] = readLeb(bytes, memory.body);
const flags = bytes[at++];
if (count !== 1 || (flags & 2) === 0) {
return { bytes, memory: null };
}
const [initial, afterInitial] = readLeb(bytes, at);
const declared = flags & 1 ? readLeb(bytes, afterInitial)[0] : 65536;
const shared =
typeof SharedArrayBuffer === 'function' &&
globalThis.crossOriginIsolated !== false;
let maximum = declared;
let created = null;
if (shared) {
// Halving down to what the module needs, as a 32-bit browser or one
// short of address space refuses a large reservation.
maximum = Math.min(declared, kSharedTryPages);
for (;;) {
try {
// Quoted, as closure renames a key its externs lack.
created = new WebAssembly.Memory({
'initial': initial,
'maximum': maximum,
'shared': shared,
});
break;
} catch (error) {
if (!(error instanceof RangeError) || maximum <= initial) {
throw error;
}
maximum = Math.max(initial, maximum >>> 1);
}
}
} else {
created = new WebAssembly.Memory({ initial, maximum });
}
const name = (text) => [...leb(text.length), ...Array.from(text, (c) => c.charCodeAt(0))];
const entry = [
...name(kMemoryImport[0]),
...name(kMemoryImport[1]),
2,
shared ? 3 : 1,
...leb(initial),
...leb(maximum),
];
const [importCount, first] = readLeb(bytes, imports.body);
const parts = [bytes.subarray(0, 8)];
for (const section of all) {
if (section === memory) {
continue;
}
let body = bytes.subarray(section.body, section.end);
if (section === imports) {
body = Uint8Array.from([
...leb(importCount + 1),
...bytes.subarray(first, section.end),
...entry,
]);
}
parts.push(Uint8Array.from([section.id, ...leb(body.length)]), body);
}
const out = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
let offset = 0;
for (const part of parts) {
out.set(part, offset);
offset += part.length;
}
return { bytes: out, memory: created };
}
// A member of a parallel module shares the memory the page's instance already
// filled, so its data segments are made passive, which instantiating leaves
// alone. Its start is already lifted out.
function passiveData(bytes) {
const all = sectionsOf(bytes);
const data = all.find((section) => section.id === 11);
if (data === undefined) {
return bytes;
}
let [count, at] = readLeb(bytes, data.body);
const body = [Uint8Array.from(leb(count))];
for (let i = 0; i < count; i++) {
let flags;
[flags, at] = readLeb(bytes, at);
if (flags === 2) {
at = readLeb(bytes, at)[1];
}
// The offset is one constant instruction and end.
if (flags !== 1) {
for (let op = bytes[at++]; op !== 0x0b; op = bytes[at++]) {
at = readLeb(bytes, at)[1];
}
}
const [length, first] = readLeb(bytes, at);
body.push(Uint8Array.from([1, ...leb(length)]), bytes.subarray(first, first + length));
at = first + length;
}
const parts = [bytes.subarray(0, 8)];
for (const section of all) {
const sectionBody =
section === data ? concatBytes(body) : bytes.subarray(section.body, section.end);
parts.push(Uint8Array.from([section.id, ...leb(sectionBody.length)]), sectionBody);
}
return concatBytes(parts);
}
function concatBytes(parts) {
const out = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
let at = 0;
for (const part of parts) {
out.set(part, at);
at += part.length;
}
return out;
}
// Args by index: spreading a subarray of the heap cost more than the call.
function callExport(fn, args, at, argc) {
switch (argc) {
case 0:
return fn();
case 1:
return fn(args[at]);
case 2:
return fn(args[at], args[at + 1]);
case 3:
return fn(args[at], args[at + 1], args[at + 2]);
case 4:
return fn(args[at], args[at + 1], args[at + 2], args[at + 3]);
case 5:
return fn(args[at], args[at + 1], args[at + 2], args[at + 3],
args[at + 4]);
case 6:
return fn(args[at], args[at + 1], args[at + 2], args[at + 3],
args[at + 4], args[at + 5]);
case 7:
return fn(args[at], args[at + 1], args[at + 2], args[at + 3],
args[at + 4], args[at + 5], args[at + 6]);
case 8:
return fn(args[at], args[at + 1], args[at + 2], args[at + 3],
args[at + 4], args[at + 5], args[at + 6], args[at + 7]);
default:
return fn(...args.subarray(at, at + argc));
}
}
function installRiveScripting(Module) {
// Primitives over the librive heap and exports, handed over by librive
// itself on first use because only code inside it can see them.
let host = null;
// A pool thread's own clock starts late, so lanes read the page's, as
// native lanes share one steady clock.
let laneNow = monotonicNow;
const vms = new Map();
// Bridge traffic, tallied only while a page measures it.
const counters = {
on: false,
hostCalls: 0,
bytesStaged: 0,
bytesCopiedOut: 0,
bytesRead: 0,
bytesWritten: 0,
};
// What the generated imports need from librive, for calls under ctx,
// binding only that namespace when only names one.
function librive(ctx, only = null) {
return {
calls: bindRiveHostCalls(host.hostCall, ctx, only),
heapU8: host.heapU8,
stackSave: host.stackSave,
stackAlloc: host.stackAlloc,
stackRestore: host.stackRestore,
malloc: host.malloc,
free: host.free,
counters,
};
}
// Tests stand in for an engine without SIMD with their own validator,
// and run offline processors on the natives a worklet uses.
const validate =
Module['riveScriptingValidate'] ??
((bytes) => WebAssembly.validate(bytes));
const laneTwin = Module['riveScriptingLaneTwin'] === true;
let features = null;
// Why this engine refuses a module or a lane module it carries, when a
// SIMD flavor it lacks is the reason; null otherwise.
function missingSimd(bytes) {
features ??= {
simd: validate(kSimdProbe),
relaxed: validate(kRelaxedSimdProbe),
};
const modules = [bytes, ...laneModulesOf(bytes)];
if (
(features.simd && features.relaxed) ||
modules.every((module) => validate(module))
) {
return null;
}
const needed = Math.max(...modules.map(simdNeeded));
if (!features.simd && needed > 0) {
return "this browser lacks WebAssembly SIMD, so this file's scripts " +
'are off; bake with wasmSimd: off to support it';
}
if (!features.relaxed && needed === 2) {
return "this browser lacks WebAssembly relaxed SIMD, so this file's " +
'scripts are off; bake with wasmSimd: on to support it';
}
return null;
}
// The module's bytes once its memory is the runner's to give.
function withMemory(entry) {
const { bytes, memory } = importMemory(entry.bytes);
entry.parallelMemory = memory;
return bytes;
}
const sharedMemory = (entry) =>
typeof SharedArrayBuffer === 'function' &&
entry.parallelMemory?.buffer instanceof SharedArrayBuffer;
// The bytes a team thread instantiates a member from, or null where a
// call never gets more than one part.
function memberBytes(entry, lifted) {
return sharedMemory(entry) && teamWorkerOf !== null ? passiveData(lifted) : null;
}
// Members on the team once the page's own instance has started.
function adoptMembers(entry, bytes) {
if (bytes !== null && entry.instance !== null) {
entry.parallel = parallel.setUp(entry, bytes, entry.parallelSize());
}
}
function importsFor(entry, module) {
const imports = createRiveModuleImports(
librive(entry.ctx),
() => {
if (entry.memory === null) {
// Only a start function liftStart could not move.
throw new Error(
'script passed memory to the host while its module ' +
'was still starting'
);
}
return entry.memory;
}
);
if (entry.parallelMemory !== null) {
const space = (imports[kMemoryImport[0]] ??= {});
space[kMemoryImport[1]] = entry.parallelMemory;
// Calls share the memory with a team of threads only where it is
// shared; elsewhere a call gets one part. Where librive allows
// more, the page picks how many.
const size = space['size'];
const shared = sharedMemory(entry);
space['size'] = () =>
shared && size() > 1 ? parallel.parts(runner['parallelParts']) : 1;
const rt = imports['rive_rt_v1'];
const budget = rt['budget_exceeded'];
// A budget the page's own part already reported is not reported
// again for a member that ran out at the same time.
rt['budget_exceeded'] = (ms) => {
entry.budgeted = true;
return budget(ms);
};
const report = {
thrown: (at, length) => rt['error'](at, length),
budget: (ms) => (entry.budgeted ? undefined : budget(ms)),
};
space['run'] = (control) => {
entry.budgeted = false;
return parallel.run(entry, entry.parallel, control >>> 0, report);
};
space['waiting'] = parallel.waiting;
entry.parallelSize = space['size'];
}
// The browser refuses a module with an import nothing provides.
for (const wanted of WebAssembly.Module.imports(module)) {
if (wanted['kind'] === 'function') {
const space = (imports[wanted['module']] ??= {});
space[wanted['name']] ??= unlinkedImport(
wanted['module'],
wanted['name']
);
}
}
return imports;
}
// Before its lanes compile and a start liftStart left in place runs, as
// top levels already pass strings and a refused module must do neither.
function announceExports(entry, module) {
const mark = host.stackSave();
for (const { name } of WebAssembly.Module.exports(module)) {
if (!name.startsWith('__rive')) {
continue;
}
const capacity = name.length * 3 + 1;
const ptr = host.stackAlloc(capacity);
host.writeUtf8(name, ptr, capacity);
host.exports['_rive_web_vm_module_export'](entry.ctx.vm, ptr);
}
host.stackRestore(mark);
const refusal =
host.exports['_rive_web_vm_start_refusal'](entry.ctx.vm);
if (refusal !== 0) {
throw new Error(host.utf8(refusal));
}
}
function adopt(entry, instance) {
entry.memory = instance.exports['memory'];
entry.bytes = null;
// State of the call in progress, which a trap unwinds without
// restoring; a global the module cannot write is not state.
entry.callState = Object.keys(instance.exports)
.filter((name) => name.startsWith('__riveCall'))
.map((name) => instance.exports[name])
.filter((global) => {
if (!(global instanceof WebAssembly.Global)) {
return false;
}
try {
global.value = global.value;
return true;
} catch {
return false;
}
});
// One stack for nested calls, so hot paths allocate nothing.
entry.callSaved = [];
// A metered module's own fuel bounds its top level, as it does its
// calls.
const fuelMs = host.exports['_rive_web_vm_start_fuel'](entry.ctx.vm);
const arm = instance.exports['__riveFuelArm'];
const end = instance.exports['__riveFuelEnd'];
const fueled = fuelMs > 0 && arm !== undefined && end !== undefined;
const booting = host.exports['_rive_web_vm_booting'];
booting(entry.ctx.vm);
const mark = host.stackSave();
// A wait in the top level moves a metered module's fuel on with a call.
entry.instance = instance;
try {
if (fueled) arm(fuelMs);
instance.exports[kLiftedStartExport]?.();
if (fueled) end();
} catch (error) {
entry.instance = null;
// A host fault skips the epilogues of the librive frames it unwinds.
host.stackRestore(mark);
entry.ctx.raised = null;
throw error;
} finally {
booting(0);
}
}
async function prepareEntry(entry) {
try {
const lifted = liftStart(withMemory(entry));
const module = await WebAssembly.compile(lifted);
const members = memberBytes(entry, lifted);
if (entry.ctx.vm === 0) {
return;
}
announceExports(entry, module);
const lanes = prepareLanes(module);
const instance = await WebAssembly.instantiate(
module,
importsFor(entry, module)
);
await lanes;
// Released while instantiating.
if (entry.ctx.vm === 0) {
return;
}
adopt(entry, instance);
adoptMembers(entry, members);
if (entry.parallel !== null) {
await parallel.ready(entry.parallel);
}
} catch (error) {
entry.error = errorText(error);
}
}
// Lanes run the lane modules a script module carries, on whichever thread
// runs them, reaching only their own natives, shared memory and the console.
// Compiled lane modules, oldest first, matched by id or by their lifted
// bytes, which librive hands over; a dropped one only costs a recompile.
const laneModules = [];
const kLaneModuleCache = 8;
// The page's idle pthread workers, on a pthread build.
let threads = () => [];
// A team thread's worker by thread, on a pthread build.
let teamWorkerOf = null;
const parallel = createParallel({
can: () => teamWorkerOf !== null,
start() {
const thread = host.exports['_rive_web_parallel_team_thread']();
return thread === 0 ? null : (teamWorkerOf(thread) ?? null);
},
});
function sameBytes(a, b) {
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function cacheLane(bytes, module, error) {
// job is the instance a finished job left on this thread for the next.
const compiled = { bytes, module, error, ids: new Set(), job: null };
laneModules.push(compiled);
if (laneModules.length > kLaneModuleCache) {
laneModules.shift();
}
return compiled;
}
const laneCached = (bytes) => laneModules.some((lane) => sameBytes(lane.bytes, bytes));
// A thread that missed the page's compile compiles its own.
function shareLane(bytes, module) {
if (laneCached(bytes)) {
return;
}
cacheLane(bytes, module, null);
for (const worker of threads()) {
worker.postMessage({ 'riveLane': { 'bytes': bytes, 'module': module } });
}
}
const takeLane = (data) => {
if (parallel.message(data)) {
return;
}
const lane = data?.['riveLane'];
if (lane !== undefined) {
shareLane(lane['bytes'], lane['module']);
}
};
const nodeThreads = globalThis.process?.getBuiltinModule?.('worker_threads');
if (nodeThreads?.isMainThread === false) {
nodeThreads.parentPort.on('message', takeLane);
} else if (globalThis.WorkerGlobalScope !== undefined) {
globalThis.addEventListener('message', (event) => takeLane(event.data));
}
function checkLaneImports(module, kind) {
for (const wanted of WebAssembly.Module.imports(module)) {
if (laneImportRefusal(kind, wanted['module'], wanted['name']) !== null) {
throw new Error(laneImportError(wanted['module'], wanted['name']));
}
}
}
// Compiles a main module's lane sections for every thread, off the page's
// thread unless now. One that fails is left to fail where it first runs.
function prepareLanes(main, now = false) {
const compiles = [];
for (const [name, kind] of kLaneSections) {
for (const section of WebAssembly.Module.customSections(main, name)) {
const bytes = liftStart(new Uint8Array(section));
if (laneCached(bytes)) {
continue;
}
const share = (module) => {
checkLaneImports(module, kind);
shareLane(bytes, module);
};
if (now) {
try {
share(new WebAssembly.Module(bytes));
} catch (error) {}
} else {
compiles.push(WebAssembly.compile(bytes).then(share).catch(() => {}));
}
}
}
return Promise.all(compiles);
}
function laneModule(id, bytes, kind) {
let compiled = laneModules.find((lane) => lane.ids.has(id));
if (compiled === undefined) {
const lifted = bytes();
compiled = laneModules.find((lane) => sameBytes(lane.bytes, lifted));
if (compiled === undefined) {
compiled = cacheLane(lifted, null, null);
try {
const module = new WebAssembly.Module(lifted);
checkLaneImports(module, kind);
compiled.module = module;
} catch (error) {
compiled.error = errorText(error);
}
}
compiled.ids.add(id);
if (compiled.ids.size > kLaneModuleCache) {
compiled.ids.delete(compiled.ids.values().next().value);
}
}
return compiled;
}
// A lane's shared imports: librive's natives, or with twin Atomics on
// librive's heap reaching owner's objects, as an audio worklet does.
function sharedImports(twin = false, owner = 0) {
return (memory, fail) =>
twin
? createSharedLaneImports(
() => host.heapU8().buffer,
host.exports['_rive_shared_table'](),
owner,
memory,
null,
fail
)
: createRiveModuleImports(
librive(
{ vm: 1, raised: null, hostFault: false, counters },
'rive_shared_v1'
),
memory,
'rive_shared_v1'
)['rive_shared_v1'];
}
// A browser cannot interrupt a lane, so a metered one's fuel checks throw
// why librive would.
function laneFuel(lane) {
const stop = host.laneStop(lane);
if (stop !== null) {
throw stop;
}
}
// The instance a job left idle on this thread, or a new one, whose imports
// reach whichever job it runs.
function jobInstance(compiled) {
const idle = compiled.job;
compiled.job = null;
if (idle !== null) {
idle.timers.clear();
return idle;
}
const job = { lane: 0, cancelled: null, timers: new Map(), reset: false };
return Object.assign(
job,
instantiateLane({
module: compiled.module,
natives: 'rive_job_v1',
own: () => ({ 'cancelled': () => job.cancelled() }),
shared: sharedImports(),
log: (line) => host.laneLog(job.lane, line),
timers: job.timers,
now: laneNow,
fuel: () => laneFuel(job.lane),
})
);
}
// A stop reaches a running job through its cancelled() and its fuel
// checks. The output views the job's memory.
function runJob(lane, id, bytes, entry, input, cancelled) {
const compiled = laneModule(id, bytes, 'job');
if (compiled.error !== null) {
return { ok: false, error: compiled.error };
}
const job = jobInstance(compiled);
if (job.error !== undefined) {
return { ok: false, error: job.error };
}
job.lane = lane;
job.cancelled = cancelled;
const entered = enterLane(
job,
{ prefix: kLaneEntryPrefixes['job'], entry, input },
job.reset
);
if (entered.error !== undefined) {
return { ok: false, error: entered.error };
}
try {
const buffer = job.memory.buffer;
const words = new Uint32Array(buffer, entered.result >>> 0, 2);
const output =
words[1] === 0 ? new Uint8Array(0) : new Uint8Array(buffer, words[0], words[1]);
// Only a job that returned, unstopped, with small memory leaves its
// instance; the next resets it once this output is copied out.
if (
job.exports[kLaneResetExport] !== undefined &&
buffer.byteLength <= kReuseMaxPages * 65536 &&
!cancelled()
) {
job.reset = true;
compiled.job = job;
}
return { ok: true, output };
} catch (error) {
return { ok: false, error: job.failure(error) };
}
}
// Workers keep their instance between wakes, on the thread that started
// them; librive steps each one and owns its waits.
const workers = new Map();
let nextWorker = 1;
// A worker's natives call back into librive through natives.
function workerStart(lane, id, bytes, entry, input, natives) {
const compiled = laneModule(id, bytes, 'worker');
if (compiled.error !== null) {
return { ok: false, error: compiled.error };
}
const started = startLane({
module: compiled.module,
natives: 'rive_worker_v1',
// A view of the worker's memory, which librive copies once.
own: (memory) => ({
'finished': (ok, at, length) =>
natives.finished(
ok,
new Uint8Array(memory().buffer, at >>> 0, length >>> 0)
),
'wait': natives.wait,
'stopping': natives.stopping,
}),
onThrow: (text) => host.laneFail(lane, text),
shared: sharedImports(),
log: (line) => host.laneLog(lane, line),
now: laneNow,
fuel: () => laneFuel(lane),
prefix: kLaneEntryPrefixes['worker'],
entry,
input,
free: true,
});
if (started.error !== undefined) {
return { ok: false, error: started.error };
}
const worker = nextWorker++;
workers.set(worker, {
wake: started.exports[kWorkerWakeExport],
collect: started.exports[kFrameMinorExport],
});
return { ok: true, id: worker };
}
// Returns null once the worker took the wake, else the error.
function workerWake(worker, wait, value) {
try {
workers.get(worker).wake(wait, value);
return null;
} catch (error) {
return errorText(error);
}
}
// Back at the host no frame is live, so the frame collector may run.
// Returns null, or the error that ended the worker.
function workerCollect(worker) {
try {
workers.get(worker)?.collect?.();
return null;
} catch (error) {
return errorText(error);
}
}
function workerEnd(worker) {
workers.delete(worker);
}
// A processor rendered offline: librive pulls each block.
const processors = new Map();
let nextProcessor = 1;
function processorStart(lane, id, bytes, entry, input, format, sharedOwner) {
const compiled = laneModule(id, bytes, 'processor');
if (compiled.error !== null) {
return { ok: false, error: compiled.error };
}
const started = startProcessorLane(
compiled.module,
entry,
input,
format,
sharedImports(laneTwin, sharedOwner),
(line) => host.laneLog(lane, line)
);
if (started.error !== undefined) {
return { ok: false, error: started.error };
}
const processor = nextProcessor++;
processors.set(processor, started.lane);
return { ok: true, id: processor };
}
function processorRender(processor, frames, startFrame, sink) {
return processors.get(processor).render(frames, startFrame, sink);
}
// Processors in real time run on an audio worklet that reaches librive's
// heap through Atomics; README.md says what the host provides for it.
// owners: the librive processor and module behind each worklet id.
const audio = { output: null, owners: new Map(), next: 1 };
// Checks of the worklet's block counter that may see no block before the
// output ends. A start outlasts init's budget, which ends a metered one.
const kStallCheckMs = 50;
const kStallChecks = 2;
const kStartStallChecks = kProcessorInitMs / kStallCheckMs + 10;
const kReadyChecks = 40;
// A stuck browser worklet holds up only its own context, and a slow block
// that returns fails on its budget, so a stall there must last longer.
const kBrowserStallChecks = 20;
// An ended NRDP thread ran on for up to 39 ms on the devices we measured.
const kEndedThreadMs = 200;
const kContextClosed = 'script audio context closed';
// A context the browser lets start does so well within this.
const kGestureWaitMs = 1000;
// NRDP's names are quoted so a closure compiled host keeps them.
const nrdp = () => globalThis['nrdp'];
const onNrdp = () => nrdp()?.['audio']?.['output'] !== undefined;
// The worklet a host serves, else the one a threaded build carries, which
// needs nothing served beside the runtime. NRDP only runs its own bundle.
let carriedWorklet = null;
function workletUrl() {
const given = runner['audioWorkletUrl'];
if (typeof given === 'string') {
return given;
}
const source = Module['riveAudioWorkletSource'];
if (onNrdp() || typeof source !== 'string') {
return null;
}
carriedWorklet ??= URL.createObjectURL(
new Blob([source], { type: 'text/javascript' })
);
return carriedWorklet;
}
// Null when processors can run in real time, else why not.
function audioRefusal() {
if (!onNrdp() && globalThis.crossOriginIsolated !== true) {
return 'real time audio needs cross origin isolation';
}
// The worklet reaches librive's heap through Atomics.
if (
typeof SharedArrayBuffer === 'undefined' ||
!(host.memory().buffer instanceof SharedArrayBuffer)
) {
return 'real time audio needs librive built with threads';
}
if (workletUrl() === null) {
return 'real time audio needs riveScripting.audioWorkletUrl';
}
if (typeof AudioContext === 'undefined') {
return 'real time audio needs Web Audio';
}
const given = runner['audioContext'];
if (given?.state === 'closed') {
return 'real time audio cannot start on a closed AudioContext';
}
// A stuck worklet holds every later addModule on its context.
if (contextHolds.get(given)?.stalled) {
return "real time audio stalled the host's AudioContext; hand riveScripting a new one";
}
return null;
}
// What both outputs share: messages queue until the worklet can take
// them, and those that never reach it fail their processors.
function audioQueue() {
let queue = [];
let send = null;
return {
post(message) {
if (send !== null) {
send(message);
} else {
queue.push(message);
}
},
open(sender) {
send = sender;
for (const message of queue) {
send(message);
}
queue = [];
},
fail(text) {
for (const message of queue) {
audioEvent({ 'id': message['id'], 'kind': 'failed', 'text': text });
}
queue = [];
},
};
}
// The worklets run uncompiled, so keys that cross to them are quoted.
function workletOptions(holds) {
return {
'numberOfInputs': 0,
'numberOfOutputs': 1,
'outputChannelCount': [2],
'processorOptions': {
'memory': host.memory(),
'table': host.exports['_rive_shared_table'](),
'counter': holds.buffer,
},
};
}
const newHolds = () => new Int32Array(new SharedArrayBuffer(kHoldWords * 4));
// Frees the lock and lane word a worklet that is surely gone left held.
const releaseLane = (holds) =>
releaseSharedLane(
() => host.memory().buffer,
host.exports['_rive_shared_table'](),
holds
);
function failOwners(text) {
for (const id of [...audio.owners.keys()]) {
audioEvent({ 'id': id, 'kind': 'failed', 'text': text });
}
}
// Calls end with why once the worklet stops counting blocks for
// stallChecks while processors wait on it, or once context closes.
function watchBlocks(context, holds, readyChecks, stallChecks, end, closed = end) {
let ready = false;
let seen = -1;
let stalled = 0;
const timer = setInterval(() => {
if (context.state === 'closed') {
clearInterval(timer);
closed(kContextClosed);
return;
}
const now = Atomics.load(holds, kHoldBlocks);
// A suspended context renders nothing without being stuck. A
// stall outlives the stop of the processor that caused it.
const waiting =
(audio.owners.size > 0 || stalled > 0) && context.state === 'running';
stalled = now === seen && waiting ? stalled + 1 : 0;
seen = now;
const limit = !ready
? readyChecks
: Atomics.load(holds, kHoldStarting) !== 0
? kStartStallChecks
: stallChecks;
if (stalled >= limit) {
clearInterval(timer);
end(ready ? 'processor stalled the audio thread' : 'script audio worklet never answered');
}
}, kStallCheckMs);
return {
ready() {
ready = true;
stalled = 0;
},
stop: () => clearInterval(timer),
};
}
// An output the host's worklet runs. sent: the modules it has the bytes
// of, so each crosses once; a worklet that lost them asks again.
function audioOutputOf(context, queue) {
return { context, post: queue.post, sent: new Set(), queue };
}
// An output that failed or was ended: what it still queued fails, and the
// next start makes a fresh one. Ends the context when it was ours.
function dropOutput(output, text, close = true) {
output.queue.fail(text);
if (audio.output === output) {
audio.output = null;
}
if (close && runner['audioContext'] === undefined) {
output.context.close?.();
}
}
const noWorklet = (error) =>
'script audio has no worklet: ' + errorText(error);
// A browser context's worklet keeps one lane word until the context
// closes, unless it stalled, as a stalled worklet may yet run.
const contextHolds = new WeakMap();
function browserHolds(context) {
let holds = contextHolds.get(context);
if (holds === undefined) {
holds = { words: newHolds(), stalled: false };
contextHolds.set(context, holds);
context.addEventListener('statechange', () => {
if (context.state === 'closed' && !holds.stalled) {
releaseLane(holds.words);
}
});
}
return holds;
}
// Browsers start audio only after a gesture, so a context only the runner
// holds resumes on the page's first one, and warns once while it waits.
function ownContext() {
// iOS mutes the default ambient session at the silent switch, which
// video plays through.
const session = globalThis.navigator?.['audioSession'];
if (session?.['type'] === 'auto') {
session['type'] = 'playback';
}
const context = new AudioContext();
const gestures = ['pointerdown', 'pointerup', 'keydown', 'touchend'];
const resume = () => context.resume();
const waiting = setTimeout(
() => console.warn('script audio waits for a click, tap or key press on the page'),
kGestureWaitMs
);
const started = () => {
if (context.state === 'running' || context.state === 'closed') {
clearTimeout(waiting);
context.removeEventListener('statechange', started);
for (const gesture of gestures) {
globalThis.removeEventListener(gesture, resume, { capture: true });
}
}
};
for (const gesture of gestures) {
globalThis.addEventListener(gesture, resume, { capture: true });
}
context.addEventListener('statechange', started);
started();
return context;
}
function browserOutput() {
const context = runner['audioContext'] ?? ownContext();
const queue = audioQueue();
const output = audioOutputOf(context, queue);
const holds = browserHolds(context);
let node = null;
const closed = (text) => {
if (audio.output === output) {
watch.stop();
failOwners(text);
dropOutput(output, text, false);
}
};
// Nothing ends a worklet stuck in a block, so its processors fail and the node
// leaves the mix in case it returns. Chrome's close would wait on that thread.
const stalled = (text) => {
holds.stalled = true;
node.port.onmessage = null;
node.port.postMessage({ 'kind': 'end' });
node.disconnect();
failOwners(text);
dropOutput(output, text, false);
};
const watch = watchBlocks(
context,
holds.words,
Infinity,
kBrowserStallChecks,
stalled,
closed
);
context.addEventListener('statechange', () => {
if (context.state === 'closed') {
closed(kContextClosed);
}
});
context.audioWorklet
.addModule(workletUrl())
.then(() => {
node = new AudioWorkletNode(
context,
kProcessorNode,
workletOptions(holds.words)
);
node.port.onmessage = (event) => audioEvent(event.data);
node.connect(context.destination);
watch.ready();
queue.open((message) => node.port.postMessage(message));
})
.catch((error) => {
watch.stop();
dropOutput(output, noWorklet(error));
});
return output;
}
// NRDP's worklet has no addModule: init binds a thread of ours to the
// context, which runs the bundled script and adds the processor.
function nrdpOutput() {
const url = runner['audioWorkletUrl'];
let context = runner['audioContext'];
if (context === undefined) {
// A context made before the output opens never renders.
nrdp()['audio']['output']['open']();
context = new AudioContext();
}
context['forceStart']?.();
const queue = audioQueue();
const output = audioOutputOf(context, queue);
const holds = newHolds();
let thread = null;
let ready = false;
let ended = false;
// A processor stuck in a block freezes every context; ending the
// thread lets sample playback resume.
const end = (text) => {
if (ended) {
return;
}
ended = true;
watch.stop();
thread?.['terminate']();
if (ready) {
// Waits here, where librive cannot meanwhile spin on a lock
// the ended thread left held.
for (const until = monotonicNow() + kEndedThreadMs; monotonicNow() < until; ) {}
releaseLane(holds);
failOwners(text);
}
dropOutput(output, text);
};
const watch = watchBlocks(context, holds, kReadyChecks, kStallChecks, end);
// A throw in a callback NRDP runs would escape the fetch's catch.
const guard =
(fn) =>
(...args) => {
try {
fn(...args);
} catch (error) {
end(noWorklet(error));
}
};
const onReady = guard(() => {
const node = new AudioWorkletNode(
context,
kProcessorNode,
workletOptions(holds)
);
node.connect(context.destination);
ready = true;
watch.ready();
queue.open((message) => thread['send'](message));
});
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(url + ' answered HTTP ' + response.status);
}
return response.text();
})
.then((source) => {
if (ended) {
return;
}
const worklet = context.audioWorklet;
worklet['active'] = true;
worklet['init'](
guard(() => {
if (ended) {
return;
}
thread = nrdp()['thread']['start']({
'url': url,
'source': source,
'audio': context,
});
thread.addEventListener('raw-message', (message) =>
message['kind'] === 'ready' ? onReady() : audioEvent(message)
);
})
);
})
.catch((error) => end(noWorklet(error)));
return output;
}
function audioOutput() {
audio.output ??= onNrdp() ? nrdpOutput() : browserOutput();
return audio.output;
}
// Forgets the oldest modules no processor runs, past the cache's size.
function forgetModules(output) {
const running = new Set([...audio.owners.values()].map((o) => o.moduleId));
for (const moduleId of output.sent) {
if (output.sent.size <= kLaneModuleCache) {
return;
}
if (!running.has(moduleId)) {
output.sent.delete(moduleId);
output.post({ 'kind': 'forget', 'moduleId': moduleId });
}
}
}
// Bytes rather than the compiled module: a browser's worklet may sit in
// another agent cluster, where a module cannot cross.
function postStart(output, owned, withBytes) {
const compiled = owned.compiled;
output.sent.add(owned.moduleId);
output.post({
...owned.start,
'bytes': withBytes ? compiled.bytes : null,
});
}
// owner names the processor to librive when the worklet answers.
function audioStart(owner, moduleId, bytes, entry, input, format, hardBlocks, sharedOwner) {
const compiled = laneModule(moduleId, bytes, 'processor');
if (compiled.error !== null) {
return { ok: false, error: compiled.error };
}
const output = audioOutput();
const id = audio.next++;
const owned = {
owner,
moduleId,
compiled,
start: {
'kind': 'start',
'id': id,
'moduleId': moduleId,
'entry': entry,
'input': input,
'format': {
'sampleRate': format.sampleRate,
'maxFrames': format.maxFrames,
'channels': format.channels,
},
'hardBlocks': hardBlocks,
'sharedOwner': sharedOwner,
},
};
audio.owners.set(id, owned);
postStart(output, owned, !output.sent.has(moduleId));
forgetModules(output);
return { ok: true, id };
}
function audioStop(id) {
audio.owners.delete(id);
if (audio.output !== null) {
audio.output.post({ 'kind': 'stop', 'id': id });
forgetModules(audio.output);
}
}
// The LaneState a processor reached, or a console line.
const kProcessorEvents = {
'running': kLaneStates['running'],
'failed': kLaneStates['failed'],
'log': kProcessorEventLog,
};
function audioEvent(event) {
const owned = audio.owners.get(event['id']);
if (owned === undefined) {
return;
}
if (event['kind'] === 'resend') {
if (audio.output !== null) {
postStart(audio.output, owned, true);
}
return;
}
host.processorEvent(owned.owner, kProcessorEvents[event['kind']], event['text'] ?? '');
}
function processorEnd(processor) {
processors.delete(processor);
}
const runner = {
attach(primitives) {
if (host !== null) {
return;
}
host = primitives;
// Zero where the engine has no timeOrigin.
const offset = performance.timeOrigin - host.pageOrigin || 0;
laneNow = () => performance.now() + offset;
},
attachThreads(workers, workerOf) {
threads = workers;
teamWorkerOf = workerOf;
},
register(vm, bytes) {
const copy = bytes.slice();
vms.set(vm, {
ctx: { vm, raised: null, hostFault: false, counters },
bytes: copy,
instance: null,
memory: null,
parallelMemory: null,
parallelSize: null,
parallel: null,
preparing: null,
error: missingSimd(copy),
names: new Map(),
});
},
release(vm) {
const entry = vms.get(vm);
if (entry) {
// A module still instantiating may call imports afterwards.
entry.ctx.vm = 0;
vms.delete(vm);
if (entry.parallel !== null) {
parallel.release(entry.parallel);
}
}
},
// The team a parallel call runs on, for tests to report.
parallelState() {
return parallel.state();
},
prepare() {
const pending = [];
for (const entry of vms.values()) {
if (entry.instance === null && entry.error === null) {
entry.preparing ??= prepareEntry(entry);
pending.push(entry.preparing);
}
}
return Promise.all(pending);
},
// Returns null when the VM has an instance, else the error.
start(vm) {
const entry = vms.get(vm);
if (!entry) {
return 'script module was never registered';
}
if (entry.instance === null && entry.error === null) {
if (entry.preparing !== null) {
return 'script module is still being prepared';
}
try {
const lifted = liftStart(withMemory(entry));
const module = new WebAssembly.Module(lifted);
announceExports(entry, module);
prepareLanes(module, true);
adopt(
entry,
new WebAssembly.Instance(module, importsFor(entry, module))
);
// Members start in the background; calls before they
// do get fewer parts.
adoptMembers(entry, memberBytes(entry, lifted));
} catch (error) {
entry.error = errorText(error);
}
}
return entry.error;
},
preparing(vm) {
const entry = vms.get(vm);
return entry?.instance === null &&
entry.error === null &&
entry.preparing !== null
? 1
: 0;
},
hasExport(vm, namePtr) {
const entry = vms.get(vm);
return typeof entry?.instance?.exports[host.utf8(namePtr)] ===
'function'
? 1
: 0;
},
// Args arrive as doubles: a u32 is exact in one and the engine
// converts each to the export's own parameter type.
call(vm, namePtr, argc, argv, resultPtr, trapBuffer, trapCapacity) {
const entry = vms.get(vm);
if (!entry || entry.instance === null) {
return kMissing;
}
// Export names reach librive's call seam as string literals, so
// the pointer identifies the name.
let fn = entry.names.get(namePtr);
if (fn === undefined) {
fn = entry.instance.exports[host.utf8(namePtr)] ?? null;
entry.names.set(namePtr, fn);
}
if (typeof fn !== 'function') {
return kMissing;
}
const callState = entry.callState;
const saved = entry.callSaved;
const base = saved.length;
for (let i = 0; i < callState.length; i++) {
saved.push(callState[i].value);
}
try {
const result = callExport(fn, host.heapF64(), argv >> 3, argc);
host.heapF64()[resultPtr >> 3] =
typeof result === 'number' ? result : 0;
return kOk;
} catch (error) {
entry.ctx.raised = null;
host.writeUtf8(
errorText(error),
trapBuffer,
trapCapacity
);
return entry.ctx.hostFault ? kHostFault : kTrapped;
} finally {
for (let i = 0; i < callState.length; i++) {
callState[i].value = saved[base + i];
}
saved.length = base;
}
},
raise(vm, messagePtr) {
const entry = vms.get(vm);
if (entry) {
entry.ctx.raised = host.utf8(messagePtr);
}
},
read(vm, appAddr, dst, size) {
const memory = vms.get(vm)?.memory;
if (!memory || appAddr + size > memory.buffer.byteLength) {
return 0;
}
host.heapU8().set(new Uint8Array(memory.buffer, appAddr, size), dst);
if (counters.on) counters.bytesRead += size;
return 1;
},
write(vm, appAddr, src, size) {
const memory = vms.get(vm)?.memory;
if (!memory || appAddr + size > memory.buffer.byteLength) {
return 0;
}
new Uint8Array(memory.buffer, appAddr, size).set(
host.heapU8().subarray(src, src + size)
);
if (counters.on) counters.bytesWritten += size;
return 1;
},
// Length of the zero terminated string at appAddr, or -1.
stringLength(vm, appAddr) {
const memory = vms.get(vm)?.memory;
if (!memory || appAddr >= memory.buffer.byteLength) {
return -1;
}
const end = new Uint8Array(memory.buffer).indexOf(0, appAddr);
return end < 0 ? -1 : end - appAddr;
},
pages(vm) {
const memory = vms.get(vm)?.memory;
// Not >>> 16, which reads a full 4 GiB memory as none.
return memory ? memory.buffer.byteLength / 65536 : 0;
},
// File::frameBoundary for every live VM, for hosts that keep no list
// of their files. Returns the warnings they raised.
frameBoundary() {
const warnings = [];
for (const vm of vms.keys()) {
const text = host.exports['_rive_web_vm_frame_boundary'](vm);
if (text !== 0) {
warnings.push(host.utf8(text));
}
}
return warnings;
},
// Starts or stops tallying the bridge traffic, from zero.
countHostCalls(on) {
counters.on = !!on;
counters.hostCalls = 0;
counters.bytesStaged = 0;
counters.bytesCopiedOut = 0;
counters.bytesRead = 0;
counters.bytesWritten = 0;
},
// Calls into librive, bytes staged into its heap and copied back, and
// bytes librive read and wrote through its memory seam.
hostCallCounts() {
return {
'hostCalls': counters.hostCalls,
'bytesStaged': counters.bytesStaged,
'bytesCopiedOut': counters.bytesCopiedOut,
'bytesRead': counters.bytesRead,
'bytesWritten': counters.bytesWritten,
};
},
};
runner['runJob'] = runJob;
runner['workerStart'] = workerStart;
runner['workerWake'] = workerWake;
runner['workerCollect'] = workerCollect;
runner['workerEnd'] = workerEnd;
runner['processorStart'] = processorStart;
runner['processorRender'] = processorRender;
runner['processorEnd'] = processorEnd;
runner['audioRefusal'] = audioRefusal;
runner['audioSampleRate'] = () => audioOutput().context.sampleRate;
runner['audioStart'] = audioStart;
runner['audioStop'] = audioStop;
// For hosts and tests: where the real time output stands.
runner['audioState'] = () => ({
'context': audio.output?.context.state ?? 'none',
'processors': audio.owners.size,
});
// The entries hosts call from outside this script.
runner['prepare'] = runner.prepare;
runner['frameBoundary'] = runner.frameBoundary;
runner['countHostCalls'] = runner.countHostCalls;
runner['hostCallCounts'] = runner.hostCallCounts;
Module['riveScripting'] = runner;
return runner;
}
installRiveScripting(Module);
})();