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();