commit f1317253f641fb146334bc42fe4a807a5a029a2b
parent 8456f08100e83a08ee951ce4a06e6b57ed0c6aac
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Wed, 16 Nov 2022 09:59:48 -0500
cc/vm: fix ill-conceived optimisation
Constant folding for <<n, >>n and +n can only be done on straight constants, not
constant pointers! My previous logic had no sense.
Diffstat:
5 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/fs/app/uxn/vm.c b/fs/app/uxn/vm.c
@@ -25,9 +25,7 @@ unsigned char ram[$10000];
// TODO: allow single line decl
static Stack wst;
static Stack rst;
-// TODO: under i386, having a global struct pointer doesn't work and corrupts
-// memory all around.
-// static Stack *s;
+static Stack *s;
static Device dev[$10];
static unsigned short pc; // Program Counter
@@ -37,12 +35,10 @@ static void error(int code) {
}
void push8(unsigned char val) {
- Stack *s = &wst;
if (s->ptr == $ff) { error(2); } else { s->dat[s->ptr++] = val; }
}
void push(unsigned short val) {
- Stack *s = &wst;
if (s->ptr >= $fe) { error(2); } else {
s->dat[s->ptr] = val >> 8;
s->dat[s->ptr+1] = val;
@@ -51,13 +47,11 @@ void push(unsigned short val) {
}
unsigned char pop8() {
- Stack *s = &wst;
if (!s->ptr) { error(0); } else { return s->dat[--s->ptr]; }
}
unsigned short pop16() {
unsigned short val;
- Stack *s = &wst;
if (s->ptr <= 1) { error(0); } else {
s->ptr -= 2;
val = s->dat[s->ptr] << 8;
@@ -91,7 +85,6 @@ static void _err() { error(42); }
static void LIT() { push8(peek8(pc++)); }
static void INC() { push8(pop8()+1); }
static void DUP() { unsigned char x = pop8(); push8(x); push8(x); }
-// TODO: this doesn't work under i386
static void ADD() { push8(pop8() + pop8()); }
static VMOP ops[$20] = {
LIT, INC, _err, _err, _err, _err, DUP, _err,
@@ -111,5 +104,5 @@ void uxn_init() {
pc = $100;
wst.ptr = 0;
rst.ptr = 0;
- // s = &wst;
+ s = &wst;
}
diff --git a/fs/cc/type.fs b/fs/cc/type.fs
@@ -88,7 +88,7 @@ struct[ CType
: :funcptr?
type dup ctype? if
dup type*lvl 1 = swap ctype' :funcsig? and
- else 0 then ;
+ else drop 0 then ;
: :isarg? ( dnode -- f ) storage STORAGE_PS = ;
: :isglobal? ( dnode -- f ) storage STORAGE_MEM = ;
diff --git a/fs/cc/vm/commonhi.fs b/fs/cc/vm/commonhi.fs
@@ -7,15 +7,13 @@
: bothconst? vmop :foldable? vmop^ :foldable? and ;
struct+[ VMOp
- \ We use ":isconstlo?" below because it make sense to apply those operations
- \ on pointer to constants (addresses).
: :<<n over if
- dup :isconstlo? if tuck arg swap lshift swap to arg else VMOp :<<n then
+ dup :isconst? if tuck arg swap lshift swap to arg else VMOp :<<n then
else 2drop then ;
: :>>n over if
- dup :isconstlo? if tuck arg swap rshift swap to arg else VMOp :>>n then
+ dup :isconst? if tuck arg swap rshift swap to arg else VMOp :>>n then
else 2drop then ;
- : :+n over if dup :isconstlo? if to+ arg else VMOp :+n then else 2drop then ;
+ : :+n over if dup :isconst? if to+ arg else VMOp :+n then else 2drop then ;
]struct
UNOPCNT wordtbl constops ( n -- n )
diff --git a/fs/tests/cc/cc.fs b/fs/tests/cc/cc.fs
@@ -80,6 +80,7 @@ structop3 42 #eq
structop4 globdata 12 + #eq
structop5 42 #eq
structop6 54 #eq
+structop7 42 #eq
opwidth1 42 #eq
opwidth2 42 #eq
opwidth3 $129 #eq
diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c
@@ -346,6 +346,13 @@ int structop6() {
return n;
}
+MyStruct *globdataptr;
+short structop7() {
+ globdata.bar = 42;
+ globdataptr = &globdata;
+ return globdataptr->bar;
+}
+
// we used to leak VM ops in condition blocks without {}
void cond1() {
int x = 42;