2006-06-27 10:50 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbapi.h
  * harbour/source/vm/proc.c
    + added BOOL hb_procinfo( int iLevel, char * szName,
                              USHORT * puiLine, char * szFile )

  * harbour/include/hbstack.h
  * harbour/source/vm/estack.c
    + added hb_stackTotalItems(), hb_stackDateBuffer(),
      hb_stackGetStaticsBase(), hb_stackSetStaticsBase(),
      hb_stackBaseProcInfo()

  * harbour/source/vm/garbage.c
    * indenting

  * harbour/source/vm/classes.c
  * harbour/source/vm/codebloc.c
  * harbour/source/vm/extend.c
  * harbour/source/vm/fm.c
  * harbour/source/vm/hvm.c
    * replaced direct stack access by stack functions/macros

  * harbour/source/vm/debug.c
    * removed hb_stackLenGlobal() and replace it by hb_stackTopOffset()
      Warning!!! hb_stackTopOffset() returnes results smaller by 1.
      The TOP stack item is undefined and should not be accessed by
      debuger.
    * changed HB_DBG_VMSTKGLIST() to operate on functions/macros.
      It's possible that the above will badly interact with core debugger
      code so I stop farther modifications leaving them for someone who
      knows debugger core code.
This commit is contained in:
Przemyslaw Czerpak
2006-06-27 08:53:26 +00:00
parent 5c01e3a134
commit 5cbcaa09f0
12 changed files with 356 additions and 236 deletions

View File

@@ -8,6 +8,37 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
to it. This code does not work as it should even know
and it's absolutely not reentrant safe. It will have to
be fixed before we will have .prg destructor and MT support.
As I can see the same problems has xHarbour.
2006-06-27 10:50 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
* harbour/source/vm/proc.c
+ added BOOL hb_procinfo( int iLevel, char * szName,
USHORT * puiLine, char * szFile )
* harbour/include/hbstack.h
* harbour/source/vm/estack.c
+ added hb_stackTotalItems(), hb_stackDateBuffer(),
hb_stackGetStaticsBase(), hb_stackSetStaticsBase(),
hb_stackBaseProcInfo()
* harbour/source/vm/garbage.c
* indenting
* harbour/source/vm/classes.c
* harbour/source/vm/codebloc.c
* harbour/source/vm/extend.c
* harbour/source/vm/fm.c
* harbour/source/vm/hvm.c
* replaced direct stack access by stack functions/macros
* harbour/source/vm/debug.c
* removed hb_stackLenGlobal() and replace it by hb_stackTopOffset()
Warning!!! hb_stackTopOffset() returnes results smaller by 1.
The TOP stack item is undefined and should not be accessed by
debuger.
* changed HB_DBG_VMSTKGLIST() to operate on functions/macros.
It's possible that the above will badly interact with core debugger

View File

@@ -756,6 +756,7 @@ extern char * hb_compReservedName( char * szName ); /* determines if a string
/* misc */
extern char * hb_procname( int iLevel, char * szName, BOOL bskipBlock ); /* retrieve a procedure name into a buffer */
extern BOOL hb_procinfo( int iLevel, char * szName, USHORT * puiLine, char * szFile );
/* macro compiler */

View File

@@ -93,12 +93,16 @@ typedef struct
#define hb_stackItemFromTop( n ) ( * ( hb_stack.pPos + ( int ) (n) ) )
#define hb_stackItemFromBase( n ) ( * ( hb_stack.pBase + ( int ) (n) + 1 ) )
#define hb_stackTopOffset( ) ( hb_stack.pPos - hb_stack.pItems )
#define hb_stackBaseOffset( ) ( hb_stack.pBase - hb_stack.pItems + 1)
#define hb_stackBaseOffset( ) ( hb_stack.pBase - hb_stack.pItems + 1 )
#define hb_stackTotalItems( ) ( hb_stack.wItems )
#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 ) ) )
#define hb_stackReturnItem( ) ( &hb_stack.Return )
#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_stackDecrease( n ) do { \
@@ -144,11 +148,15 @@ extern HB_ITEM_PTR hb_stackItemFromTop( int nFromTop );
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_stackBaseItem( void );
extern HB_ITEM_PTR hb_stackSelfItem( void );
extern HB_ITEM_PTR hb_stackItem( LONG iItemPos );
extern HB_ITEM_PTR hb_stackReturnItem( void );
extern char * hb_stackDateBuffer( void );
extern void hb_stackSetStaticsBase( int iBase );
extern int hb_stackGetStaticsBase( 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 */
@@ -157,17 +165,18 @@ extern void hb_stackPush( void ); /* pushes an item on to the stack
#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_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 );
extern void hb_stackOldFrame( HB_STACK_STATE * pStack );
extern void hb_stackOldFrame( HB_STACK_STATE * pStack );
#endif
HB_EXTERN_END

View File

@@ -267,10 +267,6 @@ static PMETHOD s_pMethod = NULL; /* TOFIX: The object engine is not thread
/* All functions contained in classes.c */
static PHB_ITEM hb_clsInst( USHORT uiClass );
#if 0
/* see function definition */
static void hb_clsScope( PHB_ITEM pObject, PMETHOD pMethod );
#endif
static ULONG hb_cls_MsgToNum( PHB_DYNS pMsg );
static void hb_clsDictRealloc( PCLASS pClass );
static void hb_clsRelease( PCLASS );
@@ -478,7 +474,7 @@ void hb_clsIsClassRef( void )
#if 0
static void hb_clsScope( PHB_ITEM pObject, PMETHOD pMethod )
{
PHB_ITEM * pBase = hb_stack.pBase;
long lOffset = hb_stackBaseOffset();
PHB_ITEM pCaller;
LONG iLevel = 1;
BOOL bRetVal = FALSE ;
@@ -491,142 +487,154 @@ static void hb_clsScope( PHB_ITEM pObject, PMETHOD pMethod )
char * szSelfNameObject; /* debug */
char * szSelfNameRealClass;
if ( (( uiScope & HB_OO_CLSTP_PROTECTED ) ) ||
(( uiScope & HB_OO_CLSTP_HIDDEN ) ) ||
(( uiScope & HB_OO_CLSTP_READONLY ) )
)
{
if( ( ( uiScope & HB_OO_CLSTP_PROTECTED ) ) ||
( ( uiScope & HB_OO_CLSTP_HIDDEN ) ) ||
( ( uiScope & HB_OO_CLSTP_READONLY ) ) )
{
szSelfNameObject = hb_objGetClsName( pObject ); /* debug */
szSelfNameMsg = pMessage->pSymbol->szName ;
szSelfNameRealClass = hb_objGetRealClsName( pObject, pMessage->pSymbol->szName );
while( ( iLevel-- > 0 ) && pBase != hb_stack.pItems )
pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase;
while( iLevel-- > 0 && lOffset > 1 )
lOffset = hb_stackItem( lOffset - 1 )->item.asSymbol.stackbase + 1;
szCallerNameMsg = ( *pBase )->item.asSymbol.value->szName ;
szCallerNameMsg = hb_stackItem( lOffset - 1 )->item.asSymbol.value->szName;
/* Is it an inline ? if so back one more ... */
if ( ( strcmp( szCallerNameMsg, "__EVAL" ) == 0 ) && pBase != hb_stack.pItems)
{
pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase;
szCallerNameMsg = ( *pBase )->item.asSymbol.value->szName ;
}
if( strcmp( szCallerNameMsg, "__EVAL" ) == 0 && lOffset > 1 )
{
lOffset = hb_stackItem( lOffset - 1 )->item.asSymbol.stackbase + 1;
szCallerNameMsg = hb_stackItem( lOffset - 1 )->item.asSymbol.value->szName;
}
/* Is it an eval ? if so back another one more ... */
if ( ( strcmp( szCallerNameMsg, "EVAL" ) == 0 ) && pBase != hb_stack.pItems)
{
pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase;
szCallerNameMsg = ( *pBase )->item.asSymbol.value->szName ;
}
if( ( strcmp( szCallerNameMsg, "EVAL" ) == 0 ) && lOffset > 1 )
{
lOffset = hb_stackItem( lOffset - 1 )->item.asSymbol.stackbase + 1;
szCallerNameMsg = hb_stackItem( lOffset - 1 )->item.asSymbol.value->szName;
}
/* Is it an Aeval ? if so back another one more ... */
if ( ( strcmp( szCallerNameMsg, "AEVAL" ) == 0 ) && pBase != hb_stack.pItems)
{
pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase;
szCallerNameMsg = ( *pBase )->item.asSymbol.value->szName ;
}
if ( ( strcmp( szCallerNameMsg, "AEVAL" ) == 0 ) && lOffset > 1 )
{
lOffset = hb_stackItem( lOffset - 1 )->item.asSymbol.stackbase + 1;
szCallerNameMsg = hb_stackItem( lOffset - 1 )->item.asSymbol.value->szName;
}
if( iLevel == -1 )
{
/* Now get the callers ... */
pCaller = * (pBase+1 ) ;
szCallerNameObject = hb_objGetRealClsName( pCaller, szCallerNameMsg ) ;
{
/* Now get the callers ... */
pCaller = hb_stackItem( lOffset );
szCallerNameObject = hb_objGetRealClsName( pCaller, szCallerNameMsg );
strcpy( szName, szCallerNameObject );
strcat( szName, ":" );
strcat( szName, szCallerNameMsg );
strcat( szName, ">" );
strcat( szName, szSelfNameRealClass );
strcat( szName, ">" );
strcat( szName, szSelfNameObject );
strcat( szName, ":" );
strcat( szName, szSelfNameMsg );
strcpy( szName, szCallerNameObject );
strcat( szName, ":" );
strcat( szName, szCallerNameMsg );
strcat( szName, ">" );
strcat( szName, szSelfNameRealClass );
strcat( szName, ">" );
strcat( szName, szSelfNameObject );
strcat( szName, ":" );
strcat( szName, szSelfNameMsg );
/*strcpy( szName, szSelfNameRealClass ); */
/*strcat( szName, ":" ); */
/*strcat( szName, szSelfNameMsg ); */
/*strcpy( szName, szSelfNameRealClass ); */
/*strcat( szName, ":" ); */
/*strcat( szName, szSelfNameMsg ); */
if ( uiScope & HB_OO_CLSTP_PROTECTED )
if( uiScope & HB_OO_CLSTP_PROTECTED )
{
if( ( *( pBase+1 ) )->type == HB_IT_ARRAY ) /* is the sender an object */
{
/* Trying to access a protected Msg from outside the object ... */
if ( strcmp( szCallerNameObject, szSelfNameRealClass ) != 0 )
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (protected 1)", szName, 0 );
}
else
{
/* If called from a function ... protected violation ! */
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (protected 0)", szName, 0 );
}
}
if ( uiScope & HB_OO_CLSTP_HIDDEN )
{
if( ( *( pBase+1 ) )->type == HB_IT_ARRAY ) /* is the sender an object */
{
/* Trying to access a protected Msg from outside the object ... */
if ( strcmp( szCallerNameObject, szSelfNameRealClass ) != 0 )
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (Hidden 1)", szName, 0 );
else
{
/* Now as it is an hidden Msg, it can only be called from */
/* a method of its original class */
if (! (hb_objGetRealClsName( pCaller, szCallerNameMsg) == szSelfNameRealClass) )
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (Hidden 2)", szName, 0 );
}
}
else
{
/* If called from a function ... Hidden violation ! */
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (Hidden 0)", szName, 0 );
}
}
if ( uiScope & HB_OO_CLSTP_READONLY )
{
if( ( pMethod->pFuncSym == s___msgSetData ) ||
( pMethod->pFuncSym == s___msgSetClsData ) ||
( pMethod->pFuncSym == s___msgSetShrData ) )
bRetVal = TRUE;
if (bRetVal)
if( pCaller->type == HB_IT_ARRAY ) /* is the sender an object */
{
if( ( *( pBase+1 ) )->type == HB_IT_ARRAY ) /* is the sender an object */
{
/* Trying to assign a RO Msg from outside the object ... */
if ( strcmp( szCallerNameObject, szSelfNameRealClass ) != 0 )
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (ReadOnly)", szName, 0 );
/* Trying to access a protected Msg from outside the object ... */
if( strcmp( szCallerNameObject, szSelfNameRealClass ) != 0 )
{
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (protected 1)", szName, 0 );
return;
}
}
else
{
/* If called from a function ... protected violation ! */
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (protected 0)", szName, 0 );
return;
}
}
if( uiScope & HB_OO_CLSTP_HIDDEN )
{
if( pCaller->type == HB_IT_ARRAY ) /* is the sender an object */
{
/* Trying to access a protected Msg from outside the object ... */
if( strcmp( szCallerNameObject, szSelfNameRealClass ) != 0 )
{
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (Hidden 1)", szName, 0 );
return;
}
else
{
{
/* Now as it is an hidden Msg, it can only be called from */
/* a method of its original class */
if( !( hb_objGetRealClsName( pCaller, szCallerNameMsg ) == szSelfNameRealClass ) )
{
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (Hidden 2)", szName, 0 );
return;
}
}
}
else
{
/* If called from a function ... Hidden violation ! */
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (Hidden 0)", szName, 0 );
}
}
if( uiScope & HB_OO_CLSTP_READONLY )
{
if( ( pMethod->pFuncSym == &s___msgSetData ) ||
( pMethod->pFuncSym == &s___msgSetClsData ) ||
( pMethod->pFuncSym == &s___msgSetShrData ) )
bRetVal = TRUE;
if( bRetVal )
{
if( pCaller->type == HB_IT_ARRAY ) /* is the sender an object */
{
/* Trying to assign a RO Msg from outside the object ... */
if( strcmp( szCallerNameObject, szSelfNameRealClass ) != 0 )
{
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (ReadOnly)", szName, 0 );
return;
}
else
{
#ifdef HB_CLS_ENFORCERO /* Not enabled by default */
/* can only be called from a Constructor */
/* ok Now is it a CTOR ? */
PMETHOD pCallerMethod ;
PHB_DYNS pCallerMsg = hb_dynsymGet( szCallerNameMsg );
PMETHOD pCallerMethod ;
pCallerMethod = hb_objGetpMethod( pCaller, pCallerMsg->pSymbol );
PHB_DYNS pCallerMsg = hb_dynsymGet( szCallerNameMsg );
pCallerMethod = hb_objGetpMethod( pCaller, pCallerMsg->pSymbol );
if ( pCallerMethod )
{
if ( ! (pCallerMethod->uiScope & HB_OO_CLSTP_CTOR) )
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (ReadOnly)", szName, 0 );
}
if( pCallerMethod )
{
if( ! ( pCallerMethod->uiScope & HB_OO_CLSTP_CTOR ) )
{
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (ReadOnly)", szName, 0 );
return;
}
}
#endif
}
}
else
{
/* If called from a function ... ReadOnly violation ! */
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (ReadOnly 0)", szName, 0 );
}
}
}
else
{
/* If called from a function ... ReadOnly violation ! */
hb_errRT_BASE( EG_NOMETHOD, 1004, "Scope violation (ReadOnly 0)", szName, 0 );
}
}
}
}
}
}
}
}
}
#endif
@@ -903,7 +911,7 @@ PHB_SYMB hb_objGetMethod( PHB_ITEM pObject, PHB_SYMB pMessage, BOOL * pfPopSuper
if( pClass->pMethods[ uiAt ].pMessage == pMsg )
{
PMETHOD pMethod = pClass->pMethods + uiAt;
/*hb_clsScope( pObject, pMethod );*/ /* debug */
/* hb_clsScope( pObject, pMethod ); */ /* debug */
s_pMethod = pMethod ;
return pMethod->pFuncSym;
}
@@ -960,6 +968,7 @@ BOOL hb_objHasMessage( PHB_ITEM pObject, PHB_DYNS pMessage )
return hb_objGetMethod( pObject, pMessage->pSymbol, NULL ) != NULL;
}
#ifndef HB_CLS_ENFORCERO
/*
* This function is only for backward binary compatibility
* It will be removed in the future so please do not use it.
@@ -972,16 +981,7 @@ BOOL hb_objGetpMethod( PHB_ITEM pObject, PHB_SYMB pMessage )
{
return hb_objGetMethod( pObject, pMessage, NULL ) != NULL;
}
static PHB_SYMB hb_objFuncParam( int iParam )
{
PHB_ITEM pItem = hb_param( iParam, HB_IT_SYMBOL );
if( pItem )
return pItem->item.asSymbol.value;
return NULL;
}
#endif
#ifdef HB_CLS_ENFORCERO
static PMETHOD hb_objGetpMethod( PHB_ITEM pObject, PHB_SYMB pMessage )
@@ -1018,6 +1018,16 @@ static PMETHOD hb_objGetpMethod( PHB_ITEM pObject, PHB_SYMB pMessage )
}
#endif
static PHB_SYMB hb_objFuncParam( int iParam )
{
PHB_ITEM pItem = hb_param( iParam, HB_IT_SYMBOL );
if( pItem )
return pItem->item.asSymbol.value;
return NULL;
}
/*
* Check if object has a given operator
*/

View File

@@ -250,7 +250,7 @@ void hb_codeblockEvaluate( HB_ITEM_PTR pItem )
{
HB_TRACE(HB_TR_DEBUG, ("hb_codeblockEvaluate(%p)", pItem));
hb_stack.iStatics = pItem->item.asBlock.statics;
hb_stackSetStaticsBase( pItem->item.asBlock.statics );
hb_vmExecute( pItem->item.asBlock.value->pCode, pItem->item.asBlock.value->pSymbols );
}

View File

@@ -80,29 +80,13 @@ static void AddToArray( PHB_ITEM pItem, PHB_ITEM pReturn, ULONG ulPos )
hb_itemArrayPut( pReturn, ulPos, pItem );
}
/* $Doc$
* $FuncName$ <nVars> __vmStkGCount()
* $Description$ Returns the length of the global stack
* $End$ */
static USHORT hb_stackLenGlobal( void )
{
PHB_ITEM * pItem;
USHORT uiCount = 0;
HB_TRACE(HB_TR_DEBUG, ("hb_stackLenGlobal()"));
for( pItem = hb_stack.pItems; pItem++ <= hb_stack.pPos; uiCount++ );
return uiCount;
}
/* $Doc$
* $FuncName$ <nVars> hb_dbg_vmStkGCount()
* $Description$ Returns the length of the global stack
* $End$ */
HB_FUNC( HB_DBG_VMSTKGCOUNT )
{
hb_retni( hb_stackLenGlobal() );
hb_retnl( hb_stackTopOffset() );
}
/* $Doc$
@@ -112,16 +96,15 @@ HB_FUNC( HB_DBG_VMSTKGCOUNT )
HB_FUNC( HB_DBG_VMSTKGLIST )
{
PHB_ITEM pReturn;
PHB_ITEM * pItem;
ULONG ulLen = hb_stackTopOffset();
ULONG ulPos;
USHORT uiLen = hb_stackLenGlobal();
USHORT uiPos = 1;
pReturn = hb_itemArrayNew( uiLen ); /* Create a transfer array */
for( pItem = hb_stack.pItems; pItem <= hb_stack.pPos; pItem++ )
AddToArray( *pItem, pReturn, uiPos++ );
pReturn = hb_itemArrayNew( ulLen ); /* Create a transfer array */
for( ulPos = 0; ulPos < ulLen; ++ulPos )
{
AddToArray( hb_stackItem( ulPos ), pReturn, ulPos + 1 );
}
hb_itemRelease( hb_itemReturn( pReturn ) );
}
@@ -136,7 +119,7 @@ static USHORT hb_stackLen( int iLevel )
HB_TRACE(HB_TR_DEBUG, ("hb_stackLen()"));
while( ( iLevel-- > 0 ) && pBase != hb_stack.pItems )
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;
@@ -246,12 +229,13 @@ HB_FUNC( HB_DBG_VMVARLSET )
iLocal -= USHRT_MAX;
iLocal--;
}
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_itemCopy( hb_itemUnRef( pLocal ), *(hb_stack.pBase + 4) );
}
HB_FUNC( __VMSTKLCOUNT )

View File

@@ -199,6 +199,8 @@ void hb_stackInit( void )
hb_stack.wItems = STACK_INITHB_ITEMS;
hb_stack.pEnd = hb_stack.pItems + hb_stack.wItems;
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 ) );
}
@@ -309,6 +311,47 @@ LONG hb_stackBaseOffset( void )
return hb_stack.pBase - hb_stack.pItems + 1;
}
#undef hb_stackTotalItems
LONG hb_stackTotalItems( void )
{
return hb_stack.wItems;
}
#undef hb_stackDateBuffer
char * hb_stackDateBuffer( void )
{
return hb_stack.szDate;
}
#undef hb_stackGetStaticsBase
int hb_stackGetStaticsBase( void )
{
return hb_stack.iStatics;
}
#undef hb_stackSetStaticsBase
void hb_stackSetStaticsBase( int iBase )
{
hb_stack.iStatics = iBase;
}
void hb_stackBaseProcInfo( char * szProcName, USHORT * puiProcLine )
{
/*
* This function is called by FM module and has to be ready for execution
* before stack initialization, [druzus];
*/
if( hb_stack.pPos > hb_stack.pBase )
{
strcpy( szProcName, ( * hb_stack.pBase )->item.asSymbol.value->szName );
* puiProcLine = ( * hb_stack.pBase )->item.asSymbol.lineno;
}
else
{
szProcName[ 0 ] = '\0';
* puiProcLine = 0;
}
}
/* NOTE: DEBUG function */
void hb_stackDispLocal( void )

View File

@@ -275,7 +275,7 @@ HB_EXPORT ULONG hb_parcsiz( int iParam, ... )
return 0;
}
/* NOTE: Using hb_stack.szDate as a temporary date buffer guaranties
/* NOTE: Using hb_stackDateBuffer() a temporary date buffer guaranties
good behavior when multithreading. */
HB_EXPORT char * hb_pards( int iParam, ... )
@@ -290,7 +290,7 @@ HB_EXPORT char * hb_pards( int iParam, ... )
pItem = hb_itemUnRef( pItem );
if( HB_IS_DATE( pItem ) )
return hb_dateDecStr( hb_stack.szDate, pItem->item.asDate.value );
return hb_dateDecStr( hb_stackDateBuffer(), pItem->item.asDate.value );
else if( HB_IS_ARRAY( pItem ) )
{
va_list va;
@@ -300,11 +300,11 @@ HB_EXPORT char * hb_pards( int iParam, ... )
ulArrayIndex = va_arg( va, ULONG );
va_end( va );
return hb_arrayGetDS( pItem, ulArrayIndex, hb_stack.szDate );
return hb_arrayGetDS( pItem, ulArrayIndex, hb_stackDateBuffer() );
}
}
return hb_dateDecStr( hb_stack.szDate, 0 );
return hb_dateDecStr( hb_stackDateBuffer(), 0 );
}
/* NOTE: szDate must be a 9 chars wide buffer. [vszakats] */

View File

@@ -200,17 +200,7 @@ HB_EXPORT void * hb_xalloc( ULONG ulSize ) /* allocates fixed memory, re
}
else
{
if( hb_stack.pItems && ( hb_stack.pBase != hb_stack.pItems ) )
{
pMem->uiProcLine = ( hb_stackBaseItem() )->item.asSymbol.lineno; /* PRG line number */
strcpy( pMem->szProcName,
( hb_stackBaseItem() )->item.asSymbol.value->szName ); /* PRG ProcName */
}
else
{
pMem->uiProcLine = 0; /* PRG line number */
pMem->szProcName[ 0 ] = '\0'; /* PRG ProcName */
}
hb_stackBaseProcInfo( pMem->szProcName, &pMem->uiProcLine );
}
s_lMemoryConsumed += ulSize + sizeof( HB_COUNTER );
@@ -275,17 +265,7 @@ HB_EXPORT void * hb_xgrab( ULONG ulSize ) /* allocates fixed memory, exi
}
else
{
if( hb_stack.pItems && ( hb_stack.pBase != hb_stack.pItems ) )
{
pMem->uiProcLine = ( hb_stackBaseItem() )->item.asSymbol.lineno; /* PRG line number */
strcpy( pMem->szProcName,
( hb_stackBaseItem() )->item.asSymbol.value->szName ); /* PRG ProcName */
}
else
{
pMem->uiProcLine = 0; /* PRG line number */
pMem->szProcName[ 0 ] = '\0'; /* PRG ProcName */
}
hb_stackBaseProcInfo( pMem->szProcName, &pMem->uiProcLine );
}
s_lMemoryConsumed += ulSize + sizeof( HB_COUNTER );
@@ -829,11 +809,11 @@ ULONG hb_xquery( USHORT uiMode )
break;
case HB_MEM_STACKITEMS: /* Harbour extension (Total items allocated for the stack) */
ulResult = hb_stack.wItems;
ulResult = hb_stackTotalItems();
break;
case HB_MEM_STACK: /* Harbour extension (Total memory size used by the stack [bytes]) */
ulResult = hb_stack.wItems * sizeof( HB_ITEM );
ulResult = hb_stackTotalItems() * sizeof( HB_ITEM );
break;
case HB_MEM_STACK_TOP : /* Harbour extension (Total items currently on the stack) */

View File

@@ -190,10 +190,10 @@ void hb_gcFree( void *pBlock )
hb_gcUnlink( &s_pLockedBlock, pAlloc );
else
hb_gcUnlink( &s_pCurrBlock, pAlloc );
if( pAlloc->flags & HB_GC_USERSWEEP )
hb_gcUnregisterSweep( pBlock );
HB_GARBAGE_FREE( pAlloc );
}
}
@@ -530,7 +530,7 @@ void hb_gcCollectAll( void )
else
{
HB_GARBAGE_EXTERN_PTR pFree = *pExtPtr;
pAlloc->flags &= ~ HB_GC_USERSWEEP;
*pExtPtr = ( *pExtPtr )->pNext;
hb_xfree( pFree );
@@ -582,7 +582,7 @@ void hb_gcCollectAll( void )
}
else
{
/* at least one block will not be deleted, set new stop condition */
/* at least one block will not be deleted, set new stop condition */
if( ! pAlloc )
pAlloc = s_pCurrBlock;
s_pCurrBlock = s_pCurrBlock->pNext;

View File

@@ -404,12 +404,9 @@ HB_EXPORT void hb_vmInit( BOOL bStartMainProc )
s_pDynsDbgEntry = hb_dynsymFind( "__DBGENTRY" );
hb_stack.pItems = NULL; /* keep this here as it is used by fm.c */
hb_stack.Return.type = HB_IT_NIL;
hb_xinit();
hb_errInit();
hb_stackInit();
hb_errInit();
hb_dynsymNew( &hb_symEval ); /* initialize dynamic symbol for evaluating codeblocks */
hb_dynsymNew( &hb_symEnumIndex );
@@ -3994,17 +3991,17 @@ HB_EXPORT void hb_vmSend( USHORT uiParams )
{
if( pSym->pDynSym == hb_symEnumIndex.pDynSym )
{
hb_itemPutNL( &hb_stack.Return, pEnum->item.asEnum.offset );
hb_itemPutNL( hb_stackReturnItem(), pEnum->item.asEnum.offset );
bNotHandled = FALSE;
}
else if( pSym->pDynSym == hb_symEnumBase.pDynSym )
{
hb_itemCopy( &hb_stack.Return, pEnum->item.asEnum.basePtr );
hb_itemCopy( hb_stackReturnItem(), pEnum->item.asEnum.basePtr );
bNotHandled = FALSE;
}
else if( pSym->pDynSym == hb_symEnumValue.pDynSym )
{
hb_itemCopy( &hb_stack.Return, hb_itemUnRefOnce( pEnum ) );
hb_itemCopy( hb_stackReturnItem(), hb_itemUnRefOnce( pEnum ) );
bNotHandled = FALSE;
}
}
@@ -4094,7 +4091,7 @@ HB_ITEM_PTR hb_vmEvalBlock( HB_ITEM_PTR pBlock )
hb_vmPushSymbol( &hb_symEval );
hb_vmPush( pBlock );
hb_vmDo( 0 );
return &hb_stack.Return;
return hb_stackReturnItem();
}
/* Evaluates a codeblock item using passed additional arguments
@@ -4124,7 +4121,7 @@ HB_ITEM_PTR hb_vmEvalBlockV( HB_ITEM_PTR pBlock, ULONG ulArgCount, ... )
/* added an explicit casting here for VC++ JFL */
hb_vmDo( (USHORT) ulArgCount );
return &hb_stack.Return;
return hb_stackReturnItem();
}
/* Evaluates a passed codeblock item or macro pointer item
@@ -4214,7 +4211,7 @@ static void hb_vmStaticName( BYTE bIsGlobal, USHORT uiStatic, char * szStaticNam
hb_vmPushSymbol( s_pDynsDbgEntry->pSymbol );
hb_vmPushNil();
hb_vmPushLongConst( HB_DBG_STATICNAME );
hb_vmPushLongConst( hb_stack.iStatics ); /* current static frame */
hb_vmPushLongConst( hb_stackGetStaticsBase() ); /* current static frame */
hb_vmPushLongConst( uiStatic ); /* variable index */
hb_vmPushString( szStaticName, strlen( szStaticName ) );
s_bDebuggerIsWorking = TRUE;
@@ -4271,7 +4268,7 @@ static void hb_vmSFrame( PHB_SYMB pSym ) /* sets the statics frame for a fu
HB_TRACE(HB_TR_DEBUG, ("hb_vmSFrame(%p)", pSym));
/* _INITSTATICS is now the statics frame. Statics() changed it! */
hb_stack.iStatics = pSym->value.iStaticsBase; /* pSym is { "$_INITSTATICS", HB_FS_INITEXIT, _INITSTATICS } for each PRG */
hb_stackSetStaticsBase( pSym->value.iStaticsBase );
}
static void hb_vmStatics( PHB_SYMB pSym, USHORT uiStatics ) /* initializes the global aStatics array or redimensionates it */
@@ -4649,7 +4646,7 @@ static void hb_vmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols, USHORT usLen
/* store the statics base of function where the codeblock was defined
*/
pStackTopItem->item.asBlock.statics = hb_stack.iStatics;
pStackTopItem->item.asBlock.statics = hb_stackGetStaticsBase();
/* store the number of expected parameters
*/
pStackTopItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( pCode );
@@ -4682,7 +4679,7 @@ static void hb_vmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols, USHORT u
/* store the statics base of function where the codeblock was defined
*/
pStackTopItem->item.asBlock.statics = hb_stack.iStatics;
pStackTopItem->item.asBlock.statics = hb_stackGetStaticsBase();
/* store the number of expected parameters
*/
pStackTopItem->item.asBlock.paramcnt = 0;
@@ -4713,7 +4710,7 @@ static void hb_vmPushMacroBlock( BYTE * pCode, PHB_SYMB pSymbols )
/* store the statics base of function where the codeblock was defined
*/
pStackTopItem->item.asBlock.statics = hb_stack.iStatics;
pStackTopItem->item.asBlock.statics = hb_stackGetStaticsBase();
/* store the number of expected parameters
*/
pStackTopItem->item.asBlock.paramcnt = HB_PCODE_MKUSHORT( &( pCode[ 3 ] ) );
@@ -4888,7 +4885,7 @@ static void hb_vmPushStatic( USHORT uiStatic )
HB_TRACE(HB_TR_DEBUG, ("hb_vmPushStatic(%hu)", uiStatic));
pStatic = s_aStatics.item.asArray.value->pItems + hb_stack.iStatics + uiStatic - 1;
pStatic = s_aStatics.item.asArray.value->pItems + hb_stackGetStaticsBase() + uiStatic - 1;
if( HB_IS_BYREF( pStatic ) )
hb_itemCopy( hb_stackTopItem(), hb_itemUnRef( pStatic ) );
else
@@ -4903,7 +4900,7 @@ static void hb_vmPushStaticByRef( USHORT uiStatic )
pTop->type = HB_IT_BYREF;
/* we store the offset instead of a pointer to support a dynamic stack */
pTop->item.asRefer.value = hb_stack.iStatics + uiStatic - 1;
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();
@@ -5257,7 +5254,7 @@ static void hb_vmPopStatic( USHORT uiStatic )
/* Remove MEMOFLAG if exists (assignment from field). */
pVal->type &= ~HB_IT_MEMOFLAG;
pStatic = s_aStatics.item.asArray.value->pItems + hb_stack.iStatics + uiStatic - 1;
pStatic = s_aStatics.item.asArray.value->pItems + hb_stackGetStaticsBase() + uiStatic - 1;
/* Is it Clipper compatible? */
if( HB_IS_BYREF( pStatic ) )
@@ -5939,39 +5936,22 @@ void hb_vmRequestCancel( void )
if( hb_set.HB_SET_CANCEL )
{
char buffer[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 2 ];
int i = 1, i2;
ULONG ulLine;
PHB_ITEM * pBase;
char buffer[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5 + 10 ]; /* additional 10 bytes for line info (%hu) overhead */
USHORT uiLine;
int i = 0;
hb_conOutErr( hb_conNewLine(), 0 );
sprintf( buffer, "Cancelled at: %s (%i)", ( hb_stackBaseItem() )->item.asSymbol.value->szName, ( hb_stackBaseItem() )->item.asSymbol.lineno );
hb_conOutErr( buffer, 0 );
hb_conOutErr( hb_conNewLine(), 0 );
hb_conOutErr( "Cancelled at: ", 0 );
hb_stackBaseProcInfo( buffer, &uiLine );
while( buffer[0] )
do
{
i2 = i;
hb_procname( i++, buffer, FALSE );
if( buffer[0] == 0 )
break;
pBase = hb_stack.pBase;
while( ( i2-- > 0 ) && pBase != hb_stack.pItems )
pBase = hb_stack.pItems + ( *pBase )->item.asSymbol.stackbase;
if( i2 == -1 )
ulLine = ( *pBase )->item.asSymbol.lineno;
else
ulLine = 0;
i2 = strlen( (char *) buffer );
sprintf( buffer + i2, " (%lu)", ulLine );
sprintf( buffer + strlen( buffer ), " (%hu)", uiLine );
hb_conOutErr( buffer, 0 );
hb_conOutErr( hb_conNewLine(), 0 );
}
while( hb_procinfo( ++i, buffer, &uiLine, NULL ) );
s_uiActionRequest = HB_QUIT_REQUESTED;
}
@@ -6524,7 +6504,7 @@ HB_EXPORT BOOL hb_xvmStaticAdd( USHORT uiStatic )
HB_TRACE(HB_TR_DEBUG, ("hb_xvmStaticAdd(%hu)", uiStatic));
pStatic = s_aStatics.item.asArray.value->pItems + hb_stack.iStatics + uiStatic - 1;
pStatic = s_aStatics.item.asArray.value->pItems + hb_stackGetStaticsBase() + uiStatic - 1;
if( HB_IS_BYREF( pStatic ) )
pStatic = hb_itemUnRef( pStatic );
hb_vmPlus( pStatic, hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 2 );

View File

@@ -87,7 +87,7 @@ HB_FUNC( HB_METHODNAME )
HB_FUNC( PROCNAME )
{
char szName[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 2 ];
char szName[ HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5 ];
hb_retc( hb_procname( hb_parni( 1 ) + 1, szName, FALSE ) );
}
@@ -157,7 +157,7 @@ HB_FUNC( PROCFILE )
#endif
/* NOTE: szName size must be an at least:
HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 2 [vszakats] */
HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5 [vszakats] */
char * hb_procname( int iLevel, char * szName, BOOL bSkipBlock )
{
@@ -180,7 +180,7 @@ char * hb_procname( int iLevel, char * szName, BOOL bSkipBlock )
}
}
pBase = hb_stackItem( lOffset -1 );
pBase = hb_stackItem( lOffset - 1 );
pSelf = hb_stackItem( lOffset );
if( HB_IS_OBJECT( pSelf ) ) /* it is a method name */
{
@@ -198,7 +198,7 @@ char * hb_procname( int iLevel, char * szName, BOOL bSkipBlock )
if( lPrevOffset ) /* Back to standart code block */
{
lOffset = lPrevOffset;
pBase = hb_stackItem( lOffset -1 );
pBase = hb_stackItem( lOffset - 1 );
pSelf = hb_stackItem( lOffset );
}
@@ -220,3 +220,85 @@ char * hb_procname( int iLevel, char * szName, BOOL bSkipBlock )
return szName;
}
/* NOTE: szName size must be an at least:
* HB_SYMBOL_NAME_LEN + HB_SYMBOL_NAME_LEN + 5
* szFile szie must be an at least:
* _POSIX_PATH_MAX + 1
*/
BOOL hb_procinfo( int iLevel, char * szName, USHORT * puiLine, char * szFile )
{
long lOffset = hb_stackBaseOffset();
PHB_ITEM pBase, pSelf;
PHB_SYMB pSym;
while( iLevel-- > 0 && lOffset > 1 )
lOffset = hb_stackItem( lOffset - 1 )->item.asSymbol.stackbase + 1;
if( iLevel < 0 )
{
pBase = hb_stackItem( lOffset - 1 );
pSelf = hb_stackItem( lOffset );
pSym = pBase->item.asSymbol.value;
if( szName )
{
if( HB_IS_OBJECT( pSelf ) ) /* it is a method name */
{
strcpy( szName, hb_objGetRealClsName( pSelf, pSym->szName ) );
strcat( szName, ":" );
strcat( szName, pSym->szName );
}
else
{
if( pSym == &hb_symEval || strcmp( pSym->szName, "EVAL" ) == 0 )
{
strcpy( szName, "(b)" );
if( HB_IS_BLOCK( pSelf ) )
strcat( szName, pSelf->item.asBlock.value->pDefSymb->szName );
else
strcat( szName, pSym->szName );
}
else
strcpy( szName, pSym->szName );
}
}
if( puiLine )
* puiLine = pBase->item.asSymbol.lineno;
if( szFile )
{
char * szModule;
if( ( pSym == &hb_symEval || strcmp( pSym->szName, "EVAL" ) == 0 ) &&
HB_IS_BLOCK( pSelf ) && pSelf->item.asBlock.value->pDefSymb )
pSym = pSelf->item.asBlock.value->pDefSymb;
else if( ( pSym->scope.value & HB_FS_LOCAL ) == 0 )
{
if( ( pSym->pDynSym->pSymbol->scope.value & HB_FS_LOCAL ) != 0 )
pSym = pSym->pDynSym->pSymbol;
else
pSym = NULL;
}
szModule = hb_vmFindModuleSymbolName( pSym );
if( szModule )
strcpy( szFile, szModule );
else
szFile[ 0 ] = '\0';
}
return TRUE;
}
if( szName )
szName[ 0 ] = '\0';
if( puiLine )
* puiLine = 0;
if( szFile )
szFile[ 0 ] = '\0';
return FALSE;
}