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.
This commit is contained in:
Przemyslaw Czerpak
2006-09-13 18:37:42 +00:00
parent 0e68f162e7
commit bb15806923
4 changed files with 45 additions and 14 deletions

View File

@@ -8,6 +8,21 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
* 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

View File

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

View File

@@ -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 -> <array for traverse>
@@ -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 )

View File

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