From a52fe53a017ad4b0cf1561397cc383aff27c2300 Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Sat, 7 May 2022 18:33:26 +0200 Subject: [PATCH] fix let lazy/inline chains re-using the same variable --- src/emit.rs | 13 ++++++++----- test/xorshift.cwa | 8 ++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 test/xorshift.cwa diff --git a/src/emit.rs b/src/emit.rs index dd00a79..f6d6b3b 100644 --- a/src/emit.rs +++ b/src/emit.rs @@ -289,7 +289,7 @@ struct FunctionContext<'a> { functions: &'a HashMap, locals: &'a ast::Locals, labels: Vec, - let_values: HashMap, + let_values: HashMap>, 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!(), } diff --git a/test/xorshift.cwa b/test/xorshift.cwa new file mode 100644 index 0000000..0fd69d4 --- /dev/null +++ b/test/xorshift.cwa @@ -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 +} \ No newline at end of file