mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
get scratchpad to run
This commit is contained in:
parent
48386f2fc6
commit
89ad21145b
4 changed files with 111 additions and 29 deletions
|
@ -2095,7 +2095,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
ref full_layout,
|
ref full_layout,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let function_value = function_value_by_name(env, layout_ids, full_layout, name);
|
let function_value = function_value_by_name(env, layout_ids, *full_layout, name);
|
||||||
|
|
||||||
invoke_roc_function(
|
invoke_roc_function(
|
||||||
env,
|
env,
|
||||||
|
@ -3102,7 +3102,7 @@ pub fn build_proc_header_new<'a, 'ctx, 'env>(
|
||||||
build_proc_header(env, layout_ids, symbol, &layout, proc)
|
build_proc_header(env, layout_ids, symbol, &layout, proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_proc_header<'a, 'ctx, 'env>(
|
pub fn build_proc_header<'a, 'b, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
|
@ -3117,31 +3117,48 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
.to_symbol_string(symbol, &env.interns);
|
.to_symbol_string(symbol, &env.interns);
|
||||||
|
|
||||||
use roc_mono::ir::HostExposedLayouts;
|
use roc_mono::ir::HostExposedLayouts;
|
||||||
match &proc.host_exposed_layouts {
|
let copy = proc.host_exposed_layouts.clone();
|
||||||
|
match copy {
|
||||||
HostExposedLayouts::NotHostExposed => {}
|
HostExposedLayouts::NotHostExposed => {}
|
||||||
HostExposedLayouts::HostExposed { rigids: _, aliases } => {
|
HostExposedLayouts::HostExposed { rigids: _, aliases } => {
|
||||||
for (name, layout) in aliases {
|
for (name, (symbol, top_level, layout)) in aliases {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Closure(arguments, closure, result) => {
|
Layout::Closure(arguments, closure, result) => {
|
||||||
// define closure size and return value size, e.g.
|
// define closure size and return value size, e.g.
|
||||||
//
|
//
|
||||||
// * roc__mainForHost_1_Update_size() -> i64
|
// * roc__mainForHost_1_Update_size() -> i64
|
||||||
// * roc__mainForHost_1_Update_result_size() -> i64
|
// * roc__mainForHost_1_Update_result_size() -> i64
|
||||||
build_closure_caller(env, &fn_name, *name, arguments, closure, result)
|
|
||||||
|
let evaluator_layout = env.arena.alloc(top_level).full();
|
||||||
|
let evaluator_name = layout_ids
|
||||||
|
.get_new(symbol, evaluator_layout)
|
||||||
|
.to_symbol_string(symbol, &env.interns);
|
||||||
|
|
||||||
|
let evaluator = function_value_by_name_help(
|
||||||
|
env,
|
||||||
|
evaluator_layout,
|
||||||
|
symbol,
|
||||||
|
&evaluator_name,
|
||||||
|
);
|
||||||
|
|
||||||
|
build_closure_caller(
|
||||||
|
env, &fn_name, evaluator, name, arguments, closure, result,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Layout::FunctionPointer(arguments, result) => {
|
Layout::FunctionPointer(arguments, result) => {
|
||||||
// define function size (equal to pointer size) and return value size, e.g.
|
// define function size (equal to pointer size) and return value size, e.g.
|
||||||
//
|
//
|
||||||
// * roc__mainForHost_1_Update_size() -> i64
|
// * roc__mainForHost_1_Update_size() -> i64
|
||||||
// * roc__mainForHost_1_Update_result_size() -> i64
|
// * roc__mainForHost_1_Update_result_size() -> i64
|
||||||
build_function_caller(env, &fn_name, *name, arguments, result)
|
build_function_caller(env, &fn_name, name, arguments, result)
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// for anything else we only define the size symbol, e.g.
|
|
||||||
//
|
|
||||||
// * roc__mainForHost_1_Model_size() -> i64
|
|
||||||
build_host_exposed_alias_size(env, &fn_name, *name, layout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Layout::Builtin(_) => {}
|
||||||
|
Layout::PhantomEmptyStruct => {}
|
||||||
|
Layout::Struct(_) => {}
|
||||||
|
Layout::Union(_) => {}
|
||||||
|
Layout::RecursivePointer => {}
|
||||||
|
Layout::Pointer(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3177,9 +3194,10 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
pub fn build_closure_caller<'a, 'ctx, 'env>(
|
pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
env: &'a Env<'a, 'ctx, 'env>,
|
env: &'a Env<'a, 'ctx, 'env>,
|
||||||
def_name: &str,
|
def_name: &str,
|
||||||
|
evaluator: FunctionValue<'ctx>,
|
||||||
alias_symbol: Symbol,
|
alias_symbol: Symbol,
|
||||||
arguments: &[Layout<'a>],
|
arguments: &[Layout<'a>],
|
||||||
lambda_set: &LambdaSet<'a>,
|
lambda_set: LambdaSet<'a>,
|
||||||
result: &Layout<'a>,
|
result: &Layout<'a>,
|
||||||
) {
|
) {
|
||||||
use inkwell::types::BasicType;
|
use inkwell::types::BasicType;
|
||||||
|
@ -3248,7 +3266,7 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
let mut parameters = function_value.get_params();
|
let mut parameters = function_value.get_params();
|
||||||
let output = parameters.pop().unwrap().into_pointer_value();
|
let output = parameters.pop().unwrap().into_pointer_value();
|
||||||
let closure_data_ptr = parameters.pop().unwrap().into_pointer_value();
|
let closure_data_ptr = parameters.pop().unwrap().into_pointer_value();
|
||||||
let function_ptr = parameters.pop().unwrap().into_pointer_value();
|
let _function_ptr = parameters.pop().unwrap().into_pointer_value();
|
||||||
|
|
||||||
let closure_data = builder.build_load(closure_data_ptr, "load_closure_data");
|
let closure_data = builder.build_load(closure_data_ptr, "load_closure_data");
|
||||||
|
|
||||||
|
@ -3259,9 +3277,12 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
*param = builder.build_load(param.into_pointer_value(), "load_param");
|
*param = builder.build_load(param.into_pointer_value(), "load_param");
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.push(closure_data);
|
// parameters.push(closure_data);
|
||||||
|
|
||||||
let call_result = invoke_and_catch(env, function_value, function_ptr, ¶meters, result_type);
|
// let call_result = invoke_and_catch(env, function_value, function_ptr, ¶meters, result_type);
|
||||||
|
|
||||||
|
let call_result =
|
||||||
|
invoke_and_catch(env, function_value, evaluator, &[closure_data], result_type);
|
||||||
|
|
||||||
builder.build_store(output, call_result);
|
builder.build_store(output, call_result);
|
||||||
|
|
||||||
|
@ -3277,11 +3298,11 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// STEP 4: build a {} -> u64 function that gives the size of the closure
|
// STEP 4: build a {} -> u64 function that gives the size of the closure
|
||||||
let layout = Layout::Closure(arguments, *lambda_set, result);
|
let layout = Layout::Closure(arguments, lambda_set, result);
|
||||||
build_host_exposed_alias_size(env, def_name, alias_symbol, &layout);
|
build_host_exposed_alias_size(env, def_name, alias_symbol, &layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_function_caller<'a, 'ctx, 'env>(
|
fn build_function_caller<'a, 'ctx, 'env>(
|
||||||
env: &'a Env<'a, 'ctx, 'env>,
|
env: &'a Env<'a, 'ctx, 'env>,
|
||||||
def_name: &str,
|
def_name: &str,
|
||||||
alias_symbol: Symbol,
|
alias_symbol: Symbol,
|
||||||
|
@ -3500,14 +3521,23 @@ pub fn verify_fn(fn_val: FunctionValue<'_>) {
|
||||||
fn function_value_by_name<'a, 'ctx, 'env>(
|
fn function_value_by_name<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
layout: &Layout<'a>,
|
layout: Layout<'a>,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let fn_name = layout_ids
|
let fn_name = layout_ids
|
||||||
.get(symbol, layout)
|
.get_new(symbol, layout)
|
||||||
.to_symbol_string(symbol, &env.interns);
|
.to_symbol_string(symbol, &env.interns);
|
||||||
let fn_name = fn_name.as_str();
|
let fn_name = fn_name.as_str();
|
||||||
|
|
||||||
|
function_value_by_name_help(env, layout, symbol, fn_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn function_value_by_name_help<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
layout: Layout<'a>,
|
||||||
|
symbol: Symbol,
|
||||||
|
fn_name: &str,
|
||||||
|
) -> FunctionValue<'ctx> {
|
||||||
env.module.get_function(fn_name).unwrap_or_else(|| {
|
env.module.get_function(fn_name).unwrap_or_else(|| {
|
||||||
if symbol.is_builtin() {
|
if symbol.is_builtin() {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
@ -3546,7 +3576,7 @@ fn call_with_args<'a, 'ctx, 'env>(
|
||||||
_parent: FunctionValue<'ctx>,
|
_parent: FunctionValue<'ctx>,
|
||||||
args: &[BasicValueEnum<'ctx>],
|
args: &[BasicValueEnum<'ctx>],
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let fn_val = function_value_by_name(env, layout_ids, layout, symbol);
|
let fn_val = function_value_by_name(env, layout_ids, *layout, symbol);
|
||||||
|
|
||||||
let call = env.builder.build_call(fn_val, args, "call");
|
let call = env.builder.build_call(fn_val, args, "call");
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ pub enum HostExposedLayouts<'a> {
|
||||||
NotHostExposed,
|
NotHostExposed,
|
||||||
HostExposed {
|
HostExposed {
|
||||||
rigids: BumpMap<Lowercase, Layout<'a>>,
|
rigids: BumpMap<Lowercase, Layout<'a>>,
|
||||||
aliases: BumpMap<Symbol, Layout<'a>>,
|
aliases: BumpMap<Symbol, (Symbol, TopLevelFunctionLayout<'a>, Layout<'a>)>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1907,7 +1907,55 @@ fn specialize_external<'a>(
|
||||||
let layout = layout_cache
|
let layout = layout_cache
|
||||||
.from_var(env.arena, *variable, env.subs)
|
.from_var(env.arena, *variable, env.subs)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
aliases.insert(*symbol, layout);
|
|
||||||
|
let name = env.unique_symbol();
|
||||||
|
|
||||||
|
match layout {
|
||||||
|
Layout::Closure(argument_layouts, lambda_set, return_layout) => {
|
||||||
|
let assigned = env.unique_symbol();
|
||||||
|
let unit = env.unique_symbol();
|
||||||
|
|
||||||
|
let hole = env.arena.alloc(Stmt::Ret(assigned));
|
||||||
|
|
||||||
|
let body = match_on_lambda_set(
|
||||||
|
env,
|
||||||
|
lambda_set,
|
||||||
|
Symbol::ARG_CLOSURE,
|
||||||
|
env.arena.alloc([unit]),
|
||||||
|
argument_layouts,
|
||||||
|
*return_layout,
|
||||||
|
assigned,
|
||||||
|
hole,
|
||||||
|
);
|
||||||
|
|
||||||
|
let body = let_empty_struct(unit, env.arena.alloc(body));
|
||||||
|
|
||||||
|
let proc = Proc {
|
||||||
|
name,
|
||||||
|
args: env
|
||||||
|
.arena
|
||||||
|
.alloc([(lambda_set.runtime_representation(), Symbol::ARG_CLOSURE)]),
|
||||||
|
body,
|
||||||
|
closure_data_layout: None,
|
||||||
|
ret_layout: *return_layout,
|
||||||
|
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||||
|
must_own_arguments: false,
|
||||||
|
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||||
|
};
|
||||||
|
|
||||||
|
let top_level = TopLevelFunctionLayout {
|
||||||
|
arguments: env.arena.alloc([lambda_set.runtime_representation()]),
|
||||||
|
result: *return_layout,
|
||||||
|
};
|
||||||
|
|
||||||
|
procs
|
||||||
|
.specialized
|
||||||
|
.insert((name, top_level), InProgressProc::Done(proc));
|
||||||
|
|
||||||
|
aliases.insert(*symbol, (name, top_level, layout));
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostExposedLayouts::HostExposed {
|
HostExposedLayouts::HostExposed {
|
||||||
|
@ -4337,7 +4385,7 @@ fn construct_closure_data<'a>(
|
||||||
match lambda_set.layout_for_member(name) {
|
match lambda_set.layout_for_member(name) {
|
||||||
ClosureRepresentation::Union {
|
ClosureRepresentation::Union {
|
||||||
tag_id,
|
tag_id,
|
||||||
tag_layout,
|
tag_layout: _,
|
||||||
union_size,
|
union_size,
|
||||||
tag_name,
|
tag_name,
|
||||||
} => {
|
} => {
|
||||||
|
|
|
@ -1893,7 +1893,11 @@ pub struct LayoutIds<'a> {
|
||||||
impl<'a> LayoutIds<'a> {
|
impl<'a> LayoutIds<'a> {
|
||||||
/// Returns a LayoutId which is unique for the given symbol and layout.
|
/// Returns a LayoutId which is unique for the given symbol and layout.
|
||||||
/// If given the same symbol and same layout, returns the same LayoutId.
|
/// If given the same symbol and same layout, returns the same LayoutId.
|
||||||
pub fn get(&mut self, symbol: Symbol, layout: &Layout<'a>) -> LayoutId {
|
pub fn get<'b>(&mut self, symbol: Symbol, layout: &'b Layout<'a>) -> LayoutId {
|
||||||
|
self.get_new(symbol, *layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_new(&mut self, symbol: Symbol, layout: Layout<'a>) -> LayoutId {
|
||||||
// Note: this function does some weird stuff to satisfy the borrow checker.
|
// Note: this function does some weird stuff to satisfy the borrow checker.
|
||||||
// There's probably a nicer way to write it that still works.
|
// There's probably a nicer way to write it that still works.
|
||||||
let ids = self.by_symbol.entry(symbol).or_insert_with(|| IdsByLayout {
|
let ids = self.by_symbol.entry(symbol).or_insert_with(|| IdsByLayout {
|
||||||
|
@ -1902,12 +1906,12 @@ impl<'a> LayoutIds<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get the id associated with this layout, or default to next_id.
|
// Get the id associated with this layout, or default to next_id.
|
||||||
let answer = ids.by_id.get(layout).copied().unwrap_or(ids.next_id);
|
let answer = ids.by_id.get(&layout).copied().unwrap_or(ids.next_id);
|
||||||
|
|
||||||
// If we had to default to next_id, it must not have been found;
|
// If we had to default to next_id, it must not have been found;
|
||||||
// store the ID we're going to return and increment next_id.
|
// store the ID we're going to return and increment next_id.
|
||||||
if answer == ids.next_id {
|
if answer == ids.next_id {
|
||||||
ids.by_id.insert(*layout, ids.next_id);
|
ids.by_id.insert(layout, ids.next_id);
|
||||||
|
|
||||||
ids.next_id += 1;
|
ids.next_id += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@ pub export fn main() u8 {
|
||||||
|
|
||||||
if (flag == 0) {
|
if (flag == 0) {
|
||||||
// all is well
|
// all is well
|
||||||
const function_pointer = @intToPtr(*const u8, elements[1]);
|
const function_pointer = @intToPtr(*const u8, 1);
|
||||||
const closure_data_pointer = @ptrCast([*]u8, output[16..size]);
|
const closure_data_pointer = @ptrCast([*]u8, output[8..size]);
|
||||||
|
|
||||||
call_the_closure(function_pointer, closure_data_pointer);
|
call_the_closure(function_pointer, closure_data_pointer);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue