Skip to content

Commit

Permalink
fbc: string*n - redim and erase
Browse files Browse the repository at this point in the history
for string*n arrays and type fields
- initialize new elements to spaces
- erase static arrays with spaces
  • Loading branch information
jayrm committed Mar 9, 2024
1 parent 7122301 commit da8f145
Show file tree
Hide file tree
Showing 9 changed files with 436 additions and 8 deletions.
4 changes: 2 additions & 2 deletions changelog.txt
Expand Up @@ -11,8 +11,8 @@ Version 1.20.0
- gfxlib2: on x86 32-bit, query the cpu type for MMX capability only when setting the graphics mode with SCREEN[RES] or when setting x86 MMX feature with ScreenControl fb.SET_X86_MMX_ENABLED function
- rtlib: optimize string concatenation reallocations: do not reallocate to smaller memory buffer if the contents are to be preserved
- limit WSTRING*N, ZSTRING*N, STRING*N types to 2^31-1 and show an 'invalid size' error if the size given is less than 1 or greater than the limit
- STRING*N occupies N bytes in memory, pads the variable / field with spaces, and does not automatically append a terminating null character
- STRING*N variables and type fields are initialized to spaces by default
- STRING*N occupies N bytes in memory, pads the variable / field with spaces, and no longer automatically appends a terminating null character
- STRING*N variables, static and dynamic arrays, and UDT fields are initialized to spaces by default
- internal: types containing only STRING*N fields or child types containing only STRING*N fields will initialize to spaces using a memory fill operation, and where other data types are present will induce the creation of an implicit constructor
- unions containing STRING*N fields will initialize to spaces if the first field is a STRING*N type, otherwise will initialize to zero
- LEN(STRING*N) = SIZEOF(STRING*N) due to padding and no null terminator
Expand Down
51 changes: 46 additions & 5 deletions src/compiler/rtl-array.bas
Expand Up @@ -154,6 +154,17 @@
( FB_DATATYPE_VOID, FB_PARAMMODE_BYDESC, FALSE ) _
} _
), _
/' function fb_ArrayFill( array() as any, byval value as const long ) as long '/ _
( _
@FB_RTL_ARRAYFILL, NULL, _
FB_DATATYPE_LONG, FB_FUNCMODE_FBCALL, _
NULL, FB_RTL_OPT_NONE, _
2, _
{ _
( FB_DATATYPE_VOID, FB_PARAMMODE_BYDESC, FALSE ), _
( typeSetIsConst( FB_DATATYPE_LONG ), FB_PARAMMODE_BYVAL, FALSE ) _
} _
), _
/' function fb_ArrayClearObj _
( _
array() as any, _
Expand Down Expand Up @@ -355,15 +366,16 @@ end sub
'' destruct elements if needed and then re-initialize
''
'' fb_ArrayClear* rtlib functions are called when it is known at
'' compile time that array is static (fixed length). It it is unknown
'' compile time that array is static (fixed length). If it is unknown
'' at compile time, then rtlArrayErase() should be used instead and
'' the runtime library will do a run time check on the array's
'' descriptor flags to determine if it is static or dynamic.
''
function rtlArrayClear( byval arrayexpr as ASTNODE ptr ) as ASTNODE ptr
dim as ASTNODE ptr proc = any
dim as integer dtype = any
dim as FBSYMBOL ptr ctor = any, dtor = any, subtype = any
dim as FBSYMBOL ptr ctor = NULL, dtor = NULL, subtype = any
dim as integer fillchar = 0

function = NULL

Expand All @@ -379,9 +391,14 @@ function rtlArrayClear( byval arrayexpr as ASTNODE ptr ) as ASTNODE ptr
if( (ctor = NULL) and (symbGetCompCtorHead( subtype ) <> NULL) ) then
errReport( FB_ERRMSG_NODEFAULTCTORDEFINED )
end if
else
ctor = NULL
dtor = NULL

if( symbGetUDTHasFilledField( subtype ) ) then
fillchar = 32
end if

elseif( dtype = FB_DATATYPE_FIXSTR ) then
fillchar = 32

end if

if( (ctor <> NULL) or (dtor <> NULL) ) then
Expand Down Expand Up @@ -415,6 +432,21 @@ function rtlArrayClear( byval arrayexpr as ASTNODE ptr ) as ASTNODE ptr
if( astNewARG( proc, arrayexpr, dtype ) = NULL ) then
exit function
end if

elseif( fillchar <> 0 ) then
'' fb_ArrayFill()
proc = astNewCALL( PROCLOOKUP( ARRAYFILL ) )

'' array() as any
if( astNewARG( proc, arrayexpr, dtype ) = NULL ) then
exit function
end if

'' byval fillchar as long
if( astNewARG( proc, astNewCONSTi( fillchar ) ) = NULL ) then
exit function
end if

else
'' fb_ArrayClear()
proc = astNewCALL( PROCLOOKUP( ARRAYCLEAR ) )
Expand Down Expand Up @@ -600,6 +632,15 @@ function rtlArrayRedim _

if( (ctor = NULL) and (dtor = NULL) ) then
'' byval doclear as integer

if( doclear ) then
if( (dtype = FB_DATATYPE_FIXSTR) orelse _
((dtype = FB_DATATYPE_STRUCT) andalso _
(symbGetUDTHasFilledField( symbGetSubtype( sym ) ))) ) then
doclear = 32
end if
end if

if( astNewARG( proc, astNewCONSTi( doclear ) ) = NULL ) then
exit function
end if
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/rtl.bi
Expand Up @@ -140,6 +140,7 @@
#define FB_RTL_ARRAYDESTRUCTOBJ "fb_ArrayDestructObj"
#define FB_RTL_ARRAYDESTRUCTSTR "fb_ArrayDestructStr"
#define FB_RTL_ARRAYCLEAR "fb_ArrayClear"
#define FB_RTL_ARRAYFILL "fb_ArrayFill"
#define FB_RTL_ARRAYCLEAROBJ "fb_ArrayClearObj"
#define FB_RTL_ARRAYERASE "fb_ArrayErase"
#define FB_RTL_ARRAYERASEOBJ "fb_ArrayEraseObj"
Expand Down Expand Up @@ -551,6 +552,7 @@ enum FB_RTL_IDX
FB_RTL_IDX_ARRAYDESTRUCTOBJ
FB_RTL_IDX_ARRAYDESTRUCTSTR
FB_RTL_IDX_ARRAYCLEAR
FB_RTL_IDX_ARRAYFILL
FB_RTL_IDX_ARRAYCLEAROBJ
FB_RTL_IDX_ARRAYERASE
FB_RTL_IDX_ARRAYERASEOBJ
Expand Down
9 changes: 9 additions & 0 deletions src/rtlib/array_clear.c
Expand Up @@ -12,6 +12,7 @@
for plain arrays: fbc calls fb_ArrayClear()
for object arrays: fbc calls fb_ArrayClearObj()
for FBSTRING arrays: fbc calls fb_ArrayDestructStr()
for STRING*N arrays: fbc calls fb_ArrayFill()
*/

#include "fb.h"
Expand All @@ -23,3 +24,11 @@ FBCALL int fb_ArrayClear( FBARRAY *array )

return fb_ErrorSetNum( FB_RTERROR_OK );
}

FBCALL int fb_ArrayFill( FBARRAY *array, int fillchar )
{
if( array->ptr )
memset( array->ptr, fillchar, array->size );

return fb_ErrorSetNum( FB_RTERROR_OK );
}
7 changes: 6 additions & 1 deletion src/rtlib/array_redim.c
Expand Up @@ -75,7 +75,12 @@ int fb_hArrayAlloc
/* Allocte new buffer */
/* Clearing is not needed if not requested, or if ctors will be called
(ctors take care of clearing themselves) */
if( doclear && (ctor == NULL) )
if( doclear == 32 && (ctor == NULL) )
{
array->ptr = malloc( size );
memset( array->ptr, 32, size );
}
else if( doclear && (ctor == NULL) )
array->ptr = calloc( size, 1 );
else
array->ptr = malloc( size );
Expand Down
2 changes: 2 additions & 0 deletions src/rtlib/array_redimpresv.c
Expand Up @@ -76,6 +76,8 @@ int fb_hArrayRealloc
this_ += element_len;
--objects;
}
} else if( doclear == 32 ) {
memset( (void *)this_, 32, size - array->size );
} else if( doclear ) {
memset( (void *)this_, 0, size - array->size );
}
Expand Down
1 change: 1 addition & 0 deletions src/rtlib/fb_array.h
Expand Up @@ -52,6 +52,7 @@ FBCALL int fb_ArrayClear ( FBARRAY *array );
FBCALL int fb_ArrayClearObj ( FBARRAY *array, FB_DEFCTOR ctor, FB_DEFCTOR dtor );
FBCALL int fb_ArrayErase ( FBARRAY *array );
FBCALL int fb_ArrayEraseObj ( FBARRAY *array, FB_DEFCTOR ctor, FB_DEFCTOR dtor );
FBCALL int fb_ArrayFill ( FBARRAY *array, int fillchar );
FBCALL FBARRAY *fb_ArrayGetDesc ( FBARRAY *array );
FBCALL void fb_ArrayStrErase ( FBARRAY *array );
int fb_ArrayRedimEx ( FBARRAY *array, size_t element_len, int doclear, int isvarlen, size_t dimensions, ... );
Expand Down

0 comments on commit da8f145

Please sign in to comment.