#include "bh.h"
+#define POINTER_SIZE 4
+
enum BasicKind {
Basic_Kind_Void,
{ 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" } },
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;
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;
} 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);
}
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) {
}
if (idx == 1) {
two->type = &basic_types[Basic_Kind_U32];
- two->offset = 8;
+ two->offset = POINTER_SIZE;
}
return 1;
}
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;
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: {
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;
}
}
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) {
WI(WI_PTR_ADD);
}
- reserve_size += 12;
+ reserve_size += 4 + POINTER_SIZE;
break;
}
}
// 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;
}
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;
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);
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;
}
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;
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;
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;
}
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);
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);
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);
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;
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;
}
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);
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;
}
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;
}
}
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);
}
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 = {
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);
Testing a simple structure.
-SimpleStruct<24, 8>(41, 67, Steve)
+SimpleStruct<16, 4>(41, 67, Steve)
Testing a simple union.
Testing a polymorphic union with use.
-16 == 16
+8 == 16
0, 5678.0000