ChangeLog 20000206-16:15 GMT+1
This commit is contained in:
@@ -1,3 +1,20 @@
|
||||
20000206-16:15 GMT+1 Ryszard Glab <rglab@imid.med.pl>
|
||||
|
||||
*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 <alinares@fivetech.com>
|
||||
* source/debug/debugger.prg
|
||||
* Mouse support to select pulldown top items (just that for now)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user