made it easy to change between 4 and 8 byte pointers
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 1 Dec 2021 20:25:44 +0000 (14:25 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 1 Dec 2021 20:25:44 +0000 (14:25 -0600)
include/types.h
src/types.c
src/wasm_emit.c
src/wasm_type_table.h
tests/struct_robustness

index 1e95215790a0cc43480f86568ecba21db7d167bd..fa03138dec32d81d7ec388e851d7b626375f883f 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "bh.h"
 
+#define POINTER_SIZE 4
+
 enum BasicKind {
     Basic_Kind_Void,
 
index 9850512fe011a675f5ce319f9daee01c071f2107..3cf40a3cff68c90710cc473935c1c6f1adbca037 100644 (file)
@@ -25,7 +25,7 @@ Type basic_types[] = {
     { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_f32, { Basic_Kind_F32,    Basic_Flag_Float,                         4,  4, "f32"    } },
     { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_f64, { Basic_Kind_F64,    Basic_Flag_Float,                         8,  4, "f64"    } },
 
-    { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_rawptr, { Basic_Kind_Rawptr, Basic_Flag_Pointer,                    8,  8, "rawptr" } },
+    { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_rawptr, { Basic_Kind_Rawptr, Basic_Flag_Pointer,                    POINTER_SIZE,  POINTER_SIZE, "rawptr" } },
 
     { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_i8x16, { Basic_Kind_I8X16,  Basic_Flag_SIMD,                        16, 16, "i8x16" } },
     { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_i16x8, { Basic_Kind_I16X8,  Basic_Flag_SIMD,                        16, 16, "i16x8" } },
@@ -210,14 +210,14 @@ u32 type_size_of(Type* type) {
 
     switch (type->kind) {
         case Type_Kind_Basic:    return type->Basic.size;
-        case Type_Kind_Pointer:  return 8;
+        case Type_Kind_Pointer:  return POINTER_SIZE;
         case Type_Kind_Function: return 4;
         case Type_Kind_Array:    return type->Array.size;
         case Type_Kind_Struct:   return type->Struct.size;
         case Type_Kind_Enum:     return type_size_of(type->Enum.backing);
-        case Type_Kind_Slice:    return 16; // HACK: These should not have to be 16 bytes in size, they should only have to be 12,
-        case Type_Kind_VarArgs:  return 16; // but there are alignment issues right now with that so I decided to not fight it and just make them 16 bytes in size.
-        case Type_Kind_DynArray: return 32; // data (8), count (4), capacity (4), allocator { func (4), ---(4), data (8) }
+        case Type_Kind_Slice:    return POINTER_SIZE * 2; // HACK: These should not have to be 16 bytes in size, they should only have to be 12,
+        case Type_Kind_VarArgs:  return POINTER_SIZE * 2; // but there are alignment issues right now with that so I decided to not fight it and just make them 16 bytes in size.
+        case Type_Kind_DynArray: return POINTER_SIZE + 8 + 2 * POINTER_SIZE; // data (8), count (4), capacity (4), allocator { func (4), ---(4), data (8) }
         case Type_Kind_Compound: return type->Compound.size;
         case Type_Kind_Distinct: return type_size_of(type->Distinct.base_type);
         default:                 return 0;
@@ -229,14 +229,14 @@ u32 type_alignment_of(Type* type) {
 
     switch (type->kind) {
         case Type_Kind_Basic:    return type->Basic.alignment;
-        case Type_Kind_Pointer:  return 8;
+        case Type_Kind_Pointer:  return POINTER_SIZE;
         case Type_Kind_Function: return 4;
         case Type_Kind_Array:    return type_alignment_of(type->Array.elem);
         case Type_Kind_Struct:   return type->Struct.alignment;
         case Type_Kind_Enum:     return type_alignment_of(type->Enum.backing);
-        case Type_Kind_Slice:    return 8;
-        case Type_Kind_VarArgs:  return 8;
-        case Type_Kind_DynArray: return 8;
+        case Type_Kind_Slice:    return POINTER_SIZE;
+        case Type_Kind_VarArgs:  return POINTER_SIZE;
+        case Type_Kind_DynArray: return POINTER_SIZE;
         case Type_Kind_Compound: return 4; // HACK
         case Type_Kind_Distinct: return type_alignment_of(type->Distinct.base_type);
         default: return 1;
@@ -755,7 +755,7 @@ Type* type_make_pointer(bh_allocator alloc, Type* to) {
     } else {
         Type* ptr_type = type_create(Type_Kind_Pointer, alloc, 0);
         ptr_type->Pointer.base.flags |= Basic_Flag_Pointer;
-        ptr_type->Pointer.base.size = 8;
+        ptr_type->Pointer.base.size = POINTER_SIZE;
         ptr_type->Pointer.elem = to;
 
         type_register(ptr_type);
@@ -1020,15 +1020,15 @@ Type* type_get_contained_type(Type* type) {
 }
 
 static const StructMember slice_members[] = {
-    { 0, 0, NULL,                         "data",  NULL, -1, 0, 0 },
-    { 8, 1, &basic_types[Basic_Kind_U32], "count", NULL, -1, 0, 0 },
+    { 0,            0, NULL,                         "data",  NULL, -1, 0, 0 },
+    { POINTER_SIZE, 1, &basic_types[Basic_Kind_U32], "count", NULL, -1, 0, 0 },
 };
 
 static const StructMember array_members[] = {
-    { 0,  0, NULL,                         "data",      NULL, -1, 0, 0 },
-    { 8,  1, &basic_types[Basic_Kind_U32], "count",     NULL, -1, 0, 0 },
-    { 12, 2, &basic_types[Basic_Kind_U32], "capacity",  NULL, -1, 0, 0 },
-    { 16, 3, NULL,                         "allocator", NULL, -1, 0, 0 },
+    { 0,                0, NULL,                         "data",      NULL, -1, 0, 0 },
+    { POINTER_SIZE,     1, &basic_types[Basic_Kind_U32], "count",     NULL, -1, 0, 0 },
+    { POINTER_SIZE + 4, 2, &basic_types[Basic_Kind_U32], "capacity",  NULL, -1, 0, 0 },
+    { POINTER_SIZE + 8, 3, NULL,                         "allocator", NULL, -1, 0, 0 },
 };
 
 b32 type_lookup_member(Type* type, char* member, StructMember* smem) {
@@ -1133,7 +1133,7 @@ b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) {
             }
             if (idx == 1) {
                 two->type = &basic_types[Basic_Kind_U32];
-                two->offset = 8;
+                two->offset = POINTER_SIZE;
             }
 
             return 1;
@@ -1145,16 +1145,16 @@ b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) {
             }
             if (idx == 1) {
                 two->type = &basic_types[Basic_Kind_U32];
-                two->offset = 8;
+                two->offset = POINTER_SIZE;
             }
             if (idx == 2) {
                 two->type = &basic_types[Basic_Kind_U32];
-                two->offset = 12;
+                two->offset = POINTER_SIZE + 4;
             }
             if (idx == 3 || idx == 4) {
                 Type* allocator_type = type_build_from_ast(context.ast_alloc, builtin_allocator_type);
                 type_linear_member_lookup(allocator_type, idx - 3, two);
-                two->offset += 16;
+                two->offset += POINTER_SIZE + 8;
             }
 
             return 1;
@@ -1181,15 +1181,15 @@ i32 type_get_idx_of_linear_member_with_offset(Type* type, u32 offset) {
         case Type_Kind_Slice:
         case Type_Kind_VarArgs: {
             if (offset == 0) return 0;
-            if (offset == 8) return 1;
+            if (offset == POINTER_SIZE) return 1;
             return -1;
         }
         case Type_Kind_DynArray: {
-            if (offset == 0)   return 0;
-            if (offset == 8)   return 1;
-            if (offset == 12)  return 2;
-            if (offset == 16)  return 3;
-            if (offset == 24)  return 4;
+            if (offset == 0)                    return 0;
+            if (offset == POINTER_SIZE)         return 1;
+            if (offset == POINTER_SIZE + 4)     return 2;
+            if (offset == POINTER_SIZE + 8)     return 3;
+            if (offset == POINTER_SIZE * 2 + 8) return 4;
             return -1;
         }
         case Type_Kind_Compound: {
index a624a9058e2e929c29191df0160e9a4c313cadcf..4f4988efd2c84331d84bfee8ecbdc1abafcb09b7 100644 (file)
@@ -1527,7 +1527,7 @@ EMIT_FUNC(call, AstCall* call) {
 
                 WIL(WI_LOCAL_GET, stack_top_store_local);
                 WID(WI_I32_CONST, vararg_any_types[i]);
-                emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Type_Index], vararg_offset + i * any_size + 8);
+                emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Type_Index], vararg_offset + i * any_size + POINTER_SIZE);
 
                 reserve_size += any_size;
             }
@@ -1554,11 +1554,11 @@ EMIT_FUNC(call, AstCall* call) {
             }
             emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Rawptr], reserve_size);
 
-            // NOTE: There will be 4 uninitialized bytes here, because pointers are only 4 bytes in WASM.
+            // NOTE: There may be 4 uninitialized bytes here, because pointers are only 4 bytes in WASM.
 
             WIL(WI_LOCAL_GET, stack_top_store_local);
             WID(WI_I32_CONST, vararg_count);
-            emit_store_instruction(mod, &code, &basic_types[Basic_Kind_I32], reserve_size + 8);
+            emit_store_instruction(mod, &code, &basic_types[Basic_Kind_I32], reserve_size + POINTER_SIZE);
 
             WIL(WI_LOCAL_GET, stack_top_store_local);
             if (reserve_size > 0) {
@@ -1566,7 +1566,7 @@ EMIT_FUNC(call, AstCall* call) {
                 WI(WI_PTR_ADD);
             }
 
-            reserve_size += 12;
+            reserve_size += 4 + POINTER_SIZE;
             break;
         }
     }
@@ -3478,9 +3478,15 @@ static b32 emit_raw_data_(OnyxWasmModule* mod, ptr data, AstTyped* node) {
         // NOTE: This assumes the address and the length fields have been filled out
         // by emit_string_literal.
         u32* sdata = (u32 *) data;
-        sdata[0] = sl->addr;
-        sdata[1] = 0x00;
-        sdata[2] = sl->length;
+        if (POINTER_SIZE == 4) {
+            sdata[0] = sl->addr;
+            sdata[1] = sl->length;
+        } else {
+            sdata[0] = sl->addr;
+            sdata[1] = 0;
+            sdata[2] = sl->length;
+            sdata[3] = 0;
+        }
         break;
     }
 
@@ -3534,12 +3540,12 @@ static b32 emit_raw_data_(OnyxWasmModule* mod, ptr data, AstTyped* node) {
 
         case Basic_Kind_I32:
         case Basic_Kind_U32:
+        case Basic_Kind_Rawptr:
             *((i32 *) data) = ((AstNumLit *) node)->value.i;
             return retval;
 
         case Basic_Kind_I64:
         case Basic_Kind_U64:
-        case Basic_Kind_Rawptr:
             *((i64 *) data) = ((AstNumLit *) node)->value.l;
             return retval;
 
index 2712843d0377a89a3313f25bfabd4df2cb9e6bb0..b858c0ccfb9f0102654a3575ac858dc36920ecc8 100644 (file)
@@ -8,11 +8,25 @@ u64 build_type_table(OnyxWasmModule* module) {
     bh_arr_new(global_heap_allocator, base_patch_locations, 256);
 
 #define PATCH (bh_arr_push(base_patch_locations, table_buffer.length))
+#define WRITE_PTR(val) \
+    bh_buffer_align(&table_buffer, POINTER_SIZE); \
+    PATCH; \
+    if (POINTER_SIZE == 4) bh_buffer_write_u32(&table_buffer, val); \
+    if (POINTER_SIZE == 8) bh_buffer_write_u64(&table_buffer, val); 
+#define WRITE_SLICE(ptr, count) \
+    WRITE_PTR(ptr); \
+    if (POINTER_SIZE == 4) bh_buffer_write_u32(&table_buffer, count); \
+    if (POINTER_SIZE == 8) bh_buffer_write_u64(&table_buffer, count); 
 
     // This is the data behind the "type_table" slice in type_info.onyx
+    #if (POINTER_SIZE == 4)
+        #define Table_Info_Type u32
+    #else
+        #define Table_Info_Type u64
+    #endif
     u32 type_count = bh_arr_length(type_map.entries) + 1;
-    u64* table_info = bh_alloc_array(global_heap_allocator, u64, type_count); // HACK
-    memset(table_info, 0, type_count * sizeof(u64));
+    Table_Info_Type* table_info = bh_alloc_array(global_heap_allocator, Table_Info_Type, type_count); // HACK
+    memset(table_info, 0, type_count * sizeof(Table_Info_Type));
 
     bh_buffer table_buffer;
     bh_buffer_init(&table_buffer, global_heap_allocator, 4096);
@@ -94,10 +108,7 @@ u64 build_type_table(OnyxWasmModule* module) {
                 bh_buffer_write_u32(&table_buffer, type->kind);
                 bh_buffer_write_u32(&table_buffer, type_size_of(type));
                 bh_buffer_write_u32(&table_buffer, type_alignment_of(type));
-                bh_buffer_align(&table_buffer, 8);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, components_base);
-                bh_buffer_write_u64(&table_buffer, components_count);
+                WRITE_SLICE(components_base, components_count);
                 break;
             }
 
@@ -116,9 +127,7 @@ u64 build_type_table(OnyxWasmModule* module) {
                 bh_buffer_write_u32(&table_buffer, type_alignment_of(type));
                 bh_buffer_write_u32(&table_buffer, type->Function.return_type->id);
 
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, parameters_base);
-                bh_buffer_write_u64(&table_buffer, parameters_count);
+                WRITE_SLICE(parameters_base, parameters_count);
 
                 bh_buffer_write_u32(&table_buffer, type->Function.vararg_arg_pos > 0 ? 1 : 0);
                 break;
@@ -143,9 +152,7 @@ u64 build_type_table(OnyxWasmModule* module) {
                     u32 name_loc = name_locations[i++];
 
                     bh_buffer_align(&table_buffer, 8);
-                    PATCH;
-                    bh_buffer_write_u64(&table_buffer, name_loc);
-                    bh_buffer_write_u64(&table_buffer, (*value)->token->length);
+                    WRITE_SLICE(name_loc, (*value)->token->length);
 
                     assert((*value)->value->kind == Ast_Kind_NumLit);
                     AstNumLit *num = (AstNumLit *) (*value)->value;
@@ -162,12 +169,8 @@ u64 build_type_table(OnyxWasmModule* module) {
                 bh_buffer_write_u32(&table_buffer, type_size_of(type));
                 bh_buffer_write_u32(&table_buffer, type_alignment_of(type));
                 bh_buffer_write_u32(&table_buffer, type->Enum.backing->id);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, name_base);
-                bh_buffer_write_u64(&table_buffer, name_length);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, member_base);
-                bh_buffer_write_u64(&table_buffer, member_count);
+                WRITE_SLICE(name_base, name_length);
+                WRITE_SLICE(member_base, member_count);
                 bh_buffer_write_u32(&table_buffer, type->Enum.is_flags ? 1 : 0);
                 break;
             }
@@ -300,9 +303,7 @@ u64 build_type_table(OnyxWasmModule* module) {
                     meta_locations[i] = table_buffer.length;
 
                     fori (k, 0, bh_arr_length(meta_tags)) {
-                        PATCH;
-                        bh_buffer_write_u64(&table_buffer, meta_tag_locations[k]);
-                        bh_buffer_write_u64(&table_buffer, meta_tags[k]->type->id);
+                        WRITE_SLICE(meta_tag_locations[k], meta_tags[k]->type->id);
                     }
 
                     bh_arr_free(meta_tag_locations);
@@ -320,21 +321,14 @@ u64 build_type_table(OnyxWasmModule* module) {
                     u32 value_loc = value_locations[i];
                     u32 meta_loc = meta_locations[i++];
 
-                    bh_buffer_align(&table_buffer, 8);
-                    PATCH;
-                    bh_buffer_write_u64(&table_buffer, name_loc);
-                    bh_buffer_write_u64(&table_buffer, strlen(mem->name));
+                    WRITE_SLICE(name_loc, strlen(mem->name));
                     bh_buffer_write_u32(&table_buffer, mem->offset);
                     bh_buffer_write_u32(&table_buffer, mem->type->id);
                     bh_buffer_write_byte(&table_buffer, mem->used ? 1 : 0);
                     
-                    bh_buffer_align(&table_buffer, 8);
-                    PATCH;
-                    bh_buffer_write_u64(&table_buffer, value_loc);
+                    WRITE_PTR(value_loc);
 
-                    PATCH;
-                    bh_buffer_write_u64(&table_buffer, meta_loc);
-                    bh_buffer_write_u64(&table_buffer, bh_arr_length(mem->meta_tags));
+                    WRITE_SLICE(meta_loc, bh_arr_length(mem->meta_tags));
                 }
 
                 bh_buffer_align(&table_buffer, 8);
@@ -342,9 +336,7 @@ u64 build_type_table(OnyxWasmModule* module) {
 
                 i = 0;
                 bh_arr_each(AstPolySolution, sln, s->poly_sln) {
-                    bh_buffer_align(&table_buffer, 8);
-                    PATCH;
-                    bh_buffer_write_u64(&table_buffer, param_locations[i++]);
+                    WRITE_PTR(param_locations[i++]);
 
                     if (sln->kind == PSK_Type) bh_buffer_write_u32(&table_buffer, basic_types[Basic_Kind_Type_Index].id);
                     else                       bh_buffer_write_u32(&table_buffer, sln->value->type->id);
@@ -373,9 +365,7 @@ u64 build_type_table(OnyxWasmModule* module) {
                 u32 struct_tag_base = table_buffer.length;
 
                 fori (i, 0, bh_arr_length(s->meta_tags)) {
-                    PATCH;
-                    bh_buffer_write_u64(&table_buffer, struct_tag_locations[i]);
-                    bh_buffer_write_u64(&table_buffer, s->meta_tags[i]->type->id);
+                    WRITE_SLICE(struct_tag_locations[i], s->meta_tags[i]->type->id);
                 }
 
                 u32 name_base = 0;
@@ -398,18 +388,10 @@ u64 build_type_table(OnyxWasmModule* module) {
                     bh_buffer_write_u32(&table_buffer, 0);
                 }
 
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, name_base);
-                bh_buffer_write_u64(&table_buffer, name_length);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, members_base);
-                bh_buffer_write_u64(&table_buffer, s->mem_count);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, params_base);
-                bh_buffer_write_u64(&table_buffer, bh_arr_length(s->poly_sln));
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, struct_tag_base);
-                bh_buffer_write_u64(&table_buffer, bh_arr_length(s->meta_tags));
+                WRITE_SLICE(name_base, name_length);
+                WRITE_SLICE(members_base, s->mem_count);
+                WRITE_SLICE(params_base, bh_arr_length(s->poly_sln));
+                WRITE_SLICE(struct_tag_base, bh_arr_length(s->meta_tags));
 
                 break;
             }
@@ -446,9 +428,7 @@ u64 build_type_table(OnyxWasmModule* module) {
                 u32 tags_count = bh_arr_length(type->PolyStruct.meta_tags);
 
                 fori (i, 0, tags_count) {
-                    PATCH;
-                    bh_buffer_write_u64(&table_buffer, tag_locations[i]);
-                    bh_buffer_write_u64(&table_buffer, type->PolyStruct.meta_tags[i]->type->id);
+                    WRITE_SLICE(tag_locations[i], type->PolyStruct.meta_tags[i]->type->id);
                 }
 
                 bh_buffer_align(&table_buffer, 8);
@@ -456,13 +436,8 @@ u64 build_type_table(OnyxWasmModule* module) {
                 bh_buffer_write_u32(&table_buffer, type->kind);
                 bh_buffer_write_u32(&table_buffer, 0);
                 bh_buffer_write_u32(&table_buffer, 0);
-                bh_buffer_write_u32(&table_buffer, 0);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, name_base);
-                bh_buffer_write_u64(&table_buffer, name_length);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, tags_base);
-                bh_buffer_write_u64(&table_buffer, tags_count);
+                WRITE_SLICE(name_base, name_length);
+                WRITE_SLICE(tags_base, tags_count);
 
                 break;
             }
@@ -478,9 +453,7 @@ u64 build_type_table(OnyxWasmModule* module) {
                 bh_buffer_write_u32(&table_buffer, type_size_of(type));
                 bh_buffer_write_u32(&table_buffer, type_alignment_of(type));
                 bh_buffer_write_u32(&table_buffer, type->Distinct.base_type->id);
-                PATCH;
-                bh_buffer_write_u64(&table_buffer, name_base);
-                bh_buffer_write_u64(&table_buffer, name_length);
+                WRITE_SLICE(name_base, name_length);
                 break;
             }
         }
@@ -497,7 +470,7 @@ u64 build_type_table(OnyxWasmModule* module) {
 
     WasmDatum type_table_data = {
         .offset = offset,
-        .length = type_count * 8,
+        .length = type_count * POINTER_SIZE,
         .data = table_info,
     };
     bh_arr_push(module->data, type_table_data);
@@ -509,10 +482,18 @@ u64 build_type_table(OnyxWasmModule* module) {
     }
 
     bh_arr_each(u32, patch_loc, base_patch_locations) {
-        u64* loc = bh_pointer_add(table_buffer.data, *patch_loc);
-        if (*loc == 0) continue;
-        
-        *loc += offset;
+        if (POINTER_SIZE == 4) {
+            u32* loc = bh_pointer_add(table_buffer.data, *patch_loc);
+            if (*loc == 0) continue;
+            
+            *loc += offset;
+        }
+        if (POINTER_SIZE == 8) {
+            u64* loc = bh_pointer_add(table_buffer.data, *patch_loc);
+            if (*loc == 0) continue;
+            
+            *loc += offset;
+        }
     }
 
     WasmDatum type_info_data = {
@@ -525,12 +506,12 @@ u64 build_type_table(OnyxWasmModule* module) {
 
     u64 global_data_ptr = offset;
 
-    u64* tmp_data = bh_alloc(global_heap_allocator, 16);
+    Table_Info_Type* tmp_data = bh_alloc(global_heap_allocator, 2 * POINTER_SIZE);
     tmp_data[0] = type_table_location;
     tmp_data[1] = type_count;
     WasmDatum type_table_global_data = {
         .offset = offset,
-        .length = 16,
+        .length = 2 * POINTER_SIZE,
         .data = tmp_data,
     };
     bh_arr_push(module->data, type_table_global_data);
index 894dcadb46f94097ee243645c6ab267946ff8e1a..87e08b79b8767572bc9a86f4763dc0398904d05f 100644 (file)
@@ -1,5 +1,5 @@
 Testing a simple structure.
-SimpleStruct<24, 8>(41, 67, Steve)
+SimpleStruct<16, 4>(41, 67, Steve)
 
 
 Testing a simple union.
@@ -36,5 +36,5 @@ PolyUnion(1234)
 
 
 Testing a polymorphic union with use.
-16 == 16
+8 == 16
 0, 5678.0000