PHB_REGEX hb_regexGet( PHB_ITEM pRegExItm, int iFlags ) { PHB_REGEX pRegEx = NULL; HB_BOOL fArgError = HB_TRUE; if( pRegExItm ) { if( HB_IS_POINTER( pRegExItm ) ) { pRegEx = ( PHB_REGEX ) hb_itemGetPtrGC( pRegExItm, &s_gcRegexFuncs ); if( pRegEx ) fArgError = HB_FALSE; } else if( HB_IS_STRING( pRegExItm ) ) { HB_SIZE nLen = hb_itemGetCLen( pRegExItm ); const char * szRegEx = hb_itemGetCPtr( pRegExItm ); if( nLen > 0 ) { fArgError = HB_FALSE; pRegEx = hb_regexCompile( szRegEx, nLen, iFlags ); } } } if( fArgError ) hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, 1, pRegExItm ); else if( ! pRegEx ) /* hb_regexCompile() failed */ hb_errRT_BASE_SubstR( EG_ARG, 3015, NULL, HB_ERR_FUNCNAME, 1, pRegExItm ); return pRegEx; }
/* Mark a passed item as used so it will be not released by the GC */ void hb_gcItemRef( HB_ITEM_PTR pItem ) { HB_THREAD_STUB ULONG ulSize; HB_ITEM FakedItem; PHB_ITEM pKey; PHB_ITEM pValue; HB_CODEBLOCK_PTR pCBlock; USHORT ui; #ifdef SIMULATE_ITEMREF_RECURSION PITEMREF_RESUMEINFO pResumeInfo = (PITEMREF_RESUMEINFO) hb_xgrab( sizeof( ITEMREF_RESUMEINFO ) ); int iResumeCounter = 0; #endif FakedItem.type = HB_IT_ARRAY; ItemRef_Top: while( HB_IS_BYREF( pItem ) ) { if( HB_IS_EXTREF( pItem ) ) { pItem->item.asExtRef.func->mark( pItem->item.asExtRef.value ); RETURN_OR_RESUME_ITEMREF(); } if( HB_IS_MEMVAR( pItem ) == FALSE ) { if( pItem->item.asRefer.offset == 0 ) { FakedItem.item.asArray.value = pItem->item.asRefer.BasePtr.pBaseArray; //hb_gcItemRef( &FakedItem ); NESTED_ITEMREF( &FakedItem, 1 ); ItemRef_ResumePoint_1: // return; RETURN_OR_RESUME_ITEMREF(); } } else { if( HB_VM_STACK.pPos == HB_VM_STACK.pItems ) { //return; RETURN_OR_RESUME_ITEMREF(); } } pItem = hb_itemUnRefOnce( pItem ); } if( HB_IS_ARRAY( pItem ) ) { HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) pItem->item.asArray.value; //printf( "Array %p\n", pItem->item.asArray.value ); --pAlloc; /* Check this array only if it was not checked yet */ if( pAlloc->used == s_uUsedFlag ) { ulSize = pItem->item.asArray.value->ulLen; /* mark this block as used so it will be no re-checked from * other references */ pAlloc->used ^= HB_GC_USED_FLAG; /* mark also all array elements */ pItem = pItem->item.asArray.value->pItems; //printf( "Items %p\n", pItem ); while( ulSize ) { //printf( "Item %p\n", pItem ); //hb_gcItemRef( pItem ); NESTED_ITEMREF( pItem, 2 ); ItemRef_ResumePoint_2: ++pItem; --ulSize; } } } else if( HB_IS_HASH( pItem ) ) { HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) pItem->item.asHash.value; --pAlloc; /* Check this hash only if it was not checked yet */ if( pAlloc->used == s_uUsedFlag ) { ulSize = pItem->item.asHash.value->ulLen; pKey = pItem->item.asHash.value->pKeys; pValue = pItem->item.asHash.value->pValues; /* mark this block as used so it will be no re-checked from * other references */ pAlloc->used ^= HB_GC_USED_FLAG; /* mark also all hash elements */ while( ulSize ) { //printf( "Kry %p Value: %p\n", pKey, pValue ); //hb_gcItemRef( pKey ); NESTED_ITEMREF( pKey, 3 ); ItemRef_ResumePoint_3: //hb_gcItemRef( pValue ); NESTED_ITEMREF( pValue, 4 ); ItemRef_ResumePoint_4: ++pKey; ++pValue; --ulSize; } } } else if( HB_IS_BLOCK( pItem ) ) { HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) pItem->item.asBlock.value; --pAlloc; /* Check this block only if it was not checked yet */ if( pAlloc->used == s_uUsedFlag ) { pCBlock = pItem->item.asBlock.value; ui = 1; pAlloc->used ^= HB_GC_USED_FLAG; /* mark this codeblock as used */ /* mark as used all detached variables in a codeblock */ while( ui <= pCBlock->uiLocals ) { //hb_gcItemRef( &pCBlock->pLocals[ ui ] ); NESTED_ITEMREF( &pCBlock->pLocals[ ui ] , 5 ); ItemRef_ResumePoint_5: ++ui; } } } else if( HB_IS_POINTER( pItem ) ) { /* check if this memory was allocated by a hb_gcAlloc() */ if ( pItem->item.asPointer.collect ) { HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) pItem->item.asPointer.value; --pAlloc; /* Check this memory only if it was not checked yet */ if( pAlloc->used == s_uUsedFlag ) { /* mark this memory as used so it will be no re-checked from * other references */ pAlloc->used ^= HB_GC_USED_FLAG; } } } /* all other data types don't need the GC */ RETURN_OR_RESUME_ITEMREF(); }
/* Mark a passed item as used so it will be not released by the GC */ void hb_gcItemRef( PHB_ITEM pItem ) { while( HB_IS_BYREF( pItem ) ) { if( HB_IS_ENUM( pItem ) ) return; else if( HB_IS_EXTREF( pItem ) ) { pItem->item.asExtRef.func->mark( pItem->item.asExtRef.value ); return; } else if( ! HB_IS_MEMVAR( pItem ) && pItem->item.asRefer.offset == 0 && pItem->item.asRefer.value >= 0 ) { /* array item reference */ PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asRefer.BasePtr.array ); if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag ) { /* mark this array as used */ pAlloc->used ^= HB_GC_USED_FLAG; /* mark also all array elements */ pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) ); } return; } pItem = hb_itemUnRefOnce( pItem ); } if( HB_IS_ARRAY( pItem ) ) { PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asArray.value ); /* Check this array only if it was not checked yet */ if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag ) { /* mark this array as used so it will be no re-checked from * other references */ pAlloc->used ^= HB_GC_USED_FLAG; /* mark also all array elements */ pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) ); } } else if( HB_IS_HASH( pItem ) ) { PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asHash.value ); /* Check this hash table only if it was not checked yet */ if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag ) { /* mark this hash table as used */ pAlloc->used ^= HB_GC_USED_FLAG; /* mark also all hash elements */ pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) ); } } else if( HB_IS_BLOCK( pItem ) ) { PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asBlock.value ); if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag ) { /* mark this codeblock as used */ pAlloc->used ^= HB_GC_USED_FLAG; /* mark as used all detached variables in a codeblock */ pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) ); } } else if( HB_IS_POINTER( pItem ) ) { if( pItem->item.asPointer.collect ) { PHB_GARBAGE pAlloc = HB_GC_PTR( pItem->item.asPointer.value ); if( ( pAlloc->used & ~HB_GC_DELETE ) == s_uUsedFlag ) { /* mark this memory block as used */ pAlloc->used ^= HB_GC_USED_FLAG; /* mark also all internal user blocks attached to this block */ pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) ); } } } /* all other data types don't need the GC */ }
PHB_ITEM hb_itemDo( PHB_ITEM pItem, HB_SIZE ulPCount, ... ) { HB_THREAD_STUB PHB_ITEM pResult = NULL; HB_TRACE( HB_TR_DEBUG, ( "hb_itemDo(%p, %hu, ...)", pItem, ulPCount ) ); if( pItem ) { PHB_SYMB pSymbol = NULL; if( HB_IS_STRING( pItem ) ) { PHB_DYNS pDynSym = hb_dynsymFindName( pItem->item.asString.value ); if( pDynSym ) pSymbol = pDynSym->pSymbol; } else if( HB_IS_POINTER( pItem ) ) pSymbol = ( PHB_SYMB ) pItem->item.asPointer.value; else if( HB_IS_SYMBOL( pItem ) ) pSymbol = pItem->item.asSymbol.value; if( pSymbol ) { hb_vmPushState(); hb_vmPushSymbol( pSymbol ); hb_vmPushNil(); if( ulPCount ) { register ULONG ulParam; va_list va; va_start( va, ulPCount ); for( ulParam = 1; ulParam <= ulPCount; ulParam++ ) hb_vmPush( va_arg( va, PHB_ITEM ) ); va_end( va ); } hb_vmDo( ( USHORT ) ulPCount ); pResult = hb_itemNew( NULL ); hb_itemForwardValue( pResult, &( HB_VM_STACK.Return ) ); hb_vmPopState(); } else if( HB_IS_BLOCK( pItem ) ) { hb_vmPushState(); hb_vmPushSymbol( &hb_symEval ); hb_vmPush( pItem ); if( ulPCount ) { register ULONG ulParam; va_list va; va_start( va, ulPCount ); for( ulParam = 1; ulParam <= ulPCount; ulParam++ ) hb_vmPush( va_arg( va, PHB_ITEM ) ); va_end( va ); } hb_vmSend( ( USHORT ) ulPCount ); pResult = hb_itemNew( NULL ); hb_itemForwardValue( pResult, &( HB_VM_STACK.Return ) ); hb_vmPopState(); } else if( HB_IS_ARRAY( pItem ) ) { hb_vmPushState(); if( hb_execFromArray( pItem ) ) { pResult = hb_itemNew( NULL ); hb_itemForwardValue( pResult, &( HB_VM_STACK.Return ) ); } hb_vmPopState(); } } return pResult; }