diff --git a/harbour/source/vm/classes.c b/harbour/source/vm/classes.c index 3d7e8007d4..2e00c7364d 100644 --- a/harbour/source/vm/classes.c +++ b/harbour/source/vm/classes.c @@ -1190,6 +1190,51 @@ HB_EXPORT USHORT hb_objSetClass( PHB_ITEM pItem, const char * szClass, const cha /* ================================================ */ +/* + * Get the class handle + */ +static USHORT hb_objGetClassH( PHB_ITEM pObject ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_objGetClassH(%p)", pObject)); + + if( HB_IS_ARRAY( pObject ) ) + { + if( pObject->item.asArray.value->uiClass != 0 ) + return pObject->item.asArray.value->uiClass; + else + return s_uiArrayClass; + } + /* built in types */ + else if( HB_IS_NIL( pObject ) ) + return s_uiNilClass; + + else if( HB_IS_STRING( pObject ) ) + return s_uiCharacterClass; + + else if( HB_IS_NUMERIC( pObject ) ) + return s_uiNumericClass; + + else if( HB_IS_DATE( pObject ) ) + return s_uiDateClass; + + else if( HB_IS_LOGICAL( pObject ) ) + return s_uiLogicalClass; + + else if( HB_IS_BLOCK( pObject ) ) + return s_uiBlockClass; + + else if( HB_IS_HASH( pObject ) ) + return s_uiHashClass; + + else if( HB_IS_POINTER( pObject ) ) + return s_uiPointerClass; + + else if( HB_IS_SYMBOL( pObject ) ) + return s_uiSymbolClass; + + return 0; +} + /* * Get the class name of an object */ @@ -1277,26 +1322,23 @@ HB_EXPORT USHORT hb_clsFindClass( const char * szClass, const char * szFunc ) */ HB_EXPORT const char * hb_objGetRealClsName( PHB_ITEM pObject, const char * szName ) { + USHORT uiClass; + HB_TRACE(HB_TR_DEBUG, ("hb_objGetrealClsName(%p,%s)", pObject, szName)); - if( HB_IS_OBJECT( pObject ) ) + uiClass = hb_objGetClassH( pObject ); + if( uiClass && uiClass <= uiClass ) { - USHORT uiClass; + PHB_DYNS pMsg = hb_dynsymFindName( szName ); - uiClass = pObject->item.asArray.value->uiClass; - if( uiClass && uiClass <= uiClass ) + if( pMsg ) { - PHB_DYNS pMsg = hb_dynsymFindName( szName ); - - if( pMsg ) - { - PMETHOD pMethod = hb_clsFindMsg( &s_pClasses[ uiClass ], pMsg ); - if( pMethod ) - uiClass = pMethod->uiSprClass; - } - if( uiClass && uiClass <= s_uiClasses ) - return s_pClasses[ uiClass ].szName; + PMETHOD pMethod = hb_clsFindMsg( &s_pClasses[ uiClass ], pMsg ); + if( pMethod ) + uiClass = pMethod->uiSprClass; } + if( uiClass && uiClass <= s_uiClasses ) + return s_pClasses[ uiClass ].szName; } return hb_objGetClsName( pObject ); @@ -1485,7 +1527,7 @@ static void hb_clsMakeSuperObject( PHB_ITEM pDest, PHB_ITEM pObject, hb_arraySet( pDest, 1, pObject ); /* And transform it into a fake object */ /* backup of actual handel */ - pDest->item.asArray.value->uiPrevCls = pObject->item.asArray.value->uiClass; + pDest->item.asArray.value->uiPrevCls = hb_objGetClassH( pObject ); /* superclass handel casting */ pDest->item.asArray.value->uiClass = uiSuperClass; } @@ -1991,12 +2033,14 @@ void hb_objDestructorCall( PHB_ITEM pObject ) */ BOOL hb_objHasOperator( PHB_ITEM pObject, USHORT uiOperator ) { + USHORT uiClass; + HB_TRACE(HB_TR_DEBUG, ("hb_objHasOperator(%p,%hu)", pObject, uiOperator)); - if( HB_IS_OBJECT( pObject ) ) + uiClass = hb_objGetClassH( pObject ); + if( uiClass && uiClass <= s_uiClasses ) { - PCLASS pClass = &s_pClasses[ pObject->item.asArray.value->uiClass ]; - return ( pClass->ulOpFlags & ( 1UL << uiOperator ) ) != 0; + return ( s_pClasses[ uiClass ].ulOpFlags & ( 1UL << uiOperator ) ) != 0; } return FALSE; @@ -3601,9 +3645,9 @@ HB_FUNC( __SENDER ) */ HB_FUNC( __CLASSH ) { - PHB_ITEM pObject = hb_param( 1, HB_IT_OBJECT ); + PHB_ITEM pObject = hb_param( 1, HB_IT_ANY ); - hb_retni( pObject ? pObject->item.asArray.value->uiClass : 0 ); + hb_retni( pObject ? hb_objGetClassH( pObject ) : 0 ); } /* ================================================ */ @@ -3865,9 +3909,8 @@ static HARBOUR hb___msgScopeErr( void ) hb_stackBaseItem()->item.asSymbol.stackstate->uiClass ].pMethods + hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; - pszProcName = hb_xstrcpy( NULL, - s_pClasses[ pObject->item.asArray.value->uiClass ].szName, - ":", pMethod->pMessage->pSymbol->szName, NULL ); + pszProcName = hb_xstrcpy( NULL, hb_objGetClsName( pObject ), ":", + pMethod->pMessage->pSymbol->szName, NULL ); if( pMethod->uiScope & HB_OO_CLSTP_HIDDEN ) hb_errRT_BASE( EG_NOMETHOD, 41, "Scope violation (hidden)", pszProcName, 0 ); else @@ -3883,9 +3926,8 @@ static HARBOUR hb___msgTypeErr( void ) hb_stackBaseItem()->item.asSymbol.stackstate->uiClass ].pMethods + hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; - pszProcName = hb_xstrcpy( NULL, - s_pClasses[ pObject->item.asArray.value->uiClass ].szName, - ":", pMethod->pMessage->pSymbol->szName + 1, NULL ); + pszProcName = hb_xstrcpy( NULL, hb_objGetClsName( pObject ), ":", + pMethod->pMessage->pSymbol->szName + 1, NULL ); hb_errRT_BASE( EG_NOMETHOD, 44, "Assigned value is wrong class", pszProcName, HB_ERR_ARGS_BASEPARAMS ); hb_xfree( pszProcName ); } @@ -3913,9 +3955,10 @@ static HARBOUR hb___msgRealClass( void ) { PHB_ITEM pObject = hb_stackSelfItem(); USHORT uiClass = hb_clsSenderMethodClasss(); + USHORT uiCurClass = hb_objGetClassH( pObject ); - if( uiClass && uiClass != pObject->item.asArray.value->uiClass && - hb_clsSenderObjectClasss() == pObject->item.asArray.value->uiClass ) + if( uiClass && uiClass != uiCurClass && + hb_clsSenderObjectClasss() == uiCurClass ) { hb_clsMakeSuperObject( hb_stackReturnItem(), pObject, uiClass ); } @@ -4034,24 +4077,28 @@ static HARBOUR hb___msgSetShrData( void ) static HARBOUR hb___msgGetData( void ) { PHB_ITEM pObject = hb_stackSelfItem(); - USHORT uiObjClass = pObject->item.asArray.value->uiClass; - USHORT uiClass = hb_stackBaseItem()->item.asSymbol.stackstate->uiClass; - PCLASS pClass = &s_pClasses[ uiClass ]; - PMETHOD pMethod = pClass->pMethods + - hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; - ULONG ulIndex = pMethod->uiData; - if( uiClass != uiObjClass ) + if( HB_IS_ARRAY( pObject ) ) { - ulIndex += hb_clsParentInstanceOffset( &s_pClasses[ uiObjClass ], - s_pClasses[ pMethod->uiSprClass ].pClassSym ); - } - else - { - ulIndex += pMethod->uiOffset; - } + USHORT uiObjClass = pObject->item.asArray.value->uiClass; + USHORT uiClass = hb_stackBaseItem()->item.asSymbol.stackstate->uiClass; + PCLASS pClass = &s_pClasses[ uiClass ]; + PMETHOD pMethod = pClass->pMethods + + hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; + ULONG ulIndex = pMethod->uiData; - hb_arrayGet( pObject, ulIndex, hb_stackReturnItem() ); + if( uiClass != uiObjClass ) + { + ulIndex += hb_clsParentInstanceOffset( &s_pClasses[ uiObjClass ], + s_pClasses[ pMethod->uiSprClass ].pClassSym ); + } + else + { + ulIndex += pMethod->uiOffset; + } + + hb_arrayGet( pObject, ulIndex, hb_stackReturnItem() ); + } } /* @@ -4061,46 +4108,50 @@ static HARBOUR hb___msgGetData( void ) */ static HARBOUR hb___msgSetData( void ) { - PHB_ITEM pReturn = hb_param( 1, HB_IT_ANY ); PHB_ITEM pObject = hb_stackSelfItem(); - USHORT uiObjClass = pObject->item.asArray.value->uiClass; - USHORT uiClass = hb_stackBaseItem()->item.asSymbol.stackstate->uiClass; - PCLASS pClass = &s_pClasses[ uiClass ]; - PMETHOD pMethod = pClass->pMethods + - hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; - ULONG ulIndex = pMethod->uiData; - if( uiClass != uiObjClass ) + if( HB_IS_ARRAY( pObject ) ) { - ulIndex += hb_clsParentInstanceOffset( &s_pClasses[ uiObjClass ], - s_pClasses[ pMethod->uiSprClass ].pClassSym ); - } - else - { - ulIndex += pMethod->uiOffset; - } + PHB_ITEM pReturn = hb_param( 1, HB_IT_ANY ); + USHORT uiObjClass = pObject->item.asArray.value->uiClass; + USHORT uiClass = hb_stackBaseItem()->item.asSymbol.stackstate->uiClass; + PCLASS pClass = &s_pClasses[ uiClass ]; + PMETHOD pMethod = pClass->pMethods + + hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; + ULONG ulIndex = pMethod->uiData; - if( !pReturn ) - hb_arrayGet( pObject, ulIndex, hb_stackReturnItem() ); - - else - { - if( pMethod->itemType && ! ( pMethod->itemType & pReturn->type ) ) + if( uiClass != uiObjClass ) { - if( pMethod->itemType == HB_IT_NUMINT && HB_IS_NUMERIC( pReturn ) ) - hb_itemPutNInt( pReturn, hb_itemGetNInt( pReturn ) ); - else - { - (s___msgTypeErr.value.pFunPtr)(); - return; - } + ulIndex += hb_clsParentInstanceOffset( &s_pClasses[ uiObjClass ], + s_pClasses[ pMethod->uiSprClass ].pClassSym ); + } + else + { + ulIndex += pMethod->uiOffset; } - /* will arise only if the class has been modified after first instance */ - if( ulIndex > hb_arrayLen( pObject ) ) /* Resize needed ? */ - hb_arraySize( pObject, ulIndex ); /* Make large enough */ - hb_arraySet( pObject, ulIndex, pReturn ); - hb_itemReturnForward( pReturn ); + if( !pReturn ) + hb_arrayGet( pObject, ulIndex, hb_stackReturnItem() ); + + else + { + if( pMethod->itemType && ! ( pMethod->itemType & pReturn->type ) ) + { + if( pMethod->itemType == HB_IT_NUMINT && HB_IS_NUMERIC( pReturn ) ) + hb_itemPutNInt( pReturn, hb_itemGetNInt( pReturn ) ); + else + { + (s___msgTypeErr.value.pFunPtr)(); + return; + } + } + + /* will arise only if the class has been modified after first instance */ + if( ulIndex > hb_arrayLen( pObject ) ) /* Resize needed ? */ + hb_arraySize( pObject, ulIndex ); /* Make large enough */ + hb_arraySet( pObject, ulIndex, pReturn ); + hb_itemReturnForward( pReturn ); + } } } @@ -4119,12 +4170,14 @@ static HARBOUR hb___msgNull( void ) #ifndef HB_NO_PROFILER void hb_mthAddTime( ULONG ulClockTicks ) { - PMETHOD pMethod = - s_pClasses[ hb_stackSelfItem()->item.asArray.value->uiClass ]. - pMethods + hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; - - pMethod->ulCalls++; - pMethod->ulTime += ulClockTicks; + PMETHOD pMethod = s_pClasses[ hb_objGetClassH( hb_stackSelfItem() ) ]. + pMethods; + if( pMethod ) + { + pMethod += hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod; + pMethod->ulCalls++; + pMethod->ulTime += ulClockTicks; + } } #endif