mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-29 10:50:05 +00:00
Remove #relative slices; Replace with #relative multi-pointers
This commit is contained in:
+85
-118
@@ -349,9 +349,10 @@ gb_internal lbAddr lb_addr(lbValue addr) {
|
||||
if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) {
|
||||
GB_ASSERT(is_type_pointer(addr.type));
|
||||
v.kind = lbAddr_RelativePointer;
|
||||
} else if (addr.type != nullptr && is_type_relative_slice(type_deref(addr.type))) {
|
||||
GB_ASSERT(is_type_pointer(addr.type));
|
||||
v.kind = lbAddr_RelativeSlice;
|
||||
} else if (addr.type != nullptr && is_type_relative_multi_pointer(type_deref(addr.type))) {
|
||||
GB_ASSERT(is_type_pointer(addr.type) ||
|
||||
is_type_multi_pointer(addr.type));
|
||||
v.kind = lbAddr_RelativePointer;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
@@ -424,6 +425,43 @@ gb_internal Type *lb_addr_type(lbAddr const &addr) {
|
||||
return type_deref(addr.addr.type);
|
||||
}
|
||||
|
||||
|
||||
gb_internal lbValue lb_relative_pointer_to_pointer(lbProcedure *p, lbAddr const &addr) {
|
||||
GB_ASSERT(addr.kind == lbAddr_RelativePointer);
|
||||
|
||||
Type *t = base_type(lb_addr_type(addr));
|
||||
GB_ASSERT(is_type_relative_pointer(t) || is_type_relative_multi_pointer(t));
|
||||
|
||||
Type *pointer_type = nullptr;
|
||||
Type *base_integer = nullptr;
|
||||
if (t->kind == Type_RelativePointer) {
|
||||
pointer_type = t->RelativePointer.pointer_type;
|
||||
base_integer = t->RelativePointer.base_integer;
|
||||
} else if (t->kind == Type_RelativeMultiPointer) {
|
||||
pointer_type = t->RelativeMultiPointer.pointer_type;
|
||||
base_integer = t->RelativeMultiPointer.base_integer;
|
||||
}
|
||||
|
||||
lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
||||
lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(base_integer));
|
||||
offset = lb_emit_load(p, offset);
|
||||
|
||||
if (!is_type_unsigned(base_integer)) {
|
||||
offset = lb_emit_conv(p, offset, t_i64);
|
||||
}
|
||||
offset = lb_emit_conv(p, offset, t_uintptr);
|
||||
lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
||||
absolute_ptr = lb_emit_conv(p, absolute_ptr, pointer_type);
|
||||
|
||||
lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, base_integer));
|
||||
|
||||
// NOTE(bill): nil check
|
||||
lbValue nil_ptr = lb_const_nil(p->module, pointer_type);
|
||||
lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr);
|
||||
return final_ptr;
|
||||
}
|
||||
|
||||
|
||||
gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
||||
if (addr.addr.value == nullptr) {
|
||||
GB_PANIC("Illegal addr -> nullptr");
|
||||
@@ -434,28 +472,8 @@ gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
||||
case lbAddr_Map:
|
||||
return lb_internal_dynamic_map_get_ptr(p, addr.addr, addr.map.key);
|
||||
|
||||
case lbAddr_RelativePointer: {
|
||||
Type *rel_ptr = base_type(lb_addr_type(addr));
|
||||
GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
||||
|
||||
lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
||||
lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
||||
offset = lb_emit_load(p, offset);
|
||||
|
||||
if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
||||
offset = lb_emit_conv(p, offset, t_i64);
|
||||
}
|
||||
offset = lb_emit_conv(p, offset, t_uintptr);
|
||||
lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
||||
absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
|
||||
|
||||
lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer));
|
||||
|
||||
// NOTE(bill): nil check
|
||||
lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type);
|
||||
lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr);
|
||||
return final_ptr;
|
||||
}
|
||||
case lbAddr_RelativePointer:
|
||||
return lb_relative_pointer_to_pointer(p, addr);
|
||||
|
||||
case lbAddr_SoaVariable:
|
||||
// TODO(bill): FIX THIS HACK
|
||||
@@ -477,6 +495,9 @@ gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
||||
|
||||
gb_internal lbValue lb_build_addr_ptr(lbProcedure *p, Ast *expr) {
|
||||
lbAddr addr = lb_build_addr(p, expr);
|
||||
if (addr.kind == lbAddr_RelativePointer) {
|
||||
return addr.addr;
|
||||
}
|
||||
return lb_addr_get_ptr(p, addr);
|
||||
}
|
||||
|
||||
@@ -685,9 +706,20 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
||||
|
||||
if (addr.kind == lbAddr_RelativePointer) {
|
||||
Type *rel_ptr = base_type(lb_addr_type(addr));
|
||||
GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
||||
GB_ASSERT(rel_ptr->kind == Type_RelativePointer ||
|
||||
rel_ptr->kind == Type_RelativeMultiPointer);
|
||||
Type *pointer_type = nullptr;
|
||||
Type *base_integer = nullptr;
|
||||
|
||||
value = lb_emit_conv(p, value, rel_ptr->RelativePointer.pointer_type);
|
||||
if (rel_ptr->kind == Type_RelativePointer) {
|
||||
pointer_type = rel_ptr->RelativePointer.pointer_type;
|
||||
base_integer = rel_ptr->RelativePointer.base_integer;
|
||||
} else if (rel_ptr->kind == Type_RelativeMultiPointer) {
|
||||
pointer_type = rel_ptr->RelativeMultiPointer.pointer_type;
|
||||
base_integer = rel_ptr->RelativeMultiPointer.base_integer;
|
||||
}
|
||||
|
||||
value = lb_emit_conv(p, value, pointer_type);
|
||||
|
||||
GB_ASSERT(is_type_pointer(addr.addr.type));
|
||||
lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
||||
@@ -696,54 +728,20 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
||||
offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, "");
|
||||
offset.type = t_uintptr;
|
||||
|
||||
if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
||||
if (!is_type_unsigned(base_integer)) {
|
||||
offset = lb_emit_conv(p, offset, t_i64);
|
||||
}
|
||||
offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer);
|
||||
offset = lb_emit_conv(p, offset, base_integer);
|
||||
|
||||
lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
||||
lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(base_integer));
|
||||
offset = lb_emit_select(p,
|
||||
lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)),
|
||||
lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer),
|
||||
lb_const_nil(p->module, base_integer),
|
||||
offset
|
||||
);
|
||||
LLVMBuildStore(p->builder, offset.value, offset_ptr.value);
|
||||
return;
|
||||
|
||||
} else if (addr.kind == lbAddr_RelativeSlice) {
|
||||
Type *rel_ptr = base_type(lb_addr_type(addr));
|
||||
GB_ASSERT(rel_ptr->kind == Type_RelativeSlice);
|
||||
|
||||
value = lb_emit_conv(p, value, rel_ptr->RelativeSlice.slice_type);
|
||||
|
||||
GB_ASSERT(is_type_pointer(addr.addr.type));
|
||||
lbValue ptr = lb_emit_conv(p, lb_emit_struct_ep(p, addr.addr, 0), t_uintptr);
|
||||
lbValue val_ptr = lb_emit_conv(p, lb_slice_elem(p, value), t_uintptr);
|
||||
lbValue offset = {};
|
||||
offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, "");
|
||||
offset.type = t_uintptr;
|
||||
|
||||
if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
||||
offset = lb_emit_conv(p, offset, t_i64);
|
||||
}
|
||||
offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer);
|
||||
|
||||
|
||||
lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
||||
offset = lb_emit_select(p,
|
||||
lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)),
|
||||
lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer),
|
||||
offset
|
||||
);
|
||||
LLVMBuildStore(p->builder, offset.value, offset_ptr.value);
|
||||
|
||||
lbValue len = lb_slice_len(p, value);
|
||||
len = lb_emit_conv(p, len, rel_ptr->RelativePointer.base_integer);
|
||||
|
||||
lbValue len_ptr = lb_emit_struct_ep(p, addr.addr, 1);
|
||||
LLVMBuildStore(p->builder, len.value, len_ptr.value);
|
||||
|
||||
return;
|
||||
} else if (addr.kind == lbAddr_Map) {
|
||||
lb_internal_dynamic_map_set(p, addr.addr, addr.map.type, addr.map.key, value, p->curr_stmt);
|
||||
return;
|
||||
@@ -1020,67 +1018,43 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
|
||||
|
||||
if (addr.kind == lbAddr_RelativePointer) {
|
||||
Type *rel_ptr = base_type(lb_addr_type(addr));
|
||||
GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
||||
Type *base_integer = nullptr;
|
||||
Type *pointer_type = nullptr;
|
||||
GB_ASSERT(rel_ptr->kind == Type_RelativePointer ||
|
||||
rel_ptr->kind == Type_RelativeMultiPointer);
|
||||
|
||||
if (rel_ptr->kind == Type_RelativePointer) {
|
||||
base_integer = rel_ptr->RelativePointer.base_integer;
|
||||
pointer_type = rel_ptr->RelativePointer.pointer_type;
|
||||
} else if (rel_ptr->kind == Type_RelativeMultiPointer) {
|
||||
base_integer = rel_ptr->RelativeMultiPointer.base_integer;
|
||||
pointer_type = rel_ptr->RelativeMultiPointer.pointer_type;
|
||||
}
|
||||
|
||||
lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
||||
lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
||||
lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(base_integer));
|
||||
offset = lb_emit_load(p, offset);
|
||||
|
||||
|
||||
if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
||||
if (!is_type_unsigned(base_integer)) {
|
||||
offset = lb_emit_conv(p, offset, t_i64);
|
||||
}
|
||||
offset = lb_emit_conv(p, offset, t_uintptr);
|
||||
lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
||||
absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
|
||||
absolute_ptr = lb_emit_conv(p, absolute_ptr, pointer_type);
|
||||
|
||||
lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer));
|
||||
lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, base_integer));
|
||||
|
||||
// NOTE(bill): nil check
|
||||
lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type);
|
||||
lbValue nil_ptr = lb_const_nil(p->module, pointer_type);
|
||||
lbValue final_ptr = {};
|
||||
final_ptr.type = absolute_ptr.type;
|
||||
final_ptr.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, "");
|
||||
|
||||
return lb_emit_load(p, final_ptr);
|
||||
|
||||
} else if (addr.kind == lbAddr_RelativeSlice) {
|
||||
Type *rel_ptr = base_type(lb_addr_type(addr));
|
||||
GB_ASSERT(rel_ptr->kind == Type_RelativeSlice);
|
||||
|
||||
lbValue offset_ptr = lb_emit_struct_ep(p, addr.addr, 0);
|
||||
lbValue ptr = lb_emit_conv(p, offset_ptr, t_uintptr);
|
||||
lbValue offset = lb_emit_load(p, offset_ptr);
|
||||
|
||||
|
||||
if (!is_type_unsigned(rel_ptr->RelativeSlice.base_integer)) {
|
||||
offset = lb_emit_conv(p, offset, t_i64);
|
||||
if (rel_ptr->kind == Type_RelativeMultiPointer) {
|
||||
return final_ptr;
|
||||
}
|
||||
offset = lb_emit_conv(p, offset, t_uintptr);
|
||||
lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
||||
|
||||
Type *slice_type = base_type(rel_ptr->RelativeSlice.slice_type);
|
||||
GB_ASSERT(rel_ptr->RelativeSlice.slice_type->kind == Type_Slice);
|
||||
Type *slice_elem = slice_type->Slice.elem;
|
||||
Type *slice_elem_ptr = alloc_type_pointer(slice_elem);
|
||||
|
||||
absolute_ptr = lb_emit_conv(p, absolute_ptr, slice_elem_ptr);
|
||||
|
||||
lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativeSlice.base_integer));
|
||||
|
||||
// NOTE(bill): nil check
|
||||
lbValue nil_ptr = lb_const_nil(p->module, slice_elem_ptr);
|
||||
lbValue data = {};
|
||||
data.type = absolute_ptr.type;
|
||||
data.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, "");
|
||||
|
||||
lbValue len = lb_emit_load(p, lb_emit_struct_ep(p, addr.addr, 1));
|
||||
len = lb_emit_conv(p, len, t_int);
|
||||
|
||||
lbAddr slice = lb_add_local_generated(p, slice_type, false);
|
||||
lb_fill_slice(p, slice, data, len);
|
||||
return lb_addr_load(p, slice);
|
||||
|
||||
return lb_emit_load(p, final_ptr);
|
||||
|
||||
} else if (addr.kind == lbAddr_Map) {
|
||||
Type *map_type = base_type(type_deref(addr.addr.type));
|
||||
@@ -2139,17 +2113,10 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
|
||||
case Type_RelativePointer:
|
||||
return lb_type_internal(m, type->RelativePointer.base_integer);
|
||||
case Type_RelativeMultiPointer:
|
||||
return lb_type_internal(m, type->RelativeMultiPointer.base_integer);
|
||||
|
||||
case Type_RelativeSlice:
|
||||
{
|
||||
LLVMTypeRef base_integer = lb_type_internal(m, type->RelativeSlice.base_integer);
|
||||
|
||||
unsigned field_count = 2;
|
||||
LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
|
||||
fields[0] = base_integer;
|
||||
fields[1] = base_integer;
|
||||
return LLVMStructTypeInContext(ctx, fields, field_count, false);
|
||||
}
|
||||
|
||||
case Type_Matrix:
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user