about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--elf.e3
-rw-r--r--evoke.e6
-rw-r--r--labels.e13
-rw-r--r--transform.e84
4 files changed, 100 insertions, 6 deletions
diff --git a/elf.e b/elf.e
index 5f0cfc4..1d2d7a0 100644
--- a/elf.e
+++ b/elf.e
@@ -68,6 +68,7 @@
   ~ to use the label system to keep track of its size. The only place this is
   ~ actually referenced is right here in the header.
   current-offset 4 roll - L!' elf-header-size
+  L' elf-header-size set-label-non-offset
   ~ : deindent
   ;
 
@@ -124,6 +125,7 @@
   ~   As with the file header, we use the label system to keep track of the
   ~ program header's size.
   current-offset 4 roll - L!' elf-program-header-size
+  L' elf-program-header-size set-label-non-offset
   ~ : deindent
   ;
 
@@ -157,6 +159,7 @@
   ~   As with the file header, we use the label system to keep track of the
   ~ program header's size.
   current-offset 4 roll - L!' elf-program-header-size
+  L' elf-program-header-size set-label-non-offset
   ~ : deindent
   ;
 
diff --git a/evoke.e b/evoke.e
index 8faed81..b9fea2e 100644
--- a/evoke.e
+++ b/evoke.e
@@ -21,6 +21,12 @@ s" source-to-precompile" variable
   ~ :   This particular program is 'evoke', the compiler. If you already have
   ~ : a binary copy of 'hex', run this file through it and you'll have a
   ~ : working compiler. Pretty sweet, right?
+  ~ :
+  ~ :   If you're auditing this by hand, first off, thank you for doing that.
+  ~ : You may wish to pull up the source code side-by-side with the hex dump;
+  ~ : there's a lot of structural stuff in the actual source that aids in
+  ~ : readability but isn't easily reproduced in this form, though every
+  ~ : effort has been made.
   ~ : blank-line
   0x08000000 L!' origin
 
diff --git a/labels.e b/labels.e
index f528219..6ac26b2 100644
--- a/labels.e
+++ b/labels.e
@@ -137,7 +137,7 @@
   label-value @ ;
 
 ~   This overwrites the value of a label, also doing all necessary status
-~ checks and jupdates to keep track of the cirumstances under which it was
+~ checks and updates to keep track of the cirumstances under which it was
 ~ set. The label loop relies on all write accesses going through this word.
 ~
 ~ (new label value, label entry pointer --)
@@ -169,6 +169,17 @@
   ~ (updated status, entry, new value, entry)
   label-value ! label-status ! ;
 
+~   Since labels have dictionary entry headers but aren't in the main
+~ dictionary, we get to use the entry flag bits for other things. The only one
+~ we have right now is a feature that acts as a hint to anything trying to
+~ display metadata about labels, to the effect that this one represents
+~ something other than an offset in the file.
+~
+~ (label entry pointer --)
+: set-label-non-offset dup entry-flags@ 0x01 | swap entry-flags! ;
+~ (label entry pointer -- boolean)
+: is-label-non-offset entry-flags@ 0x01 & ;
+
 ~   This is a convenience helper which downstream code can use to check how
 ~ many bytes it has output thus-far.
 ~ (output memory start, current output point
diff --git a/transform.e b/transform.e
index 042f1d9..279ca72 100644
--- a/transform.e
+++ b/transform.e
@@ -2750,6 +2750,12 @@ allocate-transformation-state s" transformation-state" variable
   ~ : functionality needed for the log-load routine to run, then invoke the
   ~ : log-load routine to copy a more complete set of functionality into
   ~ : memory.
+  ~ :
+  ~ :   The log-load routine is super important, but also extremely verbose,
+  ~ : which necessarily makes it hard to read. If you're skimming this file
+  ~ : for the first time to get a sense of what it contains, you might want
+  ~ : to search for the words "label transform" to get to the stuff that makes
+  ~ : better introductory reading.
   ~ : blank-line
 
   main-input-buffer dup push-input-buffer
@@ -3373,17 +3379,17 @@ allocate-transformation-state s" transformation-state" variable
 ~ keyword from the dictionary entry header. All three of these save pointer to
 ~ their respective strings in a push-subitem-string metadata entry.
 ~
+~   Admit it, you thought writing out "metadata entry" so many times instead
+~ of just "entry" was silly because there was no other kind of entry in
+~ consideration, right up until you got to "dictionary entry". If so, hey
+~ look, neat, right? ;)
+~
 ~   The -data variant treats the value as opaque, and creates an
 ~ -entry-type-saved-data metadata entry. Unlike the others, these entries do
 ~ not affect the subitem entry stack; they're consumed and removed from the
 ~ entry array before entry execution even starts, by the matching data-*
 ~ command.
 ~
-~   Admit it, you thought writing out "metadata entry" so many times instead
-~ of just "entry" was silly because there was no other kind of entry in
-~ consideration, right up until you got to "dictionary entry". If so, hey
-~ look, neat, right? ;)
-~
 ~   Anyway, notice that when the various provide-* commands execute, all
 ~ they're doing is capturing values and creating metadata entries. Like all
 ~ metadata entries, these are attached to the latest output point as of the
@@ -4747,6 +4753,59 @@ allocate-transformation-state s" transformation-state" variable
     3unroll 1+ swap 1- swap 3roll
   } while drop ;
 
+~   This has complex logic, so we do it as a trace rather than with magic
+~ comments.
+~
+~ (new label value, label entry pointer --)
+: hex-set-label-trace
+  ~   If the value is zero, don't bother making an entry. There's a bunch of
+  ~ unused labels set to zero and even if they were used, showing them at the
+  ~ start of the file would not provide useful information.
+  over 0 = { drop drop exit } if
+
+  ~   Similarly, if the label has its non-offset bit set, we don't need an
+  ~ entry for that, either
+  ~
+  ~   It's worth noting that this bit is set by the code being compiled,
+  ~ potentially after it has already called label-set, and therefore after
+  ~ this trace. This introduces an ordering dependency, though it's unlikely
+  ~ to come up in practice because the bit is kept across label-loop passes
+  ~ and as long as there are any forward references there will always be at
+  ~ least two passes.
+  dup is-label-non-offset { drop drop exit } if
+
+  ~   Recall that label values are offsets within the output file. This is not
+  ~ otherwise a requirement, compiled code can use their values for anything
+  ~ it wants, but the label transform treats them as offsets and so does the
+  ~ ELF code.
+  ~
+  ~   We want to create metadata entries associated with that offset; recall
+  ~ also that entries' data starts are host addresses which must be within
+  ~ the label-loop buffer. So...
+  over
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-label-loop-buffer-start @ +
+  0
+  ~ (new label value, label entry pointer, entry data start,
+  ~  entry data length)
+
+  2dup hex-output-metadata-entry-type-push-subitem-hex64 7 roll
+  add-hex-output-metadata-entry
+  ~ (label entry pointer, entry data start, entry data length)
+
+  2dup hex-output-metadata-entry-type-push-subitem-string
+  6 roll entry-to-name
+
+  swap-transform-variables here @ swap-transform-variables dup 3unroll
+  ~ (copy, original, copy)
+  over stringlen 1+ memcopy
+  swap-transform-variables allocate-string swap-transform-variables
+  add-hex-output-metadata-entry
+
+  hex-output-metadata-entry-type-line-comment
+  s" label # at offset # is here."
+  add-hex-output-metadata-entry ;
+
 ~ (data start, data length --)
 : hex-pack-trace
   ~   We keep a running tally of the next address in the output, for the
@@ -5017,6 +5076,21 @@ allocate-transformation-state s" transformation-state" variable
     exit
   } if
 
+  dup s" set-label" stringcmp 0 = {
+    create dropstring
+    s" docol" find entry-to-execution-token execute ,
+    make-hidden
+
+    ~ (new label value, label entry pointer --)
+    s" 2dup" find entry-to-execution-token ,
+    ' hex-set-label-trace entry-to-execution-token ,
+    ~ Fall through to the inner implementation.
+
+    ' ] entry-to-execution-token execute
+    exit
+  } if
+
+
   dup s" packstring" stringcmp 0 = {
     create dropstring
     s" docol" find entry-to-execution-token execute ,