summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--transform.e68
1 files changed, 67 insertions, 1 deletions
diff --git a/transform.e b/transform.e
index 9605341..3079414 100644
--- a/transform.e
+++ b/transform.e
@@ -2606,6 +2606,12 @@ allocate-transformation-state s" transformation-state" variable
 ~   The hex transform DOES NOT WORK yet. It's still in development.
 ~ TODO update this note when it does work
 
+~   The hex transform keeps some large, complex state as it runs, unlike the
+~ label and log-load transforms, which only require very simple state. This
+~ state is called the "output metadata"; a buffer for storing it is provided
+~ by the transform's caller, and referenced during the transform via
+~ transformation-state-output-metadata.
+~
 ~   The output metadata is a header structure followed by an array of
 ~ entry structures, as follows:
 ~
@@ -3145,7 +3151,67 @@ allocate-transformation-state s" transformation-state" variable
   ' ] entry-to-execution-token execute
   ;
 
-: hex-semicolon-alternate [ ' ; entry-to-execution-token , ]
+: hex-trace
+  ~ value@ here @ swap 0 hex-output-metadata-entry-type-line-comment
+  ~ add-hex-output-metadata-entry
+  ." tracey tracey" newline ;
+
+~   We want to trace every call to a Forth word, for use in generating
+~ metadata. To do this, we want to add a prefix trap to the calls, but we
+~ can't put the logic in hex-colon-alternate because we don't know which
+~ words are Forth words and which are assembly words until we see the
+~ semicolon.
+~
+~   So, we do it here in hex-semicolon-alternate. The word body has already
+~ been compiled at this point, so we slide the whole body forward to make
+~ room. This is explicitly allowed by our compilation model; you may be
+~ aware that it's also how high-level flow control is implemented.
+~
+~   You might find it useful to compare this code to the implementations of
+~ high-level flow-control utilities in log-load.e; it operates under a very
+~ similar set of constraints, except that fortunately we don't have the
+~ nightmare multi-dictionary situation that the log-load transform does.
+: hex-semicolon-alternate
+  latest @ entry-to-execution-token 8 +
+  dup dup dup
+  ~ (start, start, start, start)
+
+  ~   The actual body of the trap is just a single word long (see below). If
+  ~ that ever changes, make sure to keep the amount we slide by in sync with
+  ~ it.
+  8 + swap ~ TODO change number of words
+  ~ (start, start, adjusted start, start)
+
+  here @ swap -
+  ~ (start, start, adjusted start, length)
+
+  memmove
+  ~ (start)
+
+  ~   We're going to use comma to append compiled code, so let's swap out the
+  ~ value of "here" to point to the space we just opened up.
+  here @ swap here !
+  ~ (old "here")
+
+  ~   This applies to every single word terminated with semicolon, which is
+  ~ all the Forth words that are created directly rather than with "variable"
+  ~ or some similar high-level facility. Because we also can't have forward
+  ~ references, that means we can't assume we'll have any available words in
+  ~ the transformed code to call, at all. So, the only thing we can usefully
+  ~ have the trap do is call a word that's defined as part of the transform.
+  ~
+  ~   Fortunately, we do get to assume there will be a normal entry header in
+  ~ place for the word we're trapping. So we don't need to scrounge up any
+  ~ runtime data for the trap's benefit; the trap will be able to get what it
+  ~ needs by inspecting the control stack and the log.
+  ' hex-trace entry-to-execution-token ,
+
+  ~   We're done compiling the trap's contents, so swap "here" back. Again,
+  ~ keep this in sync with the length of the trap.
+  8 + here !
+
+  ~ Now we do the regular semicolon stuff.
+  [ ' ; entry-to-execution-token , ]
   ; make-immediate
 
 : hex-semicolon-assembly-alternate