From 2fc69d4894c43aac6aaebf03cee376e8051f9543 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Fri, 5 Nov 2010 12:00:28 +0000 Subject: [PATCH] 2010-11-05 12:59 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * include/hbvm.h * src/vm/hvm.c + Added hb_vmPushPointerGC(). * contrib/hbqt/qtcore/hbqt_init.cpp + Added experimental (not activated) code example to pass GC collected pointer back from callbacks. This is just intermediate step, as it should return .prg level class, but at least some room for leaks can be avoided this way, plus the pointer type is identifiable. Based on code posted to list by Pritpal. --- harbour/ChangeLog | 12 ++++++++++++ harbour/contrib/hbqt/qtcore/hbqt_init.cpp | 12 ++++++++++++ harbour/include/hbvm.h | 3 ++- harbour/src/vm/hvm.c | 15 +++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 8e59fa59ba..5d325cde46 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,18 @@ The license applies to all entries newer than 2009-04-28. */ +2010-11-05 12:59 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * include/hbvm.h + * src/vm/hvm.c + + Added hb_vmPushPointerGC(). + + * contrib/hbqt/qtcore/hbqt_init.cpp + + Added experimental (not activated) code example to pass GC collected + pointer back from callbacks. This is just intermediate step, as it + should return .prg level class, but at least some room for leaks + can be avoided this way, plus the pointer type is identifiable. + Based on code posted to list by Pritpal. + 2010-11-05 00:58 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * config/cygwin/gcc.mk * include/hbwmain.c diff --git a/harbour/contrib/hbqt/qtcore/hbqt_init.cpp b/harbour/contrib/hbqt/qtcore/hbqt_init.cpp index 40fc4caae1..ce833f4ff1 100644 --- a/harbour/contrib/hbqt/qtcore/hbqt_init.cpp +++ b/harbour/contrib/hbqt/qtcore/hbqt_init.cpp @@ -73,6 +73,14 @@ #include #include +//#define _RET_GC_PTR_ + +#ifdef _RET_GC_PTR_ +HB_EXTERN_BEGIN +extern void * hbqt_gcAllocate_QTime( void * pObj, bool bNew ); +HB_EXTERN_END +#endif + /*----------------------------------------------------------------------*/ static void hbqt_SlotsExecPointer( PHB_ITEM * codeBlock, void ** arguments ) @@ -225,7 +233,11 @@ static void hbqt_SlotsExecQTime( PHB_ITEM * codeBlock, void ** arguments ) { hb_vmPushEvalSym(); hb_vmPush( codeBlock ); +#ifdef _RET_GC_PTR_ + hb_vmPushPointerGC( hbqt_gcAllocate_QTime( new QTime( ( *reinterpret_cast< QTime( * ) >( arguments[ 1 ] ) ) ), true ) ); /* TOFIX: Pass .prg level object to callback */ +#else hb_vmPushPointer( new QTime( ( *reinterpret_cast< QTime( * ) >( arguments[ 1 ] ) ) ) ); /* TOFIX: Pass .prg level object to callback */ +#endif hb_vmSend( 1 ); } diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index 3b1fdf3a8c..5cee7a7397 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -166,7 +166,8 @@ extern HB_EXPORT void hb_vmPushTimeStamp( long lJulian, long lMilliSec ); /* extern HB_EXPORT void hb_vmPushSymbol( PHB_SYMB pSym ); /* pushes a function pointer onto the stack */ extern HB_EXPORT void hb_vmPushDynSym( PHB_DYNS pDynSym ); /* pushes a function/method pointer onto the stack */ extern HB_EXPORT void hb_vmPushEvalSym( void ); /* pushes a codeblock eval symbol onto the stack */ -extern HB_EXPORT void hb_vmPushPointer( void * ); /* push an item of HB_IT_POINTER type */ +extern HB_EXPORT void hb_vmPushPointer( void * pPointer ); /* push an item of HB_IT_POINTER type */ +extern HB_EXPORT void hb_vmPushPointerGC( void * pPointer ); /* push an item of GC HB_IT_POINTER type */ extern HB_EXPORT void hb_vmPushItemRef( PHB_ITEM pItem ); /* push item reference */ #ifdef HB_LEGACY_LEVEL3 extern HB_EXPORT void hb_vmPushState( void ); /* push current VM state on stack */ diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index f93598d676..8bfd895762 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -6777,6 +6777,21 @@ void hb_vmPushPointer( void * pPointer ) pItem->item.asPointer.single = HB_FALSE; } +void hb_vmPushPointerGC( void * pPointer ) +{ + HB_STACK_TLS_PRELOAD + PHB_ITEM pItem = hb_stackAllocItem(); + + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushPointerGC(%p)", pPointer)); + + pItem->type = HB_IT_POINTER; + pItem->item.asPointer.value = pPointer; + pItem->item.asPointer.collect = HB_TRUE; + pItem->item.asPointer.single = HB_FALSE; + + hb_gcAttach( pPointer ); +} + void hb_vmPushString( const char * szText, HB_SIZE nLength ) { HB_STACK_TLS_PRELOAD