Compare commits
8 Commits
main
...
bytebox_in
Author | SHA1 | Date |
---|---|---|
Reuben Dunnington | 8a84f57dbc | |
Reuben Dunnington | d5ab09366d | |
Reuben Dunnington | f922473ada | |
Reuben Dunnington | 6da260c051 | |
Reuben Dunnington | 03377bb014 | |
Reuben Dunnington | 75f719441f | |
Reuben Dunnington | f76817c1ed | |
Reuben Dunnington | 3f2ed41bfc |
16
build.bat
16
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 ntdll.lib
|
||||
|
||||
cl /Zi /Zc:preprocessor /std:c11 /experimental:c11atomics %INCLUDES% src\main.c /link %LIBS% /out:bin\orca.exe
|
||||
cl /Zi /Zc:preprocessor /std:c11 /experimental:c11atomics %INCLUDES% src\main.c /link %LIBS% /STACK:8388608,8388608 /out:bin\orca.exe
|
||||
)
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
// C interface for bytebox wasm runtime.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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,
|
||||
BB_ERROR_UNKNOWNIMPORT,
|
||||
BB_ERROR_INCOMPATIBLEIMPORT,
|
||||
BB_ERROR_TRAP_DEBUG,
|
||||
BB_ERROR_TRAP_UNREACHABLE,
|
||||
BB_ERROR_TRAP_INTEGERDIVISIONBYZERO,
|
||||
BB_ERROR_TRAP_INTEGEROVERFLOW,
|
||||
BB_ERROR_TRAP_INDIRECTCALLTYPEMISMATCH,
|
||||
BB_ERROR_TRAP_INVALIDINTEGERCONVERSION,
|
||||
BB_ERROR_TRAP_OUTOFBOUNDSMEMORYACCESS,
|
||||
BB_ERROR_TRAP_UNDEFINEDELEMENT,
|
||||
BB_ERROR_TRAP_UNINITIALIZEDELEMENT,
|
||||
BB_ERROR_TRAP_OUTOFBOUNDSTABLEACCESS,
|
||||
BB_ERROR_TRAP_STACKEXHAUSTED,
|
||||
};
|
||||
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;
|
||||
|
||||
typedef struct bb_module_definition bb_module_definition;
|
||||
typedef struct bb_module_instance bb_module_instance;
|
||||
typedef struct bb_import_package bb_import_package;
|
||||
|
||||
typedef void bb_host_function(void* userdata, bb_module_instance* module, const bb_val* params, bb_val* returns);
|
||||
typedef void* bb_wasm_memory_resize(void* mem, size_t new_size_bytes, size_t old_size_bytes, void* userdata);
|
||||
typedef void bb_wasm_memory_free(void* mem, size_t size_bytes, void* userdata);
|
||||
|
||||
struct bb_module_instance_instantiate_opts
|
||||
{
|
||||
bb_import_package** packages;
|
||||
size_t num_packages;
|
||||
struct {
|
||||
bb_wasm_memory_resize* resize_callback;
|
||||
bb_wasm_memory_free* free_callback;
|
||||
void* userdata;
|
||||
} wasm_memory_config;
|
||||
size_t stack_size;
|
||||
bool enable_debug;
|
||||
};
|
||||
typedef struct bb_module_instance_instantiate_opts bb_module_instance_instantiate_opts;
|
||||
|
||||
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_global_mut
|
||||
{
|
||||
BB_GLOBAL_MUT_IMMUTABLE,
|
||||
BB_GLOBAL_MUT_MUTABLE,
|
||||
};
|
||||
typedef enum bb_global_mut bb_global_mut;
|
||||
|
||||
struct bb_global
|
||||
{
|
||||
bb_val* value;
|
||||
bb_valtype type;
|
||||
bb_global_mut mut;
|
||||
};
|
||||
typedef struct bb_global bb_global;
|
||||
|
||||
enum bb_debug_trace_mode
|
||||
{
|
||||
BB_DEBUG_TRACE_NONE,
|
||||
BB_DEBUG_TRACE_FUNCTION,
|
||||
BB_DEBUG_TRACE_INSTRUCTION,
|
||||
};
|
||||
typedef enum bb_debug_trace_mode bb_debug_trace_mode;
|
||||
|
||||
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_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
|
||||
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);
|
||||
|
||||
void bb_set_debug_trace_mode(bb_debug_trace_mode mode);
|
||||
|
||||
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_error bb_module_instance_find_func(bb_module_instance* instance, const char* func_name, bb_func_handle* out_handle);
|
||||
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);
|
||||
bb_error bb_module_instance_mem_grow(bb_module_instance* instance, size_t num_pages);
|
||||
bb_global bb_module_instance_find_global(bb_module_instance* instance, const char* global_name);
|
||||
|
||||
bool bb_func_handle_isvalid(bb_func_handle handle);
|
|
@ -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
|
|
@ -78,15 +78,15 @@ ORCA_EXPORT void OnInit(void)
|
|||
|
||||
if(mg_image_is_nil(waterImage))
|
||||
{
|
||||
log_error("coulnd't load ball image\n");
|
||||
log_error("couldn't load water image\n");
|
||||
}
|
||||
if(mg_image_is_nil(ballImage))
|
||||
{
|
||||
log_error("coulnd't load ball image\n");
|
||||
log_error("couldn't load ball image\n");
|
||||
}
|
||||
if(mg_image_is_nil(paddleImage))
|
||||
{
|
||||
log_error("coulnd't load paddle image\n");
|
||||
log_error("couldn't load paddle image\n");
|
||||
}
|
||||
|
||||
str8 fontStr = loadFile(mem_scratch(), STR8("/Literata-SemiBoldItalic.ttf"));
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
#!/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']
|
||||
|
||||
firstArgIndex = 0
|
||||
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, params[0].i32_val, sizeof(' + retTypeCName + '))) = '
|
||||
firstArgIndex = 1
|
||||
|
||||
s += cname + '('
|
||||
|
||||
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':
|
||||
paramTypes.append('BB_VALTYPE_I32')
|
||||
numParams += 1
|
||||
elif retTag != 'v': #no returns
|
||||
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
|
||||
|
||||
# dummy values
|
||||
if numReturns == 0:
|
||||
retType = 'BB_VALTYPE_I32'
|
||||
|
||||
if numParams == 0:
|
||||
paramTypes.append('BB_VALTYPE_I32')
|
||||
|
||||
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 return_type = ' + 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, &return_type, 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)
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
356
src/main.c
356
src/main.c
|
@ -267,25 +267,39 @@ 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('!');
|
||||
// }
|
||||
// }
|
||||
|
||||
bool tag_to_valtype(char tag, bb_valtype* out)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case 'i': *out = BB_VALTYPE_I32; return true;
|
||||
case 'I': *out = BB_VALTYPE_I64; return true;
|
||||
case 'f': *out = BB_VALTYPE_F32; return true;
|
||||
case 'F': *out = BB_VALTYPE_F64; return true;
|
||||
case 'd': *out = BB_VALTYPE_F64; return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void orca_runtime_init(orca_runtime* runtime)
|
||||
|
@ -305,6 +319,23 @@ void orca_runtime_init(orca_runtime* runtime)
|
|||
#include"gles_api_bind_gen.c"
|
||||
#include"manual_gles_api.c"
|
||||
|
||||
i32 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", stage, errStr);
|
||||
|
||||
str8 msg = str8_pushf(mem_scratch(), "The application couldn't load: encountered fatal error at stage '%s': %s", stage, errStr);
|
||||
|
||||
const char* options[] = {"OK"};
|
||||
mp_alert_popup("Error",
|
||||
msg.ptr,
|
||||
1,
|
||||
options);
|
||||
|
||||
mp_request_quit();
|
||||
return(-1);
|
||||
}
|
||||
|
||||
i32 orca_runloop(void* user)
|
||||
{
|
||||
orca_app* app = &__orcaApp;
|
||||
|
@ -339,96 +370,147 @@ 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);
|
||||
// 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);
|
||||
// }
|
||||
|
||||
// bb_set_debug_trace_mode(BB_DEBUG_TRACE_FUNCTION);
|
||||
|
||||
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,
|
||||
.stack_size = 1024 * 64,
|
||||
.enable_debug = false,
|
||||
.wasm_memory_config = {
|
||||
.resize_callback = wasm_memory_resize_callback,
|
||||
.free_callback = wasm_memory_free_callback,
|
||||
.userdata = &app->runtime.wasmMemory,
|
||||
},
|
||||
|
||||
};
|
||||
wasm_init_err = bb_module_instance_instantiate(app->runtime.bbModuleInst, module_inst_instantiate_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
|
||||
|
||||
//NOTE: Find and type check event handlers.
|
||||
for(int i=0; i<G_EXPORT_COUNT; i++)
|
||||
{
|
||||
const g_export_desc* desc = &G_EXPORT_DESC[i];
|
||||
IM3Function handler = 0;
|
||||
m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr);
|
||||
|
||||
if(handler)
|
||||
const bb_error find_func_err = bb_module_instance_find_func(app->runtime.bbModuleInst, desc->name.ptr, &app->runtime.exports[i]);
|
||||
// IM3Function handler = 0;
|
||||
// m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr);
|
||||
|
||||
if(find_func_err == BB_ERROR_OK)
|
||||
{
|
||||
bool checked = false;
|
||||
|
||||
//NOTE: check function signature
|
||||
int retCount = m3_GetRetCount(handler);
|
||||
int argCount = m3_GetArgCount(handler);
|
||||
if(retCount == desc->retTags.len && argCount == desc->argTags.len)
|
||||
bb_func_info func_info = bb_module_instance_func_info(app->runtime.bbModuleInst, app->runtime.exports[i]);
|
||||
|
||||
bool checked = func_info.num_returns == desc->retTags.len && func_info.num_params == desc->argTags.len;
|
||||
|
||||
for(int retIndex = 0; checked && retIndex < func_info.num_returns; retIndex++)
|
||||
{
|
||||
checked = true;
|
||||
for(int retIndex = 0; retIndex < retCount; retIndex++)
|
||||
bb_valtype valtype;
|
||||
if(tag_to_valtype(desc->retTags.ptr[retIndex], &valtype) && valtype != func_info.returns[retIndex])
|
||||
{
|
||||
M3ValueType m3Type = m3_GetRetType(handler, retIndex);
|
||||
char tag = m3_type_to_tag(m3Type);
|
||||
|
||||
if(tag != desc->retTags.ptr[retIndex])
|
||||
{
|
||||
checked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(checked)
|
||||
{
|
||||
for(int argIndex = 0; argIndex < argCount; argIndex++)
|
||||
{
|
||||
M3ValueType m3Type = m3_GetArgType(handler, argIndex);
|
||||
char tag = m3_type_to_tag(m3Type);
|
||||
|
||||
if(tag != desc->argTags.ptr[argIndex])
|
||||
{
|
||||
checked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(checked)
|
||||
for(int argIndex = 0; checked && argIndex < func_info.num_params; argIndex++)
|
||||
{
|
||||
app->runtime.exports[i] = handler;
|
||||
bb_valtype valtype;
|
||||
if(tag_to_valtype(desc->argTags.ptr[argIndex], &valtype) && valtype != func_info.params[argIndex])
|
||||
{
|
||||
checked = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// int retCount = m3_GetRetCount(handler);
|
||||
// int argCount = m3_GetArgCount(handler);
|
||||
// if(retCount == desc->retTags.len && argCount == desc->argTags.len)
|
||||
// {
|
||||
// checked = true;
|
||||
// for(int retIndex = 0; retIndex < retCount; retIndex++)
|
||||
// {
|
||||
// M3ValueType m3Type = m3_GetRetType(handler, retIndex);
|
||||
// char tag = m3_type_to_tag(m3Type);
|
||||
|
||||
// if(tag != desc->retTags.ptr[retIndex])
|
||||
// {
|
||||
// checked = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if(checked)
|
||||
// {
|
||||
// for(int argIndex = 0; argIndex < argCount; argIndex++)
|
||||
// {
|
||||
// M3ValueType m3Type = m3_GetArgType(handler, argIndex);
|
||||
// char tag = m3_type_to_tag(m3Type);
|
||||
|
||||
// if(tag != desc->argTags.ptr[argIndex])
|
||||
// {
|
||||
// checked = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if(bb_func_handle_isvalid(app->runtime.exports[i]) == false)
|
||||
{
|
||||
log_error("type mismatch for event handler %.*s\n", (int)desc->name.len, desc->name.ptr);
|
||||
}
|
||||
|
@ -436,8 +518,10 @@ i32 orca_runloop(void* user)
|
|||
}
|
||||
|
||||
//NOTE: get location of the raw event slot
|
||||
IM3Global rawEventGlobal = m3_FindGlobal(app->runtime.m3Module, "_OrcaRawEvent");
|
||||
app->runtime.rawEventOffset = (u32)rawEventGlobal->intValue;
|
||||
// IM3Global rawEventGlobal = m3_FindGlobal(app->runtime.m3Module, "_OrcaRawEvent");
|
||||
// app->runtime.rawEventOffset = (u32)rawEventGlobal->intValue;
|
||||
bb_global rawEventGlobal = bb_module_instance_find_global(app->runtime.bbModuleInst, "_OrcaRawEvent");
|
||||
app->runtime.rawEventOffset = (u32)rawEventGlobal.value->i32_val;
|
||||
|
||||
//NOTE: preopen the app local root dir
|
||||
{
|
||||
|
@ -454,17 +538,22 @@ i32 orca_runloop(void* user)
|
|||
//NOTE: prepare GL surface
|
||||
mg_surface_prepare(app->surface);
|
||||
|
||||
IM3Function* exports = app->runtime.exports;
|
||||
// IM3Function* exports = app->runtime.exports;
|
||||
bb_func_handle* exports = app->runtime.exports;
|
||||
|
||||
//NOTE: call init handler
|
||||
if(exports[G_EXPORT_ON_INIT])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_ON_INIT]))
|
||||
{
|
||||
M3Result err = m3_Call(exports[G_EXPORT_ON_INIT], 0, 0);
|
||||
if(err != NULL)
|
||||
{
|
||||
log_error("runtime error: %s\n", err);
|
||||
bb_error err = bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_ON_INIT], 0, 0, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
|
||||
str8 msg = str8_pushf(mem_scratch(), "Runtime error: %s\n", err);
|
||||
// M3Result err = m3_Call(exports[G_EXPORT_ON_INIT], 0, 0);
|
||||
// if(err != NULL)
|
||||
if(err != BB_ERROR_OK)
|
||||
{
|
||||
const char* errStr = bb_error_str(err);
|
||||
log_error("runtime error: %s\n", errStr);
|
||||
|
||||
str8 msg = str8_pushf(mem_scratch(), "Runtime error: %s\n", errStr);
|
||||
const char* options[] = {"OK"};
|
||||
mp_alert_popup("Error",
|
||||
msg.ptr,
|
||||
|
@ -476,13 +565,14 @@ i32 orca_runloop(void* user)
|
|||
}
|
||||
}
|
||||
|
||||
if(exports[G_EXPORT_FRAME_RESIZE])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_FRAME_RESIZE]))
|
||||
{
|
||||
mp_rect content = mp_window_get_content_rect(app->window);
|
||||
u32 width = (u32)content.w;
|
||||
u32 height = (u32)content.h;
|
||||
const void* args[2] = {&width, &height};
|
||||
m3_Call(exports[G_EXPORT_FRAME_RESIZE], 2, args);
|
||||
const bb_val args[2] = {
|
||||
{ .i32_val = (i32)content.w },
|
||||
{ .i32_val = (i32)content.h },
|
||||
};
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_FRAME_RESIZE], args, 2, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
}
|
||||
|
||||
ui_set_context(&app->debugOverlay.ui);
|
||||
|
@ -498,14 +588,14 @@ i32 orca_runloop(void* user)
|
|||
ui_process_event(event);
|
||||
}
|
||||
|
||||
if(exports[G_EXPORT_RAW_EVENT])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_RAW_EVENT]))
|
||||
{
|
||||
#ifndef M3_BIG_ENDIAN
|
||||
mp_event* eventPtr = (mp_event*)wasm_memory_offset_to_ptr(&app->runtime.wasmMemory, app->runtime.rawEventOffset);
|
||||
memcpy(eventPtr, event, sizeof(*event));
|
||||
|
||||
const void* args[1] = {&app->runtime.rawEventOffset};
|
||||
m3_Call(exports[G_EXPORT_RAW_EVENT], 1, args);
|
||||
bb_val args[1];
|
||||
args[0].i32_val = app->runtime.rawEventOffset;
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_RAW_EVENT], args, 1, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
#else
|
||||
log_error("OnRawEvent() is not supported on big endian platforms");
|
||||
#endif
|
||||
|
@ -522,12 +612,18 @@ i32 orca_runloop(void* user)
|
|||
{
|
||||
mp_rect frame = {0, 0, event->move.frame.w, event->move.frame.h};
|
||||
|
||||
if(exports[G_EXPORT_FRAME_RESIZE])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_FRAME_RESIZE]))
|
||||
{
|
||||
u32 width = (u32)event->move.content.w;
|
||||
u32 height = (u32)event->move.content.h;
|
||||
const void* args[2] = {&width, &height};
|
||||
m3_Call(exports[G_EXPORT_FRAME_RESIZE], 2, args);
|
||||
const bb_val args[2] = {
|
||||
{ .i32_val = (i32)(u32)event->move.content.w },
|
||||
{ .i32_val = (i32)(u32)event->move.content.h },
|
||||
};
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_FRAME_RESIZE], args, 2, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
|
||||
// u32 width = (u32)event->move.content.w;
|
||||
// u32 height = (u32)event->move.content.h;
|
||||
// const void* args[2] = {&width, &height};
|
||||
// m3_Call(exports[G_EXPORT_FRAME_RESIZE], 2, args);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -535,30 +631,41 @@ i32 orca_runloop(void* user)
|
|||
{
|
||||
if(event->key.action == MP_KEY_PRESS)
|
||||
{
|
||||
if(exports[G_EXPORT_MOUSE_DOWN])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_MOUSE_DOWN]))
|
||||
{
|
||||
int key = event->key.code;
|
||||
const void* args[1] = {&key};
|
||||
m3_Call(exports[G_EXPORT_MOUSE_DOWN], 1, args);
|
||||
const bb_val key = {.i32_val = event->key.code };
|
||||
// int key = event->key.code;
|
||||
// const void* args[1] = {&key};
|
||||
// m3_Call(exports[G_EXPORT_MOUSE_DOWN], 1, args);
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_MOUSE_DOWN], &key, 1, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(exports[G_EXPORT_MOUSE_UP])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_MOUSE_UP]))
|
||||
{
|
||||
int key = event->key.code;
|
||||
const void* args[1] = {&key};
|
||||
m3_Call(exports[G_EXPORT_MOUSE_UP], 1, args);
|
||||
const bb_val key = {.i32_val = event->key.code };
|
||||
// int key = event->key.code;
|
||||
// const void* args[1] = {&key};
|
||||
// m3_Call(exports[G_EXPORT_MOUSE_UP], 1, args);
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_MOUSE_UP], &key, 1, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case MP_EVENT_MOUSE_MOVE:
|
||||
{
|
||||
if(exports[G_EXPORT_MOUSE_MOVE])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_MOUSE_MOVE]))
|
||||
{
|
||||
const void* args[4] = {&event->mouse.x, &event->mouse.y, &event->mouse.deltaX, &event->mouse.deltaY};
|
||||
m3_Call(exports[G_EXPORT_MOUSE_MOVE], 4, args);
|
||||
const bb_val args[4] = {
|
||||
{ .f32_val = event->mouse.x },
|
||||
{ .f32_val = event->mouse.y },
|
||||
{ .f32_val = event->mouse.deltaX },
|
||||
{ .f32_val = event->mouse.deltaY },
|
||||
};
|
||||
// const void* args[4] = {&event->mouse.x, &event->mouse.y, &event->mouse.deltaX, &event->mouse.deltaY};
|
||||
// m3_Call(exports[G_EXPORT_MOUSE_MOVE], 4, args);
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_MOUSE_MOVE], args, 4, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -573,18 +680,22 @@ i32 orca_runloop(void* user)
|
|||
#endif
|
||||
}
|
||||
|
||||
if(exports[G_EXPORT_KEY_DOWN])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_KEY_DOWN]))
|
||||
{
|
||||
const void* args[1] = {&event->key.code};
|
||||
m3_Call(exports[G_EXPORT_KEY_DOWN], 1, args);
|
||||
const bb_val key = {.i32_val = event->key.code };
|
||||
// const void* args[1] = {&event->key.code};
|
||||
// m3_Call(exports[G_EXPORT_KEY_DOWN], 1, args);
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_KEY_DOWN], &key, 1, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
}
|
||||
}
|
||||
else if(event->key.action == MP_KEY_RELEASE)
|
||||
{
|
||||
if(exports[G_EXPORT_KEY_UP])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_KEY_UP]))
|
||||
{
|
||||
const void* args[1] = {&event->key.code};
|
||||
m3_Call(exports[G_EXPORT_KEY_UP], 1, args);
|
||||
const bb_val key = {.i32_val = event->key.code };
|
||||
// const void* args[1] = {&event->key.code};
|
||||
// m3_Call(exports[G_EXPORT_KEY_UP], 1, args);
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_KEY_UP], &key, 1, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
@ -730,10 +841,11 @@ i32 orca_runloop(void* user)
|
|||
mg_render(app->debugOverlay.surface, app->debugOverlay.canvas);
|
||||
}
|
||||
|
||||
if(exports[G_EXPORT_FRAME_REFRESH])
|
||||
if(bb_func_handle_isvalid(exports[G_EXPORT_FRAME_REFRESH]))
|
||||
{
|
||||
mg_surface_prepare(app->surface);
|
||||
m3_Call(exports[G_EXPORT_FRAME_REFRESH], 0, 0);
|
||||
// m3_Call(exports[G_EXPORT_FRAME_REFRESH], 0, 0);
|
||||
bb_module_instance_invoke(app->runtime.bbModuleInst, exports[G_EXPORT_FRAME_REFRESH], 0, 0, 0, 0, (bb_module_instance_invoke_opts){0});
|
||||
}
|
||||
|
||||
if(app->debugOverlay.show)
|
||||
|
|
|
@ -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; i<count; i++)
|
||||
{
|
||||
stringArray[i] = (char*)_mem + stringOffsetArray[i];
|
||||
stringArray[i] = (char*)bb_module_instance_mem(module, stringOffsetArray[i], lengthArray ? lengthArray[i] : (size_t)-1);
|
||||
}
|
||||
|
||||
int* lengthArray = lengthArrayOffset ? (int*)((char*)_mem + lengthArrayOffset) : 0;
|
||||
|
||||
glShaderSource(shader, count, stringArray, lengthArray);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int manual_link_gles_api(IM3Module module)
|
||||
int manual_link_gles_api(bb_import_package* package)
|
||||
{
|
||||
M3Result res;
|
||||
res = m3_LinkRawFunction(module, "*", "glShaderSource", "v(iiii)", glShaderSource_stub);
|
||||
if(res) { log_error("error: %s\n", res); return(-1); }
|
||||
bb_valtype params[] = {BB_VALTYPE_I32, BB_VALTYPE_I32, BB_VALTYPE_I32, BB_VALTYPE_I32};
|
||||
size_t num_params = 4;
|
||||
bb_error err = bb_import_package_add_function(package, glShaderSource_stub, "glShaderSource", params, num_params, NULL, 0, NULL);
|
||||
if(err != BB_ERROR_OK) { log_error("error: %s\n", bb_error_str(err)); return(-1); }
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -8,17 +8,17 @@
|
|||
|
||||
#include"orca_app.h"
|
||||
|
||||
void* wasm_memory_resize_callback(void* p, unsigned long size, void* userData)
|
||||
void* wasm_memory_resize_callback(void* p, size_t new_size, size_t old_size, void* userData)
|
||||
{
|
||||
wasm_memory* memory = (wasm_memory*)userData;
|
||||
|
||||
if(memory->committed >= size)
|
||||
if(memory->committed >= new_size)
|
||||
{
|
||||
return(memory->ptr);
|
||||
}
|
||||
else if(memory->committed < memory->reserved)
|
||||
{
|
||||
u32 commitSize = size - memory->committed;
|
||||
u32 commitSize = new_size - memory->committed;
|
||||
|
||||
mem_base_allocator* allocator = mem_base_allocator_default();
|
||||
mem_base_commit(allocator, memory->ptr + memory->committed, commitSize);
|
||||
|
@ -30,9 +30,10 @@ void* wasm_memory_resize_callback(void* p, unsigned long size, void* userData)
|
|||
DEBUG_ASSERT(0, "Out of memory");
|
||||
return(0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void wasm_memory_free_callback(void* p, void* userData)
|
||||
void wasm_memory_free_callback(void* p, size_t size, void* userData)
|
||||
{
|
||||
wasm_memory* memory = (wasm_memory*)userData;
|
||||
|
||||
|
@ -43,24 +44,30 @@ void wasm_memory_free_callback(void* p, void* userData)
|
|||
|
||||
extern u32 orca_mem_grow(u64 size)
|
||||
{
|
||||
const size_t PAGE_SIZE = 65536;
|
||||
|
||||
orca_runtime* runtime = orca_runtime_get();
|
||||
wasm_memory* memory = &runtime->wasmMemory;
|
||||
|
||||
size = AlignUpOnPow2(size, d_m3MemPageSize);
|
||||
u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime);
|
||||
size = AlignUpOnPow2(size, PAGE_SIZE);
|
||||
// u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime);
|
||||
// bb_slice memory = bb_module_instance_mem_all(runtime->bbModuleInst);
|
||||
|
||||
u32 addr = memory->committed;
|
||||
|
||||
//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);
|
||||
// M3Result res = ResizeMemory(runtime->m3Runtime, totalSize/PAGE_SIZE);
|
||||
bb_module_instance_mem_grow(runtime->bbModuleInst, size/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;
|
||||
}
|
||||
DEBUG_ASSERT(offset < bb_module_instance_mem_all(orca_runtime_get()->bbModuleInst).length, "Wasm offset exceeds memory length")
|
||||
return memory->ptr + offset;
|
||||
// M3MemoryHeader* header = (M3MemoryHeader*)(memory->ptr);
|
||||
// DEBUG_ASSERT(offset < header->length, "Wasm offset exceeds memory length")
|
||||
// return memory->ptr + sizeof(M3MemoryHeader) + offset;
|
||||
}
|
||||
|
|
|
@ -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,18 @@ typedef struct orca_runtime
|
|||
str8 wasmBytecode;
|
||||
wasm_memory wasmMemory;
|
||||
|
||||
// wasm3 data
|
||||
IM3Environment m3Env;
|
||||
IM3Runtime m3Runtime;
|
||||
IM3Module m3Module;
|
||||
IM3Function exports[G_EXPORT_COUNT];
|
||||
// bytebox data
|
||||
bb_module_definition* bbModuleDef;
|
||||
bb_module_instance* bbModuleInst;
|
||||
bb_func_handle exports[G_EXPORT_COUNT];
|
||||
u32 rawEventOffset;
|
||||
|
||||
// wasm3 data
|
||||
// IM3Environment m3Env;
|
||||
// IM3Runtime m3Runtime;
|
||||
// IM3Module m3Module;
|
||||
// IM3Function exports[G_EXPORT_COUNT];
|
||||
// u32 rawEventOffset;
|
||||
|
||||
} orca_runtime;
|
||||
|
||||
|
|
Loading…
Reference in New Issue