From bb158069238442b68624419fa9b34f8aa28319c3 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Wed, 13 Sep 2006 18:37:42 +0000 Subject: [PATCH] 2006-09-13 20:35 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbvm.h * harbour/source/vm/hvm.c * harbour/source/vm/itemapi.c + added __enumStop() message for "FOR EACH" overloading It's guarantied that it will be sent to base item if it is an object with such message when FOR EACH ... NEXT will finish its job even if it will be interrupted by EXIT or RETURN to allow base object clear resources allocated for FOR EACH enumerator. The BREAK exception is not supported now. This is sth what I'd like to discuss soon when I'll add destructors. Please think now if we should allow to execute destructors and other cleanup user code when we are returning to nearest expection trap (BEGIN SEQUENCE / [ RECOVER /] END) cleaning the HVM stack. --- harbour/ChangeLog | 15 +++++++++++++++ harbour/include/hbvm.h | 1 + harbour/source/vm/hvm.c | 29 ++++++++++++++++++++++++++--- harbour/source/vm/itemapi.c | 14 +++----------- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 97441fb75f..acd41beb11 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,21 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + * minor cleanup + + * harbour/source/rtl/cdpapi.c + * harbour/include/hbextern.ch + + added HB_CDPLIST() - it returns array with all registered CODEPAGEs + + * harbour/source/rtl/set.c + ! fixed typo in _SET_DEFEXTENSIONS + + * harbour/tests/testrpt.prg + ! fixed syntax + ! use lower name in report name to work properly on case sensitive + file systems + +2006-09-13 20:35 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbvm.h * harbour/source/vm/hvm.c * harbour/source/vm/itemapi.c diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index c345f01ee1..5b04ebc4f7 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -94,6 +94,7 @@ extern HB_EXPORT PHB_SYMB hb_vmProcessSymbolsEx( PHB_SYMB pSymbols, USHORT uiSym extern void hb_vmExitSymbolGroup( void * hDynLib ); extern char * hb_vmFindModuleSymbolName( PHB_SYMB pSym ); + extern void hb_vmEnumRelease( PHB_ITEM pBase, PHB_ITEM pValue ); #endif extern HB_EXPORT void hb_vmSymbolInit_RT( void ); /* initialization of runtime support symbols */ diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index eef6bcdb96..9fde7b27a7 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -3024,6 +3024,29 @@ static HB_GARBAGE_FUNC( hb_enumHolderRelease ) hb_itemRelease( pHolder->pEnumRef ); } +/* + * Relase enumerator items - called from hb_itemClear() + */ +void hb_vmEnumRelease( PHB_ITEM pBase, PHB_ITEM pValue ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmEnumRelease(%p,%p)", pBase, pValue)); + + if( pValue ) + hb_itemRelease( pValue ); + + if( HB_IS_OBJECT( pBase ) && hb_vmRequestQuery() == 0 && + hb_objHasOperator( pBase, HB_OO_OP_ENUMSTOP ) ) + { + hb_stackPushReturn(); + hb_vmPushNil(); + hb_objOperatorCall( HB_OO_OP_ENUMSTOP, hb_stackItemFromTop( -1 ), + pBase, NULL, NULL ); + hb_stackPop(); + hb_stackPopReturn(); + } + + hb_itemRelease( pBase ); +} /* At this moment the eval stack should store: * -2 -> @@ -3094,7 +3117,7 @@ static void hb_vmEnumStart( BYTE nVars, BYTE nDescend ) hb_objOperatorCall( HB_OO_OP_ENUMSTART, hb_stackItemFromTop( -2 ), pItem, pEnumRef, hb_stackItemFromTop( -1 ) ); hb_stackPop(); - if( ! hb_vmPopLogical() ) + if( hb_vmRequestQuery() != 0 || ! hb_vmPopLogical() ) { fStart = FALSE; break; @@ -3165,7 +3188,7 @@ static void hb_vmEnumNext( void ) pEnum->item.asEnum.basePtr, pEnumRef, hb_stackItemFromTop( -1 ) ); hb_stackPop(); - if( ! hb_vmPopLogical() ) + if( hb_vmRequestQuery() != 0 || ! hb_vmPopLogical() ) break; } else if( ( ULONG ) ++pEnum->item.asEnum.offset > @@ -3217,7 +3240,7 @@ static void hb_vmEnumPrev( void ) pEnum->item.asEnum.basePtr, pEnumRef, hb_stackItemFromTop( -1 ) ); hb_stackPop(); - if( ! hb_vmPopLogical() ) + if( hb_vmRequestQuery() != 0 || ! hb_vmPopLogical() ) break; } else if( --pEnum->item.asEnum.offset == 0 ) diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index a71cc5d7ae..467c76c484 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -95,6 +95,7 @@ #include "hbvmopt.h" #include "hbapi.h" +#include "hbvm.h" #include "hbstack.h" #include "hbapiitm.h" #include "hbapilng.h" @@ -1281,17 +1282,8 @@ HB_EXPORT void hb_itemClear( PHB_ITEM pItem ) } else if( type & HB_IT_ENUM ) /* FOR EACH control variable */ { - /* - * pItem->item.asEnum.valuePtr is intentionally assigned to pValue to - * avoid possible problems when pItem is stack item just freed which - * can be overwritten if hb_itemRelease( pItem->item.asEnum.basePtr ) - * activate .prg destructor [druzus] - */ - PHB_ITEM pValue = pItem->item.asEnum.valuePtr; - - hb_itemRelease( pItem->item.asEnum.basePtr ); - if( pValue ) - hb_itemRelease( pValue ); + hb_vmEnumRelease( pItem->item.asEnum.basePtr, + pItem->item.asEnum.valuePtr ); } }