Skip to content

Commit

Permalink
Fix a few more bugs preventing the compiler from compiling itself!
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed May 5, 2024
1 parent af2c39b commit bed2b9e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
50 changes: 42 additions & 8 deletions src/compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ export type State = struct {
return_address: Value // This is used as the return address in inline functions
return_br: &Insn // This is used to jump back to the end of the function
inline_start_block: &Block // This represents the first block of the current function
context_ptr: int // Counts up the current free_context
}

export def destruct(state: *State) {
Expand Down Expand Up @@ -1544,7 +1545,7 @@ def convert_ref_to_ptr(tpe: &typechecking::Type, value: Value, loc: &Value, stat

// Reference metadata struct
var _ref_meta: &typechecking::Type
def ref_meta -> &typechecking::Type {
export def ref_meta -> &typechecking::Type {
if not _ref_meta {
_ref_meta = typechecking::make_struct_type([
[ tpe = builtins::int64_, name = "refcount" ] !typechecking::StructMember,
Expand Down Expand Up @@ -3616,9 +3617,13 @@ def copy_reference(value: Value, loc: &Value, state: &State) -> Value {
let size = [ kind = ValueKind::INT, tpe = builtins::int64_, i = value.tpe.tpe.size ] !Value
let size_int64 = [ kind = ValueKind::INT, tpe = builtins::int64_, i = builtins::int64_.size ] !Value

let ref_count_ptr_i8 = state.call("malloc", pointer(builtins::int8_), [size_int64], loc)
let ref_count_ptr = state.bitcast(pointer(builtins::int64_), ref_count_ptr_i8)
state.store(ref_count_ptr, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)
let ref_count_i8 = state.call("malloc", pointer(builtins::int8_), [[ kind = ValueKind::INT, tpe = builtins::size_t_, i = ref_meta().size ] !Value])
let ref_count = state.bitcast(pointer(ref_meta()), ref_count_i8)
state.store(ref_count, [ kind = ValueKind::STRUCT, tpe = ref_meta(), values = [
[kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value,
[kind = ValueKind::INT, tpe = builtins::int64_, i = 1 ] !Value
]] !Value)

let value_ptr = state.extract_value(pointer(value.tpe.tpe), value, [1], loc)
let type_ptr = state.extract_value(pointer(builtins::Type_), value, [2], loc)

Expand All @@ -3628,7 +3633,7 @@ def copy_reference(value: Value, loc: &Value, state: &State) -> Value {
let copy_ptr = state.bitcast(pointer(value.tpe.tpe), copy_ptr_i8, loc)

var ret = [ kind = ValueKind::UNDEF, tpe = value.tpe ] !Value
ret = state.insert_value(value.tpe, ret, ref_count_ptr, [0], loc)
ret = state.insert_value(value.tpe, ret, ref_count_i8, [0], loc)
ret = state.insert_value(value.tpe, ret, copy_ptr, [1], loc)
ret = state.insert_value(value.tpe, ret, type_ptr, [2], loc)

Expand Down Expand Up @@ -7653,9 +7658,10 @@ export def create_function(

let parameter_t2 = vector::make(typechecking::NamedParameter)
parameter_t2.push([ name = "__context", _tpe = typechecking::pointer(null) ] !typechecking::NamedParameter)
let free_context_tpe = typechecking::make_function_type_n(parser::make_identifier(tpe.name + ".free_context"),
free_context_parameters, vector::make(type &typechecking::Type), state.module, context = state.module
let free_context_tpe = typechecking::make_function_type_n(parser::make_identifier(tpe.name + ".free_context." + state.context_ptr),
free_context_parameters, vector::make(type &typechecking::Type), state.module, context = function.module
)
state.context_ptr += 1

let free_context = predeclare_function(free_context_tpe, state.module)
free_context.is_compiled = true
Expand Down Expand Up @@ -8296,11 +8302,24 @@ def create_destructor(tpe: &typechecking::Type, value: Value, state: &State) {
var ref: Value
var ref_count: Value
var null_br: &Insn, br: &Insn
var br1: &Insn

if typechecking::is_ref(tpe.tpe) and tpe.tpe.tpe and not is_interface(tpe.tpe.tpe) {
// Decrease ref count
ref = state.load(tpe.tpe, value)
ref_count = state.extract_value(pointer(ref_meta()), ref, [0])
let ref_count_value1 = state.ptr_to_int(ref_count)

let isnull = state.icmp(CompareInt::eq, ref_count_value1,
[ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)

br1 = make_insn(InsnKind::BR)
br1.value.br = [ cond = isnull ] !InsnBr
push_insn(br1, state)
let nonnull = make_label(state)
push_label(nonnull, state)
br1.value.br.if_false = nonnull

let ref_count_ptr = state.gep(pointer(builtins::int64_), ref_meta(), ref_count, [make_int_value(0), make_int_value(0)])
let ref_count_value = state.ptr_to_int(ref_count_ptr)
let null_cond = state.icmp(CompareInt::eq, ref_count_value, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)
Expand Down Expand Up @@ -8393,7 +8412,7 @@ def create_destructor(tpe: &typechecking::Type, value: Value, state: &State) {
let ref = state.load(tpe.tpe, value)

// Extract type
let ref_count = state.extract_value(pointer(builtins::int64_), ref, [0])
let ref_count = get_ref_count_ptr(ref, null, state)
let ref_count_value = state.ptr_to_int(ref_count)
let cond = state.icmp(CompareInt::eq, ref_count_value, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)
null_br2 = make_insn(InsnKind::BR)
Expand Down Expand Up @@ -8484,6 +8503,18 @@ def create_destructor(tpe: &typechecking::Type, value: Value, state: &State) {
state.call(fun.type_name, null, [convert_ref_to_ref(builtins::Ref_, ref, null, state)])
}

let ref_count_value1 = state.ptr_to_int(ref_count)

let isnull = state.icmp(CompareInt::eq, ref_count_value1,
[ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)

let br2 = make_insn(InsnKind::BR)
br2.value.br = [ cond = isnull ] !InsnBr
push_insn(br2, state)
let nonnull = make_label(state)
push_label(nonnull, state)
br2.value.br.if_false = nonnull

let cnt = get_weak_count_ptr(ref, null, state)
var cnt_value = state.load(builtins::int64_, cnt)
cnt_value = state.sub(builtins::int64_, cnt_value, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 1 ] !Value)
Expand All @@ -8510,6 +8541,9 @@ def create_destructor(tpe: &typechecking::Type, value: Value, state: &State) {
to_end.value.br_unc.label_ = end_label
br.value.br.if_false = end_label
null_br.value.br.if_true = end_label
br1.value.br.if_true = end_label
br2.value.br.if_true = end_label

push_label(end_label, state)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/repl.pr
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def execute(source: Str) {

stack_frame = eval::make_stack_frame(main_function.block, "main", 1)

let mem = allocate(size_of type *) !**
let mem = allocate(16) !** // FIXME What are we doing here???
@mem = (*_args) !*
stack_frame.locals("args.value") = mem

Expand Down
7 changes: 6 additions & 1 deletion src/runtime.pr
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,13 @@ export type Field = struct {
tpe: *Type
}

export type Refcount = struct {
strong_cnt: int64
weak_cnt: int64
}

export type Ref = struct {
ref_count: *int64
ref_count: *Refcount
value: *
tpe: *Type
}
Expand Down

0 comments on commit bed2b9e

Please sign in to comment.