From f420483b5f80b479f64abbaff3c3af65827fce35 Mon Sep 17 00:00:00 2001 From: Jean-Francois Lefebvre Date: Sun, 19 Aug 2001 21:24:28 +0000 Subject: [PATCH] 2001-08-19 23:30 GMT +1 JFL (mafact) --- harbour/ChangeLog | 15 +++++ harbour/include/hbapi.h | 1 - harbour/source/vm/arrays.c | 7 +++ harbour/source/vm/classes.c | 113 +++++++++++++++++++++++------------- harbour/source/vm/hvm.c | 87 ++++++++++++++++----------- 5 files changed, 149 insertions(+), 74 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index ad46fd8772..fd880636b1 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,18 @@ +2001-08-19 23:30 GMT +1 JFL (mafact) + harbour/include/hbapi.h + * changed structure of _HB_BASEARRAY (puiClsTree) + * suppressed uiClsTree not anymore needed + harbour/source/vm/arrays.c + * modified ArrayRelease() to handle the release of puiClsTree pointer + harbour/source/vm/classes.c + * Changed the way MsgSuper() return a Super Object. + Now ::Super(::nX) is allowed + ::Super:Classname() return the superClassName. + * Added some code to check or validate puiClsTree + * improved validation of scoping + harbour/source/vm/hvm.c + * Changed vmdo as vmsend to handle the new SuperObject + 2001-08-19 10:50 GMT -3 Luiz Rafael Culik *source/rdd/rddord.prg *Mapped functions to 10 character for ORDLISTCLE(),ORDLISTREB(),ORDSETFOCU() diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 39b0478371..88bae5abeb 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -238,7 +238,6 @@ typedef struct _HB_BASEARRAY USHORT uiHolders; /* number of holders of this array */ USHORT uiClass; /* offset to the classes base if it is an object */ USHORT uiPrevCls; /* for fixing after access super */ - USHORT uiClsTree; /* remember number of pushed super call */ USHORT * puiClsTree; /* remember array of super called ID Tree */ } HB_BASEARRAY, * PHB_BASEARRAY, * HB_BASEARRAY_PTR; diff --git a/harbour/source/vm/arrays.c b/harbour/source/vm/arrays.c index 6f0de213a5..6fb7c7f2a3 100644 --- a/harbour/source/vm/arrays.c +++ b/harbour/source/vm/arrays.c @@ -621,6 +621,13 @@ BOOL hb_arrayRelease( PHB_ITEM pArray ) ULONG ulLen = pBaseArray->ulLen; ULONG ulPos; + /* clear object tree as needed */ + if( pBaseArray->uiClass && pBaseArray->puiClsTree ) + { + hb_xfree(pBaseArray->puiClsTree); + pBaseArray->puiClsTree = NULL; + } + if( pBaseArray->pItems ) { for( ulPos = 0; ulPos < ulLen; ulPos++ ) diff --git a/harbour/source/vm/classes.c b/harbour/source/vm/classes.c index 8764828a97..0e55b46cb6 100644 --- a/harbour/source/vm/classes.c +++ b/harbour/source/vm/classes.c @@ -413,20 +413,20 @@ void hb_clsScope( PHB_ITEM pObject, PMETHOD pMethod ) pCaller = * (pBase+1 ) ; szCallerNameObject = hb_objGetRealClsName( pCaller, szCallerNameMsg ) ; - /*strcpy( szName, szCallerNameObject ); */ - /*strcat( szName, ":" ); */ - /*strcat( szName, szCallerNameMsg ); */ - /*strcat( szName, ">" ); */ - /*strcat( szName, szSelfNameRealClass ); */ - /*strcat( szName, ">" ); */ - /*strcat( szName, szSelfNameObject );*/ + /*strcpy( szName, szCallerNameObject ); */ + /*strcat( szName, ":" ); */ + /*strcat( szName, szCallerNameMsg ); */ + /*strcat( szName, ">" ); */ + /*strcat( szName, szSelfNameRealClass ); */ + /*strcat( szName, ">" ); */ + /*strcat( szName, szSelfNameObject ); */ + /*strcat( szName, ":" ); */ + /*strcat( szName, szSelfNameMsg ); */ strcpy( szName, szSelfNameRealClass ); strcat( szName, ":" ); strcat( szName, szSelfNameMsg ); - /*MessageBox(0,szName,hb_objGetClsName( * (pBase+1 )),0);*/ - if ( uiScope & HB_OO_CLSTP_PROTECTED ) { if( ( *( pBase+1 ) )->type == HB_IT_ARRAY ) /* is the sender an object */ @@ -627,37 +627,55 @@ char * hb_objGetRealClsName( PHB_ITEM pObject, char * szName ) { PHB_DYNS pMsg = hb_dynsymFindName( szName ); USHORT uiClass; + USHORT uiCurCls; + USHORT uiClsTree; + + uiClass = pObject->item.asArray.value->uiClass; /* default value to current class object */ - if (pObject->item.asArray.value->uiClsTree) + if (pObject->item.asArray.value->puiClsTree[0]) { - uiClass = * (pObject->item.asArray.value->puiClsTree + pObject->item.asArray.value->uiClsTree - 1 ) ; + uiClsTree = pObject->item.asArray.value->puiClsTree[0] ; + uiCurCls = pObject->item.asArray.value->puiClsTree[uiClsTree] ; } else - uiClass = pObject->item.asArray.value->uiClass; + { + uiClsTree = 1; /* Flag value */ + uiCurCls = uiClass; + } + + while (uiClsTree) + { + if( uiCurCls && uiCurCls <= s_uiClasses ) + { + PCLASS pClass = s_pClasses + ( uiCurCls - 1 ); + USHORT uiAt = ( USHORT ) ( ( ( hb_cls_MsgToNum( pMsg ) ) % pClass->uiHashKey ) * BUCKET ); + USHORT uiMask = ( USHORT ) ( pClass->uiHashKey * BUCKET ); + USHORT uiLimit = ( USHORT ) ( uiAt ? ( uiAt - 1 ) : ( uiMask - 1 ) ); + + while( uiAt != uiLimit ) + { + if( pClass->pMethods[ uiAt ].pMessage == pMsg ) + { + uiClass = (pClass->pMethods + uiAt)->uiSprClass; + uiClsTree=1; /* Flag Value */ + break; + } + uiAt++; + if( uiAt == uiMask ) + uiAt = 0; + } + } + + if (-- uiClsTree) + uiCurCls = pObject->item.asArray.value->puiClsTree[uiClsTree] ; + + } if( uiClass && uiClass <= s_uiClasses ) - { - PCLASS pClass = s_pClasses + ( uiClass - 1 ); - USHORT uiAt = ( USHORT ) ( ( ( hb_cls_MsgToNum( pMsg ) ) % pClass->uiHashKey ) * BUCKET ); - USHORT uiMask = ( USHORT ) ( pClass->uiHashKey * BUCKET ); - USHORT uiLimit = ( USHORT ) ( uiAt ? ( uiAt - 1 ) : ( uiMask - 1 ) ); - - while( uiAt != uiLimit ) - { - if( pClass->pMethods[ uiAt ].pMessage == pMsg ) - { - uiClass = (pClass->pMethods + uiAt)->uiSprClass; - break; - } - uiAt++; - if( uiAt == uiMask ) - uiAt = 0; - } - } - - szClassName = - ( s_pClasses + uiClass - 1 )->szName; + szClassName = ( s_pClasses + uiClass - 1 )->szName; + else + szClassName = "UNKNOWN"; } } @@ -1411,8 +1429,8 @@ static PHB_ITEM hb_clsInst( USHORT uiClass ) pSelf->item.asArray.value->uiClass = uiClass; pSelf->item.asArray.value->uiPrevCls = 0; - pSelf->item.asArray.value->uiClsTree = 0; - pSelf->item.asArray.value->puiClsTree = 0; + pSelf->item.asArray.value->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + pSelf->item.asArray.value->puiClsTree[0]=0; /* Initialise value if initialisation was requested */ pMeth = pClass->pMethods; @@ -1608,9 +1626,15 @@ HB_FUNC( __OBJHASMSG ) HB_FUNC( __OBJCLONE ) { PHB_ITEM pSrcObject = hb_param( 1, HB_IT_OBJECT ); + PHB_ITEM pDstObject ; if( pSrcObject ) - hb_itemRelease( hb_itemReturn( hb_arrayClone( pSrcObject, NULL ) ) ); + { + pDstObject= hb_arrayClone( pSrcObject, NULL ) ; + pDstObject->item.asArray.value->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + pDstObject->item.asArray.value->puiClsTree[0]=0; + hb_itemRelease( hb_itemReturn( pDstObject ) ); + } else hb_errRT_BASE( EG_ARG, 3001, NULL, "__OBJCLONE", 0 ); } @@ -2108,12 +2132,23 @@ static HARBOUR hb___msgEval( void ) static HARBOUR hb___msgSuper( void ) { PHB_ITEM pObject = hb_stackSelfItem(); + ULONG ulLen = pObject->item.asArray.value->ulLen; + PHB_ITEM pCopy = hb_itemArrayNew(ulLen+1); /* hb_arrayClone(pObject, NULL); */ - pObject->item.asArray.value->uiPrevCls = pObject->item.asArray.value->uiClass; /* backup of actual handel */ - pObject->item.asArray.value->uiClass = s_pMethod->uiSprClass; /* superclass handel casting */ + /* Now creating a copy wich will share all value with the original */ + for( ; ulLen > 0 ; ulLen--) + hb_itemCopy( pCopy->item.asArray.value->pItems + ulLen, pObject->item.asArray.value->pItems + ulLen ); - hb_itemReturn( pObject ); + pCopy->item.asArray.value->uiPrevCls = pObject->item.asArray.value->uiClass; /* backup of actual handel */ + pCopy->item.asArray.value->uiClass = s_pMethod->uiSprClass; /* superclass handel casting */ + pCopy->item.asArray.value->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + pCopy->item.asArray.value->puiClsTree[0] = 0 ; + + /* Now save the Self object as the last elem. */ + hb_itemArrayPut( pCopy, pCopy->item.asArray.value->ulLen , pObject ); + + hb_itemRelease(hb_itemReturn( pCopy )); } /* diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 059a1fe7f6..2d6139d69b 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -2977,8 +2977,9 @@ void hb_vmDo( USHORT uiParams ) HB_TRACE(HB_TR_DEBUG, ("hb_vmDo(%hu)", uiParams)); /* - printf( "\nItems: %i Params: %i Extra %i\n", hb_stack.pPos - hb_stack.pBase, uiParams, hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] ); + printf( "\VmDo nItems: %i Params: %i Extra %i\n", hb_stack.pPos - hb_stack.pBase, uiParams, hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] ); */ + if( hb_vm_iExtraParamsIndex && HB_IS_SYMBOL( pItem = hb_stackItemFromTop( -( uiParams + hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] + 2 ) ) ) && pItem->item.asSymbol.value == hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] ) { uiParams += hb_vm_aiExtraParams[--hb_vm_iExtraParamsIndex]; @@ -3000,6 +3001,8 @@ void hb_vmDo( USHORT uiParams ) BOOL lPopSuper = FALSE ; PHB_BASEARRAY pSelfBase = NULL; + PHB_ITEM pRealSelf=NULL; + USHORT uiClass; if( pSym == &( hb_symEval ) && HB_IS_BLOCK( pSelf ) ) pFunc = pSym->pFunPtr; /* __EVAL method = function */ @@ -3011,17 +3014,28 @@ void hb_vmDo( USHORT uiParams ) pSelfBase = pSelf->item.asArray.value; if( pSelfBase->uiPrevCls ) /* Is is a Super cast ? */ { + USHORT nPos ; + /* + printf( "\n VmDo Method: %s \n", pSym->szName ); + */ + uiClass=pSelfBase->uiClass; + /*pSelfBase->uiClass = pSelfBase->uiPrevCls;*/ + /*pSelfBase->uiPrevCls = 0 ; */ + /* take care this is a fake object */ + /* take back the real Self */ + pRealSelf = hb_arrayGetItemPtr(pSelf,pSelfBase->ulLen) ; + /* and take back the good pSelfBase */ + pSelfBase = pRealSelf->item.asArray.value; + /* Push current SuperClass handle */ lPopSuper = TRUE ; - if( pSelfBase->puiClsTree ) - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * ( pSelfBase->uiClsTree + 1 ) ); - else - pSelfBase->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - pSelfBase->uiClsTree ++ ; - pSelfBase->puiClsTree[pSelfBase->uiClsTree -1 ] = pSelfBase->uiClass; - pSelfBase->uiClass = pSelfBase->uiPrevCls; - pSelfBase->uiPrevCls = 0; + nPos=pSelfBase->puiClsTree[0]+1; + pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * ( nPos + 1 ) ); + + pSelfBase->puiClsTree[0] = nPos ; + pSelfBase->puiClsTree[ nPos ] = uiClass; + } } } @@ -3035,14 +3049,10 @@ void hb_vmDo( USHORT uiParams ) if (lPopSuper) { + USHORT nPos=pSelfBase->puiClsTree[0]-1; /* POP SuperClass handle */ - if ( -- pSelfBase->uiClsTree ) - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * ( pSelfBase->uiClsTree ) ); - else - { - hb_xfree(pSelfBase->puiClsTree); - pSelfBase->puiClsTree = 0; - } + pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * (nPos + 1) ); + pSelfBase->puiClsTree[0]=nPos; } if( bProfiler ) @@ -3119,6 +3129,10 @@ void hb_vmSend( USHORT uiParams ) HB_TRACE(HB_TR_DEBUG, ("hb_vmSend(%hu)", uiParams)); + /* + printf( "\n VmSend nItems: %i Params: %i Extra %i\n", hb_stack.pPos - hb_stack.pBase, uiParams, hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] ); + */ + if( hb_vm_iExtraParamsIndex && HB_IS_SYMBOL( pItem = hb_stackItemFromTop( -( uiParams + hb_vm_aiExtraParams[hb_vm_iExtraParamsIndex - 1] + 2 ) ) ) && pItem->item.asSymbol.value == hb_vm_apExtraParamsSymbol[hb_vm_iExtraParamsIndex - 1] ) { uiParams += hb_vm_aiExtraParams[--hb_vm_iExtraParamsIndex]; @@ -3137,7 +3151,9 @@ void hb_vmSend( USHORT uiParams ) { BOOL lPopSuper = FALSE ; - PHB_BASEARRAY pSelfBase; + PHB_BASEARRAY pSelfBase = NULL; + PHB_ITEM pRealSelf=NULL; + USHORT uiClass; if( ! ( pSym == &( hb_symEval ) && HB_IS_BLOCK( pSelf ) ) ) { @@ -3148,17 +3164,24 @@ void hb_vmSend( USHORT uiParams ) pSelfBase = pSelf->item.asArray.value; if( pSelfBase->uiPrevCls ) /* Is is a Super cast ? */ { + USHORT nPos ; + /* + printf( "\n VmSend Method: %s \n", pSym->szName ); + */ + uiClass=pSelfBase->uiClass; + /*pSelfBase->uiClass = pSelfBase->uiPrevCls;*/ + /*pSelfBase->uiPrevCls = 0 ; */ + /* take care this is a fake object */ + /* take back the real Self */ + pRealSelf = hb_arrayGetItemPtr(pSelf,pSelfBase->ulLen) ; + /* and take back the good pSelfBase */ + pSelfBase = pRealSelf->item.asArray.value; /* Push current SuperClass handle */ lPopSuper = TRUE ; - if( pSelfBase->puiClsTree ) - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * ( pSelfBase->uiClsTree + 1 ) ); - else - pSelfBase->puiClsTree = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - pSelfBase->uiClsTree ++ ; - pSelfBase->puiClsTree[pSelfBase->uiClsTree -1 ] = pSelfBase->uiClass; - - pSelfBase->uiClass = pSelfBase->uiPrevCls; - pSelfBase->uiPrevCls = 0; + nPos=pSelfBase->puiClsTree[0]+1; + pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * (nPos+1) ) ; + pSelfBase->puiClsTree[0] = nPos ; + pSelfBase->puiClsTree[ nPos ] = uiClass; } if( pFunc ) @@ -3170,14 +3193,10 @@ void hb_vmSend( USHORT uiParams ) if (lPopSuper) { - /* POP SuperClass handle */ - if ( -- pSelfBase->uiClsTree ) - pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * ( pSelfBase->uiClsTree ) ); - else - { - hb_xfree(pSelfBase->puiClsTree); - pSelfBase->puiClsTree = 0; - } + USHORT nPos=pSelfBase->puiClsTree[0]-1; + /* POP SuperClass handle */ + pSelfBase->puiClsTree = ( USHORT * ) hb_xrealloc( pSelfBase->puiClsTree, sizeof( USHORT ) * (nPos + 1) ); + pSelfBase->puiClsTree[0]=nPos; } if( bProfiler )