From 126e5eba61c3ca2b74fb9e7d52c91d90e8315a0c Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Fri, 10 Jan 2025 12:46:21 +0100 Subject: Properly fill the context stack when forcing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When calling `force_context_switch` the stack was mindlessly pushing the given name without taking into consideration how scopes are to be laid out. This made some variables/addresses that were previously preserved no longer reachable when crunching pending nodes. This patch also makes `force_context_switch` reset the stack before doing anything at all, which means that `force_context_pop` was no longer relevant. Signed-off-by: Miquel Sabaté Solà --- lib/xixanta/src/assembler.rs | 50 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'lib/xixanta/src/assembler.rs') diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index f190d33..06f0b24 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -587,8 +587,6 @@ impl<'a> Assembler<'a> { } Err(e) => errors.push(e), } - - self.context.force_context_pop(); } if errors.is_empty() { @@ -2936,6 +2934,54 @@ cpx #(4 * var2)"#, assert_instruction("stx $020, y", &[0x96, 0x20]); } + #[test] + fn jsr_inside_multiple_contexts() { + let res = just_bundles( + r#".scope Movement + .proc accelerate + rts + .endproc + + .proc update + jsr accelerate + rts + .endproc +.endscope + +jsr Movement::accelerate +jsr Movement::update + "#, + ); + + assert_eq!(res.len(), 5); + + // accelerate -> rts + assert_eq!(res[0].size, 1); + assert_eq!(res[0].bytes[0], 0x60); + + // jsr accelerate + assert_eq!(res[1].size, 3); + assert_eq!(res[1].bytes[0], 0x20); + assert_eq!(res[1].bytes[1], 0x00); + assert_eq!(res[1].bytes[2], 0x80); + + // update -> rts + assert_eq!(res[2].size, 1); + assert_eq!(res[2].bytes[0], 0x60); + + // jsr Movement::accelerate + assert_eq!(res[3].size, 3); + assert_eq!(res[3].bytes[0], 0x20); + assert_eq!(res[3].bytes[1], 0x00); + assert_eq!(res[3].bytes[2], 0x80); + + // jsr Movement::update + assert_eq!(res[4].size, 3); + assert_eq!(res[4].bytes[0], 0x20); + assert_eq!(res[4].bytes[1], 0x01); + assert_eq!(res[4].bytes[2], 0x80); + } + // Control statements #[test] -- cgit v1.2.3