diff --git a/build.bat b/build.bat index ccd88f3..9e38dcc 100644 --- a/build.bat +++ b/build.bat @@ -33,30 +33,30 @@ if %target% == orca ( copy milepost\bin\milepost.dll.lib bin ::generate wasm3 api bindings - python3 scripts\bindgen.py core src\core_api.json^ + python3 scripts\bindgen_bb.py core src\core_api.json^ --wasm3-bindings src\core_api_bind_gen.c - python3 scripts\bindgen.py gles src\gles_api.json^ + python3 scripts\bindgen_bb.py gles src\gles_api.json^ --wasm3-bindings src\gles_api_bind_gen.c - python3 scripts\bindgen.py canvas src\canvas_api.json^ + python3 scripts\bindgen_bb.py canvas src\canvas_api.json^ --guest-stubs sdk\orca_surface.c^ --guest-include graphics.h^ --wasm3-bindings src\canvas_api_bind_gen.c - python3 scripts\bindgen.py clock src\clock_api.json^ + python3 scripts\bindgen_bb.py clock src\clock_api.json^ --guest-stubs sdk\orca_clock.c^ --guest-include platform_clock.h^ --wasm3-bindings src\clock_api_bind_gen.c - python3 scripts\bindgen.py io^ + python3 scripts\bindgen_bb.py io^ src\io_api.json^ --guest-stubs sdk\io_stubs.c^ --wasm3-bindings src\io_api_bind_gen.c ::compile orca - set INCLUDES=/I src /I sdk /I ext\wasm3\source /I milepost\src /I milepost\ext - set LIBS=/LIBPATH:bin milepost.dll.lib wasm3.lib + set INCLUDES=/I src /I sdk /I ext\bytebox\include /I milepost\src /I milepost\ext + set LIBS=/LIBPATH:bin milepost.dll.lib ext\bytebox\lib\bytebox.lib cl /Zi /Zc:preprocessor /std:c11 /experimental:c11atomics %INCLUDES% src\main.c /link %LIBS% /out:bin\orca.exe ) diff --git a/ext/bytebox/include/bytebox.h b/ext/bytebox/include/bytebox.h new file mode 100644 index 0000000..d6c533a --- /dev/null +++ b/ext/bytebox/include/bytebox.h @@ -0,0 +1,147 @@ +// C interface for bytebox wasm runtime. + +#include +#include + +struct bb_slice +{ + char* data; + size_t length; +}; +typedef struct bb_slice bb_slice; + +enum bb_error +{ + BB_ERROR_OK, + BB_ERROR_FAILED, + BB_ERROR_OUTOFMEMORY, + BB_ERROR_INVALIDPARAM, + BB_ERROR_UNKNOWNEXPORT, +}; +typedef enum bb_error bb_error; + +enum bb_valtype +{ + BB_VALTYPE_I32, + BB_VALTYPE_I64, + BB_VALTYPE_F32, + BB_VALTYPE_F64, +}; +typedef enum bb_valtype bb_valtype; + +typedef float bb_v128[4]; +union bb_val +{ + int32_t i32_val; + int64_t i64_val; + float f32_val; + double f64_val; + bb_v128 v128_val; + uint32_t externref_val; +}; +typedef union bb_val bb_val; + +struct bb_module_definition_init_opts +{ + const char* debug_name; +}; +typedef struct bb_module_definition_init_opts bb_module_definition_init_opts; + +struct bb_module_definition +{ + void* module; +}; +typedef struct bb_module_definition bb_module_definition; + +// struct bb_import_function +// { +// const char* name; +// bb_host_function* func; +// bb_valtype* params; +// size_t num_params; +// bb_valtype* returns; +// size_t num_returns; +// void* userdata; +// }; +// typedef struct bb_import_function bb_import_function; + +struct bb_import_package +{ + void* package; +}; +typedef struct bb_import_package bb_import_package; + +struct bb_module_instance_instantiate_opts +{ + bb_import_package* packages; + size_t num_packages; + bool enable_debug; +}; +typedef struct bb_module_instance_instantiate_opts bb_module_instance_instantiate_opts; + +struct bb_module_instance +{ + void* module; +}; +typedef struct bb_module_instance bb_module_instance; + +struct bb_module_instance_invoke_opts +{ + bool trap_on_start; +}; +typedef struct bb_module_instance_invoke_opts bb_module_instance_invoke_opts; + +struct bb_func_handle +{ + uint32_t index; + uint32_t type; +}; +typedef struct bb_func_handle bb_func_handle; + +struct bb_func_info +{ + bb_valtype* params; + size_t num_params; + bb_valtype* returns; + size_t num_returns; +}; +typedef struct bb_func_info bb_func_info; + +enum bb_debug_trap_mode +{ + BB_DEBUG_TRAP_MODE_DISABLED, + BB_DEBUG_TRAP_MODE_ENABLED, +}; +typedef enum bb_debug_trap_mode bb_debug_trap_mode; + +typedef void bb_host_function(void* userdata, bb_module_instance* module, const bb_val* params, bb_val* returns); + +// typedef void* bb_malloc_func(size_t size, void* userdata); +// typedef void* bb_realloc_func(void* mem, size_t size, void* userdata); +// typedef void bb_free_func(void* mem, void* userdata); + +// void bb_set_memory_hooks(bb_alloc_func* alloc_func, bb_realloc_func* realloc_func, bb_free_func); + +const char* bb_error_str(bb_error err); + +bb_module_definition bb_module_definition_init(bb_module_definition_init_opts opts); +void bb_module_definition_deinit(bb_module_definition* definition); +bb_error bb_module_definition_decode(bb_module_definition* definition, const char* data, size_t length); +bb_slice bb_module_definition_get_custom_section(const bb_module_definition* definition, const char* name); + +bb_import_package bb_import_package_init(const char* name); +void bb_import_package_deinit(bb_import_package* package); // only deinit when all module_instances using the package have been deinited +void* bb_import_package_userdata(const bb_import_package* package); +bb_error bb_import_package_add_function(bb_import_package* package, bb_host_function* func, const char* export_name, bb_valtype* params, size_t num_params, bb_valtype* returns, size_t num_returns, void* userdata); + +bb_module_instance bb_module_instance_init(bb_module_definition* definition); +void bb_module_instance_deinit(bb_module_instance* instance); +bb_error bb_module_instance_instantiate(bb_module_instance* instance, bb_module_instance_instantiate_opts opts); +bb_func_handle bb_module_instance_find_func(bb_module_instance* instance, const char* func_name); +bb_func_info bb_module_instance_func_info(bb_module_instance* instance, bb_func_handle handle); +bb_error bb_module_instance_invoke(bb_module_instance* instance, bb_func_handle, const bb_val* params, size_t num_params, bb_val* returns, size_t num_returns, bb_module_instance_invoke_opts opts); +bb_error bb_module_instance_resume(bb_module_instance* instance, bb_val* returns, size_t num_returns); +bb_error bb_module_instance_step(bb_module_instance* instance, bb_val* returns, size_t num_returns); +bb_error bb_module_instance_debug_set_trap(bb_module_instance* instance, uint32_t address, bb_debug_trap_mode trap_mode); +void* bb_module_instance_mem(bb_module_instance* instance, size_t offset, size_t length); +bb_slice bb_module_instance_mem_all(bb_module_instance* instance); diff --git a/ext/bytebox/update.cmd b/ext/bytebox/update.cmd new file mode 100644 index 0000000..e45588d --- /dev/null +++ b/ext/bytebox/update.cmd @@ -0,0 +1,4 @@ +@mkdir include 2> nul +@mkdir lib 2> nul +cp E:\Dev\zig_projects\bytebox\zig-out\include\bytebox.h include\bytebox.h +cp E:\Dev\zig_projects\bytebox\zig-out\lib\bytebox.lib lib\bytebox.lib diff --git a/scripts/bindgen_bb.py b/scripts/bindgen_bb.py new file mode 100644 index 0000000..c50304b --- /dev/null +++ b/scripts/bindgen_bb.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser +import json + + +parser = ArgumentParser(prog='bindgen.py') +parser.add_argument('api') +parser.add_argument('spec') +parser.add_argument('-g', '--guest-stubs') +parser.add_argument('--guest-include') +parser.add_argument('--wasm3-bindings') + +args = parser.parse_args() + +apiName = args.api +spec = args.spec +guest_stubs_path = args.guest_stubs +if guest_stubs_path == None: + guest_stubs_path = 'bindgen_' + apiName + '_guest_stubs.c' + +wasm3_bindings_path = args.wasm3_bindings +if wasm3_bindings_path == None: + wasm3_bindings_path = 'bindgen_' + apiName + '_wasm3_bindings.c' + +host_bindings = open(wasm3_bindings_path, 'w') +guest_bindings = None + +specFile = open(spec, 'r') +data = json.load(specFile) + +def needs_arg_ptr_stub(decl): + res = (decl['ret']['tag'] == 'S') + for arg in decl['args']: + if arg['type']['tag'] == 'S': + res = True + return(res) + +for decl in data: + if needs_arg_ptr_stub(decl): + guest_bindings = open(guest_stubs_path, 'w') + if args.guest_include != None: + s = '#include"' + args.guest_include + '"\n\n' + print(s, file=guest_bindings) + break + +for decl in data: + + name = decl['name'] + cname = decl.get('cname', name) + + if needs_arg_ptr_stub(decl): + argPtrStubName = name + '_argptr_stub' + # pointer arg stub declaration + s = '' + if decl['ret']['tag'] == 'S': + s += 'void' + else: + s += decl['ret']['name'] + + s += ' ORCA_IMPORT(' + argPtrStubName + ') (' + + if decl['ret']['tag'] == 'S': + s += decl['ret']['name'] + '* __retArg' + if len(decl['args']) > 0: + s += ', ' + + for i, arg in enumerate(decl['args']): + s += arg['type']['name'] + if arg['type']['tag'] == 'S': + s += '*' + s += ' ' + arg['name'] + if i+1 < len(decl['args']): + s += ', ' + s += ');\n\n' + + # forward function to pointer arg stub declaration + s += decl['ret']['name'] + ' ' + name + '(' + for i, arg in enumerate(decl['args']): + s += arg['type']['name'] + ' ' + arg['name'] + if i+1 < len(decl['args']): + s += ', ' + s += ')\n' + s += '{\n' + s += '\t' + if decl['ret']['tag'] == 'S': + s += decl['ret']['name'] + ' __ret;\n\t' + elif decl['ret']['tag'] != 'v': + s += decl['ret']['name'] + s += ' __ret = ' + s += argPtrStubName + '(' + + if decl['ret']['tag'] == 'S': + s += '&__ret' + if len(decl['args']) > 0: + s += ', ' + + for i, arg in enumerate(decl['args']): + if arg['type']['tag'] == 'S': + s += '&' + + s += arg['name'] + if i+1 < len(decl['args']): + s += ', ' + s += ');\n' + if decl['ret']['tag'] != 'v': + s += '\treturn(__ret);\n' + s += '}\n\n' + + print(s, file=guest_bindings) + + # host-side stub + s = 'void ' + cname + '_stub(void* userdata, bb_module_instance* module, const bb_val* params, bb_val* returns)' + + gen_stub = decl.get('gen_stub', True) + if gen_stub == False: + s += ';\n\n' + else: + s += '\n{\n\t' + retTag = decl['ret']['tag'] + + if retTag == 'i': + s += 'returns[0].i32_val = ' + elif retTag == 'I': + s += 'returns[0].i64_val = ' + elif retTag == 'f': + s += 'returns[0].f32_val = ' + elif retTag == 'F': + s += 'returns[0].f64_val = ' + elif retTag == 'S': + retTypeName = decl['ret']['name'] + retTypeCName = decl['ret'].get('cname', retTypeName) + s += '*(' + retTypeCName + '*)(bb_module_instance_mem(module, returns[0].i32_val, sizeof(' + retTypeCName + '))) = ' + + s += cname + '(' + + firstArgIndex = 0 + + for i, arg in enumerate(decl['args']): + typeName = arg['type']['name'] + typeCName = arg['type'].get('cname', typeName) + argTag = arg['type']['tag'] + if argTag == 'i': + s += 'params[' + str(firstArgIndex + i) + '].i32_val' + elif argTag == 'I': + s += 'params[' + str(firstArgIndex + i) + '].i64_val' + elif argTag == 'f': + s += 'params[' + str(firstArgIndex + i) + '].f32_val' + elif argTag == 'F': + s += 'params[' + str(firstArgIndex + i) + '].f64_val' + elif argTag == 'p': + s += 'bb_module_instance_mem(module, params[' + str(firstArgIndex + i) + '].i32_val, sizeof(1))' + elif argTag == 'S': + s += '*(' + typeCName + '*)bb_module_instance_mem(module, params[' + str(firstArgIndex + i) + '].i32_val, sizeof(' + typeCName + '))' + else: + print('unrecognized type ' + typeCName + ' in procedure signature\n') + break + + if i+1 < len(decl['args']): + s += ', ' + + s += ');\n}\n' + + print(s, file=host_bindings) + +# link function +s = 'int bindgen_link_' + apiName + '_api(bb_import_package* package)\n{\n' + +def translateTag(tag): + if tag == 'i' or tag == 'p': + return 'BB_VALTYPE_I32' + elif tag == 'I': + return 'BB_VALTYPE_I64' + elif tag == 'f': + return 'BB_VALTYPE_F32' + elif tag == 'F': + return 'BB_VALTYPE_F64' + elif tag == 'v': + return '' + print('translateTag: unhandled tag "' + tag + '" with type ') + print(type(tag)) + print('\n') + return '' + +for decl in data: + name = decl['name'] + cname = decl.get('cname', name) + + if needs_arg_ptr_stub(decl): + name = name + '_argptr_stub' + + retTag = decl['ret']['tag'] + + retType = '' + numReturns = 0 + paramTypes = [] + numParams = 0 + if retTag == 'S': + retType = 'BB_VALTYPE_I32' # unused, but we need something to put in the the returns array since 0-size arrays are illegal in C + paramTypes.append('BB_VALTYPE_I32') + elif retTag == 'v': #no returns + retType = 'BB_VALTYPE_I32' #unused but we need a dummy value + numReturns = 0 + else: + retType = translateTag(retTag) + numReturns = 1 + + for arg in decl['args']: + tag = arg['type']['tag'] + if tag == 'p' or tag == 'S': + tag = 'i' + paramTypes.append(translateTag(tag)) + numParams += 1 + + if numParams == 0: + paramTypes.append('BB_VALTYPE_I32') # unused but need a dummy value to avoid 0-length array + + s += '\t{\n' + s += '\t\tbb_valtype params[] = {' + ', '.join(paramTypes) + '};\n' + s += '\t\tsize_t num_params = ' + str(len(paramTypes)) + ';\n' + s += '\t\tbb_valtype returns[] = {' + retType + '};\n' + s += '\t\tsize_t num_returns = ' + str(numReturns) + ';\n' + + s += '\t\tbb_error err = bb_import_package_add_function(package, ' + cname + '_stub, "' + name + '", params, num_params, returns, num_returns, NULL);\n' + s += '\t\tif(err != BB_ERROR_OK) { log_error("error: %s\\n", bb_error_str(err)); return(-1); }\n' + s += '\t}\n' + + +s += '\treturn(0);\n}\n' + +print(s, file=host_bindings) diff --git a/src/canvas_api_bind.c b/src/canvas_api_bind.c index 9c7175f..76bc2ea 100644 --- a/src/canvas_api_bind.c +++ b/src/canvas_api_bind.c @@ -6,16 +6,16 @@ typedef struct wasm_str8 i32 offset; } wasm_str8; -const void* mg_text_outlines_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem) +const void* mg_text_outlines_stub(void* userdata, bb_module_instance* module, const bb_val* params, bb_val* returns) { - wasm_str8 wasmStr = *(wasm_str8*)((char*)_mem + *(i32*)&_sp[0]); + wasm_str8 wasmStr = *(wasm_str8*)bb_module_instance_mem(module, params[0].i32_val, sizeof(wasm_str8)); - ///////////////////////////////////////////////////////////////////// - //TODO: bound checks str8 str = {.len = wasmStr.len, - .ptr = (char*)_mem + wasmStr.offset}; - ///////////////////////////////////////////////////////////////////// + .ptr = (char*)bb_module_instance_mem(module, wasmStr.offset, wasmStr.len)}; - mg_text_outlines(str); + if(str.ptr) + { + mg_text_outlines(str); + } return(0); } diff --git a/src/io_impl.c b/src/io_impl.c index bce2a4e..54eb598 100644 --- a/src/io_impl.c +++ b/src/io_impl.c @@ -18,16 +18,17 @@ io_cmp orca_io_wait_single_req(io_req* wasmReq) //NOTE: convert the req->buffer wasm pointer to a native pointer // for some reason, wasm3 memory doesn't start at the beginning of the block we give it. u64 bufferIndex = (u64)req.buffer & 0xffffffff; - u32 memSize = 0; - char* memory = (char*)m3_GetMemory(orca->runtime.m3Runtime, &memSize, 0); + // u32 memSize = 0; + // char* memory = (char*)m3_GetMemory(orca->runtime.m3Runtime, &memSize, 0); + bb_slice memory = bb_module_instance_mem_all(orca->runtime.bbModuleInst); - if(bufferIndex + req.size > memSize) + if(bufferIndex + req.size > memory.length) { cmp.error = IO_ERR_ARG; } else { - req.buffer = memory + bufferIndex; + req.buffer = memory.data + bufferIndex; if(req.op == IO_OP_OPEN_AT) { diff --git a/src/main.c b/src/main.c index afcbce4..23b3839 100644 --- a/src/main.c +++ b/src/main.c @@ -267,26 +267,26 @@ void log_entry_ui(orca_debug_overlay* overlay, log_entry* entry) } -char m3_type_to_tag(M3ValueType type) -{ - switch(type) - { - case c_m3Type_none: - return('v'); - case c_m3Type_i32: - return('i'); - case c_m3Type_i64: - return('I'); - case c_m3Type_f32: - return('f'); - case c_m3Type_f64: - return('d'); +// char m3_type_to_tag(M3ValueType type) +// { +// switch(type) +// { +// case c_m3Type_none: +// return('v'); +// case c_m3Type_i32: +// return('i'); +// case c_m3Type_i64: +// return('I'); +// case c_m3Type_f32: +// return('f'); +// case c_m3Type_f64: +// return('d'); - case c_m3Type_unknown: - default: - return('!'); - } -} +// case c_m3Type_unknown: +// default: +// return('!'); +// } +// } void orca_runtime_init(orca_runtime* runtime) { @@ -305,6 +305,21 @@ void orca_runtime_init(orca_runtime* runtime) #include"gles_api_bind_gen.c" #include"manual_gles_api.c" +void* quit_on_wasm_init_failure(const char* stage, bb_error err) +{ + const char* errStr = bb_error_str(err); + log_error("wasm error at init stage '%s': %s\n", errStr); + + const char* options[] = {"OK"}; + mp_alert_popup("Error", + "The application couldn't load: encountered fatal error at stage '%s': %s", + stage, + errStr); + + mp_request_quit(); + return((void*)-1); +} + i32 orca_runloop(void* user) { orca_app* app = &__orcaApp; @@ -339,53 +354,81 @@ i32 orca_runloop(void* user) fread(app->runtime.wasmBytecode.ptr, 1, app->runtime.wasmBytecode.len, file); fclose(file); - u32 stackSize = 65536; - app->runtime.m3Env = m3_NewEnvironment(); + bb_error wasm_init_err; + bb_module_definition_init_opts module_def_init_opts = { .debug_name = bundleNameCString }; + app->runtime.bbModuleDef = bb_module_definition_init(module_def_init_opts); + wasm_init_err = bb_module_definition_decode(&app->runtime.bbModuleDef, app->runtime.wasmBytecode.ptr, app->runtime.wasmBytecode.len); + if (wasm_init_err != BB_ERROR_OK) + { + return quit_on_wasm_init_failure("wasm decode", wasm_init_err); + } - app->runtime.m3Runtime = m3_NewRuntime(app->runtime.m3Env, stackSize, NULL); - m3_RuntimeSetMemoryCallbacks(app->runtime.m3Runtime, wasm_memory_resize_callback, wasm_memory_free_callback, &app->runtime.wasmMemory); + // TODO [ReubenD] - allow specifying stack size + // TODO [ReubenD] - allow overriding wasm memory alloc/resize/free + + // u32 stackSize = 65536; + // app->runtime.m3Env = m3_NewEnvironment(); + + // app->runtime.m3Runtime = m3_NewRuntime(app->runtime.m3Env, stackSize, NULL); + // m3_RuntimeSetMemoryCallbacks(app->runtime.m3Runtime, wasm_memory_resize_callback, wasm_memory_free_callback, &app->runtime.wasmMemory); //NOTE: host memory will be freed when runtime is freed. //TODO check errors - m3_ParseModule(app->runtime.m3Env, &app->runtime.m3Module, (u8*)app->runtime.wasmBytecode.ptr, app->runtime.wasmBytecode.len); - m3_LoadModule(app->runtime.m3Runtime, app->runtime.m3Module); - m3_SetModuleName(app->runtime.m3Module, bundleNameCString); + // m3_ParseModule(app->runtime.m3Env, &app->runtime.m3Module, (u8*)app->runtime.wasmBytecode.ptr, app->runtime.wasmBytecode.len); + // m3_LoadModule(app->runtime.m3Runtime, app->runtime.m3Module); + // m3_SetModuleName(app->runtime.m3Module, bundleNameCString); mem_arena_clear(mem_scratch()); //NOTE: bind orca APIs - bindgen_link_core_api(app->runtime.m3Module); - bindgen_link_canvas_api(app->runtime.m3Module); - bindgen_link_clock_api(app->runtime.m3Module); - bindgen_link_io_api(app->runtime.m3Module); - bindgen_link_gles_api(app->runtime.m3Module); - manual_link_gles_api(app->runtime.m3Module); + bb_import_package module_imports = bb_import_package_init("*"); + bindgen_link_core_api(&module_imports); + bindgen_link_canvas_api(&module_imports); + bindgen_link_clock_api(&module_imports); + bindgen_link_io_api(&module_imports); + bindgen_link_gles_api(&module_imports); + manual_link_gles_api(&module_imports); //NOTE: compile - M3Result res = m3_CompileModule(app->runtime.m3Module); - if(res) + // M3Result res = m3_CompileModule(app->runtime.m3Module); + // if(res) + // { + // M3ErrorInfo errInfo = {0}; + // m3_GetErrorInfo(app->runtime.m3Runtime, &errInfo); + + // log_error("wasm error: %s\n", errInfo.message); + + // const char* options[] = {"OK"}; + // mp_alert_popup("Error", + // "The application couldn't load: can't compile web assembly module", + // 1, + // options); + // mp_request_quit(); + // return(-1); + // } + + app->runtime.bbModuleInst = bb_module_instance_init(&app->runtime.bbModuleDef); + bb_module_instance_instantiate_opts module_inst_instantiate_opts = { .packages = &module_imports, .num_packages = 1, .enable_debug = false, }; + wasm_init_err = bb_module_instance_instantiate(&app->runtime.bbModuleInst, bb_module_instance_instantiate_opts opts); + + if (wasm_init_err != BB_ERROR_OK) { - M3ErrorInfo errInfo = {0}; - m3_GetErrorInfo(app->runtime.m3Runtime, &errInfo); - - log_error("wasm error: %s\n", errInfo.message); - - const char* options[] = {"OK"}; - mp_alert_popup("Error", - "The application couldn't load: can't compile web assembly module", - 1, - options); - - mp_request_quit(); - return(-1); + return quit_on_wasm_init_failure("wasm instantiate", wasm_init_err); } + bb_import_package_deinit(&module_imports); // safe to deinit this now that the module has been instantiated + + // TODO up next: expose a cached handle to functions to invoke instead of a string search + //NOTE: Find and type check event handlers. for(int i=0; iruntime.m3Runtime, desc->name.ptr); + + bb_func_handle handler; + bb_module_instance_find_func(&app->runtime.bbModuleInst, desc->name.ptr); + // IM3Function handler = 0; + // m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr); if(handler) { diff --git a/src/manual_gles_api.c b/src/manual_gles_api.c index e7a52ce..c002e22 100644 --- a/src/manual_gles_api.c +++ b/src/manual_gles_api.c @@ -1,29 +1,28 @@ -const void* glShaderSource_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem) +void glShaderSource_stub(void* userdata, bb_module_instance* module, const bb_val* params, bb_val* returns) { - i32 shader = *(i32*)&_sp[0]; - i32 count = *(i32*)&_sp[1]; - i32 stringArrayOffset = *(i32*)&_sp[2]; - i32 lengthArrayOffset = *(i32*)&_sp[3]; + i32 shader = params[0].i32_val; + i32 count = params[1].i32_val; + i32 stringArrayOffset = params[2].i32_val; + i32 lengthArrayOffset = params[3].i32_val; - int* stringOffsetArray = (int*)((char*)_mem + stringArrayOffset); + const int* lengthArray = lengthArrayOffset ? (int*)(bb_module_instance_mem(module, lengthArrayOffset, count * sizeof(int))) : 0; + const int* stringOffsetArray = (int*)(bb_module_instance_mem(module, stringArrayOffset, count * sizeof(int))); const char** stringArray = (const char**)mem_arena_alloc_array(mem_scratch(), char*, count); for(int i=0; icommitted >= size) - { - return(memory->ptr); - } - else if(memory->committed < memory->reserved) - { - u32 commitSize = size - memory->committed; + // if(memory->committed >= size) + // { + // return(memory->ptr); + // } + // else if(memory->committed < memory->reserved) + // { + // u32 commitSize = size - memory->committed; - mem_base_allocator* allocator = mem_base_allocator_default(); - mem_base_commit(allocator, memory->ptr + memory->committed, commitSize); - memory->committed += commitSize; - return(memory->ptr); - } - else - { - DEBUG_ASSERT(0, "Out of memory"); - return(0); - } + // mem_base_allocator* allocator = mem_base_allocator_default(); + // mem_base_commit(allocator, memory->ptr + memory->committed, commitSize); + // memory->committed += commitSize; + // return(memory->ptr); + // } + // else + // { + // DEBUG_ASSERT(0, "Out of memory"); + // return(0); + // } + return NULL; } void wasm_memory_free_callback(void* p, void* userData) { - wasm_memory* memory = (wasm_memory*)userData; +// wasm_memory* memory = (wasm_memory*)userData; - mem_base_allocator* allocator = mem_base_allocator_default(); - mem_base_release(allocator, memory->ptr, memory->reserved); - memset(memory, 0, sizeof(wasm_memory)); +// mem_base_allocator* allocator = mem_base_allocator_default(); +// mem_base_release(allocator, memory->ptr, memory->reserved); +// memset(memory, 0, sizeof(wasm_memory)); } extern u32 orca_mem_grow(u64 size) { - orca_runtime* runtime = orca_runtime_get(); - wasm_memory* memory = &runtime->wasmMemory; + return 0; + // const size_t PAGE_SIZE = 65536; - size = AlignUpOnPow2(size, d_m3MemPageSize); - u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime); + // orca_runtime* runtime = orca_runtime_get(); + // wasm_memory* memory = &runtime->wasmMemory; - u32 addr = memory->committed; + // size = AlignUpOnPow2(size, PAGE_SIZE); + // u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime); - //NOTE: call resize memory, which will call our custom resize callback... this is a bit involved because - // wasm3 doesn't allow resizing the memory directly - M3Result res = ResizeMemory(runtime->m3Runtime, totalSize/d_m3MemPageSize); + // u32 addr = memory->committed; - return(addr); + // //NOTE: call resize memory, which will call our custom resize callback... this is a bit involved because + // // wasm3 doesn't allow resizing the memory directly + // M3Result res = ResizeMemory(runtime->m3Runtime, totalSize/PAGE_SIZE); + + // return(addr); } void* wasm_memory_offset_to_ptr(wasm_memory* memory, u32 offset) { - M3MemoryHeader* header = (M3MemoryHeader*)(memory->ptr); - DEBUG_ASSERT(offset < header->length, "Wasm offset exceeds memory length") - return memory->ptr + sizeof(M3MemoryHeader) + offset; -} \ No newline at end of file + // M3MemoryHeader* header = (M3MemoryHeader*)(memory->ptr); + // DEBUG_ASSERT(offset < header->length, "Wasm offset exceeds memory length") + // return memory->ptr + sizeof(M3MemoryHeader) + offset; + return NULL; +} diff --git a/src/orca_app.h b/src/orca_app.h index f6d74b6..a80e111 100644 --- a/src/orca_app.h +++ b/src/orca_app.h @@ -10,9 +10,11 @@ #include"platform/platform_io_internal.h" -#include"wasm3.h" -#include"m3_env.h" -#include"m3_compile.h" +#include "bytebox.h" + +// #include"wasm3.h" +// #include"m3_env.h" +// #include"m3_compile.h" #define G_EXPORTS(X) \ X(G_EXPORT_ON_INIT, "OnInit", "", "") \ @@ -65,12 +67,16 @@ typedef struct orca_runtime str8 wasmBytecode; wasm_memory wasmMemory; + // bytebox data + bb_module_definition bbModuleDef; + bb_module_instance bbModuleInst; + // wasm3 data - IM3Environment m3Env; - IM3Runtime m3Runtime; - IM3Module m3Module; - IM3Function exports[G_EXPORT_COUNT]; - u32 rawEventOffset; + // IM3Environment m3Env; + // IM3Runtime m3Runtime; + // IM3Module m3Module; + // IM3Function exports[G_EXPORT_COUNT]; + // u32 rawEventOffset; } orca_runtime;