/* * Detach public or private variable (swap current value with a memvar handle) */ static void hb_memvarDetachDynSym( PHB_DYNS pDynSym, PHB_ITEM pPrevMemvar ) { PHB_ITEM pMemvar; HB_TRACE( HB_TR_DEBUG, ( "hb_memvarDetachDynSym(%p,%p)", pDynSym, pPrevMemvar ) ); pMemvar = hb_dynsymGetMemvar( pDynSym ); hb_dynsymSetMemvar( pDynSym, pPrevMemvar ); hb_memvarValueDecRef( pMemvar ); }
static void hb_memvarCreateFromDynSymbol( PHB_DYNS pDynVar, int iScope, PHB_ITEM pValue ) { HB_TRACE( HB_TR_DEBUG, ( "hb_memvarCreateFromDynSymbol(%p, %d, %p)", pDynVar, iScope, pValue ) ); if( iScope & HB_VSCOMP_PUBLIC ) { /* If the variable with the same name exists already * then the current value have to be unchanged */ if( ! hb_dynsymGetMemvar( pDynVar ) ) { PHB_ITEM pMemvar = hb_memvarValueNew(); hb_dynsymSetMemvar( pDynVar, pMemvar ); if( pValue ) { hb_itemCopy( pMemvar, pValue ); /* Remove MEMOFLAG if exists (assignment from field). */ pMemvar->type &= ~HB_IT_MEMOFLAG; } else { /* new PUBLIC variable - initialize it to .F. */ pMemvar->type = HB_IT_LOGICAL; /* NOTE: PUBLIC variables named CLIPPER and HARBOUR are initialized */ /* to .T., this is normal Clipper behaviour. [vszakats] */ pMemvar->item.asLogical.value = ( strcmp( pDynVar->pSymbol->szName, "HARBOUR" ) == 0 || strcmp( pDynVar->pSymbol->szName, "CLIPPER" ) == 0 ); } } } else { /* Create new PRIVATE var and add it to the PRIVATE variables stack */ hb_memvarAddPrivate( pDynVar, pValue ); } }
/* * This function pushes passed dynamic symbol that belongs to PRIVATE variable * into the stack. The value will be popped from it if the variable falls * outside the scope (either by using RELEASE, CLEAR ALL, CLEAR MEMORY or by * an exit from the function/procedure) * */ static void hb_memvarAddPrivate( PHB_DYNS pDynSym, PHB_ITEM pValue ) { HB_STACK_TLS_PRELOAD PHB_PRIVATE_STACK pPrivateStack; PHB_ITEM pMemvar; HB_TRACE( HB_TR_DEBUG, ( "hb_memvarAddPrivate(%p,%p)", pDynSym, pValue ) ); pPrivateStack = hb_stackGetPrivateStack(); pMemvar = hb_dynsymGetMemvar( pDynSym ); /* If the variable with the same name exists already * and it's PRIVATE variable declared in this function then * do not push new memvar on PRIVATEs stack */ if( pMemvar ) { HB_SIZE nCount = pPrivateStack->count; while( nCount > pPrivateStack->base ) { if( pDynSym == pPrivateStack->stack[ nCount - 1 ].pDynSym ) break; --nCount; } if( nCount <= pPrivateStack->base ) pMemvar = NULL; } if( ! pMemvar ) { /* Allocate the value from the end of table */ if( pPrivateStack->count == pPrivateStack->size ) { /* No more free values in the table - expand the table */ if( pPrivateStack->size == 0 ) { pPrivateStack->stack = ( PHB_PRIVATE_ITEM ) hb_xgrab( sizeof( HB_PRIVATE_ITEM ) * TABLE_INITHB_VALUE ); pPrivateStack->size = TABLE_INITHB_VALUE; pPrivateStack->count = pPrivateStack->base = 0; } else { pPrivateStack->size += TABLE_EXPANDHB_VALUE; pPrivateStack->stack = ( PHB_PRIVATE_ITEM ) hb_xrealloc( pPrivateStack->stack, sizeof( HB_PRIVATE_ITEM ) * pPrivateStack->size ); } } pPrivateStack->stack[ pPrivateStack->count ].pDynSym = pDynSym; pPrivateStack->stack[ pPrivateStack->count++ ].pPrevMemvar = hb_dynsymGetMemvar( pDynSym ); if( pValue && HB_IS_MEMVAR( pValue ) ) { pMemvar = pValue->item.asMemvar.value; hb_xRefInc( pMemvar ); pValue = NULL; } else pMemvar = hb_memvarValueNew(); hb_dynsymSetMemvar( pDynSym, pMemvar ); } if( pValue ) { hb_itemCopy( pMemvar, pValue ); /* Remove MEMOFLAG if exists (assignment from field). */ pMemvar->type &= ~HB_IT_MEMOFLAG; } }