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>,
|
functions: &'a HashMap<String, u32>,
|
||||||
locals: &'a ast::Locals,
|
locals: &'a ast::Locals,
|
||||||
labels: Vec<String>,
|
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,
|
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()));
|
.instruction(&Instruction::LocalSet(local.index.unwrap()));
|
||||||
}
|
}
|
||||||
ast::LetType::Lazy | ast::LetType::Inline => {
|
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 } => {
|
ast::Expr::Variable { name, local_id } => {
|
||||||
if let &Some(id) = 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 {
|
match let_type {
|
||||||
ast::LetType::Lazy => {
|
ast::LetType::Lazy => {
|
||||||
let expr = ctx.let_values.remove(&id).unwrap().0;
|
|
||||||
emit_expression(ctx, expr);
|
emit_expression(ctx, expr);
|
||||||
|
ctx.let_values.get_mut(&id).unwrap().clear();
|
||||||
ctx.function
|
ctx.function
|
||||||
.instruction(&Instruction::LocalTee(ctx.locals[id].index.unwrap()));
|
.instruction(&Instruction::LocalTee(ctx.locals[id].index.unwrap()));
|
||||||
}
|
}
|
||||||
ast::LetType::Inline => {
|
ast::LetType::Inline => {
|
||||||
let expr = *expr;
|
|
||||||
emit_expression(ctx, expr);
|
emit_expression(ctx, expr);
|
||||||
|
ctx.let_values.get_mut(&id).unwrap().push((expr, let_type));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => 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