Files
harbour-core/harbour/source/compiler/hbpcode.c
Przemyslaw Czerpak 8ce0d03aa0 2007-03-09 04:40 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/common.mak
  * harbour/makefile.bc
  * harbour/makefile.vc
  * harbour/bin/hb-func.sh
  * harbour/config/global.cf
  * harbour/include/error.ch
  * harbour/include/hbcomp.h
  * harbour/include/hbcompdf.h
  * harbour/include/hbexpra.c
  * harbour/include/hbexprb.c
  - harbour/include/hbexprc.c
  * harbour/include/hbexprop.h
  * harbour/include/hbmacro.h
  * harbour/source/Makefile
  * harbour/source/common/expropt1.c
  * harbour/source/common/expropt2.c
  * harbour/source/compiler/Makefile
  - harbour/source/compiler/exproptc.c
  - harbour/source/compiler/harbour.c
  * harbour/source/compiler/harbour.y
  * harbour/source/compiler/harbour.yyc
  * harbour/source/compiler/hbcomp.c
  * harbour/source/compiler/hbgenerr.c
  + harbour/source/compiler/hbmain.c
  * harbour/source/compiler/hbpcode.c
  * harbour/source/macro/Makefile
  * harbour/source/macro/macro.y
  * harbour/source/macro/macro.yyc
  - harbour/source/macro/macroc.c
  + harbour/source/main/Makefile
  + harbour/source/main/harbour.c
  * harbour/source/vm/macro.c
    * resolved name conflicts between compiler and macro compiler.
      Now new compiler library is created.
      There are some things which can be improved and cleaned yet
      but it's enough to create single binaries with compiler+HVM+RTLs.
      I updated non GNU make files but I cannot tested the modifications
      - please check and fix me if necessary
2007-03-09 03:44:42 +00:00

697 lines
29 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_pushstrshort )
{
HB_SYMBOL_UNUSED( cargo );
return 2 + pFunc->pCode[ lPCodePos + 1 ];
}
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_pushstrlarge )
{
HB_SYMBOL_UNUSED( cargo );
return 4 + HB_PCODE_MKUINT24( &pFunc->pCode[ lPCodePos + 1 ] );
}
static HB_PSIZE_FUNC( hb_p_pushstrhidden )
{
HB_SYMBOL_UNUSED( cargo );
return 4 + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 2 ] );
}
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_pushblocklarge )
{
HB_SYMBOL_UNUSED( cargo );
return HB_PCODE_MKUINT24( &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, */
1, /* 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 */
4, /* HB_P_LARGEFRAME */
4, /* HB_P_LARGEVFRAME */
0, /* HB_P_PUSHSTRHIDDEN */
5, /* HB_P_LOCALADDINT */
1, /* HB_P_MODEQPOP */
1, /* HB_P_EXPEQPOP */
1, /* HB_P_MODEQ */
1, /* HB_P_EXPEQ */
1, /* HB_P_DUPLUNREF */
0, /* HB_P_MPUSHBLOCKLARGE, */
0, /* HB_P_MPUSHSTRLARGE */
0, /* HB_P_PUSHBLOCKLAREG, */
0, /* HB_P_PUSHSTRLARGE */
2, /* HB_P_SWAP */
1, /* HB_P_PUSHVPARAMS */
1, /* HB_P_PUSHUNREF */
4, /* HB_P_SEQALWAYS */
4, /* HB_P_ALWAYSBEGIN */
1, /* HB_P_ALWAYSEND */
1, /* HB_P_DECEQPOP */
1, /* HB_P_INCEQPOP */
1, /* HB_P_DECEQ */
1, /* HB_P_INCEQ */
3, /* HB_P_LOCALDEC */
3, /* HB_P_LOCALINC */
3, /* HB_P_LOCALINCPUSH */
3 /* HB_P_PUSHFUNCSYM */
};
/*
* 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 */
NULL, /* HB_P_LARGEFRAME */
NULL, /* HB_P_LARGEVFRAME */
hb_p_pushstrhidden, /* HB_P_PUSHSTRHIDDEN */
NULL, /* HB_P_LOCALADDINT */
NULL, /* HB_P_MODEQPOP */
NULL, /* HB_P_EXPEQPOP */
NULL, /* HB_P_MODEQ */
NULL, /* HB_P_EXPEQ */
NULL, /* HB_P_DUPLUNREF */
NULL, /* HB_P_MPUSHBLOCKLARGE */
NULL, /* HB_P_MPUSHSTRLARGE */
hb_p_pushblocklarge, /* HB_P_PUSHBLOCKLARGE, */
hb_p_pushstrlarge, /* HB_P_PUSHSTRLARGE */
NULL, /* HB_P_SWAP */
NULL, /* HB_P_PUSHVPARAMS */
NULL, /* HB_P_PUSHUNREF */
NULL, /* HB_P_SEQALWAYS */
NULL, /* HB_P_ALWAYSBEGIN */
NULL, /* HB_P_ALWAYSEND */
NULL, /* HB_P_DECEQPOP */
NULL, /* HB_P_INCEQPOP */
NULL, /* HB_P_DECEQ */
NULL, /* HB_P_INCEQ */
NULL, /* HB_P_LOCALDEC */
NULL, /* HB_P_LOCALINC */
NULL, /* HB_P_LOCALINCPUSH */
NULL /* HB_P_PUSHFUNCSYM */
};
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 )
{
char szOpcode[ 16 ];
snprintf( szOpcode, sizeof( szOpcode ), "%i", opcode );
hb_errInternal( HB_EI_COMPBADOPSIZE, "Invalid (zero) opcode %s size in hb_compPCodeEval()", szOpcode, NULL );
++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 )
{
char szMsg[ 100 ];
snprintf( szMsg, sizeof( szMsg ), "Wrong PCODE (%d) size (%ld!=%d)", opcode, ulSkip, hb_comp_pcode_len[ opcode ] );
hb_errInternal( HB_EI_COMPBADOPSIZE, szMsg, NULL, NULL );
}
#endif
ulPos += ulSkip;
}
else
{
char szOpcode[ 16 ];
snprintf( szOpcode, sizeof( szOpcode ), "%i", opcode );
hb_errInternal( HB_EI_COMPBADOPCODE, "Invalid opcode: %s in hb_compPCodeEval()", szOpcode, NULL );
++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
{
char szOpcode[ 16 ];
snprintf( szOpcode, sizeof( szOpcode ), "%i", opcode );
hb_errInternal( HB_EI_COMPBADOPCODE, "Invalid opcode: %s in hb_compPCodeTrace()", szOpcode, NULL );
++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_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;
}