sketch of a proof of concept

This commit is contained in:
Folkert 2020-10-11 01:54:50 +02:00
parent 79d3b0ac01
commit 4f9b27b694
6 changed files with 65 additions and 18 deletions

View file

@ -372,6 +372,7 @@ pub fn gen_from_mono_module(
for ((symbol, layout), proc) in loaded.procedures {
let fn_val = build_proc_header(&env, &mut layout_ids, symbol, &layout, &proc);
dbg!(&fn_val);
headers.push((proc, fn_val));
}
@ -395,7 +396,7 @@ pub fn gen_from_mono_module(
}
// Uncomment this to see the module's optimized LLVM instruction output:
// env.module.print_to_stderr();
env.module.print_to_stderr();
mpm.run_on(module);

View file

@ -1899,15 +1899,16 @@ fn call_with_args<'a, 'ctx, 'env>(
let fn_name = layout_ids
.get(symbol, layout)
.to_symbol_string(symbol, &env.interns);
let fn_name = fn_name.as_str();
let fn_val = env
.module
.get_function(fn_name.as_str())
.unwrap_or_else(|| {
let fn_val = env.module.get_function(fn_name).unwrap_or_else(|| {
if symbol.is_builtin() {
panic!("Unrecognized builtin function: {:?}", symbol)
panic!("Unrecognized builtin function: {:?}", fn_name)
} else {
panic!("Unrecognized non-builtin function: {:?}", symbol)
panic!(
"Unrecognized non-builtin function: {:?} {:?}",
fn_name, layout
)
}
});

View file

@ -12,6 +12,8 @@ roc_module = { path = "../module" }
roc_types = { path = "../types" }
roc_can = { path = "../can" }
roc_unify = { path = "../unify" }
roc_constrain = { path = "../constrain" }
roc_solve = { path = "../solve" }
roc_problem = { path = "../problem" }
ven_pretty = { path = "../../vendor/pretty" }
bumpalo = { version = "3.2", features = ["collections"] }

View file

@ -1208,30 +1208,44 @@ pub fn specialize_all<'a>(
mut procs: Procs<'a>,
layout_cache: &mut LayoutCache<'a>,
) -> Procs<'a> {
let mut pending_specializations = procs.pending_specializations.unwrap_or_default();
// add the specializations that other modules require of us
use roc_constrain::module::{to_type, FreeVars};
use roc_solve::solve::insert_type_into_subs;
for (name, solved_type) in procs.externals_others_need.drain() {
use roc_solve::solve::{insert_type_into_subs, unsafe_copy_var_help};
use roc_types::subs::VarStore;
let it = procs.externals_others_need.clone();
for (name, solved_type) in it.into_iter() {
let snapshot = env.subs.snapshot();
let mut free_vars = FreeVars::default();
let mut var_store = ();
let normal_type = to_type(solved_type, &mut free_vars, &mut var_store);
let mut var_store = VarStore::new_from_subs(env.subs);
let normal_type = to_type(&solved_type, &mut free_vars, &mut var_store);
dbg!(name, &normal_type);
let next = var_store.fresh().index();
let variables_introduced = next as usize - (env.subs.len() - 1);
env.subs.extend_by(variables_introduced);
let fn_var = insert_type_into_subs(env.subs, &normal_type);
let layout = layout_cache
.from_var(&env.arena, fn_var, env.subs)
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
let partial_proc = match procs.partial_procs.get(&name) {
let mut partial_proc = match procs.partial_procs.get(&name) {
Some(v) => v.clone(),
None => {
unreachable!("now this is an error");
}
};
partial_proc.annotation = unsafe_copy_var_help(env.subs, partial_proc.annotation);
match specialize_external(env, &mut procs, name, layout_cache, fn_var, partial_proc) {
Ok(proc) => {
dbg!(name, &layout);
procs.specialized.insert((name, layout), Done(proc));
}
Err(error) => {
@ -1243,8 +1257,12 @@ pub fn specialize_all<'a>(
procs.runtime_errors.insert(name, error_msg);
}
}
env.subs.rollback_to(snapshot);
}
let mut pending_specializations = procs.pending_specializations.unwrap_or_default();
// When calling from_can, pending_specializations should be unavailable.
// This must be a single pass, and we must not add any more entries to it!
procs.pending_specializations = None;

View file

@ -1191,6 +1191,13 @@ fn introduce(subs: &mut Subs, rank: Rank, pools: &mut Pools, vars: &[Variable])
pool.extend(vars);
}
pub fn unsafe_copy_var_help(subs: &mut Subs, var: Variable) -> Variable {
let rank = Rank::NONE;
let mut pools = Pools::default();
deep_copy_var(subs, rank, &mut pools, var)
}
fn deep_copy_var(subs: &mut Subs, rank: Rank, pools: &mut Pools, var: Variable) -> Variable {
let copy = deep_copy_var_help(subs, rank, pools, var);

View file

@ -72,6 +72,14 @@ impl VarStore {
VarStore { next: next_var.0 }
}
pub fn new_from_subs(subs: &Subs) -> Self {
// TODO why -2, are we not overwriting something here?
let next_var = (subs.utable.len() - 1) as u32;
debug_assert!(next_var >= Variable::FIRST_USER_SPACE_VAR.0);
VarStore { next: next_var }
}
pub fn fresh(&mut self) -> Variable {
// Increment the counter and return the value it had before it was incremented.
let answer = self.next;
@ -163,6 +171,10 @@ impl Variable {
pub unsafe fn unsafe_test_debug_variable(v: u32) -> Self {
Variable(v)
}
pub fn index(&self) -> u32 {
self.0
}
}
impl Into<OptVariable> for Variable {
@ -255,6 +267,12 @@ impl Subs {
subs
}
pub fn extend_by(&mut self, entries: usize) {
for _ in self.len()..entries {
self.utable.new_key(flex_var_descriptor());
}
}
pub fn fresh(&mut self, value: Descriptor) -> Variable {
self.utable.new_key(value)
}