diff options
| -rw-r--r-- | core.e | 2 | ||||
| -rw-r--r-- | evoke.e | 55 | ||||
| -rw-r--r-- | execution.e | 21 | ||||
| -rw-r--r-- | transform.e | 11 |
4 files changed, 37 insertions, 52 deletions
diff --git a/core.e b/core.e index 479fd26..9393a04 100644 --- a/core.e +++ b/core.e @@ -24,7 +24,7 @@ : drop [ here @ - : rax pop-reg64 + :rax pop-reg64 here ! ] ;asm : 2drop diff --git a/evoke.e b/evoke.e index 86e79c8..c1ee096 100644 --- a/evoke.e +++ b/evoke.e @@ -1,46 +1,16 @@ -~ cat labels.e elf.e execution.e transform.e evoke.e \ +~ (cat labels.e elf.e execution.e transform.e; \ +~ echo 65536 read-to-buffer; \ +~ cat core.e; \ +~ echo pyrzqxgl; \ +~ cat evoke.e) \ ~ | ./quine > evoke && chmod 755 evoke && ./evoke -1024 read-to-buffer -~ Any word that ends with a normal semicolon will require this, so its -~ definition has to be near the start. -: exit - [ here @ - :rsi pack-popcontrol - here ! ] ;asm - -: lit - [ here @ - lods64 - :rax push-reg64 - here ! ] ;asm - -: sys-exit - [ here @ - 60 :rax mov-reg64-imm64 - :rdi pop-reg64 - syscall - hlt - here ! ] ;asm - -: happy-path 42 sys-exit ; - -~ : lods64 ; -~ : :rax ; -~ : push-reg64 ; -~ : mov-reg64-imm64 ; -~ : :rdi ; -~ : pop-reg64 ; -~ : syscall ; -~ : hlt ; -~ : here ; -~ : @ ; -~ : ! ; -~ : [ ; -~ : ] ; +s" source-to-precompile" variable +1024 read-to-buffer +: foo 4 . ; pyrzqxgl -s" source-to-precompile" variable +s" source-to-heap-copy" variable ~ (output memory start, current output point ~ -- output memory start, current output point) @@ -54,10 +24,11 @@ s" source-to-precompile" variable 0x08000000 L!' origin elf-file-header elf-program-header - cold-start - warm-start + output-cold-start + source-to-heap-copy output-warm-start output-docol - source-to-precompile transform + output-exit + source-to-precompile label-transform 0 L!' final-word-name current-offset L!' total-size 0 L!' : diff --git a/execution.e b/execution.e index bd27f7e..6af9e2c 100644 --- a/execution.e +++ b/execution.e @@ -310,7 +310,7 @@ ~ ~ (output memory start, current output point ~ -- output memory start, current output point) -: cold-start +: output-cold-start current-offset L' cold-start set-label cld ~ clear the DF flag @@ -466,6 +466,7 @@ L@' warm-start L@' origin + :rsi mov-reg64-imm64 pack-next ; + ~ Routine warm-start ~ ~~~~~~~~~~~~~~~~~~ ~ @@ -473,15 +474,23 @@ ~ been initialized, and the structure of this routine is an array of codeword ~ pointers. It was directly jumped to from cold-start. There's nowhere to ~ return to, so it needs to never return. -: warm-start +~ +~ (output buffer start, output point, input string pointer +~ -- output buffer start, output point) +: output-warm-start ~ 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 + 3roll + + ~ log-load-transform + drop ~ TODO this is tied to the specific example in evoke - L@' happy-path L@' origin + pack64 + ~ L@' happy-path L@' origin + pack64 ~ Before handing off to us, cold-start pushed a single value onto the ~ stack, a pointer to the beginning of the heap. Now, we load our entire @@ -607,11 +616,15 @@ ~ We pop the control stack, and then, since this is threaded execution, we ~ do the next thing the caller wants to do, by inlining "next". ~ +~ This word would work fine with the label transformation, so we could put +~ it in core.e, but we choose to define it here because it's easier to +~ understand when it's close to the rest of the execution stuff. +~ ~ (previous entry address, output point ~ -- new entry address, output point) : output-exit s" exit" output-create - L!' exit + current-offset L!' exit :rsi pack-popcontrol pack-next ; diff --git a/transform.e b/transform.e index f8a4ee4..fc6e69e 100644 --- a/transform.e +++ b/transform.e @@ -3,6 +3,7 @@ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ ~ TODO explain what problem this is solving and why +~ The process of ~ ~ The label transform operates on code that compiles itself, and ensures ~ that the result of the compilation is suitable to be included in an @@ -300,10 +301,10 @@ allocate-transform-state s" transform-state" variable ~ analogous to "interpret", and reading interpret.e may help in understanding ~ it, though it's meant to still make sense on its own. ~ -~ It expects to be called from "transform", below, which loops. +~ It expects to be called from "label-transform", below, which loops. ~ ~ (-- done) -: transform-one +: label-transform-one word ~ If no word was returned, exit. @@ -344,7 +345,7 @@ allocate-transform-state s" transform-state" variable ~ word. First check whether we have an immediate entry, then if so, check ~ that entry's flags. Notice that this means the generated code can't ~ override an immediate word with a non-immediate word of the same name. - over dup { entry-flags@ 0x01 & not } if + over dup { entry-flags@ 0x01 & not } { not } if-else { ~ Either there was no immediate entry, or the immediate entry wasn't @@ -445,7 +446,7 @@ allocate-transform-state s" transform-state" variable ~ ~ (output buffer start, output point, input string pointer ~ -- output buffer start, output point) -: transform +: label-transform main-input-buffer dup push-input-buffer ~ TODO the arguments for this seem to be backwards from the documentation swap attach-string-to-input-buffer @@ -465,7 +466,7 @@ allocate-transform-state s" transform-state" variable ~ It's important that the stack has nothing of ours on it that persists ~ across iterations, so that client code can add and remove stuff there as ~ it sees fit. - { transform-one + { label-transform-one ~ (done) ~ When the loop is done, get the real values of "here" and "latest" |