mirror of
https://github.com/exoticorn/curlywas.git
synced 2026-01-20 11:46:43 +01:00
fix let lazy/inline chains re-using the same variable
This commit is contained in:
13
src/emit.rs
13
src/emit.rs
@@ -289,7 +289,7 @@ struct FunctionContext<'a> {
|
||||
functions: &'a HashMap<String, u32>,
|
||||
locals: &'a ast::Locals,
|
||||
labels: Vec<String>,
|
||||
let_values: HashMap<u32, (&'a ast::Expression, ast::LetType)>,
|
||||
let_values: HashMap<u32, Vec<(&'a ast::Expression, ast::LetType)>>,
|
||||
intrinsics: &'a Intrinsics,
|
||||
}
|
||||
|
||||
@@ -385,7 +385,10 @@ fn emit_expression<'a>(ctx: &mut FunctionContext<'a>, expr: &'a ast::Expression)
|
||||
.instruction(&Instruction::LocalSet(local.index.unwrap()));
|
||||
}
|
||||
ast::LetType::Lazy | ast::LetType::Inline => {
|
||||
ctx.let_values.insert(local_id.unwrap(), (value, *let_type));
|
||||
ctx.let_values
|
||||
.entry(local_id.unwrap())
|
||||
.or_default()
|
||||
.push((value, *let_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -612,17 +615,17 @@ fn emit_expression<'a>(ctx: &mut FunctionContext<'a>, expr: &'a ast::Expression)
|
||||
}
|
||||
ast::Expr::Variable { name, local_id } => {
|
||||
if let &Some(id) = local_id {
|
||||
if let Some((expr, let_type)) = ctx.let_values.get(&id) {
|
||||
if let Some((expr, let_type)) = ctx.let_values.get_mut(&id).and_then(|s| s.pop()) {
|
||||
match let_type {
|
||||
ast::LetType::Lazy => {
|
||||
let expr = ctx.let_values.remove(&id).unwrap().0;
|
||||
emit_expression(ctx, expr);
|
||||
ctx.let_values.get_mut(&id).unwrap().clear();
|
||||
ctx.function
|
||||
.instruction(&Instruction::LocalTee(ctx.locals[id].index.unwrap()));
|
||||
}
|
||||
ast::LetType::Inline => {
|
||||
let expr = *expr;
|
||||
emit_expression(ctx, expr);
|
||||
ctx.let_values.get_mut(&id).unwrap().push((expr, let_type));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
8
test/xorshift.cwa
Normal file
8
test/xorshift.cwa
Normal file
@@ -0,0 +1,8 @@
|
||||
// simple test to see whether lazy/inline chains with the same variable compile correctly
|
||||
|
||||
fn xorshift(x: i32) -> i32 {
|
||||
let lazy x = x ^ (x << 13);
|
||||
let lazy x = x ^ (x #>> 17);
|
||||
let inline x = x ^ (x << 5);
|
||||
x
|
||||
}
|
||||
Reference in New Issue
Block a user