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(&<paramList>), aVal[&<indexList>], {&<itemList>}
   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.
This commit is contained in:
Przemyslaw Czerpak
2006-07-04 11:27:48 +00:00
parent 351d42b158
commit 688bec195a
9 changed files with 493 additions and 530 deletions

View File

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

View File

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

View File

@@ -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
*/
}
}

View File

@@ -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 */

View File

@@ -112,20 +112,25 @@ HB_FUNC( HB_DBG_VMSTKGLIST )
* $FuncName$ <nVars> __vmStkLCount( <nProcLevel> )
* $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 )

View File

@@ -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 )
{
/*

File diff suppressed because it is too large Load Diff

View File

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

View File

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