@@ -150,10 +150,7 @@ static void local_raw_free(LocalAllocator* la, WasmType wt) {
150150 la -> freed [idx ]++ ;
151151}
152152
153- static u64 local_allocate_type_in_memory (LocalAllocator * la , Type * type ) {
154- u32 size = type_size_of (type );
155- u32 alignment = type_alignment_of (type );
156-
153+ static u64 local_allocate_bytes_in_memory (LocalAllocator * la , u32 size , u32 alignment ) {
157154 bh_align (la -> curr_stack , alignment );
158155
159156 if (la -> max_stack < la -> curr_stack )
@@ -172,12 +169,24 @@ static u64 local_allocate_type_in_memory(LocalAllocator* la, Type *type) {
172169 return la -> curr_stack - size ;
173170}
174171
172+ static void local_free_bytes_in_memory (LocalAllocator * la , u32 size , u32 alignment ) {
173+ bh_align (size , alignment );
174+
175+ la -> curr_stack -= size ;
176+ }
177+
178+ static u64 local_allocate_type_in_memory (LocalAllocator * la , Type * type ) {
179+ u32 size = type_size_of (type );
180+ u32 alignment = type_alignment_of (type );
181+
182+ return local_allocate_bytes_in_memory (la , size , alignment );
183+ }
184+
175185static void local_free_type_in_memory (LocalAllocator * la , Type * type ) {
176186 u32 size = type_size_of (type );
177187 u32 alignment = type_alignment_of (type );
178- bh_align (size , alignment );
179188
180- la -> curr_stack -= size ;
189+ local_free_bytes_in_memory ( la , size , alignment ) ;
181190}
182191
183192static u64 local_allocate (LocalAllocator * la , AstTyped * local ) {
@@ -769,6 +778,19 @@ EMIT_FUNC(statement, AstNode* stmt) {
769778 * pcode = code ;
770779}
771780
781+ EMIT_FUNC_RETURNING (u64 , stack_alloc , u32 size , u32 alignment ) {
782+ u32 local_idx = local_allocate_bytes_in_memory (mod -> local_alloc , size , alignment );
783+
784+ bh_arr_push (mod -> local_allocations , ((AllocatedSpace ) {
785+ .kind = Allocated_Space_Kind_Raw ,
786+ .depth = bh_arr_length (mod -> structured_jump_target ),
787+ .size = size ,
788+ .alignment = alignment
789+ }));
790+
791+ return local_idx ;
792+ }
793+
772794EMIT_FUNC_RETURNING (u64 , local_allocation , AstTyped * stmt ) {
773795 //
774796 // If the statement does not have a type, it should not
@@ -809,6 +831,7 @@ EMIT_FUNC_RETURNING(u64, local_allocation, AstTyped* stmt) {
809831 }
810832
811833 bh_arr_push (mod -> local_allocations , ((AllocatedSpace ) {
834+ .kind = Allocated_Space_Kind_Local ,
812835 .depth = bh_arr_length (mod -> structured_jump_target ),
813836 .expr = stmt ,
814837 }));
@@ -821,10 +844,19 @@ EMIT_FUNC_NO_ARGS(free_local_allocations) {
821844
822845 u64 depth = bh_arr_length (mod -> structured_jump_target );
823846 while (bh_arr_length (mod -> local_allocations ) > 0 && bh_arr_last (mod -> local_allocations ).depth >= depth ) {
824- // CHECK: Not sure this next line is okay to be here...
825- bh_imap_delete (& mod -> local_map , (u64 ) bh_arr_last (mod -> local_allocations ).expr );
847+ AllocatedSpace alloc = bh_arr_last (mod -> local_allocations );
848+ switch (alloc .kind ) {
849+ case Allocated_Space_Kind_Local :
850+ // CHECK: Not sure this next line is okay to be here...
851+ bh_imap_delete (& mod -> local_map , (u64 ) alloc .expr );
852+ local_free (mod -> local_alloc , alloc .expr );
853+ break ;
854+
855+ case Allocated_Space_Kind_Raw :
856+ local_free_bytes_in_memory (mod -> local_alloc , alloc .size , alloc .alignment );
857+ break ;
858+ }
826859
827- local_free (mod -> local_alloc , bh_arr_last (mod -> local_allocations ).expr );
828860 bh_arr_pop (mod -> local_allocations );
829861 }
830862}
@@ -2085,7 +2117,7 @@ EMIT_FUNC(call, AstCall* call) {
20852117 WIL (NULL , WI_GLOBAL_SET , stack_trace_pass_global );
20862118 }
20872119
2088- if (call -> callee -> kind == Ast_Kind_Function ) {
2120+ if (call -> callee -> kind == Ast_Kind_Function && !(( AstFunction * ) call -> callee ) -> captures ) {
20892121 CodePatchInfo code_patch ;
20902122 code_patch .kind = Code_Patch_Callee ;
20912123 code_patch .func_idx = mod -> current_func_idx ;
@@ -3349,17 +3381,23 @@ EMIT_FUNC(expression, AstTyped* expr) {
33493381 }
33503382
33513383 // Allocate the block
3352- WIL (NULL , WI_I32_CONST , func -> captures -> total_size_in_bytes );
3384+ if (func -> captures -> alloc_on_stack ) {
3385+ u32 address = emit_stack_alloc (mod , & code , func -> captures -> total_size_in_bytes , 16 );
3386+ emit_stack_address (mod , & code , address , NULL );
33533387
3354- CodePatchInfo code_patch ;
3355- code_patch .kind = Code_Patch_Callee ;
3356- code_patch .func_idx = mod -> current_func_idx ;
3357- code_patch .instr = bh_arr_length (code );
3358- code_patch .node_related_to_patch = (AstNode * ) mod -> context -> builtins .closure_block_allocate ;
3359- bh_arr_push (mod -> code_patches , code_patch );
3360- WIL (NULL , WI_CALL , 0 );
3388+ } else {
3389+ WIL (NULL , WI_I32_CONST , func -> captures -> total_size_in_bytes );
3390+
3391+ CodePatchInfo code_patch ;
3392+ code_patch .kind = Code_Patch_Callee ;
3393+ code_patch .func_idx = mod -> current_func_idx ;
3394+ code_patch .instr = bh_arr_length (code );
3395+ code_patch .node_related_to_patch = (AstNode * ) mod -> context -> builtins .closure_block_allocate ;
3396+ bh_arr_push (mod -> code_patches , code_patch );
3397+ WIL (NULL , WI_CALL , 0 );
33613398
3362- ensure_node_has_been_submitted_for_emission (mod -> context , (AstNode * ) mod -> context -> builtins .closure_block_allocate );
3399+ ensure_node_has_been_submitted_for_emission (mod -> context , (AstNode * ) mod -> context -> builtins .closure_block_allocate );
3400+ }
33633401
33643402 u64 capture_block_ptr = local_raw_allocate (mod -> local_alloc , WASM_TYPE_PTR );
33653403 WIL (NULL , WI_LOCAL_TEE , capture_block_ptr );
0 commit comments