duskos

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

commit 0c76db4d8cfe5fda1ff9ebee84e7eb6cf634e194
parent bf64567e2fb0e616a17ece781e92f1a099607145
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed,  5 Jul 2023 13:10:15 -0400

comp/c: struct sizes are always aligned to 4b

This prevents unaligned access in struct arrays.

Diffstat:
Mfs/comp/c/fgen.fs | 2+-
Mfs/comp/c/gen.fs | 2+-
Mfs/comp/c/type.fs | 9+++------
Mfs/emul/uxn/vm.c | 4----
Mfs/tests/comp/c/cc.fs | 2+-
Mfs/tests/comp/c/type.fs | 2+-
6 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/fs/comp/c/fgen.fs b/fs/comp/c/fgen.fs @@ -143,7 +143,7 @@ MAXSWITCHCASES << Stack :new structbind Stack _cases \ array is a Stack : _copyArray ( array cdecl -- ) - dup CDecl :elemsize >r >r \ V1=sz V2=cdecl + dup CDecl :typesize >r >r \ V1=sz V2=cdecl dup Stack :count V1 * tuck ( arraysz stack arraysz ) _litarena :[ V1 writeStack _litarena :] ( arraysz a ) litn r> dup, CDecl :halop @, litn compile move rdrop ; diff --git a/fs/comp/c/gen.fs b/fs/comp/c/gen.fs @@ -25,7 +25,7 @@ require /sys/scratch.fs '=' readChar? if ( cdecl ) nextt parseExpression case ( cdecl ) ExprOp :isconst? of r@ ExprOp arg , endof - ExprOp :isarray? of r@ ExprOp arg over CDecl :elemsize writeStack endof + ExprOp :isarray? of r@ ExprOp arg over CDecl :typesize writeStack endof _err endcase else to nexttputback dup CDecl :size allot then ( cdecl ) ',' readChar? if diff --git a/fs/comp/c/type.fs b/fs/comp/c/type.fs @@ -103,13 +103,10 @@ struct[ CDecl \ Combined size of all fields in the LL. : :size ( self -- size ) dup :isarg? over :funcsig? or if drop CELLSZ exit then - 0 swap begin ( res cdecl ) ?dup while + r! 0 swap begin ( res cdecl ) ?dup while \ V1=self tuck dup :typesize ( cdecl res cdecl n ) - swap nbelem 1 max * + swap llnext repeat ( res ) ; - - \ When the CDecl is an array, return the size of a single element. - : :elemsize ( self -- size ) - dup nbelem _assert :typesize ; + swap nbelem 1 max * + swap llnext repeat ( res ) + r> :struct? if align4 then ; : :argssize ( self -- size ) dup :funcsig? _assert args llcnt CELLSZ * ; diff --git a/fs/emul/uxn/vm.c b/fs/emul/uxn/vm.c @@ -17,10 +17,6 @@ typedef void (*VMOP) (); static uchar ram[$10000]; static Stack wst, rst, *src, *dst; -// TODO: This is probably broken on ARM. Device's total size is uneven. The -// fields are aligned, so access to dev[0] is fine, but access to dev[1] will be -// unaligned. Struct size need to be aligned to 4b, but this will need careful -// adjustments to CDecl. static Device dev[$10]; static ushort pc; // Program Counter static int bs; // byte/short 0=byte 1=short diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs @@ -123,7 +123,7 @@ to' myval ptrari4 # 42 unaryop1 42 #eq to' myval unaryop2 to' myval #eq myval 42 #eq -ptrari5 6 + @ 42 #eq +ptrari5 8 + @ 42 #eq 123 456 ptrari6 123 456 + #eq $1234 2 ptrari7 $1238 #eq ptrari8 @ 42 #eq \ struct that was changed in ptrari5() diff --git a/fs/tests/comp/c/type.fs b/fs/tests/comp/c/type.fs @@ -18,7 +18,7 @@ _parse short STOP TYPE_SHORT #eq _parse void STOP TYPE_VOID #eq _parse struct Struct1 { unsigned int foo; short *bar; char baz[2]; } STOP -( type ) dup typesize 10 #eq +( type ) dup typesize 12 #eq \ struct sizes are aligned to 4b S" bar" over CDecl :find dup CDecl type TYPE_SHORT #eq dup CDecl lvl 1 #eq