aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mssola@mssola.com>2026-07-07 23:15:00 +0200
committerMiquel Sabaté Solà <mssola@mssola.com>2026-07-07 23:15:00 +0200
commit6b43fd7c0773bd97c4bd80145a17d67062afd4ea (patch)
tree77cc5576da60fbd4e2fcb5297a78c84e2b7bf4a1
parentca7ff2c299dbd15b89adae73caa356584977dd46 (diff)
downloadtools.nes-6b43fd7c0773bd97c4bd80145a17d67062afd4ea.tar.gz
tools.nes-6b43fd7c0773bd97c4bd80145a17d67062afd4ea.zip
Preserve the 'accessed' member on macro arguments
Macro arguments get tampered with every time a new call has to be bundled. Deep down this is done by cloning the underlying object, but this resets any increase on the 'accessed' member, giving always the impression that macro arguments are never accessed. Fix this by at least preserving this member when cloning a macro argument. Note that this is neither the most elegant solution, and probably not the most correct. As in, it will probably get into a non-precise count after some calls. But at least it will be a non-zero value, which is more than enough to what this is actually used for. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
-rw-r--r--lib/xixanta/src/object.rs13
-rwxr-xr-xscripts/test-e2e.sh7
-rw-r--r--tests/expected/unused_macro_arg.nesbin0 -> 27 bytes
-rw-r--r--tests/expected/unused_macro_arg.txt0
-rw-r--r--tests/unused_macro_arg.s27
5 files changed, 46 insertions, 1 deletions
diff --git a/lib/xixanta/src/object.rs b/lib/xixanta/src/object.rs
index 36b15dc..08f94fd 100644
--- a/lib/xixanta/src/object.rs
+++ b/lib/xixanta/src/object.rs
@@ -343,7 +343,18 @@ impl Context {
self.to_human()
));
}
- *sc = object.clone();
+
+ match object.object_type {
+ // For macro arguments, we still want to preserve the
+ // 'accessed' member, as arguments are re-created on each
+ // use and this information might get lost in the process.
+ ObjectType::Argument => {
+ let before = sc.accessed;
+ *sc = object.clone();
+ sc.accessed = before;
+ }
+ _ => *sc = object.clone(),
+ }
}
None => {
scope.insert(id.value.clone(), object.to_owned());
diff --git a/scripts/test-e2e.sh b/scripts/test-e2e.sh
index 524c75e..9505274 100755
--- a/scripts/test-e2e.sh
+++ b/scripts/test-e2e.sh
@@ -119,6 +119,13 @@ echo "test: custom => unused_definition.nes"
diff tests/out/unused_definition.txt tests/expected/unused_definition.txt
exit_code=$((exit_code + $?))
+echo "test: custom => unused_macro_arg.nes"
+./target/debug/nasm -c empty -Werror --asan tests/unused_macro_arg.s -o tests/out/unused_macro_arg.nes 2>tests/out/unused_macro_arg.txt
+diff tests/out/unused_macro_arg.txt tests/expected/unused_macro_arg.txt
+exit_code=$((exit_code + $?))
+diff tests/out/unused_macro_arg.nes tests/expected/unused_macro_arg.nes
+exit_code=$((exit_code + $?))
+
##
# code.nes
diff --git a/tests/expected/unused_macro_arg.nes b/tests/expected/unused_macro_arg.nes
new file mode 100644
index 0000000..4a14648
--- /dev/null
+++ b/tests/expected/unused_macro_arg.nes
Binary files differ
diff --git a/tests/expected/unused_macro_arg.txt b/tests/expected/unused_macro_arg.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/expected/unused_macro_arg.txt
diff --git a/tests/unused_macro_arg.s b/tests/unused_macro_arg.s
new file mode 100644
index 0000000..fe4d7f0
--- /dev/null
+++ b/tests/unused_macro_arg.s
@@ -0,0 +1,27 @@
+.segment "HEADER"
+ .byte 'N', 'E', 'S', $1A
+ .byte $02, $01
+ .byte $00
+ .byte $00
+
+.segment "CODE"
+
+;;; asan:stack full
+
+.macro BCD_ADD ADDR
+ adc ADDR
+ bcc :+
+ nop
+:
+.endmacro
+
+.proc add_to_player_y
+ BCD_ADD additions
+
+ rts
+
+additions:
+ .byte $FF
+.endproc
+
+jsr add_to_player_y