Skip to content

Commit

Permalink
Fix lambda ref count initializer
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed May 5, 2024
1 parent cf0b819 commit 9ac047b
Showing 1 changed file with 32 additions and 23 deletions.
55 changes: 32 additions & 23 deletions src/compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ def convert_ref_to_ref(tpe: &typechecking::Type, value: Value, loc: &Value, stat

add_type_meta(tpe, state)

let extract1_ret = state.extract_value(pointer(ref_meta), value, [0], loc)
let extract1_ret = state.extract_value(pointer(ref_meta()), value, [0], loc)
let extract2_ret = state.extract_value(pointer(value.tpe.tpe), value, [1], loc)
let extract3_ret = state.extract_value(pointer(builtins::Type_), value, [2], loc)
let bitcast_ret = state.bitcast(pointer(tpe.tpe if tpe.tpe else builtins::int8_), extract2_ret, loc)
Expand All @@ -1439,7 +1439,7 @@ def convert_ref_to_ref(tpe: &typechecking::Type, value: Value, loc: &Value, stat
push_label(nonnull, state)
br1.value.br.if_false = nonnull

let meta = state.load(ref_meta, extract1_ret, loc)
let meta = state.load(ref_meta(), extract1_ret, loc)
let refcount = state.extract_value(builtins::int64_, meta, [0], loc)
let iszero = state.icmp(CompareInt::sle, refcount,
[ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value, loc)
Expand Down Expand Up @@ -1488,7 +1488,7 @@ def convert_ref_to_ref(tpe: &typechecking::Type, value: Value, loc: &Value, stat

def convert_ref_to_ptr(tpe: &typechecking::Type, value: Value, loc: &Value, state: &State) -> Value {
if is_weak_ref(value.tpe) {
let meta = state.extract_value(pointer(ref_meta), value, [0], loc)
let meta = state.extract_value(pointer(ref_meta()), value, [0], loc)

let ref_value = state.ptr_to_int(meta, loc)
let isnull = state.icmp(CompareInt::eq, ref_value,
Expand All @@ -1501,7 +1501,7 @@ def convert_ref_to_ptr(tpe: &typechecking::Type, value: Value, loc: &Value, stat
push_label(nonnull, state)
br1.value.br.if_false = nonnull

let meta_val = state.load(ref_meta, meta, loc)
let meta_val = state.load(ref_meta(), meta, loc)
let cnt = state.extract_value(builtins::int64_, meta_val, [0], loc)
let iszero = state.icmp(CompareInt::sle, cnt, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)
let res = state.alloca(pointer(tpe.tpe), loc)
Expand Down Expand Up @@ -1543,10 +1543,16 @@ def convert_ref_to_ptr(tpe: &typechecking::Type, value: Value, loc: &Value, stat
}

// Reference metadata struct
let ref_meta = typechecking::make_struct_type([
[ tpe = builtins::int64_, name = "refcount" ] !typechecking::StructMember,
[ tpe = builtins::int64_, name = "weakcount" ] !typechecking::StructMember
])
var _ref_meta: &typechecking::Type
def ref_meta -> &typechecking::Type {
if not _ref_meta {
_ref_meta = typechecking::make_struct_type([
[ tpe = builtins::int64_, name = "refcount" ] !typechecking::StructMember,
[ tpe = builtins::int64_, name = "weakcount" ] !typechecking::StructMember
])
}
return _ref_meta
}

def convert_value_to_ref(tpe: &typechecking::Type, value: Value, loc: &Value, state: &State, initial_ref_count: size_t = 0) -> Value {
if tpe.tpe and value.tpe.kind != tpe.tpe.kind {
Expand All @@ -1570,11 +1576,11 @@ def convert_value_to_ref(tpe: &typechecking::Type, value: Value, loc: &Value, st
if not is_null {
// create ref counts
let args1 = allocate_ref(Value, 1)
args1(0) = [ kind = ValueKind::INT, tpe = builtins::int64_, i = ref_meta.size] !Value
args1(0) = [ kind = ValueKind::INT, tpe = builtins::int64_, i = ref_meta().size] !Value
var call1_ret = state.call("malloc", pointer(builtins::int8_), args1, loc)
call1_ret = state.bitcast(pointer(ref_meta), call1_ret, loc)
refcount = state.gep(pointer(builtins::int64_), ref_meta, call1_ret, [make_int_value(0), make_int_value(0)], loc)
let weakcount = state.gep(pointer(builtins::int64_), ref_meta, call1_ret, [make_int_value(0), make_int_value(1)], loc)
call1_ret = state.bitcast(pointer(ref_meta()), call1_ret, loc)
refcount = state.gep(pointer(builtins::int64_), ref_meta(), call1_ret, [make_int_value(0), make_int_value(0)], loc)
let weakcount = state.gep(pointer(builtins::int64_), ref_meta(), call1_ret, [make_int_value(0), make_int_value(1)], loc)
state.store(refcount, [ kind = ValueKind::INT, tpe = builtins::int64_, i = initial_ref_count ] !Value)
state.store(weakcount, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 1 ] !Value)
}
Expand Down Expand Up @@ -3449,7 +3455,7 @@ def insert_destructors(scpe: &scope::Scope, loc: &Value, state: &State) {
def check_clear_ref_meta(meta_ptr: Value, loc: &Value, state: &State) {
import_cstd_function("free", state)

let meta = state.load(ref_meta, meta_ptr, loc)
let meta = state.load(ref_meta(), meta_ptr, loc)
let cnt = state.extract_value(builtins::int64_, meta, [1], loc)
let cond = state.icmp(CompareInt::sle, cnt, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)

Expand Down Expand Up @@ -3477,7 +3483,7 @@ def insert_destructor(value: Value, loc: &Value, state: &State) {
if is_weak_ref(value.tpe.tpe) {
// value refers to an address so we gotta load it first
value = state.load(value.tpe.tpe, value, loc)
let meta = state.extract_value(pointer(ref_meta), value, [0], loc)
let meta = state.extract_value(pointer(ref_meta()), value, [0], loc)
let ptr_addr = state.ptr_to_int(meta, loc)
let cond = state.icmp(CompareInt::eq, ptr_addr, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)

Expand Down Expand Up @@ -3562,7 +3568,7 @@ def insert_destructor(value: Value, loc: &Value, state: &State) {

def increase_ref_count_of_value(value: Value, loc: &Value, state: &State) {
if not is_ref_or_weak(value.tpe) { return }
let meta = state.extract_value(pointer(ref_meta), value, [0], loc)
let meta = state.extract_value(pointer(ref_meta()), value, [0], loc)

let ptr_addr = state.ptr_to_int(meta, loc)
let cond = state.icmp(CompareInt::eq, ptr_addr, [ kind = ValueKind::INT, tpe = builtins::int64_, i = 0 ] !Value)
Expand Down Expand Up @@ -5874,9 +5880,12 @@ def create_closure_context(function: &Function, ret: Value, loc: &Value, state:
let context_tpe = function.state

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

let context_tpe_value = do_create_type(reference(context_tpe), state.module)

Expand Down Expand Up @@ -8227,12 +8236,12 @@ export def create_destructor(tpe: &typechecking::Type) {
}

def get_ref_count_ptr(value: Value, loc: &Value, state: &State) -> Value {
let meta = state.extract_value(pointer(ref_meta), value, [0], loc)
return state.gep(pointer(builtins::int64_), ref_meta, meta, [make_int_value(0), make_int_value(0)], loc)
let meta = state.extract_value(pointer(ref_meta()), value, [0], loc)
return state.gep(pointer(builtins::int64_), ref_meta(), meta, [make_int_value(0), make_int_value(0)], loc)
}
def get_weak_count_ptr(value: Value, loc: &Value, state: &State) -> Value {
let meta = state.extract_value(pointer(ref_meta), value, [0], loc)
return state.gep(pointer(builtins::int64_), ref_meta, meta, [make_int_value(0), make_int_value(1)], loc)
let meta = state.extract_value(pointer(ref_meta()), value, [0], loc)
return state.gep(pointer(builtins::int64_), ref_meta(), meta, [make_int_value(0), make_int_value(1)], loc)
}

def create_destructor(tpe: &typechecking::Type, value: Value, state: &State) {
Expand Down Expand Up @@ -8290,8 +8299,8 @@ def create_destructor(tpe: &typechecking::Type, value: Value, state: &State) {
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_ptr = state.gep(pointer(builtins::int64_), ref_meta, ref_count, [make_int_value(0), make_int_value(0)])
ref_count = state.extract_value(pointer(ref_meta()), ref, [0])
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)
null_br = make_insn(InsnKind::BR)
Expand Down

0 comments on commit 9ac047b

Please sign in to comment.