Example #1
0
/*
 * Detach local variable (swap current value with a memvar handle)
 */
PHB_ITEM hb_memvarDetachLocal( PHB_ITEM pLocal )
{
   HB_TRACE( HB_TR_DEBUG, ( "hb_memvarDetachLocal(%p)", pLocal ) );

   if( HB_IS_BYREF( pLocal ) )
   {
      do
      {
         if( HB_IS_MEMVAR( pLocal ) || HB_IS_EXTREF( pLocal ) )
            break;
         else if( HB_IS_ENUM( pLocal ) )
         {
            if( ! pLocal->item.asEnum.valuePtr )
            {
               PHB_ITEM pBase = HB_IS_BYREF( pLocal->item.asEnum.basePtr ) ?
                               hb_itemUnRef( pLocal->item.asEnum.basePtr ) :
                                             pLocal->item.asEnum.basePtr;
               if( HB_IS_ARRAY( pBase ) )
               {
                  PHB_ITEM pItem = hb_itemNew( NULL );
                  hb_arrayGetItemRef( pBase, pLocal->item.asEnum.offset, pItem );
                  pLocal->item.asEnum.valuePtr = pItem;
                  pLocal = pItem;
                  break;
               }
            }
         }
         else if( pLocal->item.asRefer.value >= 0 &&
                  pLocal->item.asRefer.offset == 0 )
            break;
         pLocal = hb_itemUnRefOnce( pLocal );
      }
      while( HB_IS_BYREF( pLocal ) );
   }

   /* Change the value only if this variable is not referenced
    * by another codeblock yet.
    * In this case we have to copy the current value to a global memory
    * pool so it can be shared by codeblocks
    */
   if( ! HB_IS_MEMVAR( pLocal ) )
   {
      PHB_ITEM pMemvar = hb_memvarValueNew();

      hb_itemRawCpy( pMemvar, pLocal );
      pMemvar->type &= ~HB_IT_DEFAULT;

      pLocal->type = HB_IT_BYREF | HB_IT_MEMVAR;
      pLocal->item.asMemvar.value = pMemvar;
   }

   return pLocal;
}
Example #2
0
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 );
   }
}
Example #3
0
/*
 * 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;
   }
}