Skip to content

Commit 54578cb

Browse files
committed
Fix reference reads for pointer-represented values
1 parent 1e780c7 commit 54578cb

4 files changed

Lines changed: 58 additions & 1 deletion

File tree

ref_struct_stack_crash.lyte

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Minimal repro for stack backend handling of reference parameters to structs.
2+
// Expected behavior: both stack and LLVM finish successfully.
3+
// Observed with lyte rev 1e780c772cbf68eeec7584a188d16eb24b5ca830:
4+
// --backend llvm finishes successfully
5+
// --backend stack exits abruptly with code -1 and no diagnostic
6+
7+
struct Grain {
8+
phase: f32,
9+
gain: f32
10+
}
11+
12+
process_grain(grain: &Grain, amount: f32) -> f32 {
13+
grain.phase = grain.phase + amount
14+
grain.gain = grain.gain * 2.0
15+
grain.phase + grain.gain
16+
}
17+
18+
main {
19+
var grain: Grain
20+
grain.phase = 1.0
21+
grain.gain = 2.0
22+
let out = process_grain(grain, 1.0)
23+
assert(out == 6.0)
24+
assert(grain.phase == 2.0)
25+
assert(grain.gain == 4.0)
26+
}

src/stack_codegen.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,9 @@ impl<'a> FunctionTranslator<'a> {
10661066
}
10671067
LocalKind::Reference(slot) => {
10681068
func.emit(StackOp::LocalGet(slot));
1069-
self.emit_load(&ty, func);
1069+
if !self.is_ptr_type(&ty) {
1070+
self.emit_load(&ty, func);
1071+
}
10701072
}
10711073
LocalKind::Memory(slot) => {
10721074
if self.is_ptr_type(&ty) {

src/vm_codegen.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,9 @@ impl<'a> FunctionTranslator<'a> {
882882
// Check if it's a local variable.
883883
if let Some(&reg) = self.variables.get(name) {
884884
if self.reference_vars.contains(name) {
885+
if self.is_ptr_type(&ty) {
886+
return reg;
887+
}
885888
let dst = self.alloc_reg();
886889
self.emit_load(&ty, dst, reg, func);
887890
dst
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// expected stdout:
2+
// compilation successful
3+
// assert(true)
4+
// assert(true)
5+
// assert(true)
6+
7+
struct Grain {
8+
phase: f32,
9+
gain: f32
10+
}
11+
12+
process_grain(grain: &Grain, amount: f32) -> f32 {
13+
grain.phase = grain.phase + amount
14+
grain.gain = grain.gain * 2.0
15+
grain.phase + grain.gain
16+
}
17+
18+
main {
19+
var grain: Grain
20+
grain.phase = 1.0
21+
grain.gain = 2.0
22+
let out = process_grain(grain, 1.0)
23+
assert(out == 6.0)
24+
assert(grain.phase == 2.0)
25+
assert(grain.gain == 4.0)
26+
}

0 commit comments

Comments
 (0)