diff options
Diffstat (limited to 'compilation/execution.e')
| -rw-r--r-- | compilation/execution.e | 178 |
1 files changed, 164 insertions, 14 deletions
diff --git a/compilation/execution.e b/compilation/execution.e index ecf5ec4..e2cb2b2 100644 --- a/compilation/execution.e +++ b/compilation/execution.e @@ -419,9 +419,15 @@ ~ pointers. It was directly jumped to from cold-start. There's nowhere to ~ return to, so it needs to never return. ~ -~ (output buffer start, output point, input string pointer -~ -- output buffer start, output point) -: output-warm-start +~ There are a few optional pieces of the warm-start routine, so here in the +~ compile-time code that builds it, we break the routine into logical pieces +~ which are assembled by calling the appropriate helpers sequentially. +~ +~ Outputting the warm-start routine should always begin by calling +~ output-warm-start-header. +~ +~ (output buffer start, output point -- output buffer start, output point) +: output-warm-start-header ~ : blank-line ~ : blank-line ~ : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ @@ -453,7 +459,6 @@ ~ While it's not actually a requirement that codeword pointers be ~ word-aligned, it's highly likely that it helps performance. (Whether it ~ does is up to Intel's microcode.) - 3unroll 8 packalign current-offset L!' warm-start ~ (input string pointer, output buffer start, output point) @@ -550,23 +555,107 @@ ~ : -8 log-load-variable #-- (codeword pointer) ~ Having done that, nothing else needs to be defined in an unusual way, so - ~ we can go ahead and dispatch to the log-load transform, and do the rest of - ~ the code through that. + ~ at this point the warm-start routine can go ahead and dispatch to the + ~ log-load transform, and do the rest of the code through that. However, to + ~ allow customization, we here in output-warm-start will let our caller take + ~ responsibility for making sure that happens. + ; - ~ (input string pointer, output buffer start, output point) - 3roll log-load-transform - ~ (output buffer start, output point) +~ This helper doesn't have any actual compile-time responsibilities, it +~ exists solely for the sake of the magic comments. +~ +~ We could have it be responsible for calling log-load-transform, but +~ honestly it's nicer letting the caller be responsible for that, since the +~ caller is also responsible for calling label-transform. +~ +~ (output buffer start, output point -- output buffer start, output point) +: output-warm-start-post-log-load-transform ~ : blank-line ~ : We're now done with the log-load routine; the next little bit of code ~ : here is the final bit of the warm-start routine. + ; + - ~ Now everything we need has been added to the log and we're almost ready - ~ to jump into it. It's inconvenient for code under the log-load transform - ~ to interact with the label system, so if we want to point - ~ main-input-buffer at a string, this is the place to do it. - ~ The next layer is built now, so let's move on to it. +~ After the log-load routine finishes, everything we need has been added to +~ the log and we're almost ready to jump into dynamic code running from the +~ log. That code still needs main-input-buffer to be set up in some way. The +~ simplest approach is to attach it directly to standard input. This helper +~ outputs a snippet that does that, structured to be used as part of the +~ warm-start routine. +~ +~ Executables that don't call output-warm-start-attach-stdin will need to +~ instead call output-warm-start-attach-boot-source. Exactly one of these must +~ be used. +~ +~ (output buffer start, output point -- output buffer start, output point) +: output-warm-start-attach-stdin + L@' litstring offset-to-target-address-space pack64 + ~ : -8 litstring #-- (codeword pointer) + s" relink-main-input-buffer-to-stdin" packstring 8 packalign + L@' log-load-find-execution-token offset-to-target-address-space pack64 + ~ : -8 log-load-find-execution-token #-- (codeword pointer) + L@' execute offset-to-target-address-space pack64 + ~ : -8 execute #-- (codeword pointer) + ; + + +~ After the log-load routine finishes, everything we need has been added to +~ the log and we're almost ready to jump into dynamic code running from the +~ log. It's inconvenient for code under the log-load transform to interact +~ with the label system, so if we want to point main-input-buffer at a string, +~ that's the place to do it. +~ +~ That's optional functionality, which any given executable may or may not +~ want to use, so it's here in this helper. If your executable is built with +~ a call to output-warm-start-attach-boot-source, it must also at some point +~ include a call to output-boot-source. +~ +~ (output buffer start, output point, input string pointer +~ -- output buffer start, output point) +: output-warm-start-attach-boot-source + L@' litstring offset-to-target-address-space pack64 + ~ : -8 litstring #-- (codeword pointer) + s" main-input-buffer" packstring 8 packalign + L@' log-load-find-execution-token offset-to-target-address-space pack64 + ~ : -8 log-load-find-execution-token #-- (codeword pointer) + L@' execute offset-to-target-address-space pack64 + ~ : -8 execute #-- (codeword pointer) + L@' lit offset-to-target-address-space pack64 + ~ : -8 lit #-- (codeword pointer) + L@' boot-source offset-to-target-address-space pack64 + ~ : -8 boot-source #-- (data pointer) + L@' 3roll offset-to-target-address-space pack64 + ~ : -8 3roll #-- (codeword pointer) + L@' litstring offset-to-target-address-space pack64 + ~ : -8 litstring #-- (codeword pointer) + s" attach-string-to-input-buffer" packstring 8 packalign + L@' log-load-find-execution-token offset-to-target-address-space pack64 + ~ : -8 log-load-find-execution-token #-- (codeword pointer) + L@' swap offset-to-target-address-space pack64 + ~ : -8 swap #-- (codeword pointer) + L@' lit offset-to-target-address-space pack64 + ~ : -8 lit #-- (codeword pointer) + 4 ~ : provide-hex + pack64 + ~ : -8 # #-- (integer literal) + L@' unroll offset-to-target-address-space pack64 + ~ : -8 unroll #-- (codeword pointer) + L@' execute offset-to-target-address-space pack64 + ~ : -8 execute #-- (codeword pointer) + ; + + +~ Once the log-load routine has been run and main-input-buffer has been +~ prepared, the next layer is built. This helper outputs the final little bit +~ of the warm-start routine, which moves on to that layer. +~ +~ Outputting the warm-start routine should always end by calling +~ output-warm-start-footer. +~ +~ (output buffer start, output point -- output buffer start, output point) +: output-warm-start-footer L@' litstring offset-to-target-address-space pack64 ~ : -8 litstring #-- (codeword pointer) s" quit" packstring 8 packalign @@ -583,6 +672,67 @@ ; +~ This helper generates a single word entry named "boot-source", flagged as +~ hidden, and outputs a string as its contents. This string is meant to be +~ used by the code generated by output-warm-start-attach-boot-source, and will +~ have no significant effects otherwise. +~ +~ The helper is expecting to be called at a point where the generated output +~ already has a dictionary, and isn't in the middle of generating any +~ routines. The usual place to call it is immediately after the label +~ transform. +~ +~ (output buffer start, output point, previous entry pointer, +~ input string pointer -- output buffer start, output point) +: output-boot-source + ~ : blank-line + ~ : blank-line + ~ : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ + ~ : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ + ~ : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ + ~ : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ : blank-line + ~ : This is the start of the boot-source, which is Forth code included + ~ : as text, and invoked by the warm-start routine. At the time it runs, + ~ : the warm-start routine and the log-load routine have both completed and + ~ : the Forth execution environment is fully ready. + ~ : + ~ : The routine is stored as a dictionary entry with the "hidden" flag + ~ : set. It has a regular entry header up to, but not including, the + ~ ; codeword. Then it has text, with a null terminator and alignment + ~ : padding at the end. + ~ : + ~ : Unfortunately, this winds up being somewhat hard to read in the hex + ~ : dump. Sorry about that. + ~ : blank-line + ~ : indent + 3unroll pack64 ~ : 8 #-- (previous entry pointer) + ~ : 1 #-- (entry flags) + 0x80 pack8 + ~ : 2 bidirectional-null-terminated entry name + 0 pack8 + ~ (output buffer start, input string pointer, output point) + + s" boot-source" + ~ We do a spurious stringlen just so the magic comments can see the + ~ string's length and use it for an appropriate adjustment. + dup stringlen + ~ : provide-data + ~ : data-adjust-length + drop + ~ : 1 suppress + packstring + 8 packalign + ~ : fresh-line + ~ (output buffer start, input string pointer, output point) + + dup 3 pick - L!' boot-source + + swap packstring 8 packalign + ~ : deindent + ; + + ~ Where next? ~ ~~~~~~~~~~~ ~ |