Esempio n. 1
0
PHB_CODEBLOCK hb_codeblockMacroNew( const HB_BYTE * pBuffer, HB_SIZE nLen )
{
   HB_STACK_TLS_PRELOAD
   PHB_CODEBLOCK pCBlock;
   PHB_ITEM pBase;
   HB_BYTE * pCode;

   HB_TRACE( HB_TR_DEBUG, ( "hb_codeblockMacroNew(%p, %" HB_PFS "u)", pBuffer, nLen ) );

   /* The codeblock pcode is stored in dynamically allocated memory that
    * can be deallocated after creation of a codeblock. We have to duplicate
    * the passed buffer
    */
   /* allocate memory for code block body and detach items hb_gcAllocRaw()
    * to be safe for automatic GC activation in hb_xgrab() without
    * calling hb_gcLock()/hb_gcUnlock(). [druzus]
    */
   pCode = ( HB_BYTE * ) memcpy( hb_xgrab( nLen ), pBuffer, nLen );

   pCBlock = ( PHB_CODEBLOCK ) hb_gcAllocRaw( sizeof( HB_CODEBLOCK ), &s_gcCodeblockFuncs );
   pBase = hb_stackBaseItem();
   /* Store the number of referenced local variables */
   pCBlock->pCode     = pCode;
   pCBlock->dynBuffer = HB_TRUE;
   pCBlock->pDefSymb  = pBase->item.asSymbol.stackstate->uiClass ?
                        hb_clsMethodSym( pBase ) : pBase->item.asSymbol.value;
   pCBlock->pSymbols  = NULL;  /* macro-compiled codeblock cannot acces a local symbol table */
   pCBlock->pStatics  = hb_stackGetStaticsBase();
   pCBlock->uiLocals  = 0;
   pCBlock->pLocals   = NULL;

   HB_TRACE( HB_TR_INFO, ( "codeblock created %p", pCBlock ) );

   return pCBlock;
}
Esempio n. 2
0
/* This function releases all memory occupied by a memvar variable and
 * assigns NIL value - it releases variables created in current
 * procedure only.
 * The scope of released variables are specified using passed name's mask
 */
static void hb_memvarReleaseWithMask( const char * szMask, HB_BOOL bInclude )
{
   HB_STACK_TLS_PRELOAD
   HB_SIZE nBase, nCount;
   PHB_DYNS pDynVar;
   PHB_ITEM pMemvar;

   HB_TRACE( HB_TR_DEBUG, ( "hb_memvarReleaseWithMask(%s, %d)", szMask, ( int ) bInclude ) );

   nCount = hb_stackGetPrivateStack()->count;
   nBase = hb_stackBaseItem()->item.asSymbol.stackstate->nPrivateBase;
   while( nCount-- > nBase )
   {
      pDynVar = hb_stackGetPrivateStack()->stack[ nCount ].pDynSym;
      /* reset current value to NIL - the overriden variables will be
       * visible after exit from current procedure
       */
      pMemvar = hb_dynsymGetMemvar( pDynVar );
      if( pMemvar )
      {
         HB_BOOL fMatch = hb_strMatchCaseWildExact( pDynVar->pSymbol->szName, szMask );
         if( bInclude ? fMatch : ! fMatch )
            hb_itemClear( pMemvar );
      }
   }
}
Esempio n. 3
0
/*
 * Reset PRIVATE base offset to the level of previous function
 */
static void hb_memvarResetPrivatesBase( void )
{
   HB_STACK_TLS_PRELOAD

   HB_TRACE( HB_TR_DEBUG, ( "hb_memvarResetPrivatesBase()" ) );

   hb_stackGetPrivateStack()->base = hb_stackBaseItem()->item.asSymbol.stackstate->nPrivateBase;
}
Esempio n. 4
0
PHB_ITEM hb_errPutOperation( PHB_ITEM pError, const char * szOperation )
{
   HB_TRACE( HB_TR_DEBUG, ( "hb_errPutOperation(%p, %s)", pError, szOperation == HB_ERR_FUNCNAME ? "HB_ERR_FUNCNAME" : szOperation ) );

   if( szOperation == HB_ERR_FUNCNAME )
   {
      PHB_SYMB pSym = hb_itemGetSymbol( hb_stackBaseItem() );
      if( pSym )
         szOperation = pSym->szName;
   }

   hb_arraySetC( pError, HB_TERROR_OPERATION, szOperation );

   return pError;
}
Esempio n. 5
0
/* Creates the codeblock structure
 *
 * pBuffer -> the buffer with pcodes (without HB_P_PUSHBLOCK)
 * wLocals -> number of local variables referenced in a codeblock
 * pLocalPosTable -> a table with positions on eval stack for referenced variables
 * pSymbols    -> a pointer to the module symbol table
 *
 * Note: pLocalPosTable cannot be used if uiLocals is ZERO
 */
PHB_CODEBLOCK hb_codeblockNew( const HB_BYTE * pBuffer,
                               HB_USHORT uiLocals,
                               const HB_BYTE * pLocalPosTable,
                               PHB_SYMB pSymbols,
                               HB_SIZE nLen )
{
   HB_STACK_TLS_PRELOAD
   PHB_CODEBLOCK pCBlock;
   PHB_ITEM pLocals, pBase;
   const HB_BYTE * pCode;

   HB_TRACE( HB_TR_DEBUG, ( "hb_codeblockNew(%p, %hu, %p, %p, %" HB_PFS "u)", pBuffer, uiLocals, pLocalPosTable, pSymbols, nLen ) );

   /* Allocate memory for code block body and detach items hb_gcAllocRaw()
    * to be safe for automatic GC activation in hb_xgrab() without
    * calling hb_gcLock()/hb_gcUnlock(). [druzus]
    */

   if( nLen )
   {
      /* The codeblock pcode is stored in dynamically allocated memory that
       * can be deallocated after creation of a codeblock. We have to duplicate
       * the passed buffer
       */
      pCode = ( const HB_BYTE * ) memcpy( hb_xgrab( nLen ), pBuffer, nLen );
   }
   else
   {
      /* The codeblock pcode is stored in static segment.
       * The only allowed operation on a codeblock is evaluating it then
       * there is no need to duplicate its pcode - just store the pointer to it
       */
      pCode = pBuffer;
   }

   if( uiLocals )
   {
      /* NOTE: if a codeblock will be created by macro compiler then
       * uiLocal have to be ZERO
       * uiLocal will be also ZERO if it is a nested codeblock
       */
      HB_USHORT ui = 1;
      PHB_ITEM pLocal;

      /* Create a table that will store the values of local variables
       * accessed in a codeblock
       * The element 0 is unused
       * NOTE: This table can be shared by codeblocks created during
       * evaluation of this codeblock
       */
      pLocals = ( PHB_ITEM ) hb_xgrab( ( uiLocals + 1 ) * sizeof( HB_ITEM ) );
      pLocals[ 0 ].type = HB_IT_NIL;

      do
      {
         /* Swap the current value of local variable with the reference to this
          * value.
          */
         int iLocal = HB_PCODE_MKUSHORT( pLocalPosTable );
         pLocal = hb_stackLocalVariable( iLocal );
         pLocalPosTable += 2;

         pLocal = hb_memvarDetachLocal( pLocal );
         hb_itemRawCpy( pLocals + ui, pLocal );
         /* Increment the reference counter so this value will not be
          * released if other codeblock will be deleted
          */
         hb_memvarValueIncRef( pLocal->item.asMemvar.value );
      }
      while( ++ui <= uiLocals );
   }
   else
   {
      /* Check if this codeblock is created during evaluation of another
       * codeblock - all inner codeblocks use the local variables table
       * created during creation of the outermost codeblock
       */
      PHB_ITEM pLocal;

      pLocal = hb_stackSelfItem();
      if( HB_IS_BLOCK( pLocal ) )
      {
         PHB_CODEBLOCK pOwner = pLocal->item.asBlock.value;

         uiLocals = pOwner->uiLocals;
         pLocals  = pOwner->pLocals;
         if( pLocals )
            hb_xRefInc( pLocals );
      }
      else
         pLocals = NULL;
   }

   pBase = hb_stackBaseItem();
   pCBlock = ( PHB_CODEBLOCK ) hb_gcAllocRaw( sizeof( HB_CODEBLOCK ), &s_gcCodeblockFuncs );

   pCBlock->pCode     = pCode;
   pCBlock->dynBuffer = nLen != 0;
   pCBlock->pDefSymb  = pBase->item.asSymbol.stackstate->uiClass ?
                        hb_clsMethodSym( pBase ) : pBase->item.asSymbol.value;
   pCBlock->pSymbols  = pSymbols;
   pCBlock->pStatics  = hb_stackGetStaticsBase();
   pCBlock->uiLocals  = uiLocals;
   pCBlock->pLocals   = pLocals;

   HB_TRACE( HB_TR_INFO, ( "codeblock created %p", pCBlock ) );

   return pCBlock;
}
Esempio n. 6
0
File: math.c Progetto: emazv72/core
static int hb_matherrblock( HB_MATH_EXCEPTION * pexc )
{
   PHB_MATHERRDATA pMathErr = hb_mathErrData();
   int retval;

   /* call codeblock for both case: handled and unhandled exceptions */

   if( pMathErr->block )
   {
      PHB_ITEM pArray, pRet;
      PHB_ITEM pType, pFuncname, pError, pArg1, pArg2, pRetval, pHandled;
      const char * funcname = pexc->funcname;

      if( funcname == HB_ERR_FUNCNAME )
      {
         PHB_SYMB pSym = hb_itemGetSymbol( hb_stackBaseItem() );
         if( pSym )
            funcname = pSym->szName;
      }

      pType = hb_itemPutNI( NULL, pexc->type );
      pFuncname = hb_itemPutC( NULL, funcname );
      pError = hb_itemPutC( NULL, pexc->error );
      pArg1 = hb_itemPutND( NULL, pexc->arg1 );
      pArg2 = hb_itemPutND( NULL, pexc->arg2 );
      pRetval = hb_itemPutNDLen( NULL, pexc->retval, pexc->retvalwidth, pexc->retvaldec );
      pHandled = hb_itemPutL( NULL, pexc->handled );

      pArray = hb_itemArrayNew( 2 );
      hb_itemArrayPut( pArray, 1, pRetval );
      hb_itemArrayPut( pArray, 2, pHandled );

      /* launch error codeblock that can
         a) change the members of the array = {dRetval, lHandled} to set the
            return value of the math C RTL routine and the <exception handled
            flag> and it
         b) can return an integer value to set the return value of matherr().
         NOTE that these values are only used if lHandled was .F. and is set
         to .T. within the codeblock */
      pRet = hb_itemDo( pMathErr->block, 6, pType, pFuncname, pError, pArg1, pArg2, pArray );

      hb_itemRelease( pType );
      hb_itemRelease( pFuncname );
      hb_itemRelease( pError );
      hb_itemRelease( pArg1 );
      hb_itemRelease( pArg2 );
      hb_itemRelease( pRetval );
      hb_itemRelease( pHandled );

      if( pexc->handled )
      {
         /* math exception has already been handled, so codeblock call above
            was only informative */
         retval = 1;
      }
      else
      {
         /* exception handled by codeblock ? */
         pHandled = hb_itemArrayGet( pArray, 2 );
         if( pHandled )
         {
            pexc->handled = hb_itemGetL( pHandled );
            hb_itemRelease( pHandled );
         }

         if( pexc->handled )
         {
            /* YES ! */
            /* extract retval for math routine and matherr() */
            pRetval = hb_itemArrayGet( pArray, 1 );
            if( pRetval )
            {
               pexc->retval = hb_itemGetND( pRetval );
               hb_itemGetNLen( pRetval, &pexc->retvalwidth, &pexc->retvaldec );
               hb_itemRelease( pRetval );
            }
            if( pRet && HB_IS_NUMERIC( pRet ) )
            {
               retval = hb_itemGetNI( pRet );  /* block may also return 0 to force C math lib warnings */
               hb_itemRelease( pRet );
            }
            else
            {
               retval = 1;  /* default return value to suppress C math lib warnings */
            }
         }
         else
         {
            /* NO ! */
            retval = 1;
         }
      }
      hb_itemRelease( pArray );
   }
   else
   {
      retval = 1;  /* default return value to suppress C math lib warnings */
   }

   if( pMathErr->prevHandler )
   {
      if( pexc->handled )
      {
         /* the error is handled, so simply inform the previous handler */
         ( *pMathErr->prevHandler )( pexc );
      }
      else
      {
         /* else go on error handling within previous handler */
         retval = ( *pMathErr->prevHandler )( pexc );
      }
   }
   return retval;
}