commit 0e1a10e67eb2e7a1d8f9f6feebf499ed07b4e60e
parent d6c5cc159cb4924fe9133c47000593e380dfd2f3
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Tue, 11 Oct 2022 09:07:53 -0400
cc/vm/forth: fix bug with postop applied to struct fields
Diffstat:
4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/cc/type.fs b/fs/cc/type.fs
@@ -123,10 +123,10 @@ struct[ CType
dup :struct? _assert \ we can only export structs
dup name NEXTWORD ! struct[ llnext begin ( ctype )
?dup while
- dup name dup stype spc> NEXTWORD ! dup nbelem if ( ctype )
- SZ &+ dup type _typesize over nbelem * dup .x nl> sallot
+ dup name NEXTWORD ! dup nbelem if ( ctype )
+ SZ &+ dup type _typesize over nbelem * sallot
else ( ctype )
- dup type _typesize dup .x nl> case
+ dup type _typesize case
1 of = sfieldb endof
2 of = sfieldw endof
sfield endcase then ( ctype )
diff --git a/fs/cc/vm/forth.fs b/fs/cc/vm/forth.fs
@@ -138,7 +138,8 @@ unopmut vm--op, 1-
: apply ( w a -- n ) \ Same as unop's apply, but yield old value
tuck @ ( a w old ) dup rot execute ( a old new ) rot ! ;
: postop doer ' , does> @ ( w ) litn PS+
- vmop :&op vmop :compile vmop :forgetTOS compile apply PS- vmop :>TOS ;
+ vmop :&op vmop :TOS? if compile swap else vmop :compile then
+ vmop :forgetTOS compile apply PS- vmop :>TOS ;
postop vmop++, 1+
postop vmop--, 1-
diff --git a/fs/tests/cc/cc.fs b/fs/tests/cc/cc.fs
@@ -70,6 +70,7 @@ globdata 4 + 16b @ 42 #eq
'2' binop2 44 #eq
binop3 $605 #eq
structop1 44 #eq
+structop2 45 #eq
\ and what about inline functions?
:c int myinline() { return 42; }
diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c
@@ -290,6 +290,11 @@ short structop1() {
globdata.bar += 2;
return globdata.bar;
}
+// postop on a struct field failed under the Forth VM
+int structop2() {
+ globdata.bar++;
+ return globdata.bar;
+}
// we used to leak VM ops in condition blocks without {}
void cond1() {
int x = 42;