commit b350f881361d93aa87b572355b12cc2c5714d9a2
parent 73c0e0061e53f763a227217ec2479f2c076a8cfe
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Tue, 6 Sep 2022 16:44:42 -0400
cc: simplify vmcall, semantics
Instead of having cc/gen do direct ps+ move ops itself, add a new vmcallarg,
word to give more flexibility to the VM to handle this (will be useful for the
forth VM).
Also, remove callargallot, and simply write to PS-X offsets until vmcall, which
then has the responsibility of allocating space to PS before calling.
Writing values "under" the pointer of a hardware stack is dangerous with regards
to interrupts, but PS is not a hardware stack and push/pop operations to it are
not atomic anyways, so interrupts in Dusk will always be forbidden to access PS.
Diffstat:
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs
@@ -259,10 +259,9 @@ ASTIDCNT wordtbl gentbl ( node -- )
lastidentfound swap
oppush rot ( funcident oparg optype node )
\ pass arguments
- dup Node :childcount 1- 4 * callargallot,
- Node firstchild Node nextsibling ?dup if -4 swap begin ( cursf+ argnode )
- dup selop1 gennode swap dup selop2 ps+>op op1<>op2 vmmov, selop1 opdeinit
- 4 - swap Node nextsibling ?dup not until drop then
+ selop1 Node firstchild 0 swap begin ( idx argnode )
+ Node nextsibling ?dup while ( idx argnode )
+ dup gennode swap dup vmcallarg, 1+ swap repeat drop
\ call
oppop vmcall, ( funcident ) ?dup if dup Node id AST_FUNCTION = if
Function type if selop1 vmpspop, then else drop then then ;
diff --git a/fs/cc/vm/common.fs b/fs/cc/vm/common.fs
@@ -7,7 +7,6 @@
0 value argsz \ size of the argument portion of the SF.
0 value locsz \ size of the "local vars" portion of the SF.
-0 value callsz \ size of the args portion of a Function Call
\ Operands definition and selection
$00 const VM_NONE
diff --git a/fs/cc/vm/i386.fs b/fs/cc/vm/i386.fs
@@ -68,9 +68,6 @@ create registers AX c, BX c, CX c, DX c, SI c, DI c,
\ reinitialize selected op to VM_NONE and dealloc registers if needed
: opdeinit optype $f and VM_REGISTER = if regfree then VM_NONE optype! ;
-\ get current operand SF offset, adjusted with callsz
-: opsf+ ( -- off ) oparg callsz + ;
-
\ Deinit both ops and select Op1
: ops$
selop2 opdeinit selop1 opdeinit
@@ -85,7 +82,7 @@ create registers AX c, BX c, CX c, DX c, SI c, DI c,
VM_REGISTER of = oparg r! endof
VM_*CONSTANT of = oparg m) endof
VM_*STACKFRAME of = sp oparg d) endof
- VM_*ARGSFRAME of = bp opsf+ d) endof
+ VM_*ARGSFRAME of = bp oparg d) endof
VM_*REGISTER of = oparg r! 0 d) endof
_err endcase ;
@@ -158,13 +155,18 @@ create registers AX c, BX c, CX c, DX c, SI c, DI c,
optype if bp 0 d) opAsm mov, then
ret, ;
-: callargallot, ( bytes -- ) dup to callsz ?dup if bp i) sub, then ;
+0 value callsz \ size in bytes of args added to current call
+
+\ Write op to args
+: vmcallarg, ( idx -- ) \ idx is the index of the arg being added
+ opderef 1+ 4 * neg bp d) opAsm mov, opdeinit 4 to+ callsz ;
\ Call the address in current op. If the function has a result, you need to
\ pop it with vmpspop,
: vmcall, ( -- )
+ callsz ?dup if bp i) sub, 0 to callsz then
VM_*CONSTANT optype = if oparg VM_NONE optype! else opAsm then
- abs>rel call, opdeinit 0 to callsz ;
+ abs>rel call, opdeinit ;
\ Allocate a new register for active op and pop 4b from PS into it.
: vmpspop,