From eec39ac3d97874824c4e1aa43ff90bdd3043855e Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Sun, 6 Feb 2000 15:01:10 +0000 Subject: [PATCH] ChangeLog 20000206-16:15 GMT+1 --- harbour/ChangeLog | 17 ++++++++++++++++ harbour/doc/compiler.txt | 33 +++++++++++++++++++++++++++++++ harbour/source/compiler/harbour.c | 8 +++----- harbour/source/compiler/harbour.y | 14 +++++++------ harbour/source/vm/hvm.c | 18 ++++++----------- 5 files changed, 67 insertions(+), 23 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 2af3a2fb95..c2a0c3232d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,20 @@ +20000206-16:15 GMT+1 Ryszard Glab + + *source/vm/hvm.c + * fixed GPF/code dump during creation of a codeblock if used + for static variable initialization + + *source/compiler/harbour.y + * fixed generation of line number opcodes + + *source/compiler/harbour.c + * fixed 'unused variable' warnings generated by Borland compiler + + *doc/compiler.txt + * added note about incompatibility with Clipper in handling of + local variables during static variable initialization + + 20000206-10:12 GMT+1 Antonio Linares * source/debug/debugger.prg * Mouse support to select pulldown top items (just that for now) diff --git a/harbour/doc/compiler.txt b/harbour/doc/compiler.txt index 377bb9ec16..c6f0f78ba8 100644 --- a/harbour/doc/compiler.txt +++ b/harbour/doc/compiler.txt @@ -238,3 +238,36 @@ COUNT() function will be called only once, before addition. be changed (See also: source/compiler/expropt.c) + +Initialization of static variables +---------------------------------- + +There is a difference in handling of initialization of static variables that +are initialized with a codeblock that refers to a local variarble. +For example: + +PROCEDURE TEST() +LOCAL MyLocalVar +STATIC MyStaticVar := {|| MyLocalVar} + + MyLocalVar :=0 + ? EVAL( MyStaticVar ) + +RETURN + +The above code compiles fine in Clipper however it generates a runtime error +Error/BASE 1132 Bound error: array access +Called form (b)STATICS$(0) + +In Harbour this code generates a compile time error: +Error E0009 Illegal variable (b) initializer: 'MyLocalVar' + +Both Clipper and Harbour are handing all local variables used in a codeblock +in a special way: they are detached from the local stack of function/procedure +where they are declared. This allows to access these variables after the exit +from a function/procedure. However all static variables are initialized +in a separate procedure ('STATICS$' in Clipper and '(_INITSTATICS)' in Harbour) +before the main procedure and before all INIT procedures. The local variables +don't exist on the eval stack when static variables are initialized then +they cannot be detached. + diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index a9b087fb8f..edbed219b0 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -941,7 +941,7 @@ static int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a /* we are in a function/procedure -we don't need any tricks */ if( pFunc->pOwner ) pFunc =pFunc->pOwner; - return hb_compVariableGetPos( pFunc->pLocals, szVarName ); + iVar = hb_compVariableGetPos( pFunc->pLocals, szVarName ); } else { @@ -1884,12 +1884,10 @@ void hb_compGenPushString( char * szText, ULONG ulStrLen ) void hb_compGenPushSymbol( char * szSymbolName, int iIsFunction ) { USHORT wSym; - PCOMSYMBOL pSym; - pSym = hb_compSymbolFind( szSymbolName, &wSym ); - if( ! pSym ) /* the symbol was not found on the symbol table */ + if( ! hb_compSymbolFind( szSymbolName, &wSym ) ) /* the symbol was not found on the symbol table */ { - pSym = hb_compSymbolAdd( szSymbolName, &wSym ); + hb_compSymbolAdd( szSymbolName, &wSym ); if( iIsFunction ) hb_compFunCallAdd( szSymbolName ); } diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index f956e78e7c..ca09ff6a6d 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -308,7 +308,7 @@ Statement : ExecFlow CrlfStmnt { } | DoProc CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); } | BREAK CrlfStmnt { hb_compGenBreak(); hb_compGenPCode3( HB_P_DO, 0, 0 ); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } - | BREAK Expression CrlfStmnt { hb_compGenBreak(); hb_compExprDelete( hb_compExprGenPush( $2 ) ); + | BREAK { hb_compLinePushIfInside(); } Expression Crlf { hb_compGenBreak(); hb_compExprDelete( hb_compExprGenPush( $3 ) ); hb_compGenPCode3( HB_P_DO, 1, 0 ); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } @@ -326,12 +326,12 @@ Statement : ExecFlow CrlfStmnt { } hb_comp_bDontGenLineNum = TRUE; hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } - | RETURN Expression CrlfStmnt { + | RETURN { hb_compLinePushIfInside(); } Expression Crlf { if( hb_comp_wSeqCounter ) { hb_compGenError( hb_comp_szErrors, 'E', ERR_EXIT_IN_SEQUENCE, "RETURN", NULL ); } - hb_compExprGenPush( $2 ); /* TODO: check if return value agree with declared value */ + hb_compExprGenPush( $3 ); /* TODO: check if return value agree with declared value */ hb_compGenPCode1( HB_P_RETVALUE ); hb_compGenPCode1( HB_P_ENDPROC ); if( hb_comp_functions.pLast->bFlags & FUN_PROCEDURE ) @@ -342,9 +342,11 @@ Statement : ExecFlow CrlfStmnt { } hb_comp_bDontGenLineNum = TRUE; hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } - | PUBLIC { hb_comp_iVarScope = VS_PUBLIC; } ExtVarList + | PUBLIC { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PUBLIC; } + ExtVarList { hb_compRTVariableGen( "__MVPUBLIC" ); } CrlfStmnt - | PRIVATE { hb_comp_iVarScope = VS_PRIVATE; } ExtVarList + | PRIVATE { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PRIVATE; } + ExtVarList { hb_compRTVariableGen( "__MVPRIVATE" ); } CrlfStmnt | EXITLOOP CrlfStmnt { hb_compLoopExit(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; } @@ -1259,7 +1261,7 @@ DoWhile : WhileBegin Expression Crlf } ; -WhileBegin : WHILE { $$ = hb_comp_functions.pLast->lPCodePos; ++hb_comp_wWhileCounter; hb_compLoopStart(); } +WhileBegin : WHILE { $$ = hb_comp_functions.pLast->lPCodePos; hb_compLinePushIfInside(); ++hb_comp_wWhileCounter; hb_compLoopStart(); } ; EndWhile : END diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 13bc9fa367..664481a058 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -343,14 +343,14 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) HB_TRACE(HB_TR_DEBUG, ("hb_vmExecute(%p, %p)", pCode, pSymbols)); - /* NOTE: if pSymbols == NULL then hb_vmExecute is called from macro + /* NOTE: if pSymbols == NULL then hb_vmExecute is called from macro * evaluation. In this case all PRIVATE variables created during * macro evaluation belong to a function/procedure where macro * compiler was called. */ if( pSymbols ) ulPrivateBase = hb_memvarGetPrivatesBase(); - + while( ( bCode = pCode[ w ] ) != HB_P_ENDPROC ) { switch( bCode ) @@ -3644,15 +3644,9 @@ static void hb_vmDoInitStatics( void ) if( scope == ( FS_INIT | FS_EXIT ) ) { - /* _INITSTATICS procedure cannot call any function and it - * cannot use any local variable then it is safe to call - * this procedure directly - * hb_vmPushSymbol( pLastSymbols->pModuleSymbols + ui ); - * hb_vmPushNil(); - * hb_vmDo( 0 ); - */ - if( ( pLastSymbols->pModuleSymbols + ui )->pFunPtr ) - ( pLastSymbols->pModuleSymbols + ui )->pFunPtr(); + hb_vmPushSymbol( pLastSymbols->pModuleSymbols + ui ); + hb_vmPushNil(); + hb_vmDo( 0 ); } } } @@ -3840,4 +3834,4 @@ HARBOUR HB___VMVARSGET( void ) { hb_itemReturn( s_aStatics.item.asArray.value->pItems + hb_stack.iStatics + hb_parni( 1 ) - 1 ); -} \ No newline at end of file +}