mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
remove Boxed
This commit is contained in:
parent
56d4ac190e
commit
0171fd0959
10 changed files with 41 additions and 67 deletions
|
@ -73,7 +73,6 @@ fn jit_to_ast_help<'a>(
|
||||||
content: &Content,
|
content: &Content,
|
||||||
) -> Result<Expr<'a>, ToAstProblem> {
|
) -> Result<Expr<'a>, ToAstProblem> {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Boxed(_) => todo!(),
|
|
||||||
Layout::Builtin(Builtin::Int1) => Ok(run_jit_function!(lib, main_fn_name, bool, |num| {
|
Layout::Builtin(Builtin::Int1) => Ok(run_jit_function!(lib, main_fn_name, bool, |num| {
|
||||||
bool_to_ast(env, num, content)
|
bool_to_ast(env, num, content)
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -2495,32 +2495,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
Dec(symbol) => {
|
Dec(symbol) => {
|
||||||
let (value, layout) = load_symbol_and_layout(scope, symbol);
|
let (value, layout) = load_symbol_and_layout(scope, symbol);
|
||||||
|
|
||||||
if let Layout::Boxed(_) = layout {
|
if layout.contains_refcounted() {
|
||||||
if value.is_pointer_value() {
|
|
||||||
let value_ptr = value.into_pointer_value();
|
|
||||||
|
|
||||||
let then_block = env.context.append_basic_block(parent, "then");
|
|
||||||
let done_block = env.context.append_basic_block(parent, "done");
|
|
||||||
|
|
||||||
let condition =
|
|
||||||
env.builder.build_is_not_null(value_ptr, "box_is_not_null");
|
|
||||||
env.builder
|
|
||||||
.build_conditional_branch(condition, then_block, done_block);
|
|
||||||
|
|
||||||
{
|
|
||||||
env.builder.position_at_end(then_block);
|
|
||||||
let refcount_ptr =
|
|
||||||
PointerToRefcount::from_ptr_to_data(env, value_ptr);
|
|
||||||
refcount_ptr.decrement(env, layout);
|
|
||||||
|
|
||||||
env.builder.build_unconditional_branch(done_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
env.builder.position_at_end(done_block);
|
|
||||||
} else {
|
|
||||||
eprint!("we're likely leaking memory; see issue #985 for details");
|
|
||||||
}
|
|
||||||
} else if layout.contains_refcounted() {
|
|
||||||
decrement_refcount_layout(env, parent, layout_ids, value, layout);
|
decrement_refcount_layout(env, parent, layout_ids, value, layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2562,11 +2537,26 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
_ if layout.is_refcounted() => {
|
_ if layout.is_refcounted() => {
|
||||||
if value.is_pointer_value() {
|
if value.is_pointer_value() {
|
||||||
// BasicValueEnum::PointerValue(value_ptr) => {
|
|
||||||
let value_ptr = value.into_pointer_value();
|
let value_ptr = value.into_pointer_value();
|
||||||
let refcount_ptr =
|
|
||||||
PointerToRefcount::from_ptr_to_data(env, value_ptr);
|
let then_block = env.context.append_basic_block(parent, "then");
|
||||||
refcount_ptr.decrement(env, layout);
|
let done_block = env.context.append_basic_block(parent, "done");
|
||||||
|
|
||||||
|
let condition =
|
||||||
|
env.builder.build_is_not_null(value_ptr, "box_is_not_null");
|
||||||
|
env.builder
|
||||||
|
.build_conditional_branch(condition, then_block, done_block);
|
||||||
|
|
||||||
|
{
|
||||||
|
env.builder.position_at_end(then_block);
|
||||||
|
let refcount_ptr =
|
||||||
|
PointerToRefcount::from_ptr_to_data(env, value_ptr);
|
||||||
|
refcount_ptr.decrement(env, layout);
|
||||||
|
|
||||||
|
env.builder.build_unconditional_branch(done_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
env.builder.position_at_end(done_block);
|
||||||
} else {
|
} else {
|
||||||
eprint!("we're likely leaking memory; see issue #985 for details");
|
eprint!("we're likely leaking memory; see issue #985 for details");
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ fn build_hash_layout<'a, 'ctx, 'env>(
|
||||||
when_recursive: WhenRecursive<'a>,
|
when_recursive: WhenRecursive<'a>,
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Boxed(_) => todo!(),
|
|
||||||
Layout::Builtin(builtin) => {
|
Layout::Builtin(builtin) => {
|
||||||
hash_builtin(env, layout_ids, seed, val, layout, builtin, when_recursive)
|
hash_builtin(env, layout_ids, seed, val, layout, builtin, when_recursive)
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,6 @@ fn build_eq<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
match lhs_layout {
|
match lhs_layout {
|
||||||
Layout::Boxed(_) => todo!(),
|
|
||||||
Layout::Builtin(builtin) => {
|
Layout::Builtin(builtin) => {
|
||||||
build_eq_builtin(env, layout_ids, lhs_val, rhs_val, builtin, when_recursive)
|
build_eq_builtin(env, layout_ids, lhs_val, rhs_val, builtin, when_recursive)
|
||||||
}
|
}
|
||||||
|
@ -297,7 +296,6 @@ fn build_neq<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
match lhs_layout {
|
match lhs_layout {
|
||||||
Layout::Boxed(_) => todo!(),
|
|
||||||
Layout::Builtin(builtin) => {
|
Layout::Builtin(builtin) => {
|
||||||
build_neq_builtin(env, layout_ids, lhs_val, rhs_val, builtin, when_recursive)
|
build_neq_builtin(env, layout_ids, lhs_val, rhs_val, builtin, when_recursive)
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,14 +79,6 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
||||||
.as_basic_type_enum()
|
.as_basic_type_enum()
|
||||||
}
|
}
|
||||||
|
|
||||||
Boxed(_) => {
|
|
||||||
// TODO make this dynamic
|
|
||||||
env.context
|
|
||||||
.i64_type()
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum()
|
|
||||||
}
|
|
||||||
|
|
||||||
Builtin(builtin) => basic_type_from_builtin(env, builtin),
|
Builtin(builtin) => basic_type_from_builtin(env, builtin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -752,10 +752,6 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
||||||
Some(function)
|
Some(function)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Layout::Boxed(_) => {
|
|
||||||
// TODO
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -972,7 +972,6 @@ fn layout_spec(builder: &mut FuncDefBuilder, layout: &Layout) -> Result<TypeId>
|
||||||
} => worst_case_type(builder),
|
} => worst_case_type(builder),
|
||||||
},
|
},
|
||||||
RecursivePointer => worst_case_type(builder),
|
RecursivePointer => worst_case_type(builder),
|
||||||
Boxed(_) => worst_case_type(builder),
|
|
||||||
Closure(_, lambda_set, _) => layout_spec(builder, &lambda_set.runtime_representation()),
|
Closure(_, lambda_set, _) => layout_spec(builder, &lambda_set.runtime_representation()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,7 @@ struct VarInfo {
|
||||||
reference: bool, // true if the variable may be a reference (aka pointer) at runtime
|
reference: bool, // true if the variable may be a reference (aka pointer) at runtime
|
||||||
persistent: bool, // true if the variable is statically known to be marked a Persistent at runtime
|
persistent: bool, // true if the variable is statically known to be marked a Persistent at runtime
|
||||||
consume: bool, // true if the variable RC must be "consumed"
|
consume: bool, // true if the variable RC must be "consumed"
|
||||||
|
reset: bool, // true if the variable is the result of a Reset operation
|
||||||
}
|
}
|
||||||
|
|
||||||
type VarMap = MutMap<Symbol, VarInfo>;
|
type VarMap = MutMap<Symbol, VarInfo>;
|
||||||
|
@ -254,6 +255,7 @@ impl<'a> Context<'a> {
|
||||||
reference: false, // assume function symbols are global constants
|
reference: false, // assume function symbols are global constants
|
||||||
persistent: true, // assume function symbols are global constants
|
persistent: true, // assume function symbols are global constants
|
||||||
consume: false, // no need to consume this variable
|
consume: false, // no need to consume this variable
|
||||||
|
reset: false, // reset symbols cannot be passed as function arguments
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -310,7 +312,12 @@ impl<'a> Context<'a> {
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modify = ModifyRc::Dec(symbol);
|
let modify = if info.reset {
|
||||||
|
ModifyRc::DecRef(symbol)
|
||||||
|
} else {
|
||||||
|
ModifyRc::Dec(symbol)
|
||||||
|
};
|
||||||
|
|
||||||
self.arena.alloc(Stmt::Refcounting(modify, stmt))
|
self.arena.alloc(Stmt::Refcounting(modify, stmt))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,7 +819,7 @@ impl<'a> Context<'a> {
|
||||||
// must this value be consumed?
|
// must this value be consumed?
|
||||||
let consume = consume_call(&self.vars, call);
|
let consume = consume_call(&self.vars, call);
|
||||||
|
|
||||||
self.update_var_info_help(symbol, layout, persistent, consume)
|
self.update_var_info_help(symbol, layout, persistent, consume, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_var_info(&self, symbol: Symbol, layout: &Layout<'a>, expr: &Expr<'a>) -> Self {
|
fn update_var_info(&self, symbol: Symbol, layout: &Layout<'a>, expr: &Expr<'a>) -> Self {
|
||||||
|
@ -823,7 +830,9 @@ impl<'a> Context<'a> {
|
||||||
// must this value be consumed?
|
// must this value be consumed?
|
||||||
let consume = consume_expr(&self.vars, expr);
|
let consume = consume_expr(&self.vars, expr);
|
||||||
|
|
||||||
self.update_var_info_help(symbol, layout, persistent, consume)
|
let reset = matches!(expr, Expr::Reset(_));
|
||||||
|
|
||||||
|
self.update_var_info_help(symbol, layout, persistent, consume, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_var_info_help(
|
fn update_var_info_help(
|
||||||
|
@ -832,6 +841,7 @@ impl<'a> Context<'a> {
|
||||||
layout: &Layout<'a>,
|
layout: &Layout<'a>,
|
||||||
persistent: bool,
|
persistent: bool,
|
||||||
consume: bool,
|
consume: bool,
|
||||||
|
reset: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// should we perform incs and decs on this value?
|
// should we perform incs and decs on this value?
|
||||||
let reference = layout.contains_refcounted();
|
let reference = layout.contains_refcounted();
|
||||||
|
@ -840,6 +850,7 @@ impl<'a> Context<'a> {
|
||||||
reference,
|
reference,
|
||||||
persistent,
|
persistent,
|
||||||
consume,
|
consume,
|
||||||
|
reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ctx = self.clone();
|
let mut ctx = self.clone();
|
||||||
|
@ -857,6 +868,7 @@ impl<'a> Context<'a> {
|
||||||
reference: p.layout.contains_refcounted(),
|
reference: p.layout.contains_refcounted(),
|
||||||
consume: !p.borrow,
|
consume: !p.borrow,
|
||||||
persistent: false,
|
persistent: false,
|
||||||
|
reset: false,
|
||||||
};
|
};
|
||||||
ctx.vars.insert(p.symbol, info);
|
ctx.vars.insert(p.symbol, info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,6 @@ pub enum Layout<'a> {
|
||||||
Union(UnionLayout<'a>),
|
Union(UnionLayout<'a>),
|
||||||
RecursivePointer,
|
RecursivePointer,
|
||||||
|
|
||||||
Boxed(&'a Layout<'a>),
|
|
||||||
|
|
||||||
/// A function. The types of its arguments, then the type of its return value.
|
/// A function. The types of its arguments, then the type of its return value.
|
||||||
Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>),
|
Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>),
|
||||||
}
|
}
|
||||||
|
@ -599,7 +597,6 @@ impl<'a> Layout<'a> {
|
||||||
// We cannot memcpy pointers, because then we would have the same pointer in multiple places!
|
// We cannot memcpy pointers, because then we would have the same pointer in multiple places!
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Boxed(_) => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,7 +648,6 @@ impl<'a> Layout<'a> {
|
||||||
}
|
}
|
||||||
Closure(_, lambda_set, _) => lambda_set.stack_size(pointer_size),
|
Closure(_, lambda_set, _) => lambda_set.stack_size(pointer_size),
|
||||||
RecursivePointer => pointer_size,
|
RecursivePointer => pointer_size,
|
||||||
Boxed(_) => pointer_size,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +678,6 @@ impl<'a> Layout<'a> {
|
||||||
}
|
}
|
||||||
Layout::Builtin(builtin) => builtin.alignment_bytes(pointer_size),
|
Layout::Builtin(builtin) => builtin.alignment_bytes(pointer_size),
|
||||||
Layout::RecursivePointer => pointer_size,
|
Layout::RecursivePointer => pointer_size,
|
||||||
Layout::Boxed(_) => pointer_size,
|
|
||||||
Layout::Closure(_, captured, _) => {
|
Layout::Closure(_, captured, _) => {
|
||||||
pointer_size.max(captured.alignment_bytes(pointer_size))
|
pointer_size.max(captured.alignment_bytes(pointer_size))
|
||||||
}
|
}
|
||||||
|
@ -704,7 +699,6 @@ impl<'a> Layout<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursivePointer => true,
|
RecursivePointer => true,
|
||||||
Boxed(_) => true,
|
|
||||||
|
|
||||||
Builtin(List(_)) | Builtin(Str) => true,
|
Builtin(List(_)) | Builtin(Str) => true,
|
||||||
|
|
||||||
|
@ -738,11 +732,6 @@ impl<'a> Layout<'a> {
|
||||||
}
|
}
|
||||||
RecursivePointer => true,
|
RecursivePointer => true,
|
||||||
|
|
||||||
Boxed(_) => {
|
|
||||||
// technically we should look at layout of the box's content
|
|
||||||
// but refcount insertion needs this to return true
|
|
||||||
true
|
|
||||||
}
|
|
||||||
Closure(_, closure_layout, _) => closure_layout.contains_refcounted(),
|
Closure(_, closure_layout, _) => closure_layout.contains_refcounted(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -767,7 +756,6 @@ impl<'a> Layout<'a> {
|
||||||
}
|
}
|
||||||
Union(union_layout) => union_layout.to_doc(alloc, parens),
|
Union(union_layout) => union_layout.to_doc(alloc, parens),
|
||||||
RecursivePointer => alloc.text("*self"),
|
RecursivePointer => alloc.text("*self"),
|
||||||
Boxed(_) => alloc.text("unbox"),
|
|
||||||
Closure(args, closure_layout, result) => {
|
Closure(args, closure_layout, result) => {
|
||||||
let args_doc = args.iter().map(|x| x.to_doc(alloc, Parens::InFunction));
|
let args_doc = args.iter().map(|x| x.to_doc(alloc, Parens::InFunction));
|
||||||
|
|
||||||
|
|
|
@ -212,7 +212,7 @@ fn try_function_s<'a, 'i>(
|
||||||
if std::ptr::eq(stmt, new_stmt) || stmt == new_stmt {
|
if std::ptr::eq(stmt, new_stmt) || stmt == new_stmt {
|
||||||
stmt
|
stmt
|
||||||
} else {
|
} else {
|
||||||
insert_reset(env, w, x, new_stmt)
|
insert_reset(env, w, x, c.layout, new_stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +220,7 @@ fn insert_reset<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
w: Symbol,
|
w: Symbol,
|
||||||
x: Symbol,
|
x: Symbol,
|
||||||
|
union_layout: UnionLayout<'a>,
|
||||||
mut stmt: &'a Stmt<'a>,
|
mut stmt: &'a Stmt<'a>,
|
||||||
) -> &'a Stmt<'a> {
|
) -> &'a Stmt<'a> {
|
||||||
use crate::ir::Expr::*;
|
use crate::ir::Expr::*;
|
||||||
|
@ -246,11 +247,11 @@ fn insert_reset<'a>(
|
||||||
|
|
||||||
let reset_expr = Expr::Reset(x);
|
let reset_expr = Expr::Reset(x);
|
||||||
|
|
||||||
const I64: Layout<'static> = Layout::Builtin(crate::layout::Builtin::Int64);
|
// const I64: Layout<'static> = Layout::Builtin(crate::layout::Builtin::Int64);
|
||||||
|
|
||||||
stmt = env
|
let layout = Layout::Union(union_layout);
|
||||||
.arena
|
|
||||||
.alloc(Stmt::Let(w, reset_expr, Layout::Boxed(&I64), stmt));
|
stmt = env.arena.alloc(Stmt::Let(w, reset_expr, layout, stmt));
|
||||||
|
|
||||||
for (symbol, expr, expr_layout) in stack.into_iter().rev() {
|
for (symbol, expr, expr_layout) in stack.into_iter().rev() {
|
||||||
stmt = env
|
stmt = env
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue