about summary refs log tree commit diff
path: root/transform.e
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-09-09 22:54:07 -0700
committerIrene Knapp <ireneista@irenes.space>2026-09-09 22:54:07 -0700
commitc4489fe965c1b955229f671d893ca1db46394def (patch)
treef603061ed68df2d99111d6220a10eb06a05e7e1c /transform.e
parent2718d51422f83c53104b0daa849419784a1c91b5 (diff)
deal better with return values when underflowing the substring entry stack
it's now able to run all the way to the end of the label transform, inside the hex transform. the output leaves much to be desired, but it runs.

Force-Push: yes
Change-Id: I7cac39df599e8081fac6b050dfeb34e598bb54eb
Diffstat (limited to 'transform.e')
-rw-r--r--transform.e92
1 files changed, 58 insertions, 34 deletions
diff --git a/transform.e b/transform.e
index 38cd951..95475c2 100644
--- a/transform.e
+++ b/transform.e
@@ -3311,7 +3311,9 @@ allocate-transformation-state s" transformation-state" variable
 
     substring-entry-stack-depth@ 1+ substring-entry-stack-depth!
   } {
+    ~ We still consume the value, so that our caller doesn't crash.
     drop
+
     ." Substring entry stack overflow." newline
   } if-else ;
 
@@ -3324,6 +3326,9 @@ allocate-transformation-state s" transformation-state" variable
     substring-entry-stack-depth@ 8 * + @
   } {
     ." Substring entry stack underflow." newline
+
+    ~ We still return a value, so that our caller doesn't crash.
+    0
   } if-else ;
 
 ~ (data start, data length, entry type, string pointer, entry pointer --)
@@ -3762,38 +3767,44 @@ allocate-transformation-state s" transformation-state" variable
 
         pop-substring-entry-stack
 
-        dup hex-output-metadata-entry-type @
-        hex-output-metadata-entry-type-push-substring-decimal = {
-          dup hex-output-metadata-entry-string @ .
-        } if
-
-        dup hex-output-metadata-entry-type @
-        hex-output-metadata-entry-type-push-substring-hex8 = {
-          ." 0x"
-          dup hex-output-metadata-entry-string @ .hex8
-        } if
-
-        dup hex-output-metadata-entry-type @
-        hex-output-metadata-entry-type-push-substring-hex16 = {
-          ." 0x"
-          dup hex-output-metadata-entry-string @ .hex16
-        } if
-
-        dup hex-output-metadata-entry-type @
-        hex-output-metadata-entry-type-push-substring-hex32 = {
-          ." 0x"
-          dup hex-output-metadata-entry-string @ .hex32
-        } if
-
-        dup hex-output-metadata-entry-type @
-        hex-output-metadata-entry-type-push-substring-hex64 = {
-          ." 0x"
-          dup hex-output-metadata-entry-string @ .hex64
-        } if
-
-        dup hex-output-metadata-entry-type @
-        hex-output-metadata-entry-type-push-substring-string = {
-          dup hex-output-metadata-entry-string @ emitstring
+        ~   If we underflowed the stack, we got zero back, so make sure not to
+        ~ crash. A crash here would be a pain to debug because it would be
+        ~ unclear how much of the overall system is working, and it's a
+        ~ complex system.
+        dup {
+          dup hex-output-metadata-entry-type @
+          hex-output-metadata-entry-type-push-substring-decimal = {
+            dup hex-output-metadata-entry-string @ .
+          } if
+
+          dup hex-output-metadata-entry-type @
+          hex-output-metadata-entry-type-push-substring-hex8 = {
+            ." 0x"
+            dup hex-output-metadata-entry-string @ .hex8
+          } if
+
+          dup hex-output-metadata-entry-type @
+          hex-output-metadata-entry-type-push-substring-hex16 = {
+            ." 0x"
+            dup hex-output-metadata-entry-string @ .hex16
+          } if
+
+          dup hex-output-metadata-entry-type @
+          hex-output-metadata-entry-type-push-substring-hex32 = {
+            ." 0x"
+            dup hex-output-metadata-entry-string @ .hex32
+          } if
+
+          dup hex-output-metadata-entry-type @
+          hex-output-metadata-entry-type-push-substring-hex64 = {
+            ." 0x"
+            dup hex-output-metadata-entry-string @ .hex64
+          } if
+
+          dup hex-output-metadata-entry-type @
+          hex-output-metadata-entry-type-push-substring-string = {
+            dup hex-output-metadata-entry-string @ emitstring
+          } if
         } if
 
         ~   Tidy up. We want to treat the next character normally, so we
@@ -3804,11 +3815,16 @@ allocate-transformation-state s" transformation-state" variable
           ~ (input point, first non-word character or 0, word pointer)
           drop
 
+          ~   If we underflow the stack, we'll get zeroes back here. In order
+          ~ to avoid causing more confusing problems later, we make sure to
+          ~ discard the zeroes instead of pushing them. As above, the
+          ~ reasoning is that it's easier to diagnose what's wrong with this
+          ~ subsystem when it runs to completion.
           pop-substring-entry-stack
           pop-substring-entry-stack
           swap
-          push-substring-entry-stack
-          push-substring-entry-stack
+          dup { push-substring-entry-stack } { drop } if-else
+          dup { push-substring-entry-stack } { drop } if-else
 
           ~   We want to ignore the next character, so that this word can be
           ~ used without creating spurious spaces in the output.
@@ -3851,6 +3867,14 @@ allocate-transformation-state s" transformation-state" variable
 ~
 ~ (length to write, base address --)
 : hex-sys-write-replacement
+  ~   In intended operation, the code under transformation is a compilation
+  ~ process, and it won't output anything that isn't executable binary.
+  ~ However, while developing, it's common to have crashes, and it's nice to
+  ~ get the crash dump as ASCII rather than hex.
+  dup is-in-label-loop-buffer not {
+    sys-write exit
+  } if
+
   postprocess-metadata-entries
 
   { over 0 <= } {