implicit zero-ing of stack allocated variables
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 4 Dec 2021 18:14:43 +0000 (12:14 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 4 Dec 2021 18:14:43 +0000 (12:14 -0600)
include/astnodes.h
src/checker.c
src/wasm_emit.c

index 3b76bd00ea0db0702691e3f8b53832bc8d4a6fca..66deb9a877e2b0b24248ff033e7a292118d49ec3 100644 (file)
@@ -260,6 +260,8 @@ typedef enum AstFlags {
     Ast_Flag_Symbol_Invisible      = BH_BIT(18),
 
     Ast_Flag_Header_Check_No_Error = BH_BIT(19),
+
+    Ast_Flag_Decl_Followed_By_Init = BH_BIT(20),
 } AstFlags;
 
 typedef enum UnaryOp {
index 72d2350cbf47f99808ed3ededf1754eccab0a3c3..20cc4723a429c8d6d6b41d249ff187987f368454 100644 (file)
@@ -1911,6 +1911,13 @@ CheckStatus check_statement(AstNode** pstmt) {
 
                 YIELD(typed_stmt->token->pos, "Waiting for local variable's type.");
             }
+
+            if (typed_stmt->next != NULL && typed_stmt->next->kind == Ast_Kind_Binary_Op) {
+                AstBinaryOp *next = (AstBinaryOp *) typed_stmt->next;
+                if (next->operation == Binary_Op_Assign && next->left == typed_stmt) {
+                    typed_stmt->flags |= Ast_Flag_Decl_Followed_By_Init;
+                }
+            }
             return Check_Success;
         }
 
index b7aea1a65b6aaf7858a41371e47d9cc9096bd34d..2a9f5b98cf07226418cc42ed341cb7cd48a02654 100644 (file)
@@ -439,7 +439,28 @@ EMIT_FUNC(statement, AstNode* stmt) {
 }
 
 EMIT_FUNC(local_allocation, AstTyped* stmt) {
-    bh_imap_put(&mod->local_map, (u64) stmt, local_allocate(mod->local_alloc, stmt));
+    u64 local_idx = local_allocate(mod->local_alloc, stmt);
+    bh_imap_put(&mod->local_map, (u64) stmt, local_idx);
+
+    if (stmt->kind == Ast_Kind_Local && !(stmt->flags & Ast_Flag_Decl_Followed_By_Init)) {
+        bh_arr(WasmInstruction) code = *pcode;
+        if (local_is_wasm_local(stmt)) {
+            emit_zero_value(mod, &code, onyx_type_to_wasm_type(stmt->type));
+            WIL(WI_LOCAL_SET, local_idx);
+
+        } else {
+            emit_location(mod, &code, stmt);
+            WID(WI_I32_CONST, 0);
+            WID(WI_I32_CONST, type_size_of(stmt->type));
+            if (context.options->use_post_mvp_features) {
+                WID(WI_MEMORY_FILL, 0x00);
+            } else {
+                emit_intrinsic_memory_fill(mod, &code);
+            }
+        }
+
+        *pcode = code;
+    }
 
     bh_arr_push(mod->local_allocations, ((AllocatedSpace) {
         .depth = bh_arr_length(mod->structured_jump_target),