From 5cbcaa09f07ac0e92571281eb94fe51c2f5fa300 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Tue, 27 Jun 2006 08:53:26 +0000 Subject: [PATCH] 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. --- harbour/ChangeLog | 31 +++++ harbour/include/hbapi.h | 1 + harbour/include/hbstack.h | 15 +- harbour/source/vm/classes.c | 262 ++++++++++++++++++----------------- harbour/source/vm/codebloc.c | 2 +- harbour/source/vm/debug.c | 38 ++--- harbour/source/vm/estack.c | 43 ++++++ harbour/source/vm/extend.c | 8 +- harbour/source/vm/fm.c | 28 +--- harbour/source/vm/garbage.c | 8 +- harbour/source/vm/hvm.c | 66 +++------ harbour/source/vm/proc.c | 90 +++++++++++- 12 files changed, 356 insertions(+), 236 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index a8c8333dc7..306fe2e2f4 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,37 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + 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 diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 8d6bb92992..f28fd00c77 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -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 */ diff --git a/harbour/include/hbstack.h b/harbour/include/hbstack.h index c6192f4021..b9d9cb9c83 100644 --- a/harbour/include/hbstack.h +++ b/harbour/include/hbstack.h @@ -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 diff --git a/harbour/source/vm/classes.c b/harbour/source/vm/classes.c index 0a69289f59..c5b7d1893f 100644 --- a/harbour/source/vm/classes.c +++ b/harbour/source/vm/classes.c @@ -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 */ diff --git a/harbour/source/vm/codebloc.c b/harbour/source/vm/codebloc.c index e58cf0e622..2b70e45549 100644 --- a/harbour/source/vm/codebloc.c +++ b/harbour/source/vm/codebloc.c @@ -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 ); } diff --git a/harbour/source/vm/debug.c b/harbour/source/vm/debug.c index 3b0f9202a1..1559cf38d3 100644 --- a/harbour/source/vm/debug.c +++ b/harbour/source/vm/debug.c @@ -80,29 +80,13 @@ static void AddToArray( PHB_ITEM pItem, PHB_ITEM pReturn, ULONG ulPos ) hb_itemArrayPut( pReturn, ulPos, pItem ); } -/* $Doc$ - * $FuncName$ __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$ 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 ) diff --git a/harbour/source/vm/estack.c b/harbour/source/vm/estack.c index c4afecd495..4dfc44a682 100644 --- a/harbour/source/vm/estack.c +++ b/harbour/source/vm/estack.c @@ -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 ) diff --git a/harbour/source/vm/extend.c b/harbour/source/vm/extend.c index 95706b27fe..dcb1871393 100644 --- a/harbour/source/vm/extend.c +++ b/harbour/source/vm/extend.c @@ -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] */ diff --git a/harbour/source/vm/fm.c b/harbour/source/vm/fm.c index 256607c5cc..a0c79753a4 100644 --- a/harbour/source/vm/fm.c +++ b/harbour/source/vm/fm.c @@ -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) */ diff --git a/harbour/source/vm/garbage.c b/harbour/source/vm/garbage.c index 410f5c1e48..df9438e95f 100644 --- a/harbour/source/vm/garbage.c +++ b/harbour/source/vm/garbage.c @@ -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; diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 8920429670..9d404459d2 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -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 ); diff --git a/harbour/source/vm/proc.c b/harbour/source/vm/proc.c index cdebeebb02..3a01edfbdf 100644 --- a/harbour/source/vm/proc.c +++ b/harbour/source/vm/proc.c @@ -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; +}