From 9153285bdf3ca472e75b07a919afaaecfeaf0b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Tue, 28 Mar 2017 23:02:28 +0200 Subject: [PATCH] 2017-03-28 23:02 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbcomp.h * include/hbcompdf.h * include/hberrors.h * include/hbexprb.c * src/common/expropt1.c * src/compiler/hbgenerr.c * src/compiler/hbmain.c + added new macros HB_ET_MACRO_NOLIST and HB_ET_MACRO_NOPARE % use new HB_ET_MACRO_* macros + added new compile time error: "Code block contains both macro and with object messages ':%s'" NOTE: -kd compiler switch allows to compile codeblocks with macros and declared symbols / with object messages * replaced hb_compErrorCodeblock() with hb_compErrorCodeblockDecl() and hb_compErrorCodeblockWith() + added new C function hb_compPushMacroVar() * code simplification ; added few comments * utils/hbtest/rt_math.prg * extended test code for macro messages and macro =, pre/post ++/-- operations * src/vm/hvm.c ! protection against executing hb_threadStateNew() during GC pass inside hb_vmRequestReenterExt() * src/vm/garbage.c ! add volatile attribute to s_bCollecting variable * small modification in hb_gcAll() parameter * src/rtl/errsys.prg ; minor comment cleanup * doc/xhb-diff.txt * extended a little bit section STRONG TYPED VARIABLES --- ChangeLog.txt | 38 ++++++++++++ doc/xhb-diff.txt | 8 ++- include/hbcomp.h | 4 +- include/hbcompdf.h | 5 ++ include/hberrors.h | 9 +-- include/hbexprb.c | 122 ++++++++++++++++----------------------- src/common/expropt1.c | 8 +-- src/compiler/hbgenerr.c | 13 ++++- src/compiler/hbmain.c | 21 ++++++- src/rtl/errsys.prg | 2 +- src/vm/garbage.c | 4 +- src/vm/hvm.c | 22 +++++-- utils/hbtest/rt_math.prg | 72 +++++++++++++++++------ 13 files changed, 215 insertions(+), 113 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 42bd7a1f41..2100bb40e9 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,44 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2017-03-28 23:02 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbcomp.h + * include/hbcompdf.h + * include/hberrors.h + * include/hbexprb.c + * src/common/expropt1.c + * src/compiler/hbgenerr.c + * src/compiler/hbmain.c + + added new macros HB_ET_MACRO_NOLIST and HB_ET_MACRO_NOPARE + % use new HB_ET_MACRO_* macros + + added new compile time error: + "Code block contains both macro and with object messages ':%s'" + NOTE: -kd compiler switch allows to compile codeblocks with macros + and declared symbols / with object messages + * replaced hb_compErrorCodeblock() with hb_compErrorCodeblockDecl() and + hb_compErrorCodeblockWith() + + added new C function hb_compPushMacroVar() + * code simplification + ; added few comments + + * utils/hbtest/rt_math.prg + * extended test code for macro messages and macro =, pre/post ++/-- + operations + + * src/vm/hvm.c + ! protection against executing hb_threadStateNew() during GC pass + inside hb_vmRequestReenterExt() + + * src/vm/garbage.c + ! add volatile attribute to s_bCollecting variable + * small modification in hb_gcAll() parameter + + * src/rtl/errsys.prg + ; minor comment cleanup + + * doc/xhb-diff.txt + * extended a little bit section STRONG TYPED VARIABLES + 2017-03-24 20:02 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbcomp.h * src/compiler/hbmain.c diff --git a/doc/xhb-diff.txt b/doc/xhb-diff.txt index aa03399b3b..adb1cac87e 100644 --- a/doc/xhb-diff.txt +++ b/doc/xhb-diff.txt @@ -1414,18 +1414,22 @@ Anyhow so far in both compilers it is only source code decoration and it's simply ignored during compilation. The syntax is similar but not the same. In VO: LOCAL var1, var2 AS LOGICAL -means that var1 and var2 are character variables and are initialized to .F. +means that var1 and var2 are logical variables and are initialized to .F. at runtime. In Harbour and xHarbour 'AS ' has to be repeated after each variable so in above code only var2 is strongly typed but not var1. To declare both variables as logical ones it should be changed to: LOCAL var1 AS STRING, var2 AS STRING +and to make implicit initialication user has to write code like: + LOCAL var1 AS STRING := "foo", var2 AS STRING := "bar" +instead of: + LOCAL var := "foo", var2 := "bar" AS STRING Such syntax is also not compatible with syntax of typed object variables (see TYPED OBJECT VARIABLES below) where VAR v1, v2 AS LOGICAL declares both variables as logical ones. This can strongly confuse users so in the future adding fully functional support for strong typed variables probably it will be changed to syntax -compatible with other xBase compatible languages. +compatible with other xBase like languages. Now please remember that neither Harbour nor xHarbour make type validation during compilation and at runtime and typed variables are not implicitly initialized to empty value of given type. diff --git a/include/hbcomp.h b/include/hbcomp.h index 99b27d5a92..d0968bc759 100644 --- a/include/hbcomp.h +++ b/include/hbcomp.h @@ -268,8 +268,10 @@ extern void hb_compErrorMacro( HB_COMP_DECL, const char * szText ); extern void hb_compErrorVParams( HB_COMP_DECL, const char * szFuncOrBlock ); extern PHB_EXPR hb_compErrorStatic( HB_COMP_DECL, const char *, PHB_EXPR ); -extern void hb_compErrorCodeblock( HB_COMP_DECL, const char * szBlock ); +extern void hb_compErrorCodeblockDecl( HB_COMP_DECL, const char * szVarName ); +extern void hb_compErrorCodeblockWith( HB_COMP_DECL, const char * szMessage ); +extern void hb_compPushMacroVar( HB_COMP_DECL, const char * szText ); extern void hb_compPushMacroText( HB_COMP_DECL, const char * szText, HB_SIZE nLen, HB_BOOL fMacro ); /* Codeblocks */ diff --git a/include/hbcompdf.h b/include/hbcompdf.h index 5c29367276..4ad19a24b0 100644 --- a/include/hbcompdf.h +++ b/include/hbcompdf.h @@ -170,6 +170,11 @@ typedef enum #define HB_ET_MACRO_PARE 32 /* &variable used as parentesised expressions. */ #define HB_ET_MACRO_REFER 64 /* ¯o used in @ (pass by reference) */ #define HB_ET_MACRO_ASSIGN 128 /* o:&msgname := value */ +#define HB_ET_MACRO_NOLIST ( HB_ET_MACRO_SYMBOL | HB_ET_MACRO_ALIASED | \ + HB_ET_MACRO_ASSIGN | HB_ET_MACRO_PARE | \ + HB_ET_MACRO_REFER ) +#define HB_ET_MACRO_NOPARE ( HB_ET_MACRO_SYMBOL | HB_ET_MACRO_ALIASED | \ + HB_ET_MACRO_ASSIGN | HB_ET_MACRO_REFER ) /* types of expressions * NOTE: the order of these definition is important - change it carefully diff --git a/include/hberrors.h b/include/hberrors.h index 5b7719147e..058b408fc4 100644 --- a/include/hberrors.h +++ b/include/hberrors.h @@ -127,10 +127,11 @@ HB_EXTERN_BEGIN #define HB_COMP_ERR_ENDWITH 71 #define HB_COMP_ERR_ENDSWITCH 72 #define HB_COMP_ERR_ENDSEQ 73 -#define HB_COMP_ERR_HISTORICAL_1 74 -#define HB_COMP_ERR_HISTORICAL_2 75 -#define HB_COMP_ERR_HISTORICAL_3 76 -#define HB_COMP_ERR_HISTORICAL_4 77 +#define HB_COMP_ERR_WITHOBJECT_MACROBLOCK 74 +#define HB_COMP_ERR_HISTORICAL_1 75 +#define HB_COMP_ERR_HISTORICAL_2 76 +#define HB_COMP_ERR_HISTORICAL_3 77 +#define HB_COMP_ERR_HISTORICAL_4 78 #define HB_COMP_WARN_AMBIGUOUS_VAR 1 #define HB_COMP_WARN_MEMVAR_ASSUMED 2 diff --git a/include/hbexprb.c b/include/hbexprb.c index 26417920d1..5694fad961 100644 --- a/include/hbexprb.c +++ b/include/hbexprb.c @@ -839,9 +839,12 @@ static HB_EXPR_FUNC( hb_compExprUseRef ) PHB_EXPR pExp = pSelf->value.asReference; if( pExp->ExprType == HB_ET_MACRO ) { - pExp->value.asMacro.SubType = HB_ET_MACRO_REFER; - HB_EXPR_USE( pExp, HB_EA_PUSH_PCODE ); - break; + if( pExp->value.asMacro.SubType == HB_ET_MACRO_VAR ) + { + pExp->value.asMacro.SubType |= HB_ET_MACRO_REFER; + HB_EXPR_USE( pExp, HB_EA_PUSH_PCODE ); + break; + } } else if( pExp->ExprType == HB_ET_ARRAYAT ) { @@ -1039,19 +1042,13 @@ static HB_EXPR_FUNC( hb_compExprUseList ) case HB_EA_REDUCE: pSelf = hb_compExprReduceList( pSelf, HB_COMP_PARAM ); - if( HB_SUPPORT_XBASE && pSelf->ExprType == HB_ET_LIST ) + if( HB_SUPPORT_XBASE && pSelf->ExprType == HB_ET_LIST && + hb_compExprListLen( pSelf ) == 1 ) { - if( hb_compExprListLen( pSelf ) == 1 ) - { - PHB_EXPR pExpr = pSelf->value.asList.pExprList; - if( pExpr->ExprType == HB_ET_MACRO && - pExpr->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && - pExpr->value.asMacro.SubType != HB_ET_MACRO_REFER && - pExpr->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) - { - pExpr->value.asMacro.SubType |= HB_ET_MACRO_PARE; - } - } + PHB_EXPR pExpr = pSelf->value.asList.pExprList; + if( pExpr->ExprType == HB_ET_MACRO && + ( pExpr->value.asMacro.SubType & HB_ET_MACRO_NOPARE ) == 0 ) + pExpr->value.asMacro.SubType |= HB_ET_MACRO_PARE; } if( HB_SUPPORT_HARBOUR ) pSelf = hb_compExprListStrip( pSelf, HB_COMP_PARAM ); @@ -1091,12 +1088,8 @@ static HB_EXPR_FUNC( hb_compExprUseList ) if( HB_SUPPORT_XBASE ) { if( pExpr->ExprType == HB_ET_MACRO && - pExpr->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && - pExpr->value.asMacro.SubType != HB_ET_MACRO_REFER && - pExpr->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) - { + ( pExpr->value.asMacro.SubType & HB_ET_MACRO_NOPARE ) == 0 ) pExpr->value.asMacro.SubType |= HB_ET_MACRO_PARE; - } } if( pExpr->pNext ) @@ -1122,12 +1115,8 @@ static HB_EXPR_FUNC( hb_compExprUseList ) if( HB_SUPPORT_XBASE ) { if( pExpr->ExprType == HB_ET_MACRO && - pExpr->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && - pExpr->value.asMacro.SubType != HB_ET_MACRO_REFER && - pExpr->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) - { + ( pExpr->value.asMacro.SubType & HB_ET_MACRO_NOPARE ) == 0 ) pExpr->value.asMacro.SubType |= HB_ET_MACRO_PARE; - } } HB_EXPR_USE( pExpr, HB_EA_PUSH_POP ); @@ -1401,10 +1390,7 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) { if( HB_SUPPORT_XBASE ) { - if( pSelf->value.asList.pIndex->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && - pSelf->value.asList.pIndex->value.asMacro.SubType != HB_ET_MACRO_REFER && - pSelf->value.asList.pIndex->value.asMacro.SubType != HB_ET_MACRO_ALIASED && - ( pSelf->value.asList.pIndex->value.asMacro.SubType & HB_ET_MACRO_PARE ) == 0 ) + if( ( pSelf->value.asList.pIndex->value.asMacro.SubType & HB_ET_MACRO_NOLIST ) == 0 ) { pSelf->value.asList.pIndex->value.asMacro.SubType |= HB_ET_MACRO_LIST; fMacroIndex = HB_TRUE; @@ -1456,9 +1442,9 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) else if( pList->ExprType == HB_ET_MACRO && pList->value.asMacro.SubType == HB_ET_MACRO_VAR ) { - pList->value.asMacro.SubType = HB_ET_MACRO_REFER; + pList->value.asMacro.SubType |= HB_ET_MACRO_REFER; HB_EXPR_USE( pList, HB_EA_PUSH_PCODE ); - pList->value.asMacro.SubType = HB_ET_MACRO_VAR; + pList->value.asMacro.SubType &= ~HB_ET_MACRO_REFER; } else HB_EXPR_USE( pList, HB_EA_PUSH_PCODE ); @@ -1478,14 +1464,12 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) case HB_EA_POP_PCODE: { HB_BOOL fMacroIndex = HB_FALSE; + if( pSelf->value.asList.pIndex->ExprType == HB_ET_MACRO ) { if( HB_SUPPORT_XBASE ) { - if( pSelf->value.asList.pIndex->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && - pSelf->value.asList.pIndex->value.asMacro.SubType != HB_ET_MACRO_REFER && - pSelf->value.asList.pIndex->value.asMacro.SubType != HB_ET_MACRO_ALIASED && - ( pSelf->value.asList.pIndex->value.asMacro.SubType & HB_ET_MACRO_PARE ) == 0 ) + if( ( pSelf->value.asList.pIndex->value.asMacro.SubType & HB_ET_MACRO_NOLIST ) == 0 ) { pSelf->value.asList.pIndex->value.asMacro.SubType |= HB_ET_MACRO_LIST; fMacroIndex = HB_TRUE; @@ -1539,9 +1523,9 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) else if( pList->ExprType == HB_ET_MACRO && pList->value.asMacro.SubType == HB_ET_MACRO_VAR ) { - pList->value.asMacro.SubType = HB_ET_MACRO_REFER; + pList->value.asMacro.SubType |= HB_ET_MACRO_REFER; HB_EXPR_USE( pList, HB_EA_PUSH_PCODE ); - pList->value.asMacro.SubType = HB_ET_MACRO_VAR; + pList->value.asMacro.SubType &= ~HB_ET_MACRO_REFER; } else HB_EXPR_USE( pList, HB_EA_PUSH_PCODE ); @@ -1608,9 +1592,7 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) * 'szMacro' is a variable name */ #if ! defined( HB_MACRO_SUPPORT ) - int iEarlyEvalPass = HB_COMP_PARAM->functions.pLast->iEarlyEvalPass; - HB_GEN_FUNC1( PushVar, pSelf->value.asMacro.szMacro ); - HB_COMP_PARAM->functions.pLast->iEarlyEvalPass = iEarlyEvalPass; + hb_compPushMacroVar( HB_COMP_PARAM, pSelf->value.asMacro.szMacro ); #else HB_GEN_FUNC1( PushVar, pSelf->value.asMacro.szMacro ); #endif @@ -1646,10 +1628,16 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) if( pSelf->value.asMacro.SubType == HB_ET_MACRO_SYMBOL ) HB_GEN_FUNC1( PCode1, HB_P_MACROSYMBOL ); - else if( pSelf->value.asMacro.SubType == HB_ET_MACRO_REFER ) + else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_REFER ) HB_GEN_FUNC1( PCode1, HB_P_MACROPUSHREF ); - else if( pSelf->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) + else if( pSelf->value.asMacro.SubType == HB_ET_MACRO_ALIASED ) + { + /* NOTE: pcode for alias context is generated in + * hb_compExprUseAliasVar() + */ + } + else { if( HB_SUPPORT_XBASE ) { @@ -1678,10 +1666,6 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) /* Always add byte to pcode indicating requested macro compiler flag. */ HB_GEN_FUNC1( PCode1, ( HB_BYTE ) HB_MACRO_GENFLAGS ); } - - /* NOTE: pcode for alias context is generated in - * hb_compExprUseAliasVar() - */ break; case HB_EA_POP_PCODE: @@ -1700,9 +1684,7 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) * 'szMacro' is a variable name */ #if ! defined( HB_MACRO_SUPPORT ) - int iEarlyEvalPass = HB_COMP_PARAM->functions.pLast->iEarlyEvalPass; - HB_GEN_FUNC1( PushVar, pSelf->value.asMacro.szMacro ); - HB_COMP_PARAM->functions.pLast->iEarlyEvalPass = iEarlyEvalPass; + hb_compPushMacroVar( HB_COMP_PARAM, pSelf->value.asMacro.szMacro ); #else HB_GEN_FUNC1( PushVar, pSelf->value.asMacro.szMacro ); #endif @@ -4547,9 +4529,7 @@ static HB_BOOL hb_compExprCodeblockPush( PHB_EXPR pSelf, int iEarlyEvalPass, HB_ while( pExpr ) { if( pExpr->ExprType == HB_ET_MACRO && - pExpr->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && - pExpr->value.asMacro.SubType != HB_ET_MACRO_REFER && - pExpr->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) + ( pExpr->value.asMacro.SubType & HB_ET_MACRO_NOPARE ) == 0 ) { /* Clipper allows for list expressions in a codeblock * macro := "1,2" @@ -4643,11 +4623,18 @@ static void hb_compExprCodeblockEarly( PHB_EXPR pSelf, HB_COMP_DECL ) } else { - /* everything else is macro compiled at runtime - * {|| &variable+1} => &( '{|| &variable+1}' ) + /* generate code to check if macroexpression refers to local, static + * or field variables and generate error in such case or disable + * iEarlyEvalPass when -kd (MACRODECL) switch is used. + * In the 2nd case hb_compExprCodeblockPush() returns true and generated + * code is accepted otherwise discarded and we have to generate macro + * codeblock compiled at runtime. */ if( ! hb_compExprCodeblockPush( pSelf, 1, HB_COMP_PARAM ) ) { + /* -kd is not necessary, everything else is macro compiled at runtime + * {|| &variable+1} => &( '{|| &variable+1}' ) + */ HB_BOOL fMacroText = ( HB_COMP_PARAM->supported & HB_COMPFLAG_MACROTEXT ) != 0; HB_COMP_PARAM->supported |= HB_COMPFLAG_MACROTEXT; HB_COMP_PARAM->functions.pLast->iEarlyEvalPass = 2; @@ -4890,7 +4877,7 @@ static void hb_compExprPushOperEq( PHB_EXPR pSelf, HB_BYTE bOpEq, HB_COMP_DECL ) if( usType == HB_ET_MACRO_VAR ) { /* NOTE: direct type change */ - pSelf->value.asOperator.pLeft->value.asMacro.SubType = HB_ET_MACRO_REFER; + pSelf->value.asOperator.pLeft->value.asMacro.SubType |= HB_ET_MACRO_REFER; HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); HB_GEN_FUNC1( PCode1, bNewOp ); @@ -5041,7 +5028,7 @@ static void hb_compExprUseOperEq( PHB_EXPR pSelf, HB_BYTE bOpEq, HB_COMP_DECL ) if( usType == HB_ET_MACRO_VAR ) { /* NOTE: direct type change */ - pSelf->value.asOperator.pLeft->value.asMacro.SubType = HB_ET_MACRO_REFER; + pSelf->value.asOperator.pLeft->value.asMacro.SubType |= HB_ET_MACRO_REFER; HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE ); HB_GEN_FUNC1( PCode1, bNewOp ); @@ -5155,7 +5142,7 @@ static void hb_compExprPushPreOp( PHB_EXPR pSelf, HB_BYTE bOper, HB_COMP_DECL ) { HB_USHORT usType = pSelf->value.asOperator.pLeft->value.asMacro.SubType; /* NOTE: direct type change */ - pSelf->value.asOperator.pLeft->value.asMacro.SubType = HB_ET_MACRO_REFER; + pSelf->value.asOperator.pLeft->value.asMacro.SubType |= HB_ET_MACRO_REFER; HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); pSelf->value.asOperator.pLeft->value.asMacro.SubType = usType; @@ -5262,7 +5249,7 @@ static void hb_compExprPushPostOp( PHB_EXPR pSelf, HB_BYTE bOper, HB_COMP_DECL ) { HB_USHORT usType = pSelf->value.asOperator.pLeft->value.asMacro.SubType; /* NOTE: direct type change */ - pSelf->value.asOperator.pLeft->value.asMacro.SubType = HB_ET_MACRO_REFER; + pSelf->value.asOperator.pLeft->value.asMacro.SubType |= HB_ET_MACRO_REFER; HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); pSelf->value.asOperator.pLeft->value.asMacro.SubType = usType; @@ -5371,7 +5358,7 @@ static void hb_compExprUsePreOp( PHB_EXPR pSelf, HB_BYTE bOper, HB_COMP_DECL ) { HB_USHORT usType = pSelf->value.asOperator.pLeft->value.asMacro.SubType; /* NOTE: direct type change */ - pSelf->value.asOperator.pLeft->value.asMacro.SubType = HB_ET_MACRO_REFER; + pSelf->value.asOperator.pLeft->value.asMacro.SubType |= HB_ET_MACRO_REFER; HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE ); pSelf->value.asOperator.pLeft->value.asMacro.SubType = usType; @@ -5454,10 +5441,6 @@ static void hb_compExprUseAliasMacro( PHB_EXPR pAliasedVar, HB_BYTE bAction, HB_ */ HB_GEN_FUNC2( PushString, pAlias->value.asSymbol.name, strlen( pAlias->value.asSymbol.name ) + 1 ); HB_EXPR_USE( pVar, HB_EA_PUSH_PCODE ); - if( bAction == HB_EA_PUSH_PCODE ) - HB_GEN_FUNC1( PCode1, HB_P_MACROPUSHALIASED ); - else - HB_GEN_FUNC1( PCode1, HB_P_MACROPOPALIASED ); } else if( pVar->ExprType == HB_ET_VARIABLE ) { @@ -5466,21 +5449,18 @@ static void hb_compExprUseAliasMacro( PHB_EXPR pAliasedVar, HB_BYTE bAction, HB_ */ HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE ); HB_GEN_FUNC2( PushString, pVar->value.asSymbol.name, strlen( pVar->value.asSymbol.name ) + 1 ); - if( bAction == HB_EA_PUSH_PCODE ) - HB_GEN_FUNC1( PCode1, HB_P_MACROPUSHALIASED ); - else - HB_GEN_FUNC1( PCode1, HB_P_MACROPOPALIASED ); } else { HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE ); HB_EXPR_USE( pVar, HB_EA_PUSH_PCODE ); - if( bAction == HB_EA_PUSH_PCODE ) - HB_GEN_FUNC1( PCode1, HB_P_MACROPUSHALIASED ); - else - HB_GEN_FUNC1( PCode1, HB_P_MACROPOPALIASED ); } + if( bAction == HB_EA_PUSH_PCODE ) + HB_GEN_FUNC1( PCode1, HB_P_MACROPUSHALIASED ); + else + HB_GEN_FUNC1( PCode1, HB_P_MACROPOPALIASED ); + /* Always add byte to pcode indicating requested macro compiler flag. */ HB_GEN_FUNC1( PCode1, ( HB_BYTE ) HB_MACRO_GENFLAGS ); } diff --git a/src/common/expropt1.c b/src/common/expropt1.c index aaf28ab3a0..2850e4666d 100644 --- a/src/common/expropt1.c +++ b/src/common/expropt1.c @@ -1366,12 +1366,8 @@ HB_SIZE hb_compExprParamListCheck( HB_COMP_DECL, PHB_EXPR pExpr ) while( pElem ) { if( ( pElem->ExprType == HB_ET_MACRO && HB_SUPPORT_XBASE && - pElem->value.asMacro.SubType != HB_ET_MACRO_SYMBOL && - pElem->value.asMacro.SubType != HB_ET_MACRO_REFER && - pElem->value.asMacro.SubType != HB_ET_MACRO_ALIASED && - ( pElem->value.asMacro.SubType & HB_ET_MACRO_PARE ) == 0 ) || - ( pElem->ExprType == HB_ET_ARGLIST && - pElem->value.asList.reference ) || + ( pElem->value.asMacro.SubType & HB_ET_MACRO_NOLIST ) == 0 ) || + ( pElem->ExprType == HB_ET_ARGLIST && pElem->value.asList.reference ) || hb_compExprIsArrayToParams( pElem ) ) { /* ¯o was passed diff --git a/src/compiler/hbgenerr.c b/src/compiler/hbgenerr.c index 9ec4daa9c7..a71aae096a 100644 --- a/src/compiler/hbgenerr.c +++ b/src/compiler/hbgenerr.c @@ -98,6 +98,7 @@ const char * const hb_comp_szErrors[] = "ENDWITH does not match WITH OBJECT", "ENDSWITCH does not match SWITCH", "END SEQUENCE does not match BEGIN SEQUENCE", + "Code block contains both macro and with object messages ':%s'", /* Some historical, funny sounding error messages from original CA-Cl*pper. They serve no purpose whatsoever. [vszakats] */ "END wreaks terrible vengeance on control stack", @@ -246,11 +247,19 @@ PHB_EXPR hb_compWarnMeaningless( HB_COMP_DECL, PHB_EXPR pExpr ) return pExpr; } -void hb_compErrorCodeblock( HB_COMP_DECL, const char * szBlock ) +void hb_compErrorCodeblockDecl( HB_COMP_DECL, const char * szVarName ) { HB_BOOL fError = HB_COMP_PARAM->fError; - hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BLOCK, szBlock, NULL ); + hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BLOCK, szVarName, NULL ); + HB_COMP_PARAM->fError = fError; /* restore error flag for this line */ +} + +void hb_compErrorCodeblockWith( HB_COMP_DECL, const char * szMessage ) +{ + HB_BOOL fError = HB_COMP_PARAM->fError; + + hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_WITHOBJECT_MACROBLOCK, szMessage, NULL ); HB_COMP_PARAM->fError = fError; /* restore error flag for this line */ } diff --git a/src/compiler/hbmain.c b/src/compiler/hbmain.c index 1b750cddf7..40dae8031d 100644 --- a/src/compiler/hbmain.c +++ b/src/compiler/hbmain.c @@ -904,6 +904,17 @@ static int hb_compVariableScope( HB_COMP_DECL, const char * szVarName ) return iScope; } +void hb_compPushMacroVar( HB_COMP_DECL, const char * szVarName ) +{ + /* save and restore iEarlyEvalPass to not disable early + evaluation when only macrovar and/or macrotex is used */ + int iEarlyEvalPass = HB_COMP_PARAM->functions.pLast->iEarlyEvalPass; + + hb_compGenPushVar( szVarName, HB_COMP_PARAM ); + + HB_COMP_PARAM->functions.pLast->iEarlyEvalPass = iEarlyEvalPass; +} + void hb_compPushMacroText( HB_COMP_DECL, const char * szText, HB_SIZE nLen, HB_BOOL fMacro ) { int iEarlyEvalPass = HB_COMP_PARAM->functions.pLast->iEarlyEvalPass; @@ -2626,6 +2637,14 @@ void hb_compGenMessage( const char * szMsgName, HB_BOOL bIsObject, HB_COMP_DECL wSym = 0xFFFF; hb_compGenPCode3( HB_P_WITHOBJECTMESSAGE, HB_LOBYTE( wSym ), HB_HIBYTE( wSym ), HB_COMP_PARAM ); } + + if( ! bIsObject && HB_COMP_PARAM->functions.pLast->iEarlyEvalPass == 1 ) + { + if( HB_SUPPORT_MACRODECL ) + HB_COMP_PARAM->functions.pLast->iEarlyEvalPass = 0; + else + hb_compErrorCodeblockWith( HB_COMP_PARAM, szMsgName ? szMsgName : "&..." ); + } } void hb_compGenMessageData( const char * szMsg, HB_BOOL bIsObject, HB_COMP_DECL ) /* generates an underscore-symbol name for a data assignment */ @@ -2659,7 +2678,7 @@ static void hb_compCheckEarlyMacroEval( HB_COMP_DECL, const char * szVarName, in HB_SUPPORT_MACRODECL ) HB_COMP_PARAM->functions.pLast->iEarlyEvalPass = 0; else - hb_compErrorCodeblock( HB_COMP_PARAM, szVarName ); + hb_compErrorCodeblockDecl( HB_COMP_PARAM, szVarName ); } } diff --git a/src/rtl/errsys.prg b/src/rtl/errsys.prg index 1216cf6e4e..20830dd480 100644 --- a/src/rtl/errsys.prg +++ b/src/rtl/errsys.prg @@ -68,7 +68,7 @@ STATIC FUNCTION DefError( oError ) RETURN 0 ENDIF - // By default, retry on RDD lock error failure */ + // By default, retry on RDD lock error failure IF oError:genCode == EG_LOCK .AND. ; oError:canRetry // oError:tries++ diff --git a/src/vm/garbage.c b/src/vm/garbage.c index c00ef6dd16..2dde1f3fd5 100644 --- a/src/vm/garbage.c +++ b/src/vm/garbage.c @@ -153,7 +153,7 @@ static PHB_GARBAGE s_pLockedBlock = NULL; static PHB_GARBAGE s_pDeletedBlock = NULL; /* marks if block releasing is requested during garbage collecting */ -static HB_BOOL s_bCollecting = HB_FALSE; +static HB_BOOL volatile s_bCollecting = HB_FALSE; /* flag for used/unused blocks - the meaning of the HB_GC_USED_FLAG bit * is reversed on every collecting attempt @@ -779,7 +779,7 @@ HB_FUNC( HB_GCALL ) */ hb_ret(); - hb_gcCollectAll( hb_pcount() < 1 || hb_parl( 1 ) ); + hb_gcCollectAll( hb_parldef( 1, 1 ) ); } #ifdef HB_GC_AUTO diff --git a/src/vm/hvm.c b/src/vm/hvm.c index d53895e7d2..2afa57ca7f 100644 --- a/src/vm/hvm.c +++ b/src/vm/hvm.c @@ -889,7 +889,6 @@ void hb_vmThreadInit( void * Cargo ) if( pState->pSet ) { - /* TODO: add set sharing */ memcpy( hb_stackSetStruct(), pState->pSet, sizeof( HB_SET_STRUCT ) ); hb_xfree( pState->pSet ); pState->pSet = NULL; @@ -9021,11 +9020,26 @@ HB_BOOL hb_vmRequestReenterExt( void ) if( hb_stackId() == NULL ) { uiAction = HB_VMSTACK_REQUESTED; - /* TODO: add protection against executing hb_threadStateNew() - * during GC pass - */ + + /* protection against executing hb_threadStateNew() during GC pass */ + HB_VM_LOCK(); + for( ;; ) + { + if( hb_vmThreadRequest & HB_THREQUEST_STOP ) + hb_threadCondWait( &s_vmCond, &s_vmMtx ); + else + break; + } + s_iRunningCount++; + HB_VM_UNLOCK(); + hb_vmThreadInit( NULL ); HB_STACK_TLS_RELOAD + + HB_VM_LOCK(); + s_iRunningCount--; + hb_threadCondBroadcast( &s_vmCond ); + HB_VM_UNLOCK(); } else { diff --git a/utils/hbtest/rt_math.prg b/utils/hbtest/rt_math.prg index 385552d972..49d809fc20 100644 --- a/utils/hbtest/rt_math.prg +++ b/utils/hbtest/rt_math.prg @@ -54,7 +54,7 @@ PROCEDURE Main_MATH() LOCAL l, s, o MEMVAR s0, s1, v2 - PRIVATE s0 := "V2", s1 := "V", v2 + PRIVATE s0, s1, v2 /* Log() */ @@ -454,32 +454,53 @@ PROCEDURE Main_MATH() #ifdef __HARBOUR__ + #pragma -kd+ + o := ErrorNew() s := "oscode" + s1 := "co" o:&s := 1 + HBTEST o:&s IS 1 HBTEST o:&(s) IS 1 o:&s++ HBTEST o:&(s) IS 2 HBTEST o:&(s)++ IS 2 + HBTEST o:&s++ IS 3 ++o:&s - HBTEST o:&(s) IS 4 - HBTEST ++o:&(s) IS 5 + HBTEST o:&(s) IS 5 + HBTEST ++o:&(s) IS 6 + HBTEST ++o:&s IS 7 o:&s += 10 - HBTEST o:&(s) IS 15 - HBTEST o:&(s) += 200 IS 215 + HBTEST o:&(s) IS 17 + HBTEST o:&(s) += 200 IS 217 + HBTEST o:&s += 100 IS 317 + o:os&s1.de *= 3 + HBTEST o:os&s1.de IS 951 + HBTEST o:os&s1.de += 49 IS 1000 + HBTEST --o:os&s1.de IS 999 + HBTEST ++o:os&s1.de IS 1000 WITH OBJECT ErrorNew() - :&(s) := 1 + :&s := 1 + HBTEST :&s IS 1 HBTEST :&(s) IS 1 - :&(s)++ + :&s++ HBTEST :&(s) IS 2 HBTEST :&(s)++ IS 2 + HBTEST :&s++ IS 3 ++:&(s) - HBTEST :&(s) IS 4 - HBTEST ++:&(s) IS 5 + HBTEST :&(s) IS 5 + HBTEST ++:&(s) IS 6 + HBTEST ++:&s IS 7 :&(s) += 10 - HBTEST :&(s) IS 15 - HBTEST :&(s) += 200 IS 215 + HBTEST :&(s) IS 17 + HBTEST :&(s) += 200 IS 217 + HBTEST :&s += 100 IS 317 + :os&s1.de *= 3 + HBTEST :os&s1.de IS 951 + HBTEST :os&s1.de += 49 IS 1000 + HBTEST --:os&s1.de IS 999 + HBTEST ++:os&s1.de IS 1000 ENDWITH WITH OBJECT ErrorNew() @@ -488,25 +509,38 @@ PROCEDURE Main_MATH() :oscode++ HBTEST :oscode IS 2 HBTEST :oscode++ IS 2 + HBTEST :oscode++ IS 3 ++:oscode - HBTEST :oscode IS 4 - HBTEST ++:oscode IS 5 + HBTEST :oscode IS 5 + HBTEST ++:oscode IS 6 + HBTEST ++:oscode IS 7 :oscode += 10 - HBTEST :oscode IS 15 - HBTEST :oscode += 200 IS 215 + HBTEST :oscode IS 17 + HBTEST :oscode += 200 IS 217 + HBTEST :oscode += 100 IS 317 + :oscode *= 3 + HBTEST :oscode IS 951 + HBTEST :oscode += 49 IS 1000 + HBTEST --:oscode IS 999 + HBTEST ++:oscode IS 1000 ENDWITH + s0 := "V2" + s1 := "V" &s0 := 1 HBTEST &s0 IS 1 &s0++ HBTEST &s0 IS 2 HBTEST &(s0)++ IS 2 + HBTEST &s0++ IS 3 ++&s0 - HBTEST &s0 IS 4 - HBTEST ++&(s0) IS 5 + HBTEST &s0 IS 5 + HBTEST ++&(s0) IS 6 + HBTEST ++&s0 IS 7 &s0 += 10 - HBTEST &s0 IS 15 - HBTEST &(s0) += 200 IS 215 + HBTEST &s0 IS 17 + HBTEST &(s0) += 200 IS 217 + HBTEST &s0 += 100 IS 317 &s1.2 := 1 HBTEST &s1.2 IS 1