diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h index bbf3398d38..8b84009b49 100644 --- a/harbour/include/hberrors.h +++ b/harbour/include/hberrors.h @@ -89,6 +89,10 @@ extern "C" { #define HB_COMP_ERR_BAD_MACRO 42 #define HB_COMP_ERR_INVALID_SEND 43 #define HB_COMP_ERR_FUNC_ANNOUNCE 44 +#define HB_COMP_ERR_INVALID_JUMP 45 +#define HB_COMP_ERR_INVALID_JUMPTRUE 46 +#define HB_COMP_ERR_INVALID_JUMPFALSE 47 +#define HB_COMP_ERR_JUMP_NOT_FOUND 48 #define HB_COMP_WARN_AMBIGUOUS_VAR 1 #define HB_COMP_WARN_MEMVAR_ASSUMED 2 diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 1021c33250..affc2f65b3 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -648,11 +648,11 @@ static HB_EXPR_FUNC( hb_compExprUseIIF ) HB_EXPR_PTR pExpr = pSelf->value.asList.pExprList; HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE ); - lPosFalse = HB_EXPR_PCODE1( hb_compGenJumpFalse, 0 ); + lPosFalse = HB_EXPR_PCODE1( hb_compGenJumpFalse, -1 ); pExpr =pExpr->pNext; HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE ); - lPosEnd = HB_EXPR_PCODE1( hb_compGenJump, 0 ); + lPosEnd = HB_EXPR_PCODE1( hb_compGenJump, -1 ); pExpr =pExpr->pNext; HB_EXPR_PCODE1( hb_compGenJumpHere, lPosFalse ); @@ -1993,7 +1993,7 @@ static HB_EXPR_FUNC( hb_compExprUseOr ) HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_DUPLICATE ); - lEndPos = HB_EXPR_PCODE1( hb_compGenJumpTrue, 0 ); + lEndPos = HB_EXPR_PCODE1( hb_compGenJumpTrue, -1 ); HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_OR ); HB_EXPR_PCODE1( hb_compGenJumpHere, lEndPos ); @@ -2063,7 +2063,7 @@ static HB_EXPR_FUNC( hb_compExprUseAnd ) HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_DUPLICATE ); - lEndPos = HB_EXPR_PCODE1( hb_compGenJumpFalse, 0 ); + lEndPos = HB_EXPR_PCODE1( hb_compGenJumpFalse, -1 ); HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_AND ); HB_EXPR_PCODE1( hb_compGenJumpHere, lEndPos ); diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 071baa9ed2..03e08886bf 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -1100,25 +1100,27 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou break; case HB_P_SEQBEGIN: - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\tHB_P_SEQBEGIN, %i, %i,", + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536; + fprintf( yyc, "\tHB_P_SEQBEGIN, %i, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ] ); - if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 3 ) ); + pFunc->pCode[ lPCodePos + 2 ], + pFunc->pCode[ lPCodePos + 3 ] ); + if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 4 ) ); fprintf( yyc, "\n" ); - lPCodePos += 3; + lPCodePos += 4; break; case HB_P_SEQEND: if( hb_comp_bGenCVerbose ) fprintf( yyc, "/* %05li */ ", lPCodePos ); else fprintf( yyc, "\t" ); - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "HB_P_SEQEND, %i, %i,", + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536; + fprintf( yyc, "HB_P_SEQEND, %i, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ] ); - if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 3 ) ); + pFunc->pCode[ lPCodePos + 2 ], + pFunc->pCode[ lPCodePos + 3 ] ); + if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 4 ) ); fprintf( yyc, "\n" ); - lPCodePos += 3; + lPCodePos += 4; break; case HB_P_SEQRECOVER: @@ -1169,6 +1171,11 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou lPCodePos++; break; + case HB_P_NOOP: + fprintf( yyc, "\tHB_P_NOOP,\n" ); + lPCodePos++; + break; + default: fprintf( yyc, "\t%u, /* Incorrect pcode value: %u */\n", pFunc->pCode[ lPCodePos ], pFunc->pCode[ lPCodePos ] ); printf( "Incorrect pcode value: %u\n", pFunc->pCode[ lPCodePos ] ); diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index bf76587236..ce7fc009d6 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -1246,7 +1246,7 @@ ULONG hb_compGenJump( LONG lOffset ) { int iBytes; - /* Just a place holder so it might be a far jump...*/ + /* Just a place holder, it might be a far jump...*/ if ( lOffset == 0 ) { hb_compGenPCode3( HB_P_JUMPFAR, 0, 0 ); @@ -1276,7 +1276,7 @@ ULONG hb_compGenJumpFalse( LONG lOffset ) { int iBytes; - /* Just a place holder so it might be a far jump...*/ + /* Just a place holder, it might be a far jump...*/ if ( lOffset == 0 ) { hb_compGenPCode3( HB_P_JUMPFARFALSE, 0, 0 ); @@ -1309,11 +1309,63 @@ void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo ) if ( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX ) { + switch ( pCode[ ( ULONG ) ulFrom - 1 ] ) + { + case HB_P_JUMP : + break; + + case HB_P_JUMPTRUE : + break; + + case HB_P_JUMPFALSE : + break; + case HB_P_JUMPFAR : + pCode[ ( ULONG ) ulFrom - 1 ] = HB_P_JUMP; + pCode[ ( ULONG ) ulFrom + 2 ] = HB_P_NOOP; + break; + + case HB_P_JUMPFARTRUE : + pCode[ ( ULONG ) ulFrom - 1 ] = HB_P_JUMPTRUE; + pCode[ ( ULONG ) ulFrom + 2 ] = HB_P_NOOP; + break; + + case HB_P_JUMPFARFALSE : + pCode[ ( ULONG ) ulFrom - 1 ] = HB_P_JUMPFALSE; + pCode[ ( ULONG ) ulFrom + 2 ] = HB_P_NOOP; + break; + + case HB_P_SEQBEGIN : + break; + + case HB_P_SEQEND : + break; + + default: + printf( "\rPCode: %i", pCode[ ( ULONG ) ulFrom - 1 ] ); + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_NOT_FOUND, NULL, NULL ); + break; + } + pCode[ ( ULONG ) ulFrom ] = HB_LOBYTE( lOffset ); pCode[ ( ULONG ) ulFrom + 1 ] = HB_HIBYTE( lOffset ); } else if ( lOffset >= (-8388608L) && lOffset <= 8388607L ) { + switch ( pCode[ ( ULONG ) ulFrom - 1 ] ) + { + case HB_P_JUMP : + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_INVALID_JUMP, NULL, NULL ); + break; + + case HB_P_JUMPTRUE : + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_INVALID_JUMPTRUE, NULL, NULL ); + break; + + case HB_P_JUMPFALSE : + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_INVALID_JUMPFALSE, NULL, NULL ); + break; + } + pCode[ ( ULONG ) ulFrom ] = HB_LOBYTE( lOffset ); pCode[ ( ULONG ) ulFrom + 1 ] = HB_HIBYTE( lOffset ); pCode[ ( ULONG ) ulFrom + 2 ] = ( BYTE ) ( ( ( USHORT ) ( lOffset ) >> 16 ) & 0xFF ); @@ -1333,7 +1385,7 @@ ULONG hb_compGenJumpTrue( LONG lOffset ) { int iBytes; - /* Just a place holder so it might be a far jump...*/ + /* Just a place holder, it might be a far jump...*/ if ( lOffset == 0 ) { hb_compGenPCode3( HB_P_JUMPFARTRUE, 0, 0 ); @@ -1359,7 +1411,6 @@ ULONG hb_compGenJumpTrue( LONG lOffset ) return hb_comp_functions.pLast->lPCodePos - iBytes; } - void hb_compLinePush( void ) /* generates the pcode with the currently compiled source code line */ { if( hb_comp_bLineNumbers && ! hb_comp_bDontGenLineNum ) @@ -2056,8 +2107,9 @@ void hb_compFixReturns( void ) /* fixes all last defined function returns jumps ULONG hb_compSequenceBegin( void ) { hb_compGenPCode3( HB_P_SEQBEGIN, 0, 0 ); + hb_compGenPCode1( 0 ); - return hb_comp_functions.pLast->lPCodePos - 2; + return hb_comp_functions.pLast->lPCodePos - 3; } /* Generate the opcode to close BEGIN/END sequence @@ -2070,8 +2122,9 @@ ULONG hb_compSequenceBegin( void ) ULONG hb_compSequenceEnd( void ) { hb_compGenPCode3( HB_P_SEQEND, 0, 0 ); + hb_compGenPCode1( 0 ); - return hb_comp_functions.pLast->lPCodePos - 2; + return hb_comp_functions.pLast->lPCodePos - 3; } /* Remove unnecessary opcodes in case there were no executable statements @@ -2084,7 +2137,7 @@ void hb_compSequenceFinish( ULONG ulStartPos, int bUsualStmts ) if( ! bUsualStmts ) { hb_comp_functions.pLast->lPCodePos = ulStartPos - 1; /* remove also HB_P_SEQBEGIN */ - hb_comp_ulLastLinePos = ulStartPos - 4; + hb_comp_ulLastLinePos = ulStartPos - 5; } } } diff --git a/harbour/source/compiler/hbgenerr.c b/harbour/source/compiler/hbgenerr.c index 47c2297eb6..ca20cc4783 100644 --- a/harbour/source/compiler/hbgenerr.c +++ b/harbour/source/compiler/hbgenerr.c @@ -81,7 +81,11 @@ char * hb_comp_szErrors[] = "Bound error: \'%s\'", "Macro of declared symbol: \'%s\'", "Invalid selector in send: \'%s\'", - "ANNOUNCEd procedure \'%s\' must be a public symbol" + "ANNOUNCEd procedure \'%s\' must be a public symbol", + "Jump offset too long for HB_P_JUMP needed HB_P_JUMPFAR", + "Jump offset too long for HB_P_JUMPTRUE needed HB_P_JUMPFARTRUE", + "Jump offset too long for HB_P_JUMPFALSE needed HB_P_JUMPFARFALSE", + "HB_P_JUMPx not found when fixing offset" }; /* Table with parse warnings */ diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index ae6f440d93..1c9d308bc6 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -616,7 +616,7 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) * 2) store the address of RECOVER or END opcode */ hb_stack.pPos->type = HB_IT_LONG; - hb_stack.pPos->item.asLong.value = w + pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + hb_stack.pPos->item.asLong.value = w + pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 ); hb_stackPush(); /* * 3) store current RECOVER base @@ -639,7 +639,7 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) * we are now inside a valid SEQUENCE envelope */ bCanRecover = TRUE; - w += 3; + w += 4; break; case HB_P_SEQEND: @@ -672,7 +672,7 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) /* * skip outside of SEQUENCE structure */ - w += pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + w += pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 ); break; case HB_P_SEQRECOVER: diff --git a/harbour/source/vm/macro.c b/harbour/source/vm/macro.c index 527df50edf..bb48d62138 100644 --- a/harbour/source/vm/macro.c +++ b/harbour/source/vm/macro.c @@ -185,7 +185,7 @@ static void hb_macroSyntaxError( HB_MACRO_PTR pMacro ) if( pMacro ) { HB_TRACE(HB_TR_DEBUG, ("hb_macroSyntaxError.(%s)", pMacro->string)); - + hb_macroDelete( pMacro ); /* TODO: use pMacro->status for more detailed error messagess */ } @@ -936,7 +936,7 @@ void hb_compGenPopAliasedVar( char * szVarName, long lWorkarea, HB_MACRO_DECL ) { HB_TRACE(HB_TR_DEBUG, ("hb_compGenPopAliasedVar(%s->%s)",szAlias,szVarName)); - + if( bPushAliasValue ) { if( szAlias ) @@ -1031,7 +1031,7 @@ void hb_compGenPushAliasedVar( char * szVarName, long lWorkarea, HB_MACRO_DECL ) { HB_TRACE(HB_TR_DEBUG, ("hb_compGenPushAliasedVar(%s->%s)",szAlias,szVarName)); - + if( bPushAliasValue ) { if( szAlias )