diff --git a/harbour/harbour.spec b/harbour/harbour.spec index 595ba01ffe..50226fd508 100644 --- a/harbour/harbour.spec +++ b/harbour/harbour.spec @@ -56,7 +56,7 @@ %define name harbour %define dname Harbour -%define version 0.46.1 +%define version 0.46.2 %define releasen 0 %define hb_pref hb %define hb_arch export HB_ARCHITECTURE=linux diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 951b11c9ce..dc57281809 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -542,6 +542,13 @@ extern HB_EXPORT void * hb_xmemset( void * pDestArg, int iFill, ULONG ulLen ); / typedef HB_GARBAGE_FUNC( HB_GARBAGE_FUNC_ ); typedef HB_GARBAGE_FUNC_ * HB_GARBAGE_FUNC_PTR; +#define HB_GARBAGE_SWEEPER( hbfunc ) BOOL hbfunc( void * Cargo ) /* callback function for cleaning garbage memory pointer */ +typedef HB_GARBAGE_SWEEPER( HB_GARBAGE_SWEEPER_ ); +typedef HB_GARBAGE_SWEEPER_ * HB_GARBAGE_SWEEPER_PTR; + +extern void hb_gcRegisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo ); +extern void hb_gcUnregisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo ); + extern PHB_ITEM hb_gcGripGet( HB_ITEM_PTR pItem ); extern void hb_gcGripDrop( HB_ITEM_PTR pItem ); diff --git a/harbour/include/hbver.h b/harbour/include/hbver.h index e520100e8b..936bd4390b 100644 --- a/harbour/include/hbver.h +++ b/harbour/include/hbver.h @@ -67,8 +67,8 @@ /* NOTE: The next two fields are automatically updated by the hbverfix program */ -#define HB_VER_LENTRY "2006-05-29 14:10 UTC+0100 Ryszard Glab" -#define HB_VER_CHLCVS "ChangeLog,v 1.4894 2006/05/29 11:59:37 rglab" +#define HB_VER_LENTRY "2006-05-30 12:09 UTC+0300 Chen Kedem" +#define HB_VER_CHLCVS "ChangeLog,v 1.4896 2006/05/30 09:09:16 ckedem" /* TOFIX: The next three fields need to get updated automatically */ diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index f0183d1700..42fe0032d4 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -2306,12 +2306,7 @@ USHORT hb_compVariableGetPos( PVAR pVars, char * szVarName ) /* returns the orde { if( pVars->szName && ! strcmp( pVars->szName, szVarName ) ) { - if ( hb_comp_iWarnings < 3 ) - pVars->iUsed |= VU_USED; - /* - else - Handled by hb_compStrongType() - */ + pVars->iUsed |= VU_USED; return wVar; } diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index eb5f83cc2b..3b8aa6b2ac 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1460,9 +1460,9 @@ IfElse : ELSE Crlf { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; } EmptyStats ; -IfElseIf : ELSEIF { hb_compLinePush(); } Expression Crlf - { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; - hb_compExprDelete( hb_compExprGenPush( $3 ) ); +IfElseIf : ELSEIF { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; hb_compLinePush(); } + Expression Crlf + { hb_compExprDelete( hb_compExprGenPush( $3 ) ); $$ = hb_compGenJumpFalse( 0 ); } EmptyStats @@ -1470,9 +1470,9 @@ IfElseIf : ELSEIF { hb_compLinePush(); } Expression Crlf hb_compGenJumpHere( $5 ); } - | IfElseIf ELSEIF { hb_compLinePush(); } Expression Crlf - { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; - hb_compExprDelete( hb_compExprGenPush( $4 ) ); + | IfElseIf ELSEIF { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; hb_compLinePush(); } + Expression Crlf + { hb_compExprDelete( hb_compExprGenPush( $4 ) ); $$ = hb_compGenJumpFalse( 0 ); } EmptyStats diff --git a/harbour/source/vm/garbage.c b/harbour/source/vm/garbage.c index 3d0344abed..1702a7cd70 100644 --- a/harbour/source/vm/garbage.c +++ b/harbour/source/vm/garbage.c @@ -104,6 +104,15 @@ static HB_GARBAGE_PTR s_pCurrBlock = NULL; /* pointer to locked memory blocks */ static HB_GARBAGE_PTR s_pLockedBlock = NULL; +/* list of functions that sweeps external memory blocks */ +typedef struct _HB_GARBAGE_EXTERN { + HB_GARBAGE_SWEEPER_PTR pFunc; + void * pBlock; + struct _HB_GARBAGE_EXTERN *pNext; +} HB_GARBAGE_EXTERN, *HB_GARBAGE_EXTERN_PTR; + +static HB_GARBAGE_EXTERN_PTR s_pSweepExtern = NULL; + /* pointer to memory blocks that will be deleted */ static HB_GARBAGE_PTR s_pDeletedBlock = NULL; @@ -397,6 +406,62 @@ void hb_gcItemRef( HB_ITEM_PTR pItem ) /* all other data types don't need the GC */ } +/* Register a function which sweeps memory blocks stored outside of + * internal harbour structures + * + * NOTICE!: Cargo have to be a pointer to memory allocated with + * hb_gcAlloc() + */ +void hb_gcRegisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo ) +{ + HB_GARBAGE_EXTERN_PTR pExt; + + pExt = ( HB_GARBAGE_EXTERN_PTR ) hb_xgrab( sizeof( HB_GARBAGE_EXTERN ) ); + pExt->pFunc = pSweep; + pExt->pBlock = Cargo; + pExt->pNext = NULL; + + if( s_pSweepExtern == NULL ) + { + s_pSweepExtern = pExt; + } + else + { + pExt->pNext = s_pSweepExtern; + s_pSweepExtern = pExt; + } + +} + +void hb_gcUnregisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo ) +{ + HB_GARBAGE_EXTERN_PTR pExt; + HB_GARBAGE_EXTERN_PTR pPrev; + + pPrev = pExt = s_pSweepExtern; + while( pExt ) + { + if( pExt->pFunc == pSweep && pExt->pBlock == Cargo ) + { + if( pExt == s_pSweepExtern ) + { + s_pSweepExtern = pExt->pNext; + } + else + { + pPrev->pNext = pExt->pNext; + } + + hb_xfree( (void *) pExt ); + pExt = NULL; + } + else + { + pPrev = pExt; + pExt = pExt->pNext; + } + } +} void hb_gcCollect( void ) { @@ -426,6 +491,23 @@ void hb_gcCollectAll( void ) hb_memvarsIsMemvarRef(); hb_gcItemRef( hb_stackReturnItem() ); hb_clsIsClassRef(); + + if( s_pSweepExtern ) + { + HB_GARBAGE_EXTERN_PTR pExt = s_pSweepExtern; + + do + { + if( ( pExt->pFunc )( pExt->pBlock ) ) + { + /* block is still used */ + pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pExt->pBlock - HB_GARBAGE_SIZE ); + pAlloc->used ^= HB_GC_USED_FLAG; + } + pExt = pExt->pNext; + } + while( pExt ); + } /* check list of locked block for blocks referenced from * locked block