From 688bec195aec39a5b3110485f97ff185f63dddad Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Tue, 4 Jul 2006 11:27:48 +0000 Subject: [PATCH] 2006-07-04 13:20 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbstack.h * harbour/source/vm/estack.c - removed hb_stackTopItem() + added hb_stackItemBasePtr(), hb_stackAllocItem() * changed the item initialization/clearing in push/pop operation Now only complex item are cleared and it's not guaranteed that the top item will be set to NIL. In fact it was not guarantied even before my modifications. You coule be sure only that the allocated item will not be complex one and you can safely pass pointer to it to any other functions. It allow to clean a little bit some code and remove redundant and repeated setting HB_IT_NIL for allocated items. Now using hb_stackPush() can be necessary only in some very seldom cases. hb_stackAllocItem() allocates new item and returns pointer to this item. After some code cleaning hb_stackPush() is not used by core Harbour code at all so if you have it in your sources then please check if you should not update them. * harbour/source/rdd/usrrdd/usrrdd.c * use hb_vmPushNil() instead of hb_stackPush() * harbour/source/vm/arrays.c * changed hb_arrayNew() to be safe for automatic GC activation * some minor speed improvement * harbour/source/vm/codebloc.c * changed hb_codeblockNew() and hb_codeblockMacroNew() to be safe for automatic GC activation * harbour/source/vm/debug.c * use only stack function/macros instead of direct accessing hb_stack I hope that I haven't break anything. * harbour/source/vm/hvm.c ! use hb_stackAllocItem() instead of hb_stackTopItem() to make our HVM reentrant safe. This modifications also fixed some possible bugs which could be exploited by other modules which have to execute .prg code - f.e. in RDD when relation codeblock has to be executed to position record in fieldget/fieldput operations. * harbour/source/vm/itemapi.c * harbour/source/vm/memvars.c * use hb_stackAllocItem() The above modifications finish stack usage and making our HVM reentrant safe. There is only one thing which have to be fixed yet. It's HVM support for xbase++ syntax in things like: func(&), aVal[&], {&} To fix it we will have to change PCODE generated by compiler and replace some PCODEs used for current code by the new one. I will wait with this modifications for Ryszard. With the above exception now we are ready to implement destructors, add automatic GC and begin to work on MT though before that I'd like to clean the RT error support. Please carefully check if all is correct. It was modification in core code and even small typo can break whole application. --- harbour/include/hbstack.h | 26 +- harbour/source/rdd/usrrdd/usrrdd.c | 12 +- harbour/source/vm/arrays.c | 228 +++++++------- harbour/source/vm/codebloc.c | 102 +++--- harbour/source/vm/debug.c | 114 ++++--- harbour/source/vm/estack.c | 37 ++- harbour/source/vm/hvm.c | 485 ++++++++++++----------------- harbour/source/vm/itemapi.c | 11 +- harbour/source/vm/memvars.c | 8 +- 9 files changed, 493 insertions(+), 530 deletions(-) diff --git a/harbour/include/hbstack.h b/harbour/include/hbstack.h index b9d9cb9c83..dc871eda89 100644 --- a/harbour/include/hbstack.h +++ b/harbour/include/hbstack.h @@ -95,7 +95,7 @@ typedef struct #define hb_stackTopOffset( ) ( hb_stack.pPos - hb_stack.pItems ) #define hb_stackBaseOffset( ) ( hb_stack.pBase - hb_stack.pItems + 1 ) #define hb_stackTotalItems( ) ( hb_stack.wItems ) -#define hb_stackTopItem( ) ( * hb_stack.pPos ) +/*#define hb_stackTopItem( ) ( * hb_stack.pPos )*/ #define hb_stackBaseItem( ) ( * hb_stack.pBase ) #define hb_stackSelfItem( ) ( * ( hb_stack.pBase + 1 ) ) #define hb_stackItem( iItemPos ) ( * ( hb_stack.pItems + ( iItemPos ) ) ) @@ -103,7 +103,11 @@ typedef struct #define hb_stackDateBuffer( ) ( hb_stack.szDate ) #define hb_stackGetStaticsBase( ) ( hb_stack.iStatics ) #define hb_stackSetStaticsBase( n ) do { hb_stack.iStatics = ( n ); } while ( 0 ) +#define hb_stackItemBasePtr( ) ( &hb_stack.pItems ) +#define hb_stackAllocItem( ) ( ( ++hb_stack.pPos == hb_stack.pEnd ? \ + hb_stackIncrease() : (void) 0 ), \ + * ( hb_stack.pPos - 1 ) ) #define hb_stackDecrease( n ) do { \ if( ( hb_stack.pPos -= (n) ) < hb_stack.pItems ) \ @@ -125,7 +129,6 @@ typedef struct #define hb_stackPush( ) do { \ if( ++hb_stack.pPos == hb_stack.pEnd ) \ hb_stackIncrease(); \ - ( * hb_stack.pPos )->type = HB_IT_NIL; \ } while ( 0 ) #define hb_stackPopReturn( ) do { \ @@ -140,7 +143,6 @@ typedef struct hb_itemRawMove( * hb_stack.pPos, &hb_stack.Return ); \ if( ++hb_stack.pPos == hb_stack.pEnd ) \ hb_stackIncrease(); \ - ( * hb_stack.pPos )->type = HB_IT_NIL; \ } while ( 0 ) #else @@ -149,7 +151,7 @@ extern HB_ITEM_PTR hb_stackItemFromBase( int nFromBase ); extern LONG hb_stackTopOffset( void ); extern LONG hb_stackBaseOffset( void ); extern LONG hb_stackTotalItems( void ); -extern HB_ITEM_PTR hb_stackTopItem( void ); +/*extern HB_ITEM_PTR hb_stackTopItem( void );*/ extern HB_ITEM_PTR hb_stackBaseItem( void ); extern HB_ITEM_PTR hb_stackSelfItem( void ); extern HB_ITEM_PTR hb_stackItem( LONG iItemPos ); @@ -157,22 +159,24 @@ extern HB_ITEM_PTR hb_stackReturnItem( void ); extern char * hb_stackDateBuffer( void ); extern void hb_stackSetStaticsBase( int iBase ); extern int hb_stackGetStaticsBase( void ); +extern PHB_ITEM ** hb_stackItemBasePtr( void ); extern void hb_stackDec( void ); /* pops an item from the stack without clearing it's contents */ extern void hb_stackPop( void ); /* pops an item from the stack */ extern void hb_stackPush( void ); /* pushes an item on to the stack */ +extern HB_ITEM_PTR hb_stackAllocItem( void ); /* allocates new item on the top of stack, returns pointer to it */ #endif /* stack management functions */ -extern void hb_stackBaseProcInfo( char * szProcName, USHORT * puiProcLine ); /* get current .PRG function name and line number */ -extern void hb_stackDispLocal( void ); /* show the types of the items on the stack for debugging purposes */ -extern void hb_stackDispCall( void ); -extern void hb_stackFree( void ); /* releases all memory used by the stack */ -extern void hb_stackInit( void ); /* initializes the stack */ -extern void hb_stackIncrease( void ); /* increase the stack size */ +extern void hb_stackBaseProcInfo( char * szProcName, USHORT * puiProcLine ); /* get current .PRG function name and line number */ +extern void hb_stackDispLocal( void ); /* show the types of the items on the stack for debugging purposes */ +extern void hb_stackDispCall( void ); +extern void hb_stackFree( void ); /* releases all memory used by the stack */ +extern void hb_stackInit( void ); /* initializes the stack */ +extern void hb_stackIncrease( void ); /* increase the stack size */ -extern void hb_stackRemove( LONG lUntilPos ); +extern void hb_stackRemove( LONG lUntilPos ); #ifdef _HB_API_INTERNAL_ extern HB_ITEM_PTR hb_stackNewFrame( HB_STACK_STATE * pStack, USHORT uiParams ); diff --git a/harbour/source/rdd/usrrdd/usrrdd.c b/harbour/source/rdd/usrrdd/usrrdd.c index 713f041b88..0a7bca12f4 100644 --- a/harbour/source/rdd/usrrdd/usrrdd.c +++ b/harbour/source/rdd/usrrdd/usrrdd.c @@ -815,7 +815,7 @@ static ERRCODE hb_usrSysName( AREAP pArea, BYTE * szSysName ) HB_TRACE(HB_TR_DEBUG, ("hb_usrSysName(%p,%p)", pArea, szSysName)); lOffset = hb_stackTopOffset() - hb_stackBaseOffset(); - hb_stackPush(); + hb_vmPushNil(); if( !hb_usrPushMethod( SELF_USRNODE( pArea )->pMethods, UR_SYSNAME ) ) { hb_stackPop(); @@ -1145,7 +1145,7 @@ static ERRCODE hb_usrFieldName( AREAP pArea, USHORT uiIndex, void * szName ) HB_TRACE(HB_TR_DEBUG, ("hb_usrFieldName(%p,%hu,%p)", pArea, uiIndex, szName)); lOffset = hb_stackTopOffset() - hb_stackBaseOffset(); - hb_stackPush(); + hb_vmPushNil(); if( !hb_usrPushMethod( SELF_USRNODE( pArea )->pMethods, UR_FIELDNAME ) ) { hb_stackPop(); @@ -1289,7 +1289,7 @@ static ERRCODE hb_usrGetRec( AREAP pArea, BYTE ** pBuffer ) HB_TRACE(HB_TR_DEBUG, ("hb_usrGetRec(%p,%p)", pArea, pBuffer)); lOffset = hb_stackTopOffset() - hb_stackBaseOffset(); - hb_stackPush(); + hb_vmPushNil(); if( !hb_usrPushMethod( SELF_USRNODE( pArea )->pMethods, UR_GETREC ) ) { hb_stackPop(); @@ -1317,7 +1317,7 @@ static ERRCODE hb_usrGetValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) HB_TRACE(HB_TR_DEBUG, ("hb_usrGetValue(%p,%hu,%p)", pArea, uiIndex, pItem)); lOffset = hb_stackTopOffset() - hb_stackBaseOffset(); - hb_stackPush(); + hb_vmPushNil(); if( !hb_usrPushMethod( SELF_USRNODE( pArea )->pMethods, UR_GETVALUE ) ) { hb_stackPop(); @@ -1539,7 +1539,7 @@ static ERRCODE hb_usrAlias( AREAP pArea, BYTE * szAlias ) HB_TRACE(HB_TR_DEBUG, ("hb_usrAlias(%p,%p)", pArea, szAlias)); lOffset = hb_stackTopOffset() - hb_stackBaseOffset(); - hb_stackPush(); + hb_vmPushNil(); if( !hb_usrPushMethod( SELF_USRNODE( pArea )->pMethods, UR_ALIAS ) ) { hb_stackPop(); @@ -1915,7 +1915,7 @@ static ERRCODE hb_usrRelText( AREAP pArea, USHORT uiRelNo, void * pExpr ) HB_TRACE(HB_TR_DEBUG, ("hb_usrRelText(%p,%hu,%p)", pArea, uiRelNo, pExpr)); lOffset = hb_stackTopOffset() - hb_stackBaseOffset(); - hb_stackPush(); + hb_vmPushNil(); if( !hb_usrPushMethod( SELF_USRNODE( pArea )->pMethods, UR_RELTEXT ) ) { hb_stackPop(); diff --git a/harbour/source/vm/arrays.c b/harbour/source/vm/arrays.c index 0080bdd705..5443069400 100644 --- a/harbour/source/vm/arrays.c +++ b/harbour/source/vm/arrays.c @@ -110,33 +110,128 @@ static HB_GARBAGE_FUNC( hb_arrayReleaseGarbage ) HB_EXPORT BOOL hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ) /* creates a new array */ { - PHB_BASEARRAY pBaseArray = ( PHB_BASEARRAY ) hb_gcAlloc( sizeof( HB_BASEARRAY ), hb_arrayReleaseGarbage ); + PHB_BASEARRAY pBaseArray; + PHB_ITEM pItems; ULONG ulPos; HB_TRACE(HB_TR_DEBUG, ("hb_arrayNew(%p, %lu)", pItem, ulLen)); - hb_itemClear( pItem ); - - pItem->type = HB_IT_ARRAY; + if( HB_IS_COMPLEX( pItem ) ) + hb_itemClear( pItem ); + /* + * allocate memory for items before hb_gcAlloc() to be + * safe for automatic GC activation in hb_xgrab() without + * calling hb_gcLock()/hb_gcUnlock(). [druzus] + */ if( ulLen > 0 ) - pBaseArray->pItems = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) * ulLen ); + { + pItems = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) * ulLen ); + for( ulPos = 0; ulPos < ulLen; ++ulPos ) + ( pItems + ulPos )->type = HB_IT_NIL; + } else - pBaseArray->pItems = NULL; + pItems = NULL; + pBaseArray = ( PHB_BASEARRAY ) hb_gcAlloc( sizeof( HB_BASEARRAY ), hb_arrayReleaseGarbage ); + pBaseArray->pItems = pItems; pBaseArray->ulLen = ulLen; pBaseArray->uiClass = 0; pBaseArray->uiPrevCls = 0; pBaseArray->puiClsTree = NULL; - for( ulPos = 0; ulPos < ulLen; ulPos++ ) - ( pBaseArray->pItems + ulPos )->type = HB_IT_NIL; - + pItem->type = HB_IT_ARRAY; pItem->item.asArray.value = pBaseArray; return TRUE; } +HB_EXPORT BOOL hb_arraySize( PHB_ITEM pArray, ULONG ulLen ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_arraySize(%p, %lu)", pArray, ulLen)); + + if( HB_IS_ARRAY( pArray ) ) + { + PHB_BASEARRAY pBaseArray = pArray->item.asArray.value; + + if( ulLen != pBaseArray->ulLen ) + { + ULONG ulPos; + + if( pBaseArray->ulLen == 0 ) + { + pBaseArray->pItems = ( PHB_ITEM ) hb_xgrab( ulLen * sizeof( HB_ITEM ) ); + + for( ulPos = 0; ulPos < ulLen; ulPos++ ) + ( pBaseArray->pItems + ulPos )->type = HB_IT_NIL; + } + else + { + if( pBaseArray->ulLen < ulLen ) + { + pBaseArray->pItems = ( PHB_ITEM ) hb_xrealloc( pBaseArray->pItems, sizeof( HB_ITEM ) * ulLen ); + + /* set value for new items */ + for( ulPos = pBaseArray->ulLen; ulPos < ulLen; ulPos++ ) + ( pBaseArray->pItems + ulPos )->type = HB_IT_NIL; + } + else if( pBaseArray->ulLen > ulLen ) + { + /* release old items */ + for( ulPos = ulLen; ulPos < pBaseArray->ulLen; ulPos++ ) + { + if( HB_IS_COMPLEX( pBaseArray->pItems + ulPos ) ) + hb_itemClear( pBaseArray->pItems + ulPos ); + } + + if( ulLen == 0 ) + { + hb_xfree( pBaseArray->pItems ); + pBaseArray->pItems = NULL; + } + else + pBaseArray->pItems = ( PHB_ITEM ) hb_xrealloc( pBaseArray->pItems, sizeof( HB_ITEM ) * ulLen ); + } + } + + pBaseArray->ulLen = ulLen; + } + + return TRUE; + } + else + return FALSE; +} + +HB_EXPORT ULONG hb_arrayLen( PHB_ITEM pArray ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_arrayLen(%p)", pArray)); + + if( HB_IS_ARRAY( pArray ) ) + return pArray->item.asArray.value->ulLen; + else + return 0; +} + +HB_EXPORT BOOL hb_arrayIsObject( PHB_ITEM pArray ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_arrayIsObject(%p)", pArray)); + + if( HB_IS_ARRAY( pArray ) ) + return pArray->item.asArray.value->uiClass != 0; + else + return FALSE; +} + +/* retrives the array unique ID */ +HB_EXPORT void * hb_arrayId( PHB_ITEM pArray ) +{ + if( HB_IS_ARRAY( pArray ) ) + return ( void * ) pArray->item.asArray.value; + else + return NULL; +} + HB_EXPORT BOOL hb_arrayAdd( PHB_ITEM pArray, PHB_ITEM pValue ) { HB_TRACE(HB_TR_DEBUG, ("hb_arrayAdd(%p, %p)", pArray, pValue)); @@ -179,89 +274,6 @@ HB_EXPORT BOOL hb_arrayAddForward( PHB_ITEM pArray, PHB_ITEM pValue ) return FALSE; } -HB_EXPORT BOOL hb_arrayIsObject( PHB_ITEM pArray ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_arrayIsObject(%p)", pArray)); - - if( HB_IS_ARRAY( pArray ) ) - return pArray->item.asArray.value->uiClass != 0; - else - return FALSE; -} - -/* retrives the array unique ID */ -HB_EXPORT void * hb_arrayId( PHB_ITEM pArray ) -{ - if( HB_IS_ARRAY( pArray ) ) - return ( void * ) pArray->item.asArray.value; - else - return NULL; -} - -HB_EXPORT ULONG hb_arrayLen( PHB_ITEM pArray ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_arrayLen(%p)", pArray)); - - if( HB_IS_ARRAY( pArray ) ) - return pArray->item.asArray.value->ulLen; - else - return 0; -} - -HB_EXPORT BOOL hb_arraySize( PHB_ITEM pArray, ULONG ulLen ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_arraySize(%p, %lu)", pArray, ulLen)); - - if( HB_IS_ARRAY( pArray ) ) - { - PHB_BASEARRAY pBaseArray = pArray->item.asArray.value; - - if( ulLen != pBaseArray->ulLen ) - { - ULONG ulPos; - - if( pBaseArray->ulLen == 0 ) - { - pBaseArray->pItems = ( PHB_ITEM ) hb_xgrab( ulLen * sizeof( HB_ITEM ) ); - - for( ulPos = 0; ulPos < ulLen; ulPos++ ) - ( pBaseArray->pItems + ulPos )->type = HB_IT_NIL; - } - else - { - if( pBaseArray->ulLen < ulLen ) - { - pBaseArray->pItems = ( PHB_ITEM ) hb_xrealloc( pBaseArray->pItems, sizeof( HB_ITEM ) * ulLen ); - - /* set value for new items */ - for( ulPos = pBaseArray->ulLen; ulPos < ulLen; ulPos++ ) - ( pBaseArray->pItems + ulPos )->type = HB_IT_NIL; - } - else if( pBaseArray->ulLen > ulLen ) - { - /* release old items */ - for( ulPos = ulLen; ulPos < pBaseArray->ulLen; ulPos++ ) - hb_itemClear( pBaseArray->pItems + ulPos ); - - if( ulLen == 0 ) - { - hb_xfree( pBaseArray->pItems ); - pBaseArray->pItems = NULL; - } - else - pBaseArray->pItems = ( PHB_ITEM ) hb_xrealloc( pBaseArray->pItems, sizeof( HB_ITEM ) * ulLen ); - } - } - - pBaseArray->ulLen = ulLen; - } - - return TRUE; - } - else - return FALSE; -} - HB_EXPORT BOOL hb_arrayDel( PHB_ITEM pArray, ULONG ulIndex ) { HB_TRACE(HB_TR_DEBUG, ("hb_arrayDel(%p, %lu)", pArray, ulIndex)); @@ -276,7 +288,7 @@ HB_EXPORT BOOL hb_arrayDel( PHB_ITEM pArray, ULONG ulIndex ) if( ulIndex == ulLen ) { - hb_itemClear( pBaseArray->pItems + ulIndex - 1 ); + hb_itemSetNil( pBaseArray->pItems + ulIndex - 1 ); } else { @@ -306,7 +318,7 @@ HB_EXPORT BOOL hb_arrayIns( PHB_ITEM pArray, ULONG ulIndex ) if( ulIndex == ulLen ) { - hb_itemClear( pBaseArray->pItems + ulIndex - 1 ); + hb_itemSetNil( pBaseArray->pItems + ulIndex - 1 ); } else { @@ -346,7 +358,7 @@ HB_EXPORT BOOL hb_arrayGet( PHB_ITEM pArray, ULONG ulIndex, PHB_ITEM pItem ) } else { - hb_itemClear( pItem ); + hb_itemSetNil( pItem ); return FALSE; } } @@ -522,12 +534,12 @@ BOOL hb_arrayLast( PHB_ITEM pArray, PHB_ITEM pResult ) hb_itemCopy( pResult, pArray->item.asArray.value->pItems + ( pArray->item.asArray.value->ulLen - 1 ) ); else - hb_itemClear( pResult ); + hb_itemSetNil( pResult ); return TRUE; } - hb_itemClear( pResult ); + hb_itemSetNil( pResult ); return FALSE; } @@ -699,15 +711,21 @@ BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, ULONG * pulStart, ULONG * p if( ulStart + ulCount > ulLen ) /* check range */ ulCount = ulLen - ulStart + 1; - for( ulStart--; ulCount > 0; ulCount--, ulStart++ ) + if( ulCount > 0 ) { - PHB_ITEM pItem = pBaseArray->pItems + ulStart; - - hb_vmPushSymbol( &hb_symEval ); - hb_vmPush( bBlock ); - hb_vmPush( pItem ); - hb_vmPushLong( ulStart + 1 ); - hb_vmDo( 2 ); + do + { + hb_vmPushSymbol( &hb_symEval ); + hb_vmPush( bBlock ); + hb_vmPush( pBaseArray->pItems + ulStart - 1 ); + hb_vmPushLong( ulStart ); + hb_vmDo( 2 ); + } + while( --ulCount > 0 && ++ulStart < pBaseArray->ulLen ); + /* + * checking for ulStart < pBaseArray->ulLen is fix for + * possible GPF when codeblock decrease array size + */ } } diff --git a/harbour/source/vm/codebloc.c b/harbour/source/vm/codebloc.c index 2b70e45549..db5cac6bb5 100644 --- a/harbour/source/vm/codebloc.c +++ b/harbour/source/vm/codebloc.c @@ -113,14 +113,37 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, USHORT usLen ) { HB_CODEBLOCK_PTR pCBlock; + PHB_ITEM pLocals; + BYTE * pCode; HB_TRACE(HB_TR_DEBUG, ("hb_codeblockNew(%p, %hu, %p, %p, %hu)", pBuffer, uiLocals, pLocalPosTable, pSymbols, usLen)); - pCBlock = ( HB_CODEBLOCK_PTR ) hb_gcAlloc( sizeof( HB_CODEBLOCK ), hb_codeblockDeleteGarbage ); - - /* Store the number of referenced local variables + /* + * allocate memory for code block body and detach items hb_gcAlloc() + * to be safe for automatic GC activation in hb_xgrab() without + * calling hb_gcLock()/hb_gcUnlock(). [druzus] */ - pCBlock->uiLocals = uiLocals; + + if( usLen ) + { + /* + * The codeblock pcode is stored in dynamically allocated memory that + * can be deallocated after creation of a codeblock. We have to duplicate + * the passed buffer + */ + pCode = ( BYTE * ) hb_xgrab( usLen ); + memcpy( pCode, pBuffer, usLen ); + } + else + { + /* + * The codeblock pcode is stored in static segment. + * The only allowed operation on a codeblock is evaluating it then + * there is no need to duplicate its pcode - just store the pointer to it + */ + pCode = ( BYTE * ) pBuffer; + } + if( uiLocals ) { /* NOTE: if a codeblock will be created by macro compiler then @@ -136,11 +159,11 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, * NOTE: This table can be shared by codeblocks created during * evaluation of this codeblock */ - pCBlock->pLocals = ( PHB_ITEM ) hb_xgrab( ( uiLocals + 1 ) * sizeof( HB_ITEM ) ); - pCBlock->pLocals[ 0 ].type = HB_IT_LONG; - pCBlock->pLocals[ 0 ].item.asLong.value = 1; + pLocals = ( PHB_ITEM ) hb_xgrab( ( uiLocals + 1 ) * sizeof( HB_ITEM ) ); + pLocals[ 0 ].type = HB_IT_LONG; + pLocals[ 0 ].item.asLong.value = 1; - while( uiLocals-- ) + do { /* Swap the current value of local variable with the reference to this * value. @@ -151,13 +174,13 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, pLocalPosTable += 2; pLocal = hb_memvarDetachLocal( pLocal ); - memcpy( pCBlock->pLocals + ui, pLocal, sizeof( HB_ITEM ) ); + memcpy( pLocals + ui, pLocal, sizeof( HB_ITEM ) ); /* Increment the reference counter so this value will not be * released if other codeblock will be deleted */ hb_memvarValueIncRef( pLocal->item.asMemvar.value ); - ++ui; } + while( ++ui <= uiLocals ); } else { @@ -172,39 +195,23 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, { HB_CODEBLOCK_PTR pOwner = pLocal->item.asBlock.value; - pCBlock->uiLocals = pOwner->uiLocals; - pCBlock->pLocals = pOwner->pLocals; - if( pOwner->pLocals ) - hb_xRefInc( pOwner->pLocals ); + uiLocals = pOwner->uiLocals; + pLocals = pOwner->pLocals; + if( pLocals ) + hb_xRefInc( pLocals ); } else - pCBlock->pLocals = NULL; + pLocals = NULL; } - if( usLen ) - { - /* - * The codeblock pcode is stored in dynamically allocated memory that - * can be deallocated after creation of a codeblock. We have to duplicate - * the passed buffer - */ - pCBlock->pCode = ( BYTE * ) hb_xgrab( usLen ); - memcpy( pCBlock->pCode, pBuffer, usLen ); - pCBlock->dynBuffer = TRUE; - } - else - { - /* - * The codeblock pcode is stored in static segment. - * The only allowed operation on a codeblock is evaluating it then - * there is no need to duplicate its pcode - just store the pointer to it - */ - pCBlock->pCode = ( BYTE * ) pBuffer; - pCBlock->dynBuffer = FALSE; - } + pCBlock = ( HB_CODEBLOCK_PTR ) hb_gcAlloc( sizeof( HB_CODEBLOCK ), hb_codeblockDeleteGarbage ); + pCBlock->pCode = pCode; + pCBlock->dynBuffer = usLen != 0; pCBlock->pDefSymb = hb_stackBaseItem()->item.asSymbol.value; pCBlock->pSymbols = pSymbols; + pCBlock->uiLocals = uiLocals; + pCBlock->pLocals = pLocals; HB_TRACE(HB_TR_INFO, ("codeblock created %p", pCBlock)); @@ -214,24 +221,29 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, USHORT usLen ) { HB_CODEBLOCK_PTR pCBlock; + BYTE * pCode; HB_TRACE(HB_TR_DEBUG, ("hb_codeblockMacroNew(%p, %i)", pBuffer, usLen)); - pCBlock = ( HB_CODEBLOCK_PTR ) hb_gcAlloc( sizeof( HB_CODEBLOCK ), hb_codeblockDeleteGarbage ); - - /* Store the number of referenced local variables - */ - pCBlock->uiLocals = 0; - pCBlock->pLocals = NULL; /* * The codeblock pcode is stored in dynamically allocated memory that * can be deallocated after creation of a codeblock. We have to duplicate * the passed buffer */ - pCBlock->pCode = ( BYTE * ) hb_xgrab( usLen ); - memcpy( pCBlock->pCode, pBuffer, usLen ); - pCBlock->dynBuffer = TRUE; + /* + * allocate memory for code block body and detach items hb_gcAlloc() + * to be safe for automatic GC activation in hb_xgrab() without + * calling hb_gcLock()/hb_gcUnlock(). [druzus] + */ + pCode = ( BYTE * ) hb_xgrab( usLen ); + memcpy( pCode, pBuffer, usLen ); + pCBlock = ( HB_CODEBLOCK_PTR ) hb_gcAlloc( sizeof( HB_CODEBLOCK ), hb_codeblockDeleteGarbage ); + /* Store the number of referenced local variables */ + pCBlock->uiLocals = 0; + pCBlock->pLocals = NULL; + pCBlock->pCode = pCode; + pCBlock->dynBuffer = TRUE; pCBlock->pDefSymb = hb_stackBaseItem()->item.asSymbol.value; pCBlock->pSymbols = NULL; /* macro-compiled codeblock cannot acces a local symbol table */ diff --git a/harbour/source/vm/debug.c b/harbour/source/vm/debug.c index 1559cf38d3..f591d37bc7 100644 --- a/harbour/source/vm/debug.c +++ b/harbour/source/vm/debug.c @@ -112,20 +112,25 @@ HB_FUNC( HB_DBG_VMSTKGLIST ) * $FuncName$ __vmStkLCount( ) * $Description$ Returns params plus locals amount of the nProcLevel function * $End$ */ -static USHORT hb_stackLen( int iLevel ) +static LONG hb_stackLen( int iLevel ) { - PHB_ITEM * pBase = hb_stack.pBase; - USHORT uiCount = 0; + LONG lBaseOffset, lPrevOffset, lLen; HB_TRACE(HB_TR_DEBUG, ("hb_stackLen()")); - while( iLevel-- > 0 && pBase != hb_stack.pItems ) - { - uiCount = pBase - ( hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase ) - 2; - pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase; - } + lBaseOffset = hb_stackBaseOffset(); + while( --iLevel > 0 && lBaseOffset > 1 ) + lBaseOffset = hb_stackItem( lBaseOffset - 1 )->item.asSymbol.stackbase + 1; - return uiCount; + if( lBaseOffset > 1 ) + { + lPrevOffset = hb_stackItem( lBaseOffset - 1 )->item.asSymbol.stackbase; + lLen = lBaseOffset - lPrevOffset - 3; + } + else + lLen = 0; + + return lLen; } /* $Doc$ @@ -134,9 +139,7 @@ static USHORT hb_stackLen( int iLevel ) * $End$ */ HB_FUNC( HB_DBG_VMSTKLCOUNT ) { - int iLevel = hb_parni( 1 ) + 1; - - hb_retni( hb_stackLen( iLevel ) ); + hb_retnl( hb_stackLen( hb_parni( 1 ) + 1 ) ); } /* $Doc$ @@ -153,16 +156,16 @@ HB_FUNC( HB_DBG_VMSTKLCOUNT ) HB_FUNC( HB_DBG_VMSTKLLIST ) { PHB_ITEM pReturn; - PHB_ITEM * pItem; - PHB_ITEM * pBase = hb_stack.pItems + ( *(hb_stack.pBase) )->item.asSymbol.stackbase; + ULONG ulLen, ul; + LONG lBaseOffset, lPrevOffset; - USHORT uiLen = hb_stackLen( 1 ); - USHORT uiPos = 1; + lBaseOffset = hb_stackBaseOffset(); + lPrevOffset = hb_stackItem( lBaseOffset - 1 )->item.asSymbol.stackbase; - pReturn = hb_itemArrayNew( uiLen ); /* Create a transfer array */ - - for( pItem = pBase; pItem < hb_stack.pBase; pItem++ ) - AddToArray( *pItem, pReturn, uiPos++ ); + ulLen = lBaseOffset - lPrevOffset - 3; + pReturn = hb_itemArrayNew( ulLen ); /* Create a transfer array */ + for( ul = 0; ul < ulLen; ++ul ) + AddToArray( hb_stackItem( lPrevOffset + ul ), pReturn, ul + 1 ); hb_itemRelease( hb_itemReturn( pReturn ) ); } @@ -176,66 +179,59 @@ HB_FUNC( HB_DBG_VMSTKLLIST ) /* and locals */ HB_FUNC( HB_DBG_VMPARLLIST ) { - int iLevel = hb_parni( 1 ) + 1; - PHB_ITEM * pBase = hb_stack.pBase; - PHB_ITEM pReturn; - PHB_ITEM * pItem; - USHORT uiLen, uiPos = 1; - - while( ( iLevel-- > 0 ) && pBase != hb_stack.pItems ) - pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase; - - uiLen = ( * pBase )->item.asSymbol.paramcnt; - pReturn = hb_itemArrayNew( uiLen ); /* Create a transfer array */ - - for( pItem = pBase + 2; uiLen--; pItem++ ) - AddToArray( *pItem, pReturn, uiPos++ ); - - hb_itemRelease( hb_itemReturn( pReturn ) ); + hb_itemRelease( hb_itemReturn( hb_arrayFromParams( hb_parni( 1 ) + 1 ) ) ); } HB_FUNC( HB_DBG_VMVARLGET ) { int iLevel = hb_parni( 1 ) + 1; int iLocal = hb_parni( 2 ); - PHB_ITEM * pBase = hb_stack.pBase; + LONG lBaseOffset; - while( ( iLevel-- > 0 ) && pBase != hb_stack.pItems ) - pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase; + lBaseOffset = hb_stackBaseOffset(); + while( iLevel-- > 0 && lBaseOffset > 1 ) + lBaseOffset = hb_stackItem( lBaseOffset - 1 )->item.asSymbol.stackbase + 1; - if( iLocal > SHRT_MAX ) + if( iLevel < 0 ) { - iLocal -= USHRT_MAX; - iLocal--; + if( iLocal > SHRT_MAX ) + { + iLocal -= USHRT_MAX; + iLocal--; + } + if( iLocal >= 0 ) + hb_itemReturn( hb_itemUnRef( hb_stackItem( lBaseOffset + iLocal ) ) ); + else + hb_itemReturn( hb_codeblockGetVar( hb_stackItem( lBaseOffset ), ( LONG ) iLocal ) ); } - if( iLocal >= 0 ) - hb_itemReturn( hb_itemUnRef( *(pBase + 1 + iLocal) ) ); - else - hb_itemReturn( hb_codeblockGetVar( *(pBase+1), ( LONG ) iLocal ) ); } HB_FUNC( HB_DBG_VMVARLSET ) { int iLevel = hb_parni( 1 ) + 1; int iLocal = hb_parni( 2 ); - PHB_ITEM * pBase = hb_stack.pBase; + LONG lBaseOffset; PHB_ITEM pLocal; - while( ( iLevel-- > 0 ) && pBase != hb_stack.pItems ) - pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase; + lBaseOffset = hb_stackBaseOffset(); + while( iLevel-- > 0 && lBaseOffset > 1 ) + lBaseOffset = hb_stackItem( lBaseOffset - 1 )->item.asSymbol.stackbase + 1; - if( iLocal > SHRT_MAX ) + if( iLevel < 0 ) { - iLocal -= USHRT_MAX; - iLocal--; + if( iLocal > SHRT_MAX ) + { + iLocal -= USHRT_MAX; + iLocal--; + } + + if( iLocal >= 0 ) + pLocal = hb_stackItem( lBaseOffset + iLocal ); + else + pLocal = hb_codeblockGetVar( hb_stackItem( lBaseOffset ), ( LONG ) iLocal ); + + hb_itemCopy( hb_itemUnRef( pLocal ), hb_stackItemFromBase( 3 ) ); } - - if( iLocal >= 0 ) - pLocal = *(pBase + 1 + iLocal); - else - pLocal = hb_codeblockGetVar( *(pBase+1), ( LONG ) iLocal ); - - hb_itemCopy( hb_itemUnRef( pLocal ), *(hb_stack.pBase + 4) ); } HB_FUNC( __VMSTKLCOUNT ) diff --git a/harbour/source/vm/estack.c b/harbour/source/vm/estack.c index 4dfc44a682..667a868a77 100644 --- a/harbour/source/vm/estack.c +++ b/harbour/source/vm/estack.c @@ -141,9 +141,17 @@ void hb_stackPush( void ) /* enough room for another item ? */ if( ++hb_stack.pPos == hb_stack.pEnd ) hb_stackIncrease(); +} - /* now, push it: */ - ( * hb_stack.pPos )->type = HB_IT_NIL; +#undef hb_stackAllocItem +HB_ITEM_PTR hb_stackAllocItem( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_stackAllocItem()")); + + if( ++hb_stack.pPos == hb_stack.pEnd ) + hb_stackIncrease(); + + return * ( hb_stack.pPos - 1 ); } #undef hb_stackPushReturn @@ -156,9 +164,6 @@ void hb_stackPushReturn( void ) /* enough room for another item ? */ if( ++hb_stack.pPos == hb_stack.pEnd ) hb_stackIncrease(); - - /* now, push it: */ - ( * hb_stack.pPos )->type = HB_IT_NIL; } void hb_stackIncrease( void ) @@ -183,8 +188,13 @@ void hb_stackIncrease( void ) hb_stack.pBase = hb_stack.pItems + BaseIndex; hb_stack.wItems += STACK_EXPANDHB_ITEMS; hb_stack.pEnd = hb_stack.pItems + hb_stack.wItems; - while( EndIndex < hb_stack.wItems ) - hb_stack.pItems[ EndIndex++ ] = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) ); + + do + { + hb_stack.pItems[ EndIndex ] = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) ); + hb_stack.pItems[ EndIndex ]->type = HB_IT_NIL; + } + while( ++EndIndex < hb_stack.wItems ); } void hb_stackInit( void ) @@ -201,8 +211,11 @@ void hb_stackInit( void ) hb_stack.Return.type = HB_IT_NIL; - for( i=0; i < hb_stack.wItems; ++i ) - hb_stack.pItems[ i ] = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) ); + for( i = 0; i < hb_stack.wItems; ++i ) + { + hb_stack.pItems[ i ] = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) ); + hb_stack.pItems[ i ]->type = HB_IT_NIL; + } } void hb_stackRemove( LONG lUntilPos ) @@ -335,6 +348,12 @@ void hb_stackSetStaticsBase( int iBase ) hb_stack.iStatics = iBase; } +#undef hb_stackItemBasePtr +PHB_ITEM ** hb_stackItemBasePtr( void ) +{ + return &hb_stack.pItems; +} + void hb_stackBaseProcInfo( char * szProcName, USHORT * puiProcLine ) { /* diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 3e1aa42bcd..a6e800b2f1 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -674,8 +674,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) HB_ITEM_PTR pResult; pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmPlus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); } w++; break; @@ -704,8 +703,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) HB_ITEM_PTR pResult; pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmMinus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); } w++; break; @@ -734,8 +732,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) HB_ITEM_PTR pResult; pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmMult( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); } w++; break; @@ -764,8 +761,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) HB_ITEM_PTR pResult; pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmDivide( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); } w++; break; @@ -1054,6 +1050,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* BEGIN SEQUENCE/RECOVER/END SEQUENCE */ case HB_P_SEQBEGIN: + { /* * Create the SEQUENCE envelope * [ break return value ] -4 @@ -1062,30 +1059,32 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) * [ current recovery state ] -1 * [ ] <- new recover base */ + + PHB_ITEM pItem; + /* * 1) clear the storage for value returned by BREAK statement */ - ( hb_stackTopItem() )->type = HB_IT_NIL; - hb_stackPush(); + hb_stackAllocItem()->type = HB_IT_NIL; /* * 2) store the address of RECOVER or END opcode */ - ( hb_stackTopItem() )->type = HB_IT_LONG; - ( hb_stackTopItem() )->item.asLong.value = w + HB_PCODE_MKINT24( &pCode[ w + 1 ] ); - hb_stackPush(); + pItem = hb_stackAllocItem(); + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = w + HB_PCODE_MKINT24( &pCode[ w + 1 ] ); /* * 3) store current RECOVER base */ - ( hb_stackTopItem() )->type = HB_IT_LONG; - ( hb_stackTopItem() )->item.asLong.value = s_lRecoverBase; - hb_stackPush(); + pItem = hb_stackAllocItem(); + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = s_lRecoverBase; /* * 4) store current bCanRecover flag - in a case of nested sequences * in the same procedure/function */ - ( hb_stackTopItem() )->type = HB_IT_LOGICAL; - ( hb_stackTopItem() )->item.asLogical.value = bCanRecover; - hb_stackPush(); + pItem = hb_stackAllocItem(); + pItem->type = HB_IT_LOGICAL; + pItem->item.asLogical.value = bCanRecover; /* * set new recover base */ @@ -1096,6 +1095,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) bCanRecover = TRUE; w += 4; break; + } case HB_P_SEQEND: /* @@ -1106,20 +1106,17 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* * 4) Restore previous recovery state */ + bCanRecover = hb_stackItemFromTop( -1 )->item.asLogical.value; hb_stackDec(); - bCanRecover = ( hb_stackTopItem() )->item.asLogical.value; - ( hb_stackTopItem() )->type = HB_IT_NIL; /* * 3) Restore previous RECOVER base */ + s_lRecoverBase = hb_stackItemFromTop( -1 )->item.asLong.value; hb_stackDec(); - s_lRecoverBase = ( hb_stackTopItem() )->item.asLong.value; - ( hb_stackTopItem() )->type = HB_IT_NIL; /* * 2) Remove RECOVER address */ hb_stackDec(); - ( hb_stackTopItem() )->type = HB_IT_NIL; /* 1) Discard the value returned by BREAK statement - there * was no RECOVER clause or there was no BREAK statement */ @@ -1137,20 +1134,17 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* * 4) Restore previous recovery state */ + bCanRecover = hb_stackItemFromTop( -1 )->item.asLogical.value; hb_stackDec(); - bCanRecover = ( hb_stackTopItem() )->item.asLogical.value; - ( hb_stackTopItem() )->type = HB_IT_NIL; /* * 3) Restore previous RECOVER base */ + s_lRecoverBase = hb_stackItemFromTop( -1 )->item.asLong.value; hb_stackDec(); - s_lRecoverBase = ( hb_stackTopItem() )->item.asLong.value; - ( hb_stackTopItem() )->type = HB_IT_NIL; /* * 2) Remove RECOVER address */ hb_stackDec(); - ( hb_stackTopItem() )->type = HB_IT_NIL; /* * 1) Leave the value returned from BREAK - it will be popped * in next executed opcode @@ -1218,34 +1212,31 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_TRUE: { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); - pStackTopItem->type = HB_IT_LOGICAL; - pStackTopItem->item.asLogical.value = TRUE; - hb_stackPush(); + pItem->type = HB_IT_LOGICAL; + pItem->item.asLogical.value = TRUE; w++; } break; case HB_P_FALSE: { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); - pStackTopItem->type = HB_IT_LOGICAL; - pStackTopItem->item.asLogical.value = FALSE; - hb_stackPush(); + pItem->type = HB_IT_LOGICAL; + pItem->item.asLogical.value = FALSE; w++; } break; case HB_P_ONE: { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = 1; - pStackTopItem->item.asInteger.length = 10; - hb_stackPush(); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = 1; + pItem->item.asInteger.length = 10; HB_TRACE(HB_TR_INFO, ("(HB_P_ONE)")); w++; } @@ -1253,32 +1244,29 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_ZERO: { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = 0; - pStackTopItem->item.asInteger.length = 10; - hb_stackPush(); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = 0; + pItem->item.asInteger.length = 10; HB_TRACE(HB_TR_INFO, ("(HB_P_ZERO)")); w++; } break; case HB_P_PUSHNIL: - ( hb_stackTopItem() )->type = HB_IT_NIL; - hb_stackPush(); + hb_stackAllocItem()->type = HB_IT_NIL; HB_TRACE(HB_TR_INFO, ("(HB_P_PUSHNIL)")); w++; break; case HB_P_PUSHBYTE: { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = ( signed char ) pCode[ w + 1 ]; - pStackTopItem->item.asInteger.length = 10; - hb_stackPush(); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = ( signed char ) pCode[ w + 1 ]; + pItem->item.asInteger.length = 10; HB_TRACE(HB_TR_INFO, ("(HB_P_PUSHBYTE)")); w += 2; } @@ -1406,8 +1394,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_PUSHFIELD: /* It pushes the current value of the given field onto the eval stack */ - hb_stackPush(); - hb_rddGetFieldValue( hb_stackItemFromTop( -1 ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); + hb_rddGetFieldValue( hb_stackAllocItem(), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPushField)")); w += 3; break; @@ -1438,15 +1425,13 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_PUSHMEMVAR: - hb_stackPush(); - hb_memvarGetValue( hb_stackItemFromTop( -1 ), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); + hb_memvarGetValue( hb_stackAllocItem(), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPushMemvar)")); w += 3; break; case HB_P_PUSHMEMVARREF: - hb_stackPush(); - hb_memvarGetRefer( hb_stackItemFromTop( -1 ), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); + hb_memvarGetRefer( hb_stackAllocItem(), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); HB_TRACE(HB_TR_INFO, ("(hb_vmPushMemvarRef)")); w += 3; break; @@ -1786,8 +1771,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) HB_DYNS_PTR pDynSym = ( HB_DYNS_PTR ) HB_GET_PTR( pCode + w + 1 ); /* It pushes the current value of the given field onto the eval stack */ - hb_stackPush(); - hb_rddGetFieldValue( hb_stackItemFromTop( -1 ), pDynSym->pSymbol ); + hb_rddGetFieldValue( hb_stackAllocItem(), pDynSym->pSymbol ); HB_TRACE(HB_TR_INFO, ("(hb_vmMPushField)")); w += sizeof( HB_DYNS_PTR ) + 1; break; @@ -1796,8 +1780,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_MPUSHMEMVAR: { HB_DYNS_PTR pDynSym = ( HB_DYNS_PTR ) HB_GET_PTR( pCode + w + 1 ); - hb_stackPush(); - hb_memvarGetValue( hb_stackItemFromTop( -1 ), pDynSym->pSymbol ); + hb_memvarGetValue( hb_stackAllocItem(), pDynSym->pSymbol ); HB_TRACE(HB_TR_INFO, ("(hb_vmMPushMemvar)")); w += sizeof( HB_DYNS_PTR ) + 1; break; @@ -1806,8 +1789,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_MPUSHMEMVARREF: { HB_DYNS_PTR pDynSym = ( HB_DYNS_PTR ) HB_GET_PTR( pCode + w + 1 ); - hb_stackPush(); - hb_memvarGetRefer( hb_stackItemFromTop( -1 ), pDynSym->pSymbol ); + hb_memvarGetRefer( hb_stackAllocItem(), pDynSym->pSymbol ); HB_TRACE(HB_TR_INFO, ("(hb_vmMPushMemvarRef)")); w += sizeof( HB_DYNS_PTR ) + 1; break; @@ -3226,14 +3208,12 @@ static LONG hb_vmEnumEnd( void ) LONG lVars; /* restore stack frame offset of previous FOREACH loop */ + lOldBase = hb_stackItemFromTop( -1 )->item.asLong.value; hb_stackDec(); - lOldBase = hb_stackTopItem()->item.asLong.value; - hb_stackTopItem()->type = HB_IT_NIL; /* remove number of iterators */ + lVars = hb_stackItemFromTop( -1 )->item.asLong.value; hb_stackDec(); - lVars = hb_stackTopItem()->item.asLong.value; - hb_stackTopItem()->type = HB_IT_NIL; while( --lVars >= 0 ) { @@ -3582,8 +3562,7 @@ static void hb_vmArrayGen( ULONG ulElements ) /* generates an ulElements Array a HB_TRACE(HB_TR_DEBUG, ("hb_vmArrayGen(%lu)", ulElements)); /* create new array on HVM stack */ - pArray = hb_stackTopItem(); - hb_stackPush(); + pArray = hb_stackAllocItem(); hb_arrayNew( pArray, ulElements ); if( ulElements ) @@ -3653,9 +3632,7 @@ static void hb_vmArrayDim( USHORT uiDimensions ) /* generates an uiDimensions Ar { HB_TRACE(HB_TR_DEBUG, ("hb_vmArrayDim(%hu)", uiDimensions)); - hb_stackPush(); - - hb_vmArrayNew( hb_stackItemFromTop( -1 ), uiDimensions ); + hb_vmArrayNew( hb_stackAllocItem(), uiDimensions ); hb_itemMove( hb_stackItemFromTop( ( int ) ( -1 - uiDimensions ) ), hb_stackItemFromTop( -1 ) ); @@ -4362,17 +4339,13 @@ HB_EXPORT void hb_vmPush( PHB_ITEM pItem ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmPush(%p)", pItem)); - hb_itemCopy( hb_stackTopItem(), pItem ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pItem ); } HB_EXPORT void hb_vmPushState( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmPushState()")); - /* Save top item which can be processed at this moment */ - hb_stackPush(); - hb_stackPushReturn(); } @@ -4380,19 +4353,17 @@ HB_EXPORT void hb_vmPushNil( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmPushNil()")); - ( hb_stackTopItem() )->type = HB_IT_NIL; - hb_stackPush(); + hb_stackAllocItem()->type = HB_IT_NIL; } HB_EXPORT void hb_vmPushLogical( BOOL bValue ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLogical(%d)", (int) bValue)); - pStackTopItem->type = HB_IT_LOGICAL; - pStackTopItem->item.asLogical.value = bValue; - hb_stackPush(); + pItem->type = HB_IT_LOGICAL; + pItem->item.asLogical.value = bValue; } HB_EXPORT void hb_vmPushNumber( double dNumber, int iDec ) @@ -4447,190 +4418,170 @@ static void hb_vmPushNumInt( HB_LONG lNumber ) HB_EXPORT void hb_vmPushInteger( int iNumber ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushInteger(%d)", iNumber)); - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = iNumber; - pStackTopItem->item.asInteger.length = HB_INT_LENGTH( iNumber ); - hb_stackPush(); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = iNumber; + pItem->item.asInteger.length = HB_INT_LENGTH( iNumber ); } #if HB_INT_MAX >= INT32_MAX static void hb_vmPushIntegerConst( int iNumber ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushIntegerConst(%d)", iNumber)); - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = iNumber; - pStackTopItem->item.asInteger.length = hb_vmCalcIntWidth( iNumber ); - hb_stackPush(); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = iNumber; + pItem->item.asInteger.length = hb_vmCalcIntWidth( iNumber ); } #endif HB_EXPORT void hb_vmPushLong( long lNumber ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLong(%ld)", lNumber)); #if HB_INT_MAX >= LONG_MAX - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = ( int ) lNumber; - pStackTopItem->item.asInteger.length = HB_INT_LENGTH( lNumber ); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = ( int ) lNumber; + pItem->item.asInteger.length = HB_INT_LENGTH( lNumber ); #else - pStackTopItem->type = HB_IT_LONG; - pStackTopItem->item.asLong.value = ( HB_LONG ) lNumber; - pStackTopItem->item.asLong.length = HB_LONG_LENGTH( lNumber ); + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = ( HB_LONG ) lNumber; + pItem->item.asLong.length = HB_LONG_LENGTH( lNumber ); #endif - hb_stackPush(); } void hb_vmPushLongConst( long lNumber ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLongConst(%ld)", lNumber)); #if HB_INT_MAX >= LONG_MAX - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = ( int ) lNumber; - pStackTopItem->item.asInteger.length = hb_vmCalcIntWidth( lNumber ); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = ( int ) lNumber; + pItem->item.asInteger.length = hb_vmCalcIntWidth( lNumber ); #else - pStackTopItem->type = HB_IT_LONG; - pStackTopItem->item.asLong.value = ( HB_LONG ) lNumber; - pStackTopItem->item.asLong.length = hb_vmCalcIntWidth( lNumber ); + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = ( HB_LONG ) lNumber; + pItem->item.asLong.length = hb_vmCalcIntWidth( lNumber ); #endif - hb_stackPush(); } static void hb_vmPushHBLong( HB_LONG lNumber ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushHBLong(%" PFHL "d)", lNumber)); - pStackTopItem->type = HB_IT_LONG; - pStackTopItem->item.asLong.value = lNumber; - pStackTopItem->item.asLong.length = HB_LONG_LENGTH( lNumber ); - - hb_stackPush(); + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = lNumber; + pItem->item.asLong.length = HB_LONG_LENGTH( lNumber ); } #if !defined( HB_LONG_LONG_OFF ) static void hb_vmPushLongLongConst( LONGLONG llNumber ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLongLongConst(%" PFLL "d)", llNumber)); - pStackTopItem->type = HB_IT_LONG; - pStackTopItem->item.asLong.value = ( HB_LONG ) llNumber; - pStackTopItem->item.asLong.length = hb_vmCalcIntWidth( llNumber ); - - hb_stackPush(); + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = ( HB_LONG ) llNumber; + pItem->item.asLong.length = hb_vmCalcIntWidth( llNumber ); } #endif HB_EXPORT void hb_vmPushDouble( double dNumber, int iDec ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushDouble(%lf, %d)", dNumber, iDec)); - pStackTopItem->type = HB_IT_DOUBLE; - pStackTopItem->item.asDouble.value = dNumber; - pStackTopItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); + pItem->type = HB_IT_DOUBLE; + pItem->item.asDouble.value = dNumber; + pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); if( iDec == HB_DEFAULT_DECIMALS ) - pStackTopItem->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; + pItem->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; else - pStackTopItem->item.asDouble.decimal = iDec; - - hb_stackPush(); + pItem->item.asDouble.decimal = iDec; } static void hb_vmPushDoubleConst( double dNumber, int iWidth, int iDec ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushDoubleConst(%lf, %d, %d)", dNumber, iWidth, iDec)); - pStackTopItem->type = HB_IT_DOUBLE; - pStackTopItem->item.asDouble.value = dNumber; + pItem->type = HB_IT_DOUBLE; + pItem->item.asDouble.value = dNumber; if( iDec == HB_DEFAULT_DECIMALS ) - pStackTopItem->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; + pItem->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; else - pStackTopItem->item.asDouble.decimal = iDec; + pItem->item.asDouble.decimal = iDec; if( iWidth == HB_DEFAULT_WIDTH ) - pStackTopItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); + pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber ); else - pStackTopItem->item.asDouble.length = iWidth; - - hb_stackPush(); + pItem->item.asDouble.length = iWidth; } HB_EXPORT void hb_vmPushDate( long lDate ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushDate(%ld)", lDate)); - pStackTopItem->type = HB_IT_DATE; - pStackTopItem->item.asDate.value = lDate; - hb_stackPush(); + pItem->type = HB_IT_DATE; + pItem->item.asDate.value = lDate; } HB_EXPORT void hb_vmPushPointer( void * pPointer ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushPointer(%ld)", pPointer)); - pStackTopItem->type = HB_IT_POINTER; - pStackTopItem->item.asPointer.value = pPointer; - pStackTopItem->item.asPointer.collect = FALSE; - hb_stackPush(); + pItem->type = HB_IT_POINTER; + pItem->item.asPointer.value = pPointer; + pItem->item.asPointer.collect = FALSE; } HB_EXPORT void hb_vmPushString( char * szText, ULONG length ) { - PHB_ITEM pStackTopItem; - HB_TRACE(HB_TR_DEBUG, ("hb_vmPushString(%s, %lu)", szText, length)); - pStackTopItem = hb_stackTopItem(); - hb_stackPush(); - hb_itemPutCL( pStackTopItem, szText, length ); + hb_itemPutCL( hb_stackAllocItem(), szText, length ); } HB_EXPORT void hb_vmPushStringPcode( char * szText, ULONG length ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushStringPcode(%s, %lu)", szText, length)); - pStackTopItem->type = HB_IT_STRING; - pStackTopItem->item.asString.length = length; - pStackTopItem->item.asString.allocated = 0; - pStackTopItem->item.asString.value = szText; - hb_stackPush(); + pItem->type = HB_IT_STRING; + pItem->item.asString.length = length; + pItem->item.asString.allocated = 0; + pItem->item.asString.value = szText; } HB_EXPORT void hb_vmPushSymbol( PHB_SYMB pSym ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushSymbol(%p)", pSym)); - pStackTopItem->type = HB_IT_SYMBOL; - pStackTopItem->item.asSymbol.value = pSym; - pStackTopItem->item.asSymbol.stackbase = hb_stackTopOffset(); - hb_stackPush(); + pItem->type = HB_IT_SYMBOL; + pItem->item.asSymbol.value = pSym; + pItem->item.asSymbol.stackbase = hb_stackTopOffset() - 1; } /* -3 -> HB_P_PUSHBLOCK @@ -4644,34 +4595,33 @@ HB_EXPORT void hb_vmPushSymbol( PHB_SYMB pSym ) static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen ) { USHORT uiLocals; - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushBlock(%p,%p,%hu)", pCode, pSymbols, usLen)); - pStackTopItem->type = HB_IT_BLOCK; - uiLocals = HB_PCODE_MKUSHORT( &pCode[ 2 ] ); if( usLen ) usLen -= uiLocals << 1; - pStackTopItem->item.asBlock.value = + pItem->item.asBlock.value = hb_codeblockNew( pCode + 4 + ( uiLocals << 1 ),/* pcode buffer */ uiLocals, /* number of referenced local variables */ pCode + 4, /* table with referenced local variables */ pSymbols, usLen ); + pItem->type = HB_IT_BLOCK; + /* store the statics base of function where the codeblock was defined */ - pStackTopItem->item.asBlock.statics = hb_stackGetStaticsBase(); + pItem->item.asBlock.statics = hb_stackGetStaticsBase(); /* store the number of expected parameters */ - pStackTopItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( pCode ); + pItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( pCode ); /* store the line number where the codeblock was defined */ - pStackTopItem->item.asBlock.lineno = ( hb_stackBaseItem() )->item.asSymbol.lineno; - hb_stackPush(); + pItem->item.asBlock.lineno = hb_stackBaseItem()->item.asSymbol.lineno; } /* -2 -> HB_P_PUSHBLOCKSHORT @@ -4682,29 +4632,28 @@ static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen */ static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushBlockShort(%p,%p,%hu)", pCode, pSymbols, usLen)); - pStackTopItem->type = HB_IT_BLOCK; - - pStackTopItem->item.asBlock.value = + pItem->item.asBlock.value = hb_codeblockNew( pCode, /* pcode buffer */ 0, /* number of referenced local variables */ NULL, /* table with referenced local variables */ pSymbols, usLen ); + pItem->type = HB_IT_BLOCK; + /* store the statics base of function where the codeblock was defined */ - pStackTopItem->item.asBlock.statics = hb_stackGetStaticsBase(); + pItem->item.asBlock.statics = hb_stackGetStaticsBase(); /* store the number of expected parameters */ - pStackTopItem->item.asBlock.paramcnt = 0; + pItem->item.asBlock.paramcnt = 0; /* store the line number where the codeblock was defined */ - pStackTopItem->item.asBlock.lineno = ( hb_stackBaseItem() )->item.asSymbol.lineno; - hb_stackPush(); + pItem->item.asBlock.lineno = hb_stackBaseItem()->item.asSymbol.lineno; } /* +0 -> HB_P_MPUSHBLOCK @@ -4716,40 +4665,38 @@ static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols, USHORT u */ static void hb_vmPushMacroBlock( BYTE * pCode, PHB_SYMB pSymbols ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushMacroBlock(%p, %p)", pCode, pSymbols)); HB_SYMBOL_UNUSED( pSymbols ); /* TODO: remove pSymbols */ - pStackTopItem->type = HB_IT_BLOCK; + pItem->item.asBlock.value = hb_codeblockMacroNew( pCode + 5, HB_PCODE_MKUSHORT( &( pCode[ 1 ] ) ) - 5 ); - pStackTopItem->item.asBlock.value = hb_codeblockMacroNew( pCode + 5, HB_PCODE_MKUSHORT( &( pCode[ 1 ] ) ) - 5 ); + pItem->type = HB_IT_BLOCK; /* store the statics base of function where the codeblock was defined */ - pStackTopItem->item.asBlock.statics = hb_stackGetStaticsBase(); + pItem->item.asBlock.statics = hb_stackGetStaticsBase(); /* store the number of expected parameters */ - pStackTopItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( &( pCode[ 3 ] ) ); + pItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( &( pCode[ 3 ] ) ); /* store the line number where the codeblock was defined */ - pStackTopItem->item.asBlock.lineno = ( hb_stackBaseItem() )->item.asSymbol.lineno; - hb_stackPush(); + pItem->item.asBlock.lineno = hb_stackBaseItem()->item.asSymbol.lineno; } /* pushes current workarea number on the eval stack */ static void hb_vmPushAlias( void ) { - PHB_ITEM pStackTopItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushAlias()")); - pStackTopItem->type = HB_IT_INTEGER; - pStackTopItem->item.asInteger.value = hb_rddGetCurrentWorkAreaNumber(); - pStackTopItem->item.asInteger.length = 10; - hb_stackPush(); + pItem->type = HB_IT_INTEGER; + pItem->item.asInteger.value = hb_rddGetCurrentWorkAreaNumber(); + pItem->item.asInteger.length = 10; } /* It pops the last item from the stack to use it to select a workarea @@ -4865,19 +4812,17 @@ static void hb_vmPushLocal( SHORT iLocal ) if( HB_IS_BYREF( pLocal ) ) { - hb_itemCopy( ( hb_stackTopItem() ), hb_itemUnRef( pLocal ) ); + hb_itemCopy( hb_stackAllocItem(), hb_itemUnRef( pLocal ) ); } else { - hb_itemCopy( ( hb_stackTopItem() ), pLocal ); + hb_itemCopy( hb_stackAllocItem(), pLocal ); } - - hb_stackPush(); } static void hb_vmPushLocalByRef( SHORT iLocal ) { - HB_ITEM_PTR pTop = hb_stackTopItem(); + HB_ITEM_PTR pTop = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLocalByRef(%hd)", iLocal)); pTop->type = HB_IT_BYREF; @@ -4885,7 +4830,7 @@ static void hb_vmPushLocalByRef( SHORT iLocal ) pTop->item.asRefer.value = iLocal; pTop->item.asRefer.offset = hb_stackBaseOffset(); if( iLocal >= 0 ) - pTop->item.asRefer.BasePtr.itemsbasePtr = &hb_stack.pItems; + pTop->item.asRefer.BasePtr.itemsbasePtr = hb_stackItemBasePtr(); else { /* store direct codeblock address because an item where a codeblock @@ -4894,7 +4839,6 @@ static void hb_vmPushLocalByRef( SHORT iLocal ) */ pTop->item.asRefer.BasePtr.block = hb_stackSelfItem()->item.asBlock.value; } - hb_stackPush(); } static void hb_vmPushStatic( USHORT uiStatic ) @@ -4905,15 +4849,14 @@ static void hb_vmPushStatic( USHORT uiStatic ) pStatic = s_aStatics.item.asArray.value->pItems + hb_stackGetStaticsBase() + uiStatic - 1; if( HB_IS_BYREF( pStatic ) ) - hb_itemCopy( hb_stackTopItem(), hb_itemUnRef( pStatic ) ); + hb_itemCopy( hb_stackAllocItem(), hb_itemUnRef( pStatic ) ); else - hb_itemCopy( hb_stackTopItem(), pStatic ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pStatic ); } static void hb_vmPushStaticByRef( USHORT uiStatic ) { - HB_ITEM_PTR pTop = hb_stackTopItem(); + HB_ITEM_PTR pTop = hb_stackAllocItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushStaticByRef(%hu)", uiStatic)); pTop->type = HB_IT_BYREF; @@ -4921,12 +4864,16 @@ static void hb_vmPushStaticByRef( USHORT uiStatic ) pTop->item.asRefer.value = hb_stackGetStaticsBase() + uiStatic - 1; pTop->item.asRefer.offset = 0; /* 0 for static variables */ pTop->item.asRefer.BasePtr.itemsbase = &s_aStatics.item.asArray.value->pItems; - hb_stackPush(); } static void hb_vmPushVariable( PHB_SYMB pVarSymb ) { USHORT uiAction = E_DEFAULT; + PHB_ITEM pItem; + + HB_TRACE(HB_TR_INFO, ("(hb_vmPushVariable)")); + + pItem = hb_stackAllocItem(); do { @@ -4934,17 +4881,9 @@ static void hb_vmPushVariable( PHB_SYMB pVarSymb ) * in a current workarea - if it is not a field (FAILURE) * then try the memvar variable */ - if( hb_rddFieldGet( ( hb_stackTopItem() ), pVarSymb ) == SUCCESS ) + if( hb_rddFieldGet( pItem, pVarSymb ) != SUCCESS ) { - hb_stackPush(); - } - else - { - if( hb_memvarGet( ( hb_stackTopItem() ), pVarSymb ) == SUCCESS ) - { - hb_stackPush(); - } - else + if( hb_memvarGet( pItem, pVarSymb ) != SUCCESS ) { HB_ITEM_PTR pError; @@ -4958,26 +4897,29 @@ static void hb_vmPushVariable( PHB_SYMB pVarSymb ) } } while( uiAction == E_RETRY ); - HB_TRACE(HB_TR_INFO, ("(hb_vmPushVariable)")); } static void hb_vmDuplicate( void ) { + PHB_ITEM pItem; + HB_TRACE(HB_TR_DEBUG, ("hb_vmDuplicate()")); - hb_itemCopy( ( hb_stackTopItem() ), hb_stackItemFromTop( -1 ) ); - hb_stackPush(); + pItem = hb_stackItemFromTop( -1 ); + hb_itemCopy( hb_stackAllocItem(), pItem ); } static void hb_vmDuplTwo( void ) { + PHB_ITEM pItem; + HB_TRACE(HB_TR_DEBUG, ("hb_vmDuplTwo()")); - hb_itemCopy( ( hb_stackTopItem() ), hb_stackItemFromTop( -2 ) ); - hb_stackPush(); - hb_itemCopy( ( hb_stackTopItem() ), hb_stackItemFromTop( -2 ) ); - hb_stackPush(); + pItem = hb_stackItemFromTop( -2 ); + hb_itemCopy( hb_stackAllocItem(), pItem ); + pItem = hb_stackItemFromTop( -2 ); + hb_itemCopy( hb_stackAllocItem(), pItem ); } /* ------------------------------- */ @@ -4989,9 +4931,6 @@ HB_EXPORT void hb_vmPopState( void ) HB_TRACE_STEALTH( HB_TR_DEBUG, ( "hb_vmPopState()" ) ); hb_stackPopReturn(); - - /* Restore top item */ - hb_stackDec(); } static BOOL hb_vmPopLogical( void ) @@ -5000,10 +4939,10 @@ static BOOL hb_vmPopLogical( void ) if( HB_IS_LOGICAL( hb_stackItemFromTop( -1 ) ) ) { - hb_stackDec(); + BOOL fValue = hb_stackItemFromTop( -1 )->item.asLogical.value; - hb_stackTopItem()->type = HB_IT_NIL; - return hb_stackTopItem()->item.asLogical.value; + hb_stackDec(); + return fValue; } else { @@ -5016,14 +4955,14 @@ static BOOL hb_vmPopLogical( void ) static long hb_vmPopDate( void ) { - PHB_ITEM pStackTopItem; + long lDate; HB_TRACE(HB_TR_DEBUG, ("hb_vmPopDate()")); + lDate = hb_stackItemFromTop( -1 )->item.asDate.value; hb_stackDec(); - pStackTopItem = hb_stackTopItem(); - pStackTopItem->type = HB_IT_NIL; - return pStackTopItem->item.asDate.value; + + return lDate; } /* NOTE: Type checking should be done by the caller. */ @@ -5035,8 +4974,7 @@ static double hb_vmPopNumber( void ) HB_TRACE(HB_TR_DEBUG, ("hb_vmPopNumber()")); - hb_stackDec(); - pItem = hb_stackTopItem(); + pItem = hb_stackItemFromTop( -1 ); switch( pItem->type ) { @@ -5057,7 +4995,7 @@ static double hb_vmPopNumber( void ) return 0.0; /* To avoid GCC -O2 warning */ } - pItem->type = HB_IT_NIL; + hb_stackDec(); return dNumber; } @@ -5071,8 +5009,7 @@ static HB_LONG hb_vmPopHBLong( void ) HB_TRACE(HB_TR_DEBUG, ("hb_vmPopHBLong()")); - hb_stackDec(); - pItem = hb_stackTopItem(); + pItem = hb_stackItemFromTop( -1 ); switch( pItem->type ) { @@ -5093,7 +5030,7 @@ static HB_LONG hb_vmPopHBLong( void ) return 0; /* To avoid GCC -O2 warning */ } - pItem->type = HB_IT_NIL; + hb_stackDec(); return lNumber; } @@ -5107,8 +5044,7 @@ static double hb_vmPopDouble( int * piDec ) HB_TRACE(HB_TR_DEBUG, ("hb_vmPopDouble(%p)", piDec)); - hb_stackDec(); - pItem = hb_stackTopItem(); + pItem = hb_stackItemFromTop( -1 ); switch( pItem->type ) { @@ -5133,7 +5069,7 @@ static double hb_vmPopDouble( int * piDec ) return 0.0; /* To avoid GCC -O2 warning */ } - pItem->type = HB_IT_NIL; + hb_stackDec(); return dNumber; } @@ -6009,6 +5945,7 @@ HB_EXPORT void hb_xvmExitProc( ULONG ulPrivateBase ) HB_EXPORT void hb_xvmSeqBegin( void ) { + PHB_ITEM pItem; /* * Create the SEQUENCE envelope * To keep compatibility with pure PCODE evaluation we have @@ -6023,18 +5960,15 @@ HB_EXPORT void hb_xvmSeqBegin( void ) */ /* 1) clear the storage for value returned by BREAK statement */ - hb_stackTopItem()->type = HB_IT_NIL; - hb_stackPush(); + hb_stackAllocItem()->type = HB_IT_NIL; /* 2) the address of RECOVER or END opcode - not used in C code */ - hb_stackTopItem()->type = HB_IT_NIL; - hb_stackPush(); + hb_stackAllocItem()->type = HB_IT_NIL; /* 3) store current RECOVER base */ - hb_stackTopItem()->type = HB_IT_LONG; - hb_stackTopItem()->item.asLong.value = s_lRecoverBase; - hb_stackPush(); + pItem = hb_stackAllocItem(); + pItem->type = HB_IT_LONG; + pItem->item.asLong.value = s_lRecoverBase; /* 4) current bCanRecover flag - not used in C code */ - hb_stackTopItem()->type = HB_IT_NIL; - hb_stackPush(); + hb_stackAllocItem()->type = HB_IT_NIL; /* set new recover base */ s_lRecoverBase = hb_stackTopOffset(); } @@ -6065,14 +5999,11 @@ HB_EXPORT BOOL hb_xvmSeqEnd( LONG * plForEachBase ) /* 4) Restore previous recovery state - not used in C code */ hb_stackDec(); - hb_stackTopItem()->type = HB_IT_NIL; /* 3) Restore previous RECOVER base */ + s_lRecoverBase = hb_stackItemFromTop( -1 )->item.asLong.value; hb_stackDec(); - s_lRecoverBase = hb_stackTopItem()->item.asLong.value; - hb_stackTopItem()->type = HB_IT_NIL; /* 2) Remove RECOVER address - not used in C code */ hb_stackDec(); - hb_stackTopItem()->type = HB_IT_NIL; /* 1) Discard the value returned by BREAK statement */ hb_stackPop(); @@ -6109,14 +6040,11 @@ HB_EXPORT BOOL hb_xvmSeqRecover( LONG * plForEachBase ) /* 4) Restore previous recovery state - not used in C code */ hb_stackDec(); - hb_stackTopItem()->type = HB_IT_NIL; /* 3) Restore previous RECOVER base */ + s_lRecoverBase = hb_stackItemFromTop( -1 )->item.asLong.value; hb_stackDec(); - s_lRecoverBase = hb_stackTopItem()->item.asLong.value; - hb_stackTopItem()->type = HB_IT_NIL; /* 2) Remove RECOVER address - not used in C code */ hb_stackDec(); - hb_stackTopItem()->type = HB_IT_NIL; /* 1) Leave the value returned from BREAK */ if( s_uiActionRequest & HB_ENDPROC_REQUESTED ) @@ -6324,17 +6252,15 @@ HB_EXPORT void hb_xvmPushSelf( void ) HB_EXPORT void hb_xvmPushFuncSymbol( PHB_SYMB pSym ) { - PHB_ITEM pStackTopItem; + PHB_ITEM pItem; HB_TRACE(HB_TR_DEBUG, ("hb_xvmPushFuncSymbol(%p)", pSym)); - pStackTopItem = hb_stackTopItem(); - pStackTopItem->type = HB_IT_SYMBOL; - pStackTopItem->item.asSymbol.value = pSym; - pStackTopItem->item.asSymbol.stackbase = hb_stackTopOffset(); - hb_stackPush(); - ( hb_stackTopItem() )->type = HB_IT_NIL; - hb_stackPush(); + pItem = hb_stackAllocItem(); + pItem->type = HB_IT_SYMBOL; + pItem->item.asSymbol.value = pSym; + pItem->item.asSymbol.stackbase = hb_stackTopOffset() - 1; + hb_stackAllocItem()->type = HB_IT_NIL; } HB_EXPORT BOOL hb_xvmPopLogical( BOOL * pfValue ) @@ -6369,8 +6295,7 @@ HB_EXPORT BOOL hb_xvmPushField( PHB_SYMB pSymbol ) { HB_TRACE(HB_TR_INFO, ("hb_xvmPushField(%p)", pSymbol)); - hb_stackPush(); - hb_rddGetFieldValue( hb_stackItemFromTop( -1 ), pSymbol ); + hb_rddGetFieldValue( hb_stackAllocItem(), pSymbol ); HB_XVM_RETURN } @@ -6414,8 +6339,8 @@ HB_EXPORT BOOL hb_xvmPopField( PHB_SYMB pSymbol ) HB_EXPORT BOOL hb_xvmPushMemvar( PHB_SYMB pSymbol ) { HB_TRACE(HB_TR_INFO, ("hb_xvmPushMemvar(%p)", pSymbol)); - hb_memvarGetValue( hb_stackTopItem(), pSymbol ); - hb_stackPush(); + + hb_memvarGetValue( hb_stackAllocItem(), pSymbol ); HB_XVM_RETURN } @@ -6424,8 +6349,7 @@ HB_EXPORT BOOL hb_xvmPushMemvarByRef( PHB_SYMB pSymbol ) { HB_TRACE(HB_TR_INFO, ("hb_xvmPushMemvarByRef(%p)", pSymbol)); - hb_memvarGetRefer( hb_stackTopItem(), pSymbol ); - hb_stackPush(); + hb_memvarGetRefer( hb_stackAllocItem(), pSymbol ); HB_XVM_RETURN } @@ -7257,8 +7181,7 @@ HB_EXPORT BOOL hb_xvmPlusEq( void ) pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmPlus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); HB_XVM_RETURN } @@ -7293,8 +7216,7 @@ HB_EXPORT BOOL hb_xvmMinusEq( void ) pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmMinus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); HB_XVM_RETURN } @@ -7368,8 +7290,7 @@ HB_EXPORT BOOL hb_xvmMultEq( void ) pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmMult( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); HB_XVM_RETURN } @@ -7457,8 +7378,7 @@ HB_EXPORT BOOL hb_xvmDivEq( void ) pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) ); hb_vmDivide( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 ); - hb_itemCopy( hb_stackTopItem(), pResult ); - hb_stackPush(); + hb_itemCopy( hb_stackAllocItem(), pResult ); HB_XVM_RETURN } @@ -7570,9 +7490,8 @@ static void hb_vmArrayItemPush( ULONG ulIndex ) /* this is a constant array { 1, 2, 3 } - we cannot use * the optimization here */ - PHB_ITEM pItem = hb_stackTopItem(); + PHB_ITEM pItem = hb_stackAllocItem(); - hb_stackPush(); hb_itemMove( pItem, pArray->item.asArray.value->pItems + ulIndex - 1 ); hb_itemMove( pArray, pItem ); hb_stackDec(); diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index a58e8e253e..6567f0a15f 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -211,8 +211,6 @@ HB_EXPORT PHB_ITEM hb_itemPutC( PHB_ITEM pItem, const char * szText ) else pItem = hb_itemNew( NULL ); - pItem->type = HB_IT_STRING; - if( ulLen == 0 ) { pItem->item.asString.length = 0; @@ -234,6 +232,8 @@ HB_EXPORT PHB_ITEM hb_itemPutC( PHB_ITEM pItem, const char * szText ) hb_xmemcpy( pItem->item.asString.value, szText, ulLen + 1 ); } + pItem->type = HB_IT_STRING; + return pItem; } @@ -282,8 +282,6 @@ HB_EXPORT PHB_ITEM hb_itemPutCL( PHB_ITEM pItem, const char * szText, ULONG ulLe trash if the szText buffer is NULL, at least with hb_retclen(). [vszakats] */ - pItem->type = HB_IT_STRING; - if( szText == NULL || ulLen == 0 ) { pItem->item.asString.length = 0; @@ -305,6 +303,8 @@ HB_EXPORT PHB_ITEM hb_itemPutCL( PHB_ITEM pItem, const char * szText, ULONG ulLe pItem->item.asString.value[ ulLen ] = '\0'; } + pItem->type = HB_IT_STRING; + return pItem; } @@ -1408,8 +1408,7 @@ PHB_ITEM hb_itemUnRefOnce( PHB_ITEM pItem ) /* to avoid recursive RT error generation */ if( pItem->item.asEnum.offset >= 0 ) { - hb_stackPush(); - hb_itemPutNInt( hb_stackItemFromTop( -1 ), pItem->item.asEnum.offset ); + hb_itemPutNInt( hb_stackAllocItem(), pItem->item.asEnum.offset ); pItem->item.asEnum.offset = -1; if( !pItem->item.asEnum.valuePtr ) pItem->item.asEnum.valuePtr = hb_itemNew( NULL ); diff --git a/harbour/source/vm/memvars.c b/harbour/source/vm/memvars.c index 5513f8f4c0..abdaf1d7d7 100644 --- a/harbour/source/vm/memvars.c +++ b/harbour/source/vm/memvars.c @@ -1220,10 +1220,8 @@ HB_FUNC( __MVGET ) if( pDynVar ) { - PHB_ITEM pValue; + PHB_ITEM pValue = hb_stackAllocItem(); - hb_stackPush(); - pValue = hb_stackItemFromTop( -1 ); hb_memvarGetValue( pValue, pDynVar->pSymbol ); hb_itemReturnForward( pValue ); hb_stackDec(); @@ -1248,10 +1246,8 @@ HB_FUNC( __MVGET ) hb_itemGetCLen( pName ) ); if( pDynVar ) { - PHB_ITEM pValue; + PHB_ITEM pValue = hb_stackAllocItem(); - hb_stackPush(); - pValue = hb_stackItemFromTop( -1 ); hb_memvarGetValue( pValue, pDynVar->pSymbol ); hb_itemReturnForward( pValue ); hb_stackDec();