diff --git a/harbour/ChangeLog b/harbour/ChangeLog index ca7aa15db2..66d5486e63 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,27 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-07-09 14:40 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbexpra.c + % reduce macro expressions used in POP operation. + It allows to use code like: &("((M->VAR))") := 1 + + * harbour/include/hbexprb.c + + added support for iif() used in macro expressions passed by references: + proc MAIN() + local s := "IIF( lVar, xVar1, xVar2 )" + M->xVar1 := 1 + M->xVar2 := 2 + M->lVar := .T. + ? M->xVar1, M->xVar2 + P( @&s ) + ? M->xVar1, M->xVar2 + proc P(x) + x+=1000 + + * harbour/source/vm/hvm.c + ! fixed possible assign value lost in extended references + 2009-07-08 16:58 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * harbour/contrib/hbxbp/xbpbitmap.prg + Implemented XbpBitmap() class - mostly working. diff --git a/harbour/include/hbexpra.c b/harbour/include/hbexpra.c index 844b8e19d8..1823aa880a 100644 --- a/harbour/include/hbexpra.c +++ b/harbour/include/hbexpra.c @@ -708,6 +708,7 @@ HB_EXPR_PTR hb_macroExprGenPop( HB_EXPR_PTR pExpr, HB_COMP_DECL ) { HB_TRACE(HB_TR_DEBUG, ("hb_macroExprGenPop(%i)", pExpr->ExprType)); + pExpr = HB_EXPR_USE( pExpr, HB_EA_REDUCE ); HB_EXPR_USE( pExpr, HB_EA_LVALUE ); return HB_EXPR_USE( pExpr, HB_EA_POP_PCODE ); } diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index aa0dbac406..3b509a2893 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -802,6 +802,17 @@ static HB_EXPR_FUNC( hb_compExprUseRef ) { case HB_EA_REDUCE: pSelf->value.asReference = HB_EXPR_USE( pSelf->value.asReference, HB_EA_REDUCE ); + if( pSelf->value.asReference->ExprType == HB_ET_IIF ) + { + HB_EXPR_PTR pCond, pIIF, pFalse; + pIIF = pSelf->value.asReference; + pCond = pIIF->value.asList.pExprList; + pFalse = hb_compExprNewRef( pCond->pNext->pNext, HB_COMP_PARAM ); + pCond->pNext = hb_compExprNewRef( pCond->pNext, HB_COMP_PARAM ); + pCond->pNext->pNext = pFalse; + memcpy( pSelf, pIIF, sizeof( HB_EXPR ) ); + HB_COMP_EXPR_CLEAR( pIIF ); + } break; case HB_EA_ARRAY_AT: HB_COMP_ERROR_TYPE( pSelf ); @@ -852,6 +863,12 @@ static HB_EXPR_FUNC( hb_compExprUseRef ) break; } } + else if( pExp->ExprType == HB_ET_VARREF || + pExp->ExprType == HB_ET_REFERENCE ) + { + HB_EXPR_USE( pExp, HB_EA_PUSH_PCODE ); + break; + } hb_compErrorRefer( HB_COMP_PARAM, NULL, hb_compExprDescription( pExp ) ); break; diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index a84b410ad7..3cb44ae9dc 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -6929,10 +6929,11 @@ static void hb_vmPushLocal( int iLocal ) static void hb_vmPushLocalByRef( int iLocal ) { HB_STACK_TLS_PRELOAD - HB_ITEM_PTR pTop = hb_stackAllocItem(); + HB_ITEM_PTR pTop; HB_TRACE(HB_TR_DEBUG, ("hb_vmPushLocalByRef(%d)", iLocal)); + pTop = hb_stackAllocItem(); /* we store its stack offset instead of a pointer to support a dynamic stack */ if( iLocal >= 0 ) { @@ -6977,11 +6978,18 @@ static void hb_vmPushStaticByRef( USHORT uiStatic ) HB_TRACE(HB_TR_DEBUG, ("hb_vmPushStaticByRef(%hu)", uiStatic)); pTop = hb_stackAllocItem(); + pBase = ( PHB_ITEM ) hb_stackGetStaticsBase(); + + if( HB_IS_BYREF( pBase->item.asArray.value->pItems + uiStatic - 1 ) && + !HB_IS_ENUM( pBase->item.asArray.value->pItems + uiStatic - 1 ) ) + { + hb_itemCopy( pTop, pBase->item.asArray.value->pItems + uiStatic - 1 ); + return; + } pTop->type = HB_IT_BYREF; /* we store the offset instead of a pointer to support a dynamic stack */ pTop->item.asRefer.value = uiStatic - 1; pTop->item.asRefer.offset = 0; /* 0 for static variables */ - pBase = ( PHB_ITEM ) hb_stackGetStaticsBase(); pTop->item.asRefer.BasePtr.array = pBase->item.asArray.value; hb_gcRefInc( pBase->item.asArray.value ); } @@ -8054,11 +8062,21 @@ static PHB_ITEM hb_vmMsgRefRead( PHB_ITEM pRefer ) HB_STACK_TLS_PRELOAD hb_stackPushReturn(); - if( !pMsgRef->access ) - pMsgRef->access = hb_dynsymGetCase( pMsgRef->assign->pSymbol->szName + 1 ); - hb_vmPushDynSym( pMsgRef->access ); - hb_vmPush( &pMsgRef->object ); - hb_vmSend( 0 ); + if( ( pMsgRef->value.type & HB_IT_DEFAULT ) == 0 ) + { + hb_vmPushDynSym( pMsgRef->assign ); + hb_vmPush( &pMsgRef->object ); + hb_vmPush( &pMsgRef->value ); + hb_vmSend( 1 ); + } + else + { + if( !pMsgRef->access ) + pMsgRef->access = hb_dynsymGetCase( pMsgRef->assign->pSymbol->szName + 1 ); + hb_vmPushDynSym( pMsgRef->access ); + hb_vmPush( &pMsgRef->object ); + hb_vmSend( 0 ); + } hb_itemMove( &pMsgRef->value, hb_stackReturnItem() ); pMsgRef->value.type |= HB_IT_DEFAULT; hb_stackPopReturn(); @@ -8088,28 +8106,46 @@ static PHB_ITEM hb_vmMsgRefWrite( PHB_ITEM pRefer, PHB_ITEM pSource ) static void hb_vmMsgRefCopy( PHB_ITEM pDest ) { - hb_xRefInc( pDest->item.asExtRef.value ); + PHB_MSGREF pMsgRef = ( PHB_MSGREF ) pDest->item.asExtRef.value; + + hb_xRefInc( pMsgRef ); + + if( ( pMsgRef->value.type & HB_IT_DEFAULT ) == 0 ) + { + if( hb_vmRequestReenter() ) + { + hb_vmPushDynSym( pMsgRef->assign ); + hb_vmPush( &pMsgRef->object ); + hb_vmPush( &pMsgRef->value ); + hb_vmSend( 1 ); + hb_vmRequestRestore(); + pMsgRef->value.type |= HB_IT_DEFAULT; + } + } } static void hb_vmMsgRefClear( void * value ) { + PHB_MSGREF pMsgRef = ( PHB_MSGREF ) value; + + /* value were change by C code without calling RefWrite(), + * f.e. hb_stor*() function + */ + if( ( pMsgRef->value.type & HB_IT_DEFAULT ) == 0 ) + { + if( hb_vmRequestReenter() ) + { + hb_vmPushDynSym( pMsgRef->assign ); + hb_vmPush( &pMsgRef->object ); + hb_vmPush( &pMsgRef->value ); + hb_vmSend( 1 ); + hb_vmRequestRestore(); + pMsgRef->value.type |= HB_IT_DEFAULT; + } + } + if( hb_xRefDec( value ) ) { - PHB_MSGREF pMsgRef = ( PHB_MSGREF ) value; - /* value were change by C code without calling RefWrite(), - * f.e. hb_stor*() function - */ - if( ( pMsgRef->value.type & HB_IT_DEFAULT ) == 0 ) - { - if( hb_vmRequestReenter() ) - { - hb_vmPushDynSym( pMsgRef->assign ); - hb_vmPush( &pMsgRef->object ); - hb_vmPush( &pMsgRef->value ); - hb_vmSend( 1 ); - hb_vmRequestRestore(); - } - } if( HB_IS_COMPLEX( &pMsgRef->value ) ) hb_itemClear( &pMsgRef->value ); if( HB_IS_COMPLEX( &pMsgRef->object ) ) @@ -8183,12 +8219,17 @@ static PHB_ITEM hb_vmMsgIdxRefRead( PHB_ITEM pRefer ) if( hb_vmRequestQuery() == 0 ) { HB_STACK_TLS_PRELOAD + PHB_ITEM pObject = HB_IS_BYREF( &pMsgIdxRef->object ) ? + hb_itemUnRef( &pMsgIdxRef->object ) : + &pMsgIdxRef->object; hb_stackPushReturn(); - hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, &pMsgIdxRef->value, - HB_IS_BYREF( &pMsgIdxRef->object ) ? - hb_itemUnRef( &pMsgIdxRef->object ) : - &pMsgIdxRef->object, &pMsgIdxRef->index, NULL ); + if( ( pMsgIdxRef->value.type & HB_IT_DEFAULT ) == 0 ) + hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pObject, pObject, + &pMsgIdxRef->index, &pMsgIdxRef->value ); + else + hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, &pMsgIdxRef->value, pObject, + &pMsgIdxRef->index, NULL ); hb_stackPopReturn(); pMsgIdxRef->value.type |= HB_IT_DEFAULT; } @@ -8217,29 +8258,49 @@ static PHB_ITEM hb_vmMsgIdxRefWrite( PHB_ITEM pRefer, PHB_ITEM pSource ) static void hb_vmMsgIdxRefCopy( PHB_ITEM pDest ) { - hb_xRefInc( pDest->item.asExtRef.value ); + PHB_MSGIDXREF pMsgIdxRef = ( PHB_MSGIDXREF ) pDest->item.asExtRef.value; + + hb_xRefInc( pMsgIdxRef ); + + /* value were change by C code without calling RefWrite(), + * f.e. hb_stor*() function + */ + if( ( pMsgIdxRef->value.type & HB_IT_DEFAULT ) == 0 ) + { + if( hb_vmRequestReenter() ) + { + PHB_ITEM pObject = HB_IS_BYREF( &pMsgIdxRef->object ) ? + hb_itemUnRef( &pMsgIdxRef->object ) : + &pMsgIdxRef->object; + hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pObject, pObject, + &pMsgIdxRef->index, &pMsgIdxRef->value ); + hb_vmRequestRestore(); + } + } } static void hb_vmMsgIdxRefClear( void * value ) { + PHB_MSGIDXREF pMsgIdxRef = ( PHB_MSGIDXREF ) value; + + /* value were change by C code without calling RefWrite(), + * f.e. hb_stor*() function + */ + if( ( pMsgIdxRef->value.type & HB_IT_DEFAULT ) == 0 ) + { + if( hb_vmRequestReenter() ) + { + PHB_ITEM pObject = HB_IS_BYREF( &pMsgIdxRef->object ) ? + hb_itemUnRef( &pMsgIdxRef->object ) : + &pMsgIdxRef->object; + hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pObject, pObject, + &pMsgIdxRef->index, &pMsgIdxRef->value ); + hb_vmRequestRestore(); + } + } + if( hb_xRefDec( value ) ) { - PHB_MSGIDXREF pMsgIdxRef = ( PHB_MSGIDXREF ) value; - /* value were change by C code without calling RefWrite(), - * f.e. hb_stor*() function - */ - if( ( pMsgIdxRef->value.type & HB_IT_DEFAULT ) == 0 ) - { - if( hb_vmRequestReenter() ) - { - PHB_ITEM pObject = HB_IS_BYREF( &pMsgIdxRef->object ) ? - hb_itemUnRef( &pMsgIdxRef->object ) : - &pMsgIdxRef->object; - hb_objOperatorCall( HB_OO_OP_ARRAYINDEX, pObject, pObject, - &pMsgIdxRef->index, &pMsgIdxRef->value ); - hb_vmRequestRestore(); - } - } if( HB_IS_COMPLEX( &pMsgIdxRef->value ) ) hb_itemClear( &pMsgIdxRef->value ); if( HB_IS_COMPLEX( &pMsgIdxRef->object ) )