duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit f513fb21947f001c52a1ff283e2e7c4038d1158f
parent 778f643dbfe9a81ee03f6dc26f8a841f5b8717af
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sun,  2 Apr 2023 21:08:56 -0400

halcc: fix funcsig/rettype mixup

Diffstat:
Mfs/comp/c/egen.fs | 2+-
Mfs/comp/c/ptype.fs | 4+++-
Mfs/comp/c/type.fs | 4+++-
Mfs/tests/comp/c/cc.fs | 1+
Mfs/tests/comp/c/test.c | 8++++++++
5 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs @@ -131,7 +131,7 @@ code _callA branchA, rdrop r> ( psinitlvl ) to psoff Result currentW ?dup if PS- Result :release then \ TODO: arilvl of fun rettype isn't properly preserved here - CDecl type if PS+ Result :W else Result :none then ; + CDecl :rettype if PS+ Result :W else Result :none then ; : _incdec, ( res incsz -- res ) Result :?freeCurrentW over Result :*arisz * diff --git a/fs/comp/c/ptype.fs b/fs/comp/c/ptype.fs @@ -44,7 +44,9 @@ alias _err parseDeclarator ( type -- cdecl ) \ forward declaration endcase again ; : _parseDeclarator ( type -- cdecl ) - 0 begin ( type lvl ) + 0 over cdecl? if over CDecl :funcptr? if + dip bi CDecl type | CDecl lvl | + then then ( type lvl ) + begin ( type lvl ) '*' readChar? while ( type lvl tok ) 1+ repeat ( type lvl tok ) dup '(' isChar? if ( type lvl tok ) \ Complex type parsing is messed up. Example "int (*foo)[42]", a pointer to diff --git a/fs/comp/c/type.fs b/fs/comp/c/type.fs @@ -82,8 +82,10 @@ struct[ CDecl dup lvl if drop 0 else _ then ; : :structarrow? ( self -- f ) \ is an indirect Struct reference? dup lvl 1 = if _ else drop 0 then ; - : :funcptr? ( self -- f ) bi lvl 1 = | type :funcsig? and ; + : :funcptr? ( self -- f ) bi lvl 1 = | type bi cdecl? | :funcsig? and and ; : :constfuncsig? ( self -- f ) bi :funcsig? | :isglobal? and ; + : :rettype + dup :funcptr? if type :rettype else dup :funcsig? _assert type then ; \ Arrays, function signatures and struct ident "naturally" yield references. : :reference? bi+ nbelem bool | :funcsig? or swap :structdot? or ; diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs @@ -122,6 +122,7 @@ ptrari5 6 + @ 42 #eq $1234 2 ptrari7 $1238 #eq funcall1 138 #eq 42 funcall2 85 #eq +funcall3 scnt not # \ no PS leak/underflow 41 switch1 41 #eq 42 switch1 43 #eq switch2 42 #eq diff --git a/fs/tests/comp/c/test.c b/fs/tests/comp/c/test.c @@ -524,6 +524,14 @@ int funcall1() { int funcall2(int x) { return adder(++x, 42); } + +// Function signature type is correctly recognised in typedefs +typedef void (*Voider)(); +int funcall3() { + Voider x = cnoop; + void (*y)() = cnoop; + x(); y(); // no PS leak/underflow +} // There used to be a bug in the forth VM where an expression (something that // isn't a simple reference, but the result of a computation) with an arg on PS // would mess PS up.