mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 07:17:50 +03:00
Merge pull request #5733 from roc-lang/glue-earlier
fix off-by-one error in glue generation
This commit is contained in:
commit
e6e1a13670
@ -5,5 +5,5 @@ platform "benchmarks"
|
||||
imports [Task.{ Task }]
|
||||
provides [mainForHost]
|
||||
|
||||
mainForHost : Task {} [] as Fx
|
||||
mainForHost : Task {} []
|
||||
mainForHost = main
|
||||
|
@ -41,7 +41,6 @@ use roc_mono::ir::{
|
||||
CapturedSymbols, ExternalSpecializations, GlueLayouts, PartialProc, Proc, ProcLayout, Procs,
|
||||
ProcsBase, UpdateModeIds, UsageTrackingMap,
|
||||
};
|
||||
use roc_mono::layout::LayoutInterner;
|
||||
use roc_mono::layout::{
|
||||
GlobalLayoutInterner, LambdaName, Layout, LayoutCache, LayoutProblem, Niche, STLayoutInterner,
|
||||
};
|
||||
@ -2982,8 +2981,8 @@ fn finish_specialization<'a>(
|
||||
arena: &'a Bump,
|
||||
state: State<'a>,
|
||||
subs: Subs,
|
||||
mut layout_interner: STLayoutInterner<'a>,
|
||||
mut exposed_to_host: ExposedToHost,
|
||||
layout_interner: STLayoutInterner<'a>,
|
||||
exposed_to_host: ExposedToHost,
|
||||
module_expectations: VecMap<ModuleId, Expectations>,
|
||||
) -> Result<MonomorphizedModule<'a>, LoadingProblem<'a>> {
|
||||
if false {
|
||||
@ -3101,53 +3100,6 @@ fn finish_specialization<'a>(
|
||||
.collect();
|
||||
|
||||
let module_id = state.root_id;
|
||||
let mut glue_getters = Vec::new();
|
||||
|
||||
// the REPL does not have any platform data
|
||||
if let (
|
||||
EntryPoint::Executable {
|
||||
exposed_to_host: exposed_top_levels,
|
||||
..
|
||||
},
|
||||
Some(platform_data),
|
||||
) = (&entry_point, platform_data.as_ref())
|
||||
{
|
||||
// Expose glue for the platform, not for the app module!
|
||||
let module_id = platform_data.module_id;
|
||||
|
||||
for (_name, proc_layout) in exposed_top_levels.iter() {
|
||||
let ret = &proc_layout.result;
|
||||
for in_layout in proc_layout.arguments.iter().chain([ret]) {
|
||||
let layout = layout_interner.get(*in_layout);
|
||||
let ident_ids = interns.all_ident_ids.get_mut(&module_id).unwrap();
|
||||
let all_glue_procs = roc_mono::ir::generate_glue_procs(
|
||||
module_id,
|
||||
ident_ids,
|
||||
arena,
|
||||
&mut layout_interner,
|
||||
arena.alloc(layout),
|
||||
);
|
||||
|
||||
let lambda_set_names = all_glue_procs
|
||||
.legacy_layout_based_extern_names
|
||||
.iter()
|
||||
.map(|(lambda_set_id, _)| (*_name, *lambda_set_id));
|
||||
exposed_to_host.lambda_sets.extend(lambda_set_names);
|
||||
|
||||
let getter_names = all_glue_procs
|
||||
.getters
|
||||
.iter()
|
||||
.flat_map(|(_, glue_procs)| glue_procs.iter().map(|glue_proc| glue_proc.name));
|
||||
exposed_to_host.getters.extend(getter_names);
|
||||
|
||||
glue_getters.extend(all_glue_procs.getters.iter().flat_map(|(_, glue_procs)| {
|
||||
glue_procs
|
||||
.iter()
|
||||
.map(|glue_proc| (glue_proc.name, glue_proc.proc_layout))
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let output_path = match output_path {
|
||||
Some(path_str) => Path::new(path_str).into(),
|
||||
@ -3176,9 +3128,7 @@ fn finish_specialization<'a>(
|
||||
sources,
|
||||
timings: state.timings,
|
||||
toplevel_expects,
|
||||
glue_layouts: GlueLayouts {
|
||||
getters: glue_getters,
|
||||
},
|
||||
glue_layouts: GlueLayouts { getters: vec![] },
|
||||
uses_prebuilt_platform,
|
||||
})
|
||||
}
|
||||
|
@ -3069,9 +3069,7 @@ fn specialize_host_specializations<'a>(
|
||||
let Some(from_platform) = opt_from_platform else { continue };
|
||||
|
||||
// now run the lambda set numbering scheme
|
||||
let mut layout_env =
|
||||
layout::Env::from_components(layout_cache, env.subs, env.arena, env.target_info);
|
||||
let hels = find_lambda_sets(&mut layout_env, from_platform);
|
||||
let hels = find_lambda_sets(env.arena, env.subs, from_platform);
|
||||
|
||||
// now unify
|
||||
let mut unify_env = roc_unify::Env::new(
|
||||
@ -3099,10 +3097,18 @@ fn specialize_host_specializations<'a>(
|
||||
|
||||
let mut aliases = BumpMap::default();
|
||||
|
||||
for (id, _, raw_function_layout) in hels {
|
||||
for (var, id) in hels {
|
||||
let symbol = env.unique_symbol();
|
||||
let lambda_name = LambdaName::no_niche(symbol);
|
||||
|
||||
let mut layout_env =
|
||||
layout::Env::from_components(layout_cache, env.subs, env.arena, env.target_info);
|
||||
let lambda_set = env.subs.get_lambda_set(var);
|
||||
let raw_function_layout =
|
||||
RawFunctionLayout::from_var(&mut layout_env, lambda_set.ambient_function)
|
||||
.value()
|
||||
.unwrap();
|
||||
|
||||
let (key, (top_level, proc)) = generate_host_exposed_function(
|
||||
env,
|
||||
procs,
|
||||
@ -10001,16 +10007,17 @@ impl LambdaSetId {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_lambda_sets<'a>(
|
||||
env: &mut crate::layout::Env<'a, '_>,
|
||||
pub fn find_lambda_sets(
|
||||
arena: &Bump,
|
||||
subs: &Subs,
|
||||
initial: Variable,
|
||||
) -> Vec<'a, (LambdaSetId, Variable, RawFunctionLayout<'a>)> {
|
||||
let mut stack = bumpalo::collections::Vec::new_in(env.arena);
|
||||
) -> MutMap<Variable, LambdaSetId> {
|
||||
let mut stack = bumpalo::collections::Vec::new_in(arena);
|
||||
|
||||
// ignore the lambda set of top-level functions
|
||||
match env.subs.get_without_compacting(initial).content {
|
||||
match subs.get_without_compacting(initial).content {
|
||||
Content::Structure(FlatType::Func(arguments, _, result)) => {
|
||||
let arguments = &env.subs.variables[arguments.indices()];
|
||||
let arguments = &subs.variables[arguments.indices()];
|
||||
|
||||
stack.extend(arguments.iter().copied());
|
||||
stack.push(result);
|
||||
@ -10020,24 +10027,10 @@ fn find_lambda_sets<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
let lambda_set_variables = find_lambda_sets_help(env.subs, stack);
|
||||
let mut answer =
|
||||
bumpalo::collections::Vec::with_capacity_in(lambda_set_variables.len(), env.arena);
|
||||
|
||||
for (variable, lambda_set_id) in lambda_set_variables {
|
||||
let lambda_set = env.subs.get_lambda_set(variable);
|
||||
let raw_function_layout = RawFunctionLayout::from_var(env, lambda_set.ambient_function)
|
||||
.value()
|
||||
.unwrap();
|
||||
|
||||
let key = (lambda_set_id, variable, raw_function_layout);
|
||||
answer.push(key);
|
||||
}
|
||||
|
||||
answer
|
||||
find_lambda_sets_help(subs, stack)
|
||||
}
|
||||
|
||||
pub fn find_lambda_sets_help(
|
||||
fn find_lambda_sets_help(
|
||||
subs: &Subs,
|
||||
mut stack: Vec<'_, Variable>,
|
||||
) -> MutMap<Variable, LambdaSetId> {
|
||||
|
@ -14,7 +14,7 @@ procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.537 : [] = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.537;
|
||||
|
||||
procedure List.80 (#Derived_gen.11, #Derived_gen.12, #Derived_gen.13, #Derived_gen.14, #Derived_gen.15):
|
||||
procedure List.80 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_gen.17):
|
||||
joinpoint List.527 List.439 List.440 List.441 List.442 List.443:
|
||||
let List.529 : Int1 = CallByName Num.22 List.442 List.443;
|
||||
if List.529 then
|
||||
@ -27,7 +27,7 @@ procedure List.80 (#Derived_gen.11, #Derived_gen.12, #Derived_gen.13, #Derived_g
|
||||
dec List.439;
|
||||
ret List.440;
|
||||
in
|
||||
jump List.527 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15;
|
||||
jump List.527 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
|
||||
|
||||
procedure List.93 (List.436, List.437, List.438):
|
||||
let List.525 : U64 = 0i64;
|
||||
@ -156,8 +156,16 @@ procedure Test.80 (Test.81):
|
||||
ret Test.83;
|
||||
|
||||
procedure Test.84 (Test.86, #Attr.12):
|
||||
let Test.87 : Str = "a Lambda Set is empty. Most likely there is a type error in your program.";
|
||||
Crash Test.87
|
||||
let Test.87 : U8 = GetTagId #Attr.12;
|
||||
switch Test.87:
|
||||
case 0:
|
||||
let Test.85 : {} = CallByName Test.10 Test.86 #Attr.12;
|
||||
ret Test.85;
|
||||
|
||||
default:
|
||||
let Test.85 : {} = CallByName Test.14 Test.86 #Attr.12;
|
||||
ret Test.85;
|
||||
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.35 : List [] = Array [];
|
||||
|
@ -111,8 +111,7 @@ impl Types {
|
||||
target,
|
||||
);
|
||||
|
||||
let variables: Vec<_> = entry_points.values().copied().collect();
|
||||
for var in variables {
|
||||
for (_symbol, var) in entry_points.clone() {
|
||||
env.lambda_set_ids = env.find_lambda_sets(var);
|
||||
let id = env.add_toplevel_type(var, &mut types);
|
||||
|
||||
@ -1223,8 +1222,7 @@ impl<'a> Env<'a> {
|
||||
}
|
||||
|
||||
fn find_lambda_sets(&self, root: Variable) -> MutMap<Variable, LambdaSetId> {
|
||||
let stack = bumpalo::vec![in self.arena; root];
|
||||
roc_mono::ir::find_lambda_sets_help(self.subs, stack)
|
||||
roc_mono::ir::find_lambda_sets(self.arena, self.subs, root)
|
||||
}
|
||||
|
||||
fn add_toplevel_type(&mut self, var: Variable, types: &mut Types) -> TypeId {
|
||||
@ -1268,8 +1266,13 @@ fn add_function_type<'a>(
|
||||
|
||||
let name = format!("RocFunction_{closure_var:?}");
|
||||
|
||||
let id = env.lambda_set_ids.get(&closure_var).unwrap();
|
||||
let extern_name = format!("roc__mainForHost_{}_caller", id.0);
|
||||
let extern_name = match env.lambda_set_ids.get(&closure_var) {
|
||||
Some(id) => format!("roc__mainForHost_{}_caller", id.0),
|
||||
None => {
|
||||
debug_assert!(is_toplevel);
|
||||
String::from("this_extern_should_not_be_used_this_is_a_bug")
|
||||
}
|
||||
};
|
||||
|
||||
for arg_var in args {
|
||||
let arg_layout = env
|
||||
|
@ -5,5 +5,5 @@ platform "cli"
|
||||
imports [Task.{ Task }]
|
||||
provides [mainForHost]
|
||||
|
||||
mainForHost : Task {} [] as Fx
|
||||
mainForHost : Task {} []
|
||||
mainForHost = main
|
||||
|
@ -5,5 +5,5 @@ platform "effects"
|
||||
imports [pf.Effect]
|
||||
provides [mainForHost]
|
||||
|
||||
mainForHost : Effect.Effect {} as Fx
|
||||
mainForHost : Effect.Effect {}
|
||||
mainForHost = main
|
||||
|
@ -5,5 +5,5 @@ platform "false-interpreter"
|
||||
imports [Task.{ Task }]
|
||||
provides [mainForHost]
|
||||
|
||||
mainForHost : Str -> Task {} [] as Fx
|
||||
mainForHost : Str -> Task {} []
|
||||
mainForHost = \file -> main file
|
||||
|
Loading…
Reference in New Issue
Block a user