From: Brendan Hansen Date: Fri, 7 Aug 2020 18:55:14 +0000 (-0500) Subject: Converted to using a proper stack system; many improvements will be needed but it... X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=ab1de36d3423027eb2cd82551416866ef18c0e99;p=onyx.git Converted to using a proper stack system; many improvements will be needed but it works --- diff --git a/Makefile b/Makefile index 0e514db6..6a575b28 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -RELEASE=1 +RELEASE=0 OBJ_FILES=\ build/onyxlex.o \ diff --git a/docs/plan b/docs/plan index 25846cec..b26d4beb 100644 --- a/docs/plan +++ b/docs/plan @@ -144,6 +144,14 @@ HOW: [X] #file_contents + [X] Convert to using a proper stack based system + + [ ] Be smart about when to use the stack versus use the wasm locals + + [ ] Array literals + + [ ] Properly checking binary operators + [ ] Better checking for casts [ ] All code paths return correct value diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 3f03c4e2..63a1f95d 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -129,27 +129,32 @@ typedef enum AstKind { // only 32-bits of flags to play with typedef enum AstFlags { // Top-level flags - Ast_Flag_Exported = BH_BIT(0), - Ast_Flag_Foreign = BH_BIT(1), - Ast_Flag_Const = BH_BIT(2), - Ast_Flag_Comptime = BH_BIT(3), - Ast_Flag_Private_Package = BH_BIT(4), + Ast_Flag_Exported = BH_BIT(0), + Ast_Flag_Foreign = BH_BIT(1), + Ast_Flag_Const = BH_BIT(2), + Ast_Flag_Comptime = BH_BIT(3), + Ast_Flag_Private_Package = BH_BIT(4), + + // Global flags + Ast_Flag_Global_Stack_Top = BH_BIT(8), + Ast_Flag_Global_Stack_Base = BH_BIT(9), // Function flags - Ast_Flag_Inline = BH_BIT(8), - Ast_Flag_Intrinsic = BH_BIT(9), - Ast_Flag_Function_Used = BH_BIT(10), + Ast_Flag_Inline = BH_BIT(8), + Ast_Flag_Intrinsic = BH_BIT(9), + Ast_Flag_Function_Used = BH_BIT(10), + Ast_Flag_No_Stack = BH_BIT(11), // Expression flags - Ast_Flag_Expr_Ignored = BH_BIT(8), - Ast_Flag_Param_Splatted = BH_BIT(9), - Ast_Flag_Param_Use = BH_BIT(10), + Ast_Flag_Expr_Ignored = BH_BIT(8), + Ast_Flag_Param_Splatted = BH_BIT(9), + Ast_Flag_Param_Use = BH_BIT(10), // Type flags - Ast_Flag_Type_Is_Resolved = BH_BIT(8), + Ast_Flag_Type_Is_Resolved = BH_BIT(8), // Enum flags - Ast_Flag_Enum_Is_Flags = BH_BIT(11), + Ast_Flag_Enum_Is_Flags = BH_BIT(11), } AstFlags; typedef enum UnaryOp { @@ -475,6 +480,8 @@ extern AstBasicType basic_type_f64; extern AstBasicType basic_type_rawptr; extern AstNumLit builtin_heap_start; +extern AstGlobal builtin_stack_base; +extern AstGlobal builtin_stack_top; typedef struct BuiltinSymbol { char* sym; diff --git a/include/onyxwasm.h b/include/onyxwasm.h index a42d78ac..4ef2ea38 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -258,7 +258,7 @@ typedef struct WasmFunc { typedef struct WasmGlobal { WasmType type; - u8 mutable; + u32 mutable : 1; bh_arr(WasmInstruction) initial_value; } WasmGlobal; @@ -296,7 +296,7 @@ typedef struct OnyxWasmModule { // NOTE: Mapping ptrs to function / global indicies bh_imap index_map; - // NOTE: Mapping from local ast node ptrs to indicies + // NOTE: Mapping from local ast node ptrs to indicies or offsets, depending on the mode bh_imap local_map; // NOTE: Mapping ptrs to elements @@ -329,6 +329,8 @@ typedef struct OnyxWasmModule { u32 next_foreign_global_idx; u32 next_datum_offset; u32 next_elem_idx; + + u32 *stack_top_ptr, *stack_base_ptr; } OnyxWasmModule; OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc); diff --git a/onyx b/onyx index 0210d24e..8a908bc8 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx new file mode 100644 index 00000000..52e495f0 --- /dev/null +++ b/progs/stack_based.onyx @@ -0,0 +1,28 @@ +package main + +use "progs/print_funcs" + +use package printing + +ret_val :: proc (x: i32, y: i32) -> i32 { + big_arr : [128] i32; + big_arr[127] = 1234; + return big_arr[127] + x + y; +} + +main :: proc #export { + print("Hello, World!"); + print(cast(i32) __heap_start); + a := 12345; + + arr : [5] i32; + arr[0] = 10; + arr[1] = 20; + arr[2] = 30; + arr[3] = 40; + arr[4] = 50; + + print(ret_val(10, 4)); + + for i: 0, 5 do print(arr[i]); +} \ No newline at end of file diff --git a/src/onyx.c b/src/onyx.c index ba454dda..6be4e6f0 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -267,11 +267,6 @@ static void merge_parse_results(CompilerState* compiler_state, ParseResults* res } } } - - qsort(compiler_state->prog_info.entities, - bh_arr_length(compiler_state->prog_info.entities), - sizeof(Entity), - sort_entities); } static CompilerProgress process_source_file(CompilerState* compiler_state, char* filename) { @@ -318,6 +313,28 @@ static i32 onyx_compile(CompilerState* compiler_state) { bh_arr_fastdelete(compiler_state->queued_files, 0); } + // Add builtin one-time entities + bh_arr_push(compiler_state->prog_info.entities, ((Entity) { + .type = Entity_Type_Global_Header, + .global = &builtin_stack_base + })); + bh_arr_push(compiler_state->prog_info.entities, ((Entity) { + .type = Entity_Type_Global_Header, + .global = &builtin_stack_top + })); + bh_arr_push(compiler_state->prog_info.entities, ((Entity) { + .type = Entity_Type_Global, + .global = &builtin_stack_base + })); + bh_arr_push(compiler_state->prog_info.entities, ((Entity) { + .type = Entity_Type_Global, + .global = &builtin_stack_top + })); + + qsort(compiler_state->prog_info.entities, + bh_arr_length(compiler_state->prog_info.entities), + sizeof(Entity), + sort_entities); // NOTE: Check types and semantic rules if (compiler_state->options->verbose_output) diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 64390bcf..0b9a9c41 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -576,7 +576,8 @@ CHECK(address_of, AstAddressOf* aof) { if (aof->expr->kind != Ast_Kind_Array_Access && aof->expr->kind != Ast_Kind_Dereference && aof->expr->kind != Ast_Kind_Field_Access - && aof->expr->kind != Ast_Kind_Memres) { + && aof->expr->kind != Ast_Kind_Memres + && aof->expr->kind != Ast_Kind_Local) { onyx_message_add(Msg_Type_Literal, aof->token->pos, "cannot take the address of this"); diff --git a/src/onyxparser.c b/src/onyxparser.c index e8097273..2a7b53c4 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1115,6 +1115,10 @@ static AstFunction* parse_function_definition(OnyxParser* parser) { } } + else if (parse_possible_directive(parser, "nostack")) { + func_def->flags |= Ast_Flag_No_Stack; + } + else { OnyxToken* directive_token = expect_token(parser, '#'); OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 5f0a2869..0320cab4 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -19,7 +19,11 @@ AstBasicType basic_type_f64 = { { Ast_Kind_Basic_Type, 0, NULL, "f64" }, & AstBasicType basic_type_rawptr = { { Ast_Kind_Basic_Type, 0, NULL, "rawptr" }, &basic_types[Basic_Kind_Rawptr] }; static OnyxToken builtin_heap_start_token = { Token_Type_Symbol, 12, "__heap_start ", { 0 } }; +static OnyxToken builtin_stack_base_token = { Token_Type_Symbol, 12, "__stack_base ", { 0 } }; +static OnyxToken builtin_stack_top_token = { Token_Type_Symbol, 11, "__stack_top ", { 0 } }; AstNumLit builtin_heap_start = { Ast_Kind_NumLit, Ast_Flag_Const, &builtin_heap_start_token, NULL, (AstType *) &basic_type_rawptr, NULL, 0 }; +AstGlobal builtin_stack_base = { Ast_Kind_Global, Ast_Flag_Const | Ast_Flag_Global_Stack_Base, &builtin_stack_base_token, NULL, (AstType *) &basic_type_rawptr, NULL }; +AstGlobal builtin_stack_top = { Ast_Kind_Global, Ast_Flag_Const | Ast_Flag_Global_Stack_Top, &builtin_stack_top_token, NULL, (AstType *) &basic_type_rawptr, NULL }; const BuiltinSymbol builtin_symbols[] = { { "void", (AstNode *) &basic_type_void }, @@ -37,6 +41,8 @@ const BuiltinSymbol builtin_symbols[] = { { "rawptr", (AstNode *) &basic_type_rawptr }, { "__heap_start", (AstNode *) &builtin_heap_start }, + { "__stack_base", (AstNode *) &builtin_stack_base }, + { "__stack_top", (AstNode *) &builtin_stack_top }, { NULL, NULL }, }; @@ -524,8 +530,10 @@ void onyx_resolve_symbols() { } bh_arr_each(Entity, entity, semstate.program->entities) { - scope_enter(entity->package->private_scope); - semstate.curr_package = entity->package; + if (entity->package) { + scope_enter(entity->package->private_scope); + semstate.curr_package = entity->package; + } switch (entity->type) { case Entity_Type_Use_Package: symres_use_package(entity->use_package); break; @@ -540,6 +548,6 @@ void onyx_resolve_symbols() { default: break; } - scope_leave(); + if (entity->package) scope_leave(); } } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 6c24c76a..ad0d7811 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -263,9 +263,12 @@ COMPILE_FUNC(call, AstCall* call); COMPILE_FUNC(intrinsic_call, AstIntrinsicCall* call); COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return); COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return); +COMPILE_FUNC(local_location, AstLocal* local, u64* offset_return); COMPILE_FUNC(expression, AstTyped* expr); COMPILE_FUNC(cast, AstUnaryOp* cast); COMPILE_FUNC(return, AstReturn* ret); +COMPILE_FUNC(stack_enter, u64 stacksize); +COMPILE_FUNC(stack_leave, u32 unused); COMPILE_FUNC(function_body, AstFunction* fd) { if (fd->body == NULL) return; @@ -278,8 +281,6 @@ COMPILE_FUNC(function_body, AstFunction* fd) { compile_deferred_stmts(mod, &code, (AstNode *) fd); - WI(WI_BLOCK_END); - *pcode = code; } @@ -354,10 +355,10 @@ COMPILE_FUNC(assignment, AstBinaryOp* assign) { AstTyped* lval = assign->left; if (lval->kind == Ast_Kind_Local) { - i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) lval); - + u64 offset = 0; + compile_local_location(mod, &code, (AstLocal *) lval, &offset); compile_expression(mod, &code, assign->right); - WID(WI_LOCAL_SET, localidx); + compile_store_instruction(mod, &code, lval->type, type_get_alignment_log2(lval->type), offset); } else if (lval->kind == Ast_Kind_Global) { i32 globalidx = (i32) bh_imap_get(&mod->index_map, (u64) lval); @@ -557,10 +558,15 @@ COMPILE_FUNC(while, AstWhile* while_node) { COMPILE_FUNC(for, AstFor* for_node) { bh_arr(WasmInstruction) code = *pcode; - i32 it_idx = (i32) bh_imap_get(&mod->local_map, (u64) for_node->var); + // i32 it_idx = (i32) bh_imap_get(&mod->local_map, (u64) for_node->var); + AstLocal* var = for_node->var; + + u64 offset = 0; + compile_local_location(mod, &code, var, &offset); compile_expression(mod, &code, for_node->start); - WID(WI_LOCAL_SET, it_idx); + compile_store_instruction(mod, &code, var->type, type_get_alignment_log2(var->type), offset); + //WID(WI_LOCAL_SET, it_idx); WID(WI_BLOCK_START, 0x40); WID(WI_LOOP_START, 0x40); @@ -568,7 +574,10 @@ COMPILE_FUNC(for, AstFor* for_node) { bh_arr_push(mod->structured_jump_target, 1); bh_arr_push(mod->structured_jump_target, 2); - WID(WI_LOCAL_GET, it_idx); + offset = 0; + compile_local_location(mod, &code, var, &offset); + compile_load_instruction(mod, &code, var->type, offset); + // WID(WI_LOCAL_GET, it_idx); compile_expression(mod, &code, for_node->end); WI(WI_I32_GE_S); WID(WI_COND_JUMP, 0x01); @@ -577,13 +586,19 @@ COMPILE_FUNC(for, AstFor* for_node) { compile_statement(mod, &code, stmt); } + offset = 0; + compile_local_location(mod, &code, var, &offset); + offset = 0; + compile_local_location(mod, &code, var, &offset); + compile_load_instruction(mod, &code, var->type, offset); if (for_node->step == NULL) WID(WI_I32_CONST, 0x01); else compile_expression(mod, &code, for_node->step); - WID(WI_LOCAL_GET, it_idx); + // WID(WI_LOCAL_GET, it_idx); WI(WI_I32_ADD); - WID(WI_LOCAL_SET, it_idx); + compile_store_instruction(mod, &code, var->type, type_get_alignment_log2(var->type), offset); + //WID(WI_LOCAL_SET, it_idx); compile_deferred_stmts(mod, &code, (AstNode *) for_node); @@ -623,7 +638,7 @@ COMPILE_FUNC(deferred_stmts, AstNode* node) { // NOTE: These need to be in the same order as // the OnyxBinaryOp enum static const WasmInstructionType binop_map[][4] = { - // I32 I64 F32 F64 + // I32 I64 F32 F64 /* ADD */ { WI_I32_ADD, WI_I64_ADD, WI_F32_ADD, WI_F64_ADD }, /* SUB */ { WI_I32_SUB, WI_I64_SUB, WI_F32_SUB, WI_F64_SUB }, /* MUL */ { WI_I32_MUL, WI_I64_MUL, WI_F32_MUL, WI_F64_MUL }, @@ -856,6 +871,9 @@ COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) { } else if (aa->addr->kind == Ast_Kind_Field_Access && aa->addr->type->kind == Type_Kind_Array) { compile_field_access_location(mod, &code, (AstFieldAccess *) aa->addr, &offset); + } else if (aa->addr->kind == Ast_Kind_Local + && aa->addr->type->kind == Type_Kind_Array) { + compile_local_location(mod, &code, (AstLocal *) aa->addr, &offset); } else { compile_expression(mod, &code, aa->addr); } @@ -882,6 +900,11 @@ COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) { u64 o2 = 0; compile_array_access_location(mod, &code, (AstArrayAccess *) source_expr, &o2); offset += o2; + } else if (source_expr->kind == Ast_Kind_Local + && source_expr->type->kind != Type_Kind_Pointer) { + u64 o2 = 0; + compile_local_location(mod, &code, (AstLocal *) source_expr, &o2); + offset += o2; } else { compile_expression(mod, &code, source_expr); } @@ -891,11 +914,23 @@ COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) { *pcode = code; } +COMPILE_FUNC(local_location, AstLocal* local, u64* offset_return) { + bh_arr(WasmInstruction) code = *pcode; + + i32 stack_base_idx = (i32) bh_imap_get(&mod->index_map, (u64) &builtin_stack_base); + i32 local_offset = (i32) bh_imap_get(&mod->local_map, (u64) local); + + WID(WI_GLOBAL_GET, stack_base_idx); + + *offset_return += local_offset; + + *pcode = code; +} + COMPILE_FUNC(expression, AstTyped* expr) { bh_arr(WasmInstruction) code = *pcode; switch (expr->kind) { - case Ast_Kind_Local: case Ast_Kind_Param: { i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) expr); @@ -903,6 +938,13 @@ COMPILE_FUNC(expression, AstTyped* expr) { break; } + case Ast_Kind_Local: { + u64 offset = 0; + compile_local_location(mod, &code, (AstLocal *) expr, &offset); + compile_load_instruction(mod, &code, expr->type, offset); + break; + } + case Ast_Kind_Global: { i32 globalidx = (i32) bh_imap_get(&mod->index_map, (u64) expr); @@ -954,6 +996,14 @@ COMPILE_FUNC(expression, AstTyped* expr) { AstAddressOf* aof = (AstAddressOf *) expr; switch (aof->expr->kind) { + case Ast_Kind_Local: { + u64 offset = 0; + compile_local_location(mod, &code, (AstLocal *) aof->expr, &offset); + WID(WI_I32_CONST, offset); + WI(WI_I32_ADD); + break; + } + case Ast_Kind_Dereference: { compile_expression(mod, &code, ((AstDereference *) aof->expr)->expr); break; @@ -1206,11 +1256,57 @@ COMPILE_FUNC(return, AstReturn* ret) { } } + compile_stack_leave(mod, &code, 0); + WI(WI_RETURN); *pcode = code; } +COMPILE_FUNC(stack_enter, u64 stacksize) { + bh_arr(WasmInstruction) code = *pcode; + + u32 stack_top_idx = bh_imap_get(&mod->index_map, (u64) &builtin_stack_top); + u32 stack_base_idx = bh_imap_get(&mod->index_map, (u64) &builtin_stack_base); + + WID(WI_GLOBAL_GET, stack_top_idx); + WID(WI_GLOBAL_GET, stack_base_idx); + WID(WI_I32_STORE, ((WasmInstructionData) { 2, 0 })); + WID(WI_GLOBAL_GET, stack_top_idx); + WID(WI_I32_CONST, 4); + WI(WI_I32_ADD); + WID(WI_GLOBAL_SET, stack_top_idx); + WID(WI_GLOBAL_GET, stack_top_idx); + WID(WI_GLOBAL_SET, stack_base_idx); + WID(WI_GLOBAL_GET, stack_top_idx); + WID(WI_I32_CONST, stacksize); + WI(WI_I32_ADD); + WID(WI_GLOBAL_SET, stack_top_idx); + + *pcode = code; +} + +COMPILE_FUNC(stack_leave, u32 unused) { + bh_arr(WasmInstruction) code = *pcode; + + u32 stack_top_idx = bh_imap_get(&mod->index_map, (u64) &builtin_stack_top); + u32 stack_base_idx = bh_imap_get(&mod->index_map, (u64) &builtin_stack_base); + + WID(WI_GLOBAL_GET, stack_base_idx); + WID(WI_GLOBAL_SET, stack_top_idx); + + WID(WI_GLOBAL_GET, stack_top_idx); + WID(WI_I32_CONST, 4); + WI(WI_I32_SUB); + WID(WI_GLOBAL_SET, stack_top_idx); + + WID(WI_GLOBAL_GET, stack_top_idx); + WID(WI_I32_LOAD, ((WasmInstructionData) { 2, 0 })); + WID(WI_GLOBAL_SET, stack_base_idx); + + *pcode = code; +} + static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft) { if (ft->kind != Type_Kind_Function) return -1; @@ -1337,37 +1433,51 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) { // If there is no body then don't process the code if (fd->body != NULL) { - // NOTE: Generate the local map + // // NOTE: Generate the local map i32 localidx = 0; for (AstLocal *param = fd->params; param != NULL; param = (AstLocal *) param->next) { bh_imap_put(&mod->local_map, (u64) param, localidx++); } - static const WasmType local_types[4] = { WASM_TYPE_INT32, WASM_TYPE_INT64, WASM_TYPE_FLOAT32, WASM_TYPE_FLOAT64 }; + // static const WasmType local_types[4] = { WASM_TYPE_INT32, WASM_TYPE_INT64, WASM_TYPE_FLOAT32, WASM_TYPE_FLOAT64 }; - // HACK: This assumes that the order of the count members - // is the same as the order of the local_types above - u8* count = &wasm_func.locals.i32_count; - fori (ti, 0, 3) { - bh_arr_each(AstLocal *, local, fd->locals) { - if (onyx_type_to_wasm_type((*local)->type) == local_types[ti]) { - bh_imap_put(&mod->local_map, (u64) *local, localidx++); + // // HACK: This assumes that the order of the count members + // // is the same as the order of the local_types above + // u8* count = &wasm_func.locals.i32_count; + // fori (ti, 0, 3) { + // bh_arr_each(AstLocal *, local, fd->locals) { + // if (onyx_type_to_wasm_type((*local)->type) == local_types[ti]) { + // bh_imap_put(&mod->local_map, (u64) *local, localidx++); - (*count)++; - } - } + // (*count)++; + // } + // } + + // count++; + // } - count++; + i32 offset = 0; + bh_arr_each(AstLocal *, local, fd->locals) { + u32 size = type_size_of((*local)->type); + u32 align = type_alignment_of((*local)->type); + if (offset % align != 0) + offset += align - (offset % align); + + bh_imap_put(&mod->local_map, (u64) *local, offset); + offset += size; } + if (offset % 16 != 0) + offset += 16 - (offset % 16); + // Generate code + compile_stack_enter(mod, &wasm_func.code, (u64) offset); compile_function_body(mod, &wasm_func.code, fd); - - } else { - // NOTE: Empty bodies still need a block end instruction - bh_arr_push(wasm_func.code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); + compile_stack_leave(mod, &wasm_func.code, 0); } + bh_arr_push(wasm_func.code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); + bh_arr_push(mod->funcs, wasm_func); // NOTE: Clear the local map on exit of generating this function @@ -1422,6 +1532,12 @@ static void compile_global(OnyxWasmModule* module, AstGlobal* global) { } bh_arr_push(module->globals, glob); + + if (global->flags & Ast_Flag_Global_Stack_Top) + module->stack_top_ptr = &bh_arr_last(module->globals).initial_value[0].data.i1; + if (global->flags & Ast_Flag_Global_Stack_Base) + module->stack_base_ptr = &bh_arr_last(module->globals).initial_value[0].data.i1; + } static void compile_string_literal(OnyxWasmModule* mod, AstStrLit* strlit) { @@ -1527,6 +1643,8 @@ static void compile_file_contents(OnyxWasmModule* mod, AstFileContents* fc) { bh_arr_push(mod->data, datum); + mod->next_datum_offset = offset + length; + token_toggle_end(fc->filename); } @@ -1558,6 +1676,9 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) { .next_elem_idx = 0, .structured_jump_target = NULL, + + .stack_top_ptr = NULL, + .stack_base_ptr = NULL, }; bh_arr_new(alloc, module.types, 4); @@ -1597,12 +1718,21 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) { bh_arr_each(Entity, entity, program->entities) { - // HACK: To put this here - // NOTE: Round up to the nearest multiple of 16 - builtin_heap_start.value.i = - (module->next_datum_offset & 15) - ? ((module->next_datum_offset >> 4) + 1) << 4 - : module->next_datum_offset; + if (module->stack_base_ptr) { + *module->stack_base_ptr = module->next_datum_offset; + + if (*module->stack_base_ptr % 16 != 0) { + *module->stack_base_ptr += 16 - (*module->stack_base_ptr % 16); + } + + if (module->stack_top_ptr) + *module->stack_top_ptr = *module->stack_base_ptr; + + builtin_heap_start.value.i = *module->stack_base_ptr + (1 << 16); + if (builtin_heap_start.value.i % 16 != 0) { + builtin_heap_start.value.i += 16 - (builtin_heap_start.value.i % 16); + } + } switch (entity->type) { case Entity_Type_Function_Header: { @@ -1833,7 +1963,7 @@ static i32 output_memorysection(OnyxWasmModule* module, bh_buffer* buff) { u8* leb = uint_to_uleb128((u64) 1, &leb_len); bh_buffer_append(&vec_buff, leb, leb_len); - output_limits(4, -1, &vec_buff); + output_limits(256, -1, &vec_buff); leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); bh_buffer_append(buff, leb, leb_len); @@ -1857,7 +1987,7 @@ static i32 output_globalsection(OnyxWasmModule* module, bh_buffer* buff) { bh_arr_each(WasmGlobal, global, module->globals) { bh_buffer_write_byte(&vec_buff, global->type); - bh_buffer_write_byte(&vec_buff, global->mutable ? 0x01 : 0x00); + bh_buffer_write_byte(&vec_buff, 0x01); bh_arr_each(WasmInstruction, instr, global->initial_value) output_instruction(instr, &vec_buff);