diff --git a/milepost b/milepost index f36e144..e9e9ab6 160000 --- a/milepost +++ b/milepost @@ -1 +1 @@ -Subproject commit f36e144bc0fed66470aff0612098dba29c552604 +Subproject commit e9e9ab68c250c597fd6b7552d97977b99b103d33 diff --git a/samples/pong/src/main.c b/samples/pong/src/main.c index 240eebd..0e8a6d4 100644 --- a/samples/pong/src/main.c +++ b/samples/pong/src/main.c @@ -42,8 +42,11 @@ bool rightDown = false; g_font font; +mem_arena arena; + void OnInit(void) { + mem_arena_init(&arena); font = g_font_create_default(); //log_string(str8_lit("init procedure\n")); } @@ -95,6 +98,7 @@ void OnKeyUp(int key) void OnFrameRefresh(void) { + char* tmp = mem_arena_alloc(&arena, 512); //log_string(str8_lit("frame procedure\n")); f32 aspect = frameSize.x/frameSize.y; @@ -168,4 +172,6 @@ void OnFrameRefresh(void) g_fill(); g_matrix_pop(); + + mem_arena_clear(&arena); } diff --git a/sdk/orca.c b/sdk/orca.c index 2ba3379..4c6120e 100644 --- a/sdk/orca.c +++ b/sdk/orca.c @@ -6,4 +6,5 @@ * *****************************************************************/ -//#include"util/memory.c" +#include"platform/orca_memory.c" +#include"util/memory.c" diff --git a/sdk/orca.h b/sdk/orca.h index 683b4e2..a9db900 100644 --- a/sdk/orca.h +++ b/sdk/orca.h @@ -10,5 +10,6 @@ #include"util/typedefs.h" #include"util/lists.h" +#include"util/memory.h" #endif //__ORCA_H_ diff --git a/sdk/typedefs.h b/sdk/typedefs.h deleted file mode 100644 index e0f7e10..0000000 --- a/sdk/typedefs.h +++ /dev/null @@ -1,69 +0,0 @@ -//***************************************************************** -// -// $file: typedefs.h $ -// $author: Martin Fouilleul $ -// $date: 23/36/2015 $ -// $revision: $ -// -//***************************************************************** -#ifndef __TYPEDEFS_H_ -#define __TYPEDEFS_H_ - -#include -#include //FLT_MAX/MIN etc... - -#ifndef __cplusplus -#include -#endif //__cplusplus - -typedef uint8_t byte; -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; - -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; - -typedef float f32; -typedef double f64; - -typedef union -{ - struct - { - f32 x; - f32 y; - }; - f32 c[2]; -} vec2; - -typedef union -{ - struct - { - f32 x; - f32 y; - f32 z; - f32 w; - }; - f32 c[4]; -} vec4; - -#define vec4_expand_xyz(v) (v).x, (v).y, (v).z - -typedef union -{ - struct - { - f32 x; - f32 y; - f32 w; - f32 h; - }; - f32 c[4]; -} mp_rect; - -#endif //__TYPEDEFS_H_ diff --git a/src/bindgen_core_api.txt b/src/bindgen_core_api.txt index 90a369d..6a434b3 100644 --- a/src/bindgen_core_api.txt +++ b/src/bindgen_core_api.txt @@ -3,4 +3,6 @@ log_int v(i) cosf f(f) sinf f(f) floorf f(f) -sqrtf f(f) \ No newline at end of file +sqrtf f(f) +orca_mem_grow i(I) +orca_assert v(i) \ No newline at end of file diff --git a/src/main.c b/src/main.c index d9d77f4..ee2027b 100644 --- a/src/main.c +++ b/src/main.c @@ -10,13 +10,13 @@ #include #include -#include"wasm3.h" -#include"m3_env.h" -#include"m3_compile.h" - #define MG_INCLUDE_GL_API #include"milepost.h" +#include"orca_runtime.h" + +#include"memory_impl.c" + #define LOG_SUBSYSTEM "Orca" @@ -37,6 +37,11 @@ void mg_matrix_push_flat(float a11, float a12, float a13, mg_matrix_push(m); } +void orca_assert(bool x) +{ + ASSERT(x); +} + mg_font mg_font_create_default() { //NOTE(martin): create default font @@ -82,40 +87,10 @@ typedef struct orca_app mg_surface mtlSurface; mg_canvas canvas; + orca_runtime runtime; + } orca_app; -#define G_EVENTS(X) \ - X(G_EVENT_START, "OnInit", "", "") \ - X(G_EVENT_MOUSE_DOWN, "OnMouseDown", "", "i") \ - X(G_EVENT_MOUSE_UP, "OnMouseUp", "", "i") \ - X(G_EVENT_MOUSE_ENTER, "OnMouseEnter", "", "") \ - X(G_EVENT_MOUSE_LEAVE, "OnMouseLeave", "", "") \ - X(G_EVENT_MOUSE_MOVE, "OnMouseMove", "", "ffff") \ - X(G_EVENT_MOUSE_WHEEL, "OnMouseWheel", "", "ff") \ - X(G_EVENT_KEY_DOWN, "OnKeyDown", "", "i") \ - X(G_EVENT_KEY_UP, "OnKeyUp", "", "i") \ - X(G_EVENT_FRAME_REFRESH, "OnFrameRefresh", "", "") \ - X(G_EVENT_FRAME_RESIZE, "OnFrameResize", "", "ii") - -typedef enum { - #define G_EVENT_KIND(kind, ...) kind, - G_EVENTS(G_EVENT_KIND) - G_EVENT_COUNT -} guest_event_kind; - - -typedef struct g_event_handler_desc -{ - str8 name; - str8 retTags; - str8 argTags; -} g_event_handler_desc; - -const g_event_handler_desc G_EVENT_HANDLER_DESC[] = { - #define G_EVENT_HANDLER_DESC_ENTRY(kind, name, rets, args) {STR8(name), STR8(rets), STR8(args)}, - G_EVENTS(G_EVENT_HANDLER_DESC_ENTRY) -}; - char m3_type_to_tag(M3ValueType type) { switch(type) @@ -136,59 +111,27 @@ char m3_type_to_tag(M3ValueType type) } } -typedef struct host_memory -{ - char* ptr; - u32 reserved; - u32 committed; - -} host_memory; - -void host_memory_init(host_memory* memory) +void orca_runtime_init(orca_runtime* runtime) { + memset(runtime, 0, sizeof(orca_runtime)); mem_base_allocator* allocator = mem_base_allocator_default(); - memory->committed = 0; - memory->reserved = 4<<20; - memory->ptr = mem_base_reserve(allocator, memory->reserved); + runtime->wasmMemory.committed = 0; + runtime->wasmMemory.reserved = 4ULL<<30; + runtime->wasmMemory.ptr = mem_base_reserve(allocator, runtime->wasmMemory.reserved); } -void* host_memory_resize_callback(void* p, unsigned long size, void* userData) +orca_app __orcaApp; + +orca_runtime* orca_runtime_get() { - host_memory* memory = (host_memory*)userData; - - 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); - } -} - -void host_memory_free_callback(void* p, void* userData) -{ - host_memory* memory = (host_memory*)userData; - - mem_base_allocator* allocator = mem_base_allocator_default(); - mem_base_release(allocator, memory->ptr, memory->reserved); - memset(memory, 0, sizeof(host_memory)); + return(&__orcaApp.runtime); } void* orca_runloop(void* user) { - orca_app* app = (orca_app*)user; - mem_arena_init(mem_scratch()); + orca_app* app = &__orcaApp; + + orca_runtime_init(&app->runtime); //NOTE: loads wasm module const char* bundleNameCString = "module"; @@ -206,49 +149,46 @@ void* orca_runloop(void* user) u64 wasmSize = ftell(file); rewind(file); - u8* wasmBytes = malloc_array(u8, wasmSize); - fread(wasmBytes, 1, wasmSize, file); + app->runtime.wasmBytecode.len = wasmSize; + app->runtime.wasmBytecode.ptr = malloc_array(char, wasmSize); + fread(app->runtime.wasmBytecode.ptr, 1, app->runtime.wasmBytecode.len, file); fclose(file); u32 stackSize = 65536; - IM3Environment env = m3_NewEnvironment(); + app->runtime.m3Env = m3_NewEnvironment(); - host_memory hostMemory = {}; - host_memory_init(&hostMemory); - - IM3Runtime runtime = m3_NewRuntime(env, stackSize, NULL); - m3_RuntimeSetMemoryCallbacks(runtime, host_memory_resize_callback, host_memory_free_callback, &hostMemory); + 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. - IM3Module module = 0; - //TODO check errors - m3_ParseModule(env, &module, wasmBytes, wasmSize); - m3_LoadModule(runtime, module); - m3_SetModuleName(module, 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_scratch_clear(); //NOTE: bind orca APIs - bindgen_link_core_api(module); - bindgen_link_canvas_api(module); - bindgen_link_gles_api(module); - manual_link_gles_api(module); + bindgen_link_core_api(app->runtime.m3Module); + bindgen_link_canvas_api(app->runtime.m3Module); + bindgen_link_gles_api(app->runtime.m3Module); + manual_link_gles_api(app->runtime.m3Module); //NOTE: compile - M3Result res = m3_CompileModule(module); + M3Result res = m3_CompileModule(app->runtime.m3Module); if(res) { M3ErrorInfo errInfo = {}; - m3_GetErrorInfo(runtime, &errInfo); + m3_GetErrorInfo(app->runtime.m3Runtime, &errInfo); LOG_ERROR("wasm error: %s\n", errInfo.message); + return((void*)-1); } //NOTE: Find heap base u32 heapBase = 0; { - IM3Global global = m3_FindGlobal(module, "__heap_base"); + IM3Global global = m3_FindGlobal(app->runtime.m3Module, "__heap_base"); if(global) { M3TaggedValue val; @@ -271,15 +211,15 @@ void* orca_runloop(void* user) } //NOTE: align heap base on 16Bytes heapBase = AlignUpOnPow2(heapBase, 16); - LOG_MESSAGE("mem_size = %u, __heap_base = %u\n", m3_GetMemorySize(runtime), heapBase); + LOG_MESSAGE("mem_size = %u, __heap_base = %u\n", m3_GetMemorySize(app->runtime.m3Runtime), heapBase); //NOTE: Find and type check event handlers. - IM3Function eventHandlers[G_EVENT_COUNT] = {0}; + for(int i=0; iname.ptr); + m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr); if(handler) { @@ -320,7 +260,7 @@ void* orca_runloop(void* user) if(checked) { - eventHandlers[i] = handler; + app->runtime.eventHandlers[i] = handler; } else { @@ -334,6 +274,8 @@ void* orca_runloop(void* user) //NOTE: prepare GL surface mg_surface_prepare(app->surface); + IM3Function* eventHandlers = app->runtime.eventHandlers; + //NOTE: call init handler if(eventHandlers[G_EVENT_START]) { @@ -431,18 +373,6 @@ void* orca_runloop(void* user) } } -/* mg_surface_prepare(app->surface); - glClearColor(1, 0, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - - if(eventHandlers[G_EVENT_FRAME_REFRESH]) - { - m3_Call(eventHandlers[G_EVENT_FRAME_REFRESH], 0, 0); - } - - mg_surface_present(app->surface); -*/ - mg_canvas_prepare(app->canvas); if(eventHandlers[G_EVENT_FRAME_REFRESH]) @@ -488,13 +418,13 @@ int main(int argc, char** argv) mg_surface_swap_interval(mtlSurface, 1); mg_canvas canvas = mg_canvas_create(mtlSurface); - orca_app app = {.window = window, - .surface = surface, - .mtlSurface = mtlSurface, - .canvas = canvas}; + __orcaApp = (orca_app){.window = window, + .surface = surface, + .mtlSurface = mtlSurface, + .canvas = canvas}; pthread_t runloopThread; - pthread_create(&runloopThread, 0, orca_runloop, &app); + pthread_create(&runloopThread, 0, orca_runloop, 0); while(!mp_should_quit()) { diff --git a/src/memory_impl.c b/src/memory_impl.c new file mode 100644 index 0000000..c940b9d --- /dev/null +++ b/src/memory_impl.c @@ -0,0 +1,59 @@ +/************************************************************//** +* +* @file: memory_impl.c +* @author: Martin Fouilleul +* @date: 17/04/2023 +* +*****************************************************************/ + +#include"orca_runtime.h" + +void* wasm_memory_resize_callback(void* p, unsigned long size, void* userData) +{ + wasm_memory* memory = (wasm_memory*)userData; + + 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); + } +} + +void wasm_memory_free_callback(void* p, void* 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)); +} + +extern u32 orca_mem_grow(u64 size) +{ + orca_runtime* runtime = orca_runtime_get(); + wasm_memory* memory = &runtime->wasmMemory; + + size = AlignUpOnPow2(size, d_m3MemPageSize); + u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime); + + 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); + + return(addr); +} diff --git a/src/orca_runtime.h b/src/orca_runtime.h new file mode 100644 index 0000000..def757d --- /dev/null +++ b/src/orca_runtime.h @@ -0,0 +1,72 @@ +/************************************************************//** +* +* @file: orca_runtime.h +* @author: Martin Fouilleul +* @date: 17/04/2023 +* +*****************************************************************/ +#ifndef __ORCA_RUNTIME_H_ +#define __ORCA_RUNTIME_H_ + +#include"wasm3.h" +#include"m3_env.h" +#include"m3_compile.h" + +#define G_EVENTS(X) \ + X(G_EVENT_START, "OnInit", "", "") \ + X(G_EVENT_MOUSE_DOWN, "OnMouseDown", "", "i") \ + X(G_EVENT_MOUSE_UP, "OnMouseUp", "", "i") \ + X(G_EVENT_MOUSE_ENTER, "OnMouseEnter", "", "") \ + X(G_EVENT_MOUSE_LEAVE, "OnMouseLeave", "", "") \ + X(G_EVENT_MOUSE_MOVE, "OnMouseMove", "", "ffff") \ + X(G_EVENT_MOUSE_WHEEL, "OnMouseWheel", "", "ff") \ + X(G_EVENT_KEY_DOWN, "OnKeyDown", "", "i") \ + X(G_EVENT_KEY_UP, "OnKeyUp", "", "i") \ + X(G_EVENT_FRAME_REFRESH, "OnFrameRefresh", "", "") \ + X(G_EVENT_FRAME_RESIZE, "OnFrameResize", "", "ii") + +typedef enum { + #define G_EVENT_KIND(kind, ...) kind, + G_EVENTS(G_EVENT_KIND) + G_EVENT_COUNT +} guest_event_kind; + + +typedef struct g_event_handler_desc +{ + str8 name; + str8 retTags; + str8 argTags; +} g_event_handler_desc; + +const g_event_handler_desc G_EVENT_HANDLER_DESC[] = { + #define G_EVENT_HANDLER_DESC_ENTRY(kind, name, rets, args) {STR8(name), STR8(rets), STR8(args)}, + G_EVENTS(G_EVENT_HANDLER_DESC_ENTRY) +}; + +typedef struct wasm_memory +{ + char* ptr; + u64 reserved; + u64 committed; + +} wasm_memory; + +typedef struct orca_runtime +{ + str8 wasmBytecode; + wasm_memory wasmMemory; + + // wasm3 data + IM3Environment m3Env; + IM3Runtime m3Runtime; + IM3Module m3Module; + IM3Function eventHandlers[G_EVENT_COUNT]; + +} orca_runtime; + + +orca_runtime* orca_runtime_get(); + + +#endif //__ORCA_RUNTIME_H_