Skip to content

Commit

Permalink
Fix memory leak
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Mar 14, 2024
1 parent 6b5b925 commit 6631faf
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 45 deletions.
2 changes: 2 additions & 0 deletions src/codegen.pr
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ def type_to_str(tpe: &typechecking::Type) -> Str {
ret = "%\"" + tpe.type_name + '"'
case typechecking::TypeKind::INTERFACE_IMPL
ret = type_to_str(tpe.tpe)
case typechecking::TypeKind::TO_INFER
ret = "<?>"
case
error(debug::type_to_str(tpe), " ", typechecking::is_polymorph(tpe), "\n")
error(tpe.kind, "\n")
Expand Down
18 changes: 15 additions & 3 deletions src/compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -5791,13 +5791,17 @@ def walk_Lambda(node: &parser::Node, state: &State) -> Value {
let ret = state.alloca(node.value.lambda.closure_type, loc)

typechecking::create_type_entry(typechecking::reference(context_tpe))
let context_ptr = create_closure_context(function, ret, loc, state)
let context_ptr = create_closure_context(function, ret, loc, state, insert_temporary = true)

predeclare_function(function)
create_function(node, function.tpe, node.value.lambda.body, node.inner_scope, null, state, is_closure = true, params = node.value.lambda.parameters)
state.module.imported.add(node.tpe.type_name)

let context = create_closure_context_captures(function, loc, state)
let context = create_closure_context_captures(function, loc, state)
state.store(context_ptr, context, loc)

push_local_var(context_tpe.type_name, reference(context_tpe), state.current_function)

return state.load(node.value.lambda.closure_type, ret, loc)
}

Expand Down Expand Up @@ -5844,7 +5848,7 @@ def walk_Def(node: &parser::Node, state: &State) {
push_local_var(context_tpe.type_name, reference(context_tpe), state.current_function)
}

def create_closure_context(function: &Function, ret: Value, loc: &Value, state: &State) -> Value {
def create_closure_context(function: &Function, ret: Value, loc: &Value, state: &State, insert_temporary: bool = false) -> Value {
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)
Expand All @@ -5864,6 +5868,12 @@ def create_closure_context(function: &Function, ret: Value, loc: &Value, state:
let context_ref_ptr = state.gep(pointer(typechecking::reference(null)), ret.tpe.tpe, ret, [make_int_value(0), make_int_value(1)], loc)
state.store(context_ref_ptr, closure, loc)

if insert_temporary {
let ctx = state.alloca(typechecking::reference(null), loc)
state.store(ctx, closure, loc)
create_temporary(ctx, closure, loc, state)
}

let context_ptr = state.bitcast(pointer(context_tpe), context_ptr_i8, loc)
return context_ptr
}
Expand Down Expand Up @@ -9128,6 +9138,8 @@ def do_create_type(tpe: &typechecking::Type, svalue: &scope::Value, module: &too
value.values(8) = [ kind = ValueKind::STRUCT, tpe = array(pointer(builtins::Type_)), values = array_values ] !Value

push_variants(tpe, global, module, state, cache)
case typechecking::TypeKind::TO_INFER
// This should only happen in an error case
case
error(tpe.kind, "\n")
assert(false)
Expand Down
22 changes: 20 additions & 2 deletions src/consteval.pr
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,25 @@ def unwrap_type_def(tpe: &typechecking::Type) -> &typechecking::Type {
}

def walk_Lambda(node: &parser::Node, state: &typechecking::State) {
// We don't do a whole lot here
node.inner_scope = scope::enter_function_scope(state.scope)
let body = node.value.lambda.body
node.inner_scope = scope::enter_function_scope(state.module.scope)

// Add return for single value
if body.length == 1 {
let expr = body(0)
if not expr { return }

switch expr.kind {
case parser::NodeKind::INTEGER..=parser::NodeKind::IDENTIFIER, parser::NodeKind::DEFINED,
parser::NodeKind::RANGE..=parser::NodeKind::SHR_EQ,
parser::NodeKind::ASSIGN, parser::NodeKind::FUNC_CALL, parser::NodeKind::LAMBDA

let n = [ kind = parser::NodeKind::RETURN] !&Node
n.value.body = vector::make(type &Node)
n.value.body.push(body(0))
body(0) = n
}
}
}

export def walk_Def(node: &parser::Node, state: &typechecking::State) {
Expand Down Expand Up @@ -1161,6 +1178,7 @@ export def consteval(state: &typechecking::State) {
compiler::predeclare_functions(state.module)

let function = [
unmangled = "__main",
is_global = true,
locals = map::make(type &typechecking::Type)
] !&compiler::Function
Expand Down
2 changes: 2 additions & 0 deletions src/debug.pr
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,8 @@ export def type_to_str(tpe: &typechecking::Type, full_name: bool = false) -> Str
return variant_t_to_string(tpe, full_name)
case typechecking::TypeKind::INTERFACE_IMPL
return type_to_str(tpe.tpe, full_name) + "/" + type_to_str(tpe.intf, full_name) + "#" + tpe.module.module
case typechecking::TypeKind::TO_INFER
return "<?>"
case
error(tpe.kind, "\n")
assert
Expand Down
19 changes: 6 additions & 13 deletions src/parser.pr
Original file line number Diff line number Diff line change
Expand Up @@ -2541,7 +2541,10 @@ def parse_term(parse_state: &ParseState) -> &Node {
var node = [] !&Node
var last_string: String

if token.tpe == lexer::TokenType::O_PAREN {
if token.tpe == lexer::TokenType::O_BRACE {
back(parse_state)
return expect_lambda(parse_state)
} else if token.tpe == lexer::TokenType::O_PAREN {
node = parse_expression(parse_state)
let end_token = expect(parse_state, lexer::TokenType::C_PAREN, "Expecting ')'")
if node {
Expand Down Expand Up @@ -3139,13 +3142,8 @@ def parse_assign(parse_state: &ParseState) -> &Node {
}

def parse_expression(parse_state: &ParseState) -> &Node {
var token = peek(parse_state)
if token.tpe == lexer::TokenType::O_BRACE {
return expect_lambda(parse_state)
}

let node = parse_assign(parse_state)
token = peek(parse_state)
var token = peek(parse_state)
if token.tpe == lexer::TokenType::K_IF {
return expect_if_expr(parse_state, node)
}
Expand All @@ -3162,13 +3160,8 @@ def expect_expression(parse_state: &ParseState) -> &Node {
}

def parse_expression_no_assign(parse_state: &ParseState) -> &Node {
var token = peek(parse_state)
if token.tpe == lexer::TokenType::O_BRACE {
return expect_lambda(parse_state)
}

let node = parse_type_of(parse_state)
token = peek(parse_state)
var token = peek(parse_state)
if token.tpe == lexer::TokenType::K_IF {
return expect_if_expr(parse_state, node)
}
Expand Down
Loading

0 comments on commit 6631faf

Please sign in to comment.