Files
harbour-core/harbour/source/compiler/hbpcode.c
Przemyslaw Czerpak 9cd2098d6d 2006-11-23 20:00 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
  * harbour/include/hbcomp.h
  + harbour/include/hbcompdf.h
  * harbour/include/hberrors.h
  * harbour/include/hbexpra.c
  * harbour/include/hbexprb.c
  * harbour/include/hbexprc.c
  * harbour/include/hbexprop.h
  * harbour/include/hbmacro.h
  * harbour/include/hbpp.h
  * harbour/include/hbvm.h
  * harbour/source/common/expropt1.c
  * harbour/source/common/expropt2.c
  * harbour/source/compiler/Makefile
  * harbour/source/compiler/cmdcheck.c
  * harbour/source/compiler/complex.c
  * harbour/source/compiler/genc.c
  * harbour/source/compiler/gencc.c
  * harbour/source/compiler/gencli.c
  * harbour/source/compiler/gencobj.c
  * harbour/source/compiler/genhrb.c
  * harbour/source/compiler/genjava.c
  * harbour/source/compiler/genobj32.c
  * harbour/source/compiler/harbour.c
  * harbour/source/compiler/harbour.l
  * harbour/source/compiler/harbour.y
  * harbour/source/compiler/hbcomp.c
  * harbour/source/compiler/hbdead.c
  * harbour/source/compiler/hbfix.c
  * harbour/source/compiler/hbfunchk.c
  * harbour/source/compiler/hbgenerr.c
  * harbour/source/compiler/hbident.c
  * harbour/source/compiler/hbpcode.c
  * harbour/source/compiler/ppcomp.c
  * harbour/source/macro/macro.y
  * harbour/source/pp/ppcore.c
  * harbour/source/pp/ppgen.c
  * harbour/source/pp/pplib.c
  * harbour/source/vm/cmdarg.c
  * harbour/source/vm/estack.c
  * harbour/source/vm/fm.c
  * harbour/source/vm/macro.c
  * harbour/utils/hbpp/hbpp.c
  * harbour/utils/hbpp/hbpp.h
  * harbour/utils/hbpp/hbppcomp.c
  * harbour/utils/hbpp/hbppcore.c
  * harbour/utils/hbpp/hbpplib.c
  * harbour/utils/hbpp/pragma.c
    * changed the internal compiler API to be MT safe.
      All global and static non constant variables replaced by
      HB_COMP structure which have all compiler context settings.
      It's possible to allocate simultaneously many compiler contexts
      and compile code. Only constant/read only variables are shared.
      In macro compiler HB_COMP is replaced by HB_MACRO.
      In source code I everywhere used to macros: HB_COMP_DECL and
      HB_COMP_PARAM which are equivalents of old HB_MACRO_DECL and
      HB_MACRO_PARAM definitions.
      We will only have to change compiler FATAL errors support to
      not execute exit() for non batch systems.
    * make macro compiler fully MT safe
    * removed not longer used definitions and variables
    ! add direct accessing to PP line number information - it fixes missing
      line numbers reported recently
    ! added generating .ppo files when tokens are teken directly by compiler
      - it fixes empty .ppo file problem
    ! clear hb_stack internall variables after removing hb_stack to avoid
      possible GPF if application still works and try to access unexsiting
      hb_stack
    ! do not allocate new memory block when final FM statistic report is
      generated - it fixes problem with GPF when application compiled with
      FM statistic exits and CLIPPER envvar is set.
    ! fixed memory leak hb_cmdargCheck()
    ! added to harbour.y symbol destructors - it should fixes memory leaks
      in syntax errors but it uses quite new bison feature which is not
      fully supported yet. Unfortunately it's also not MT safe and the
      destructors implementation in 1.875c does not respect %parse-param.
      Bison documentation says that it should so I hope it will be fixed
      soon (or maybe even already is in the newest bison versions) before
      I'll add multi context compilation support. If not then I will have
      to add some workaround. I can pass compiler context pointer inside
      YYSTYPE using hack in a lexer but it will force really huge number
      modifications in existing bison rules so probably it will be much
      easier to fix bison or write a small tool to update generated parser.
    * other modifications - the total size of patch is nearly 1MB and
      detail description will have to take me few days.
2006-11-23 18:57:54 +00:00

634 lines
26 KiB
C

/*
* $Id$
*/
/*
* Harbour Project source code:
* Compiler PCode generation functions
*
* Copyright 1999 {list of individual authors and e-mail addresses}
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
/*
* The following parts are Copyright of the individual authors.
* www - http://www.harbour-project.org
*
* Copyright 2000 RonPinkas <Ron@Profit-Master.com>
* hb_compStrongType()
*
* See doc/license.txt for licensing terms.
*
*/
#include <assert.h>
#include "hbcomp.h"
#define HB_PSIZE_FUNC( func ) HB_PCODE_FUNC( func, HB_VOID_PTR )
/*
* functions for variable size PCODE tracing
*/
static HB_PSIZE_FUNC( hb_p_pushstr )
{
HB_SYMBOL_UNUSED( cargo );
return 3 + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] );
}
static HB_PSIZE_FUNC( hb_p_pushstrshort )
{
HB_SYMBOL_UNUSED( cargo );
return 2 + pFunc->pCode[ lPCodePos + 1 ];
}
static HB_PSIZE_FUNC( hb_p_pushblock )
{
HB_SYMBOL_UNUSED( cargo );
return HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] );
}
static HB_PSIZE_FUNC( hb_p_pushblockshort )
{
HB_SYMBOL_UNUSED( cargo );
return pFunc->pCode[ lPCodePos + 1 ];
}
static HB_PSIZE_FUNC( hb_p_localname )
{
ULONG ulStart = lPCodePos;
HB_SYMBOL_UNUSED( cargo );
lPCodePos += 3;
while( pFunc->pCode[ lPCodePos++ ] );
return ( lPCodePos - ulStart );
}
static HB_PSIZE_FUNC( hb_p_modulename )
{
ULONG ulStart = lPCodePos;
HB_SYMBOL_UNUSED( cargo );
lPCodePos += 3;
while( pFunc->pCode[ lPCodePos++ ]);
return ( lPCodePos - ulStart );
}
static HB_PSIZE_FUNC( hb_p_staticname )
{
ULONG ulStart = lPCodePos;
HB_SYMBOL_UNUSED( cargo );
lPCodePos += 4;
while( pFunc->pCode[ lPCodePos++ ] );
return ( lPCodePos - ulStart );
}
const BYTE hb_comp_pcode_len[] = {
1, /* HB_P_AND, */
1, /* HB_P_ARRAYPUSH, */
1, /* HB_P_ARRAYPOP, */
3, /* HB_P_ARRAYDIM, */
3, /* HB_P_ARRAYGEN, */
1, /* HB_P_EQUAL, */
1, /* HB_P_ENDBLOCK, */
1, /* HB_P_ENDPROC, */
1, /* HB_P_EXACTLYEQUAL, */
1, /* HB_P_FALSE, */
1, /* HB_P_FORTEST, */
3, /* HB_P_FUNCTION, */
2, /* HB_P_FUNCTIONSHORT, */
3, /* HB_P_FRAME, */
1, /* HB_P_FUNCPTR, */
1, /* HB_P_GREATER, */
1, /* HB_P_GREATEREQUAL, */
1, /* HB_P_DEC, */
1, /* HB_P_DIVIDE, */
3, /* HB_P_DO, */
2, /* HB_P_DOSHORT, */
1, /* HB_P_DUPLICATE, */
1, /* HB_P_DUPLTWO, */
1, /* HB_P_INC, */
1, /* HB_P_INSTRING, */
2, /* HB_P_JUMPNEAR, */
3, /* HB_P_JUMP, */
4, /* HB_P_JUMPFAR, */
2, /* HB_P_JUMPFALSENEAR, */
3, /* HB_P_JUMPFALSE, */
4, /* HB_P_JUMPFALSEFAR, */
2, /* HB_P_JUMPTRUENEAR, */
3, /* HB_P_JUMPTRUE, */
4, /* HB_P_JUMPTRUEFAR, */
1, /* HB_P_LESSEQUAL, */
1, /* HB_P_LESS, */
3, /* HB_P_LINE, */
0, /* HB_P_LOCALNAME, */
2, /* HB_P_MACROPOP, */
2, /* HB_P_MACROPOPALIASED, */
2, /* HB_P_MACROPUSH, */
3, /* HB_P_MACROARRAYGEN, */
2, /* HB_P_MACROPUSHLIST, */
2, /* HB_P_MACROPUSHINDEX, */
2, /* HB_P_MACROPUSHPARE, */
2, /* HB_P_MACROPUSHALIASED, */
1, /* HB_P_MACROSYMBOL, */
1, /* HB_P_MACROTEXT, */
3, /* HB_P_MESSAGE, */
1, /* HB_P_MINUS, */
1, /* HB_P_MODULUS, */
0, /* HB_P_MODULENAME, */
/* start: pcodes generated by macro compiler */
3, /* HB_P_MMESSAGE, */
3, /* HB_P_MPOPALIASEDFIELD, */
3, /* HB_P_MPOPALIASEDVAR, */
3, /* HB_P_MPOPFIELD, */
3, /* HB_P_MPOPMEMVAR, */
3, /* HB_P_MPUSHALIASEDFIELD, */
3, /* HB_P_MPUSHALIASEDVAR, */
0, /* HB_P_MPUSHBLOCK, */
3, /* HB_P_MPUSHFIELD, */
3, /* HB_P_MPUSHMEMVAR, */
3, /* HB_P_MPUSHMEMVARREF, */
3, /* HB_P_MPUSHSYM, */
3, /* HB_P_MPUSHVARIABLE, */
/* end: */
1, /* HB_P_MULT, */
1, /* HB_P_NEGATE, */
1, /* HB_P_NOOP, */
1, /* HB_P_NOT, */
1, /* HB_P_NOTEQUAL, */
1, /* HB_P_OR, */
4, /* HB_P_PARAMETER, */
1, /* HB_P_PLUS, */
1, /* HB_P_POP, */
1, /* HB_P_POPALIAS, */
3, /* HB_P_POPALIASEDFIELD, */
2, /* HB_P_POPALIASEDFIELDNEAR, */
3, /* HB_P_POPALIASEDVAR, */
3, /* HB_P_POPFIELD, */
3, /* HB_P_POPLOCAL, */
2, /* HB_P_POPLOCALNEAR, */
3, /* HB_P_POPMEMVAR, */
3, /* HB_P_POPSTATIC, */
3, /* HB_P_POPVARIABLE, */
1, /* HB_P_POWER, */
1, /* HB_P_PUSHALIAS, */
3, /* HB_P_PUSHALIASEDFIELD, */
2, /* HB_P_PUSHALIASEDFIELDNEAR, */
3, /* HB_P_PUSHALIASEDVAR, */
0, /* HB_P_PUSHBLOCK, */
0, /* HB_P_PUSHBLOCKSHORT, */
3, /* HB_P_PUSHFIELD, */
2, /* HB_P_PUSHBYTE, */
3, /* HB_P_PUSHINT, */
3, /* HB_P_PUSHLOCAL, */
2, /* HB_P_PUSHLOCALNEAR, */
3, /* HB_P_PUSHLOCALREF, */
5, /* HB_P_PUSHLONG, */
3, /* HB_P_PUSHMEMVAR, */
3, /* HB_P_PUSHMEMVARREF, */
1, /* HB_P_PUSHNIL, */
1 + sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE ), /* HB_P_PUSHDOUBLE, */
1, /* HB_P_PUSHSELF, */
3, /* HB_P_PUSHSTATIC, */
3, /* HB_P_PUSHSTATICREF, */
0, /* HB_P_PUSHSTR, */
0, /* HB_P_PUSHSTRSHORT, */
3, /* HB_P_PUSHSYM, */
2, /* HB_P_PUSHSYMNEAR, */
3, /* HB_P_PUSHVARIABLE, */
1, /* HB_P_RETVALUE, */
3, /* HB_P_SEND, */
2, /* HB_P_SENDSHORT, */
4, /* HB_P_SEQBEGIN, */
4, /* HB_P_SEQEND, */
1, /* HB_P_SEQRECOVER, */
3, /* HB_P_SFRAME, */
5, /* HB_P_STATICS, */
0, /* HB_P_STATICNAME, */
1, /* HB_P_SWAPALIAS, */
1, /* HB_P_TRUE, */
1, /* HB_P_ZERO, */
1, /* HB_P_ONE, */
3, /* HB_P_MACROFUNC, */
3, /* HB_P_MACRODO, */
0, /* HB_P_MPUSHSTR */
4, /* HB_P_LOCALNEARADDINT, */
1, /* HB_P_MACROPUSHREF */
9, /* HB_P_PUSHLONGLONG */
3, /* HB_P_ENUMSTART */
1, /* HB_P_ENUMNEXT */
1, /* HB_P_ENUMPREV */
1, /* HB_P_ENUMEND */
3, /* HB_P_SWITCH */
5, /* HB_P_PUSHDATE, */
/* optimalization of inlined math operations */
1, /* HB_P_PLUSEQPOP, */
1, /* HB_P_MINUSEQPOP, */
1, /* HB_P_MULTEQPOP, */
1, /* HB_P_DIVEQPOP, */
1, /* HB_P_PLUSEQ, */
1, /* HB_P_MINUSEQ, */
1, /* HB_P_MULTEQ, */
1, /* HB_P_DIVEQ, */
1, /* HB_P_WITHOBJECTSTART, */
3, /* HB_P_WITHOBJECTMESSAGE, */
1, /* HB_P_WITHOBJECTEND, */
3, /* HB_P_MACROSEND, */
1, /* HB_P_PUSHOVARREF, */
1, /* HB_P_ARRAYPUSHREF */
3 /* HB_P_VFRAME */
};
/*
* this table has pointers to functions which count
* real size of variable size PCODEs
*/
static HB_PCODE_FUNC_PTR s_psize_table[] =
{
NULL, /* HB_P_AND, */
NULL, /* HB_P_ARRAYPUSH, */
NULL, /* HB_P_ARRAYPOP, */
NULL, /* HB_P_ARRAYDIM, */
NULL, /* HB_P_ARRAYGEN, */
NULL, /* HB_P_EQUAL, */
NULL, /* HB_P_ENDBLOCK, */
NULL, /* HB_P_ENDPROC, */
NULL, /* HB_P_EXACTLYEQUAL, */
NULL, /* HB_P_FALSE, */
NULL, /* HB_P_FORTEST, */
NULL, /* HB_P_FUNCTION, */
NULL, /* HB_P_FUNCTIONSHORT, */
NULL, /* HB_P_FRAME, */
NULL, /* HB_P_FUNCPTR, */
NULL, /* HB_P_GREATER, */
NULL, /* HB_P_GREATEREQUAL, */
NULL, /* HB_P_DEC, */
NULL, /* HB_P_DIVIDE, */
NULL, /* HB_P_DO, */
NULL, /* HB_P_DOSHORT, */
NULL, /* HB_P_DUPLICATE, */
NULL, /* HB_P_DUPLTWO, */
NULL, /* HB_P_INC, */
NULL, /* HB_P_INSTRING, */
NULL, /* HB_P_JUMPNEAR, */
NULL, /* HB_P_JUMP, */
NULL, /* HB_P_JUMPFAR, */
NULL, /* HB_P_JUMPFALSENEAR, */
NULL, /* HB_P_JUMPFALSE, */
NULL, /* HB_P_JUMPFALSEFAR, */
NULL, /* HB_P_JUMPTRUENEAR, */
NULL, /* HB_P_JUMPTRUE, */
NULL, /* HB_P_JUMPTRUEFAR, */
NULL, /* HB_P_LESSEQUAL, */
NULL, /* HB_P_LESS, */
NULL, /* HB_P_LINE, */
hb_p_localname, /* HB_P_LOCALNAME, */
NULL, /* HB_P_MACROPOP, */
NULL, /* HB_P_MACROPOPALIASED, */
NULL, /* HB_P_MACROPUSH, */
NULL, /* HB_P_MACROARRAYGEN, */
NULL, /* HB_P_MACROPUSHLIST, */
NULL, /* HB_P_MACROPUSHINDEX, */
NULL, /* HB_P_MACROPUSHPARE, */
NULL, /* HB_P_MACROPUSHALIASED, */
NULL, /* HB_P_MACROSYMBOL, */
NULL, /* HB_P_MACROTEXT, */
NULL, /* HB_P_MESSAGE, */
NULL, /* HB_P_MINUS, */
NULL, /* HB_P_MODULUS, */
hb_p_modulename, /* HB_P_MODULENAME, */
/* start: pcodes generated by macro compiler */
NULL, /* HB_P_MMESSAGE, */
NULL, /* HB_P_MPOPALIASEDFIELD, */
NULL, /* HB_P_MPOPALIASEDVAR, */
NULL, /* HB_P_MPOPFIELD, */
NULL, /* HB_P_MPOPMEMVAR, */
NULL, /* HB_P_MPUSHALIASEDFIELD, */
NULL, /* HB_P_MPUSHALIASEDVAR, */
NULL, /* HB_P_MPUSHBLOCK, */
NULL, /* HB_P_MPUSHFIELD, */
NULL, /* HB_P_MPUSHMEMVAR, */
NULL, /* HB_P_MPUSHMEMVARREF, */
NULL, /* HB_P_MPUSHSYM, */
NULL, /* HB_P_MPUSHVARIABLE, */
/* end: */
NULL, /* HB_P_MULT, */
NULL, /* HB_P_NEGATE, */
NULL, /* HB_P_NOOP, */
NULL, /* HB_P_NOT, */
NULL, /* HB_P_NOTEQUAL, */
NULL, /* HB_P_OR, */
NULL, /* HB_P_PARAMETER, */
NULL, /* HB_P_PLUS, */
NULL, /* HB_P_POP, */
NULL, /* HB_P_POPALIAS, */
NULL, /* HB_P_POPALIASEDFIELD, */
NULL, /* HB_P_POPALIASEDFIELDNEAR, */
NULL, /* HB_P_POPALIASEDVAR, */
NULL, /* HB_P_POPFIELD, */
NULL, /* HB_P_POPLOCAL, */
NULL, /* HB_P_POPLOCALNEAR, */
NULL, /* HB_P_POPMEMVAR, */
NULL, /* HB_P_POPSTATIC, */
NULL, /* HB_P_POPVARIABLE, */
NULL, /* HB_P_POWER, */
NULL, /* HB_P_PUSHALIAS, */
NULL, /* HB_P_PUSHALIASEDFIELD, */
NULL, /* HB_P_PUSHALIASEDFIELDNEAR, */
NULL, /* HB_P_PUSHALIASEDVAR, */
hb_p_pushblock, /* HB_P_PUSHBLOCK, */
hb_p_pushblockshort, /* HB_P_PUSHBLOCKSHORT, */
NULL, /* HB_P_PUSHFIELD, */
NULL, /* HB_P_PUSHBYTE, */
NULL, /* HB_P_PUSHINT, */
NULL, /* HB_P_PUSHLOCAL, */
NULL, /* HB_P_PUSHLOCALNEAR, */
NULL, /* HB_P_PUSHLOCALREF, */
NULL, /* HB_P_PUSHLONG, */
NULL, /* HB_P_PUSHMEMVAR, */
NULL, /* HB_P_PUSHMEMVARREF, */
NULL, /* HB_P_PUSHNIL, */
NULL, /* HB_P_PUSHDOUBLE, */
NULL, /* HB_P_PUSHSELF, */
NULL, /* HB_P_PUSHSTATIC, */
NULL, /* HB_P_PUSHSTATICREF, */
hb_p_pushstr, /* HB_P_PUSHSTR, */
hb_p_pushstrshort, /* HB_P_PUSHSTRSHORT, */
NULL, /* HB_P_PUSHSYM, */
NULL, /* HB_P_PUSHSYMNEAR, */
NULL, /* HB_P_PUSHVARIABLE, */
NULL, /* HB_P_RETVALUE, */
NULL, /* HB_P_SEND, */
NULL, /* HB_P_SENDSHORT, */
NULL, /* HB_P_SEQBEGIN, */
NULL, /* HB_P_SEQEND, */
NULL, /* HB_P_SEQRECOVER, */
NULL, /* HB_P_SFRAME, */
NULL, /* HB_P_STATICS, */
hb_p_staticname, /* HB_P_STATICNAME, */
NULL, /* HB_P_SWAPALIAS, */
NULL, /* HB_P_TRUE, */
NULL, /* HB_P_ZERO, */
NULL, /* HB_P_ONE, */
NULL, /* HB_P_MACROFUNC, */
NULL, /* HB_P_MACRODO, */
NULL, /* HB_P_MPUSHSTR, */
NULL, /* HB_P_LOCALNEARADDINT, */
NULL, /* HB_P_MACROPUSHREF */
NULL, /* HB_P_PUSHLONGLONG */
NULL, /* HB_P_ENUMSTART */
NULL, /* HB_P_ENUMNEXT */
NULL, /* HB_P_ENUMPREV */
NULL, /* HB_P_ENUMEND */
NULL, /* HB_P_SWITCH */
NULL, /* HB_P_PUSHDATE */
/* optimalization of inlined math operations */
NULL, /* HB_P_PLUSEQPOP */
NULL, /* HB_P_MINUSEQPOP */
NULL, /* HB_P_MULTEQPOP */
NULL, /* HB_P_DIVEQPOP */
NULL, /* HB_P_PLUSEQ */
NULL, /* HB_P_MINUSEQ */
NULL, /* HB_P_MULTEQ */
NULL, /* HB_P_DIVEQ */
NULL, /* HB_P_WITHOBJECTSTART */
NULL, /* HB_P_WITHOBJECTMESSAGE */
NULL, /* HB_P_WITHOBJECTEND */
NULL, /* HB_P_MACROSEND */
NULL, /* HB_P_PUSHOVARREF */
NULL, /* HB_P_ARRAYPUSHREF */
NULL /* HB_P_VFRAME */
};
LONG hb_compPCodeSize( PFUNCTION pFunc, ULONG ulOffset )
{
LONG lSize = 0;
BYTE opcode = pFunc->pCode[ ulOffset ];
if( opcode < HB_P_LAST_PCODE )
{
lSize = hb_comp_pcode_len[ opcode ];
if( lSize == 0 )
{
HB_PCODE_FUNC_PTR pCall = s_psize_table[ opcode ];
if( pCall != NULL )
lSize = pCall( pFunc, ulOffset, NULL );
}
}
return lSize;
}
void hb_compPCodeEval( PFUNCTION pFunc, HB_PCODE_FUNC_PTR * pFunctions, void * cargo )
{
ULONG ulPos = 0;
ULONG ulSkip;
BYTE opcode;
HB_PCODE_FUNC_PTR pCall;
/* Make sure that table is correct */
assert( sizeof( hb_comp_pcode_len ) == HB_P_LAST_PCODE );
assert( sizeof( s_psize_table ) / sizeof( HB_PCODE_FUNC_PTR ) == HB_P_LAST_PCODE );
while( ulPos < pFunc->lPCodePos )
{
opcode = pFunc->pCode[ ulPos ];
if( opcode < HB_P_LAST_PCODE )
{
pCall = pFunctions[ opcode ];
ulSkip = pCall ? pCall( pFunc, ulPos, cargo ) : 0;
if( ulSkip == 0 )
{
ulSkip = hb_comp_pcode_len[ opcode ];
if( ulSkip == 0 )
{
HB_PCODE_FUNC_PTR pCall = s_psize_table[ opcode ];
if( pCall != NULL )
ulSkip = pCall( pFunc, ulPos, NULL );
}
}
if( ulSkip == 0 )
{
fprintf( hb_comp_errFile, "--- Invalid (zero) opcode %i size in hb_compPCodeEval() ---\n", opcode );
++ulPos;
}
#if 0
/*
* Test code to validate return values by PCODE eval functions,
* in some cases the eval functions can return intentionally differ
* values so it's not enabled by default. [druzus]
*/
if( hb_comp_pcode_len[ opcode ] != 0 && hb_comp_pcode_len[ opcode ] != ulSkip )
{
fprintf( stderr, "Wrong PCODE (%d) size (%ld!=%d)\n", opcode, ulSkip, hb_comp_pcode_len[ opcode ] );
fflush(stderr);
}
#endif
ulPos += ulSkip;
}
else
{
fprintf( hb_comp_errFile, "--- Invalid opcode %i in hb_compPCodeEval() ---\n", opcode );
++ulPos;
}
}
}
void hb_compPCodeTrace( PFUNCTION pFunc, HB_PCODE_FUNC_PTR * pFunctions, void * cargo )
{
ULONG ulPos = 0;
BYTE opcode;
HB_PCODE_FUNC_PTR pCall;
/* Make sure that table is correct */
assert( sizeof( hb_comp_pcode_len ) == HB_P_LAST_PCODE );
while( ulPos < pFunc->lPCodePos )
{
opcode = pFunc->pCode[ ulPos ];
if( opcode < HB_P_LAST_PCODE )
{
pCall = pFunctions[ opcode ];
if( pCall )
ulPos = pCall( pFunc, ulPos, cargo );
else
ulPos += hb_comp_pcode_len[ opcode ];
}
else
{
fprintf( hb_comp_errFile, "--- Invalid opcode %i in hb_compPCodeTrace() ---\n", opcode );
++ulPos;
}
}
}
void hb_compGenPCode1( BYTE byte, HB_COMP_DECL )
{
PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; /* get the currently defined Clipper function */
if( ! pFunc->pCode ) /* has been created the memory block to hold the pcode ? */
{
pFunc->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_CHUNK );
pFunc->lPCodeSize = HB_PCODE_CHUNK;
pFunc->lPCodePos = 0;
}
else if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 1 )
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_CHUNK );
pFunc->pCode[ pFunc->lPCodePos++ ] = byte;
}
void hb_compGenPData1( BYTE byte, HB_COMP_DECL )
{
PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; /* get the currently defined Clipper function */
if( ! pFunc->pCode ) /* has been created the memory block to hold the pcode ? */
{
pFunc->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_CHUNK );
pFunc->lPCodeSize = HB_PCODE_CHUNK;
pFunc->lPCodePos = 0;
}
else if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 1 )
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_CHUNK );
pFunc->pCode[ pFunc->lPCodePos++ ] = byte;
}
void hb_compGenPCode2( BYTE byte1, BYTE byte2, HB_COMP_DECL )
{
PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; /* get the currently defined Clipper function */
if( ! pFunc->pCode ) /* has been created the memory block to hold the pcode ? */
{
pFunc->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_CHUNK );
pFunc->lPCodeSize = HB_PCODE_CHUNK;
pFunc->lPCodePos = 0;
}
else if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 2 )
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_CHUNK );
pFunc->pCode[ pFunc->lPCodePos++ ] = byte1;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte2;
}
void hb_compGenPCode3( BYTE byte1, BYTE byte2, BYTE byte3, HB_COMP_DECL )
{
PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; /* get the currently defined Clipper function */
if( ! pFunc->pCode ) /* has been created the memory block to hold the pcode ? */
{
pFunc->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_CHUNK );
pFunc->lPCodeSize = HB_PCODE_CHUNK;
pFunc->lPCodePos = 0;
}
else if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 3 )
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_CHUNK );
pFunc->pCode[ pFunc->lPCodePos++ ] = byte1;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte2;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte3;
}
void hb_compGenPCode4( BYTE byte1, BYTE byte2, BYTE byte3, BYTE byte4, HB_COMP_DECL )
{
PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; /* get the currently defined Clipper function */
if( ! pFunc->pCode ) /* has been created the memory block to hold the pcode ? */
{
pFunc->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_CHUNK );
pFunc->lPCodeSize = HB_PCODE_CHUNK;
pFunc->lPCodePos = 0;
}
else if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 4 )
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_CHUNK );
pFunc->pCode[ pFunc->lPCodePos++ ] = byte1;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte2;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte3;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte4;
}
void hb_compGenPCodeN( BYTE * pBuffer, ULONG ulSize, HB_COMP_DECL )
{
PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; /* get the currently defined Clipper function */
if( ! pFunc->pCode ) /* has been created the memory block to hold the pcode ? */
{
pFunc->lPCodeSize = ( ( ulSize / HB_PCODE_CHUNK ) + 1 ) * HB_PCODE_CHUNK;
pFunc->pCode = ( BYTE * ) hb_xgrab( pFunc->lPCodeSize );
pFunc->lPCodePos = 0;
}
else if( pFunc->lPCodePos + ulSize > pFunc->lPCodeSize )
{
/* not enough free space in pcode buffer - increase it */
pFunc->lPCodeSize += ( ( ( ulSize / HB_PCODE_CHUNK ) + 1 ) * HB_PCODE_CHUNK );
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize );
}
memcpy( pFunc->pCode + pFunc->lPCodePos, pBuffer, ulSize );
pFunc->lPCodePos += ulSize;
}