From 01962a5f93dded91b81a95c6cbff8d95917ffce7 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Tue, 5 Apr 2011 06:41:25 +0000 Subject: [PATCH] 2011-04-05 08:41 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/vm/hvm.c * extended item references created by hb_vmPushItemRef() so they can be used to create reference chain and detached in executed PRG code. Such reference chain is cleanly break when original reference item is removed from HVM stack. --- harbour/ChangeLog | 7 ++++ harbour/src/vm/hvm.c | 92 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index e2739dd85b..39a0d73217 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,13 @@ The license applies to all entries newer than 2009-04-28. */ +2011-04-05 08:41 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/vm/hvm.c + * extended item references created by hb_vmPushItemRef() so they + can be used to create reference chain and detached in executed + PRG code. Such reference chain is cleanly break when original + reference item is removed from HVM stack. + 2011-04-04 22:34 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com) * contrib/hbqt/qtgui/qth/HBQAbstractItemModel.qth ! Formatting. diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index 15e0facfe9..e3857a90b4 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -8198,28 +8198,95 @@ static void hb_vmDoExitFunctions( void ) /* * extended item reference functions */ -static PHB_ITEM hb_vmItemRefRead( PHB_ITEM pRefer ) +static PHB_ITEM hb_vmItemRawRefRead( PHB_ITEM pRefer ) { return ( PHB_ITEM ) pRefer->item.asExtRef.value; } -static PHB_ITEM hb_vmItemRefWrite( PHB_ITEM pRefer, PHB_ITEM pSource ) +static PHB_ITEM hb_vmItemRawRefWrite( PHB_ITEM pRefer, PHB_ITEM pSource ) { HB_SYMBOL_UNUSED( pSource ); return ( PHB_ITEM ) pRefer->item.asExtRef.value; } -static void hb_vmItemRefCopy( PHB_ITEM pDest ) +static void hb_vmItemRawRefCopy( PHB_ITEM pDest ) { pDest->type = HB_IT_NIL; hb_itemCopy( pDest, ( PHB_ITEM ) pDest->item.asExtRef.value ); } -static void hb_vmItemRefDummy( void * value ) +static void hb_vmItemRawRefDummy( void * value ) { HB_SYMBOL_UNUSED( value ); } +static const HB_EXTREF s_ItmExtRawRef = { + hb_vmItemRawRefRead, + hb_vmItemRawRefWrite, + hb_vmItemRawRefCopy, + hb_vmItemRawRefDummy, + hb_vmItemRawRefDummy }; + +typedef struct +{ + HB_ITEM memvar; + PHB_ITEM value; +} HB_ITMREF, * PHB_ITMREF; + +static PHB_ITEM hb_vmItemRefRead( PHB_ITEM pRefer ) +{ + return &( ( PHB_ITMREF ) pRefer->item.asExtRef.value )->memvar; +} + +static PHB_ITEM hb_vmItemRefWrite( PHB_ITEM pRefer, PHB_ITEM pSource ) +{ + HB_SYMBOL_UNUSED( pSource ); + return ( ( PHB_ITMREF ) pRefer->item.asExtRef.value )->value; +} + +static void hb_vmItemRefCopy( PHB_ITEM pDest ) +{ + pDest->type = HB_IT_NIL; + hb_itemCopy( pDest, &( ( PHB_ITMREF ) pDest->item.asExtRef.value )->memvar ); +} + +static void hb_vmItemRefClear( void * value ) +{ + PHB_ITMREF pItmRef = ( PHB_ITMREF ) value; + +#if 1 + if( !HB_IS_MEMVAR( &pItmRef->memvar ) || + pItmRef->memvar.item.asMemvar.value != pItmRef->value || + !HB_IS_EXTREF( pItmRef->value ) || + pItmRef->value->item.asExtRef.func != &s_ItmExtRawRef ) + hb_errInternal( HB_EI_ERRUNRECOV, "hb_vmItemRefClear()", NULL, NULL ); +#endif + + if( hb_xRefDec( pItmRef->value ) ) + hb_xfree( pItmRef->value ); + else + { + pItmRef->memvar.type = HB_IT_NIL; + hb_itemCopyFromRef( &pItmRef->memvar, pItmRef->value ); + hb_itemMove( pItmRef->value, &pItmRef->memvar ); + } + + hb_xfree( value ); +} + +static void hb_vmItemRefMark( void * value ) +{ + /* the original value should be accessible from initial item so it's + * not necessary to mark if form this point. + */ +#if 1 + HB_SYMBOL_UNUSED( value ); +#else + hb_gcItemRef( ( ( PHB_ITMREF ) value )->memvar ); + hb_gcItemRef( ( ( PHB_ITMREF ) value )->value ); +#endif +} + /* * push extended item reference */ @@ -8229,17 +8296,28 @@ void hb_vmPushItemRef( PHB_ITEM pItem ) hb_vmItemRefRead, hb_vmItemRefWrite, hb_vmItemRefCopy, - hb_vmItemRefDummy, - hb_vmItemRefDummy }; + hb_vmItemRefClear, + hb_vmItemRefMark }; HB_STACK_TLS_PRELOAD + PHB_ITMREF pItmRef; PHB_ITEM pRefer; HB_TRACE(HB_TR_DEBUG, ("hb_vmPushItemRef(%p)", pItem)); + pItmRef = ( PHB_ITMREF ) hb_xgrab( sizeof( HB_ITMREF ) ); + + pItmRef->value = ( PHB_ITEM ) hb_xgrab( sizeof( HB_ITEM ) ); + pItmRef->value->type = HB_IT_BYREF | HB_IT_EXTREF; + pItmRef->value->item.asExtRef.value = ( void * ) pItem; + pItmRef->value->item.asExtRef.func = &s_ItmExtRawRef; + + pItmRef->memvar.type = HB_IT_BYREF | HB_IT_MEMVAR; + pItmRef->memvar.item.asMemvar.value = pItmRef->value; + pRefer = hb_stackAllocItem(); pRefer->type = HB_IT_BYREF | HB_IT_EXTREF; - pRefer->item.asExtRef.value = ( void * ) pItem; + pRefer->item.asExtRef.value = ( void * ) pItmRef; pRefer->item.asExtRef.func = &s_ItmExtRef; }