1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basic.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <basic/sbx.hxx> 32*cdf0e10cSrcweir #include "sbcomp.hxx" 33*cdf0e10cSrcweir #include "image.hxx" 34*cdf0e10cSrcweir #include <limits> 35*cdf0e10cSrcweir #include <com/sun/star/script/ModuleType.hpp> 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir // nInc ist die Inkrementgroesse der Puffer 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir SbiCodeGen::SbiCodeGen( SbModule& r, SbiParser* p, short nInc ) 40*cdf0e10cSrcweir : rMod( r ), aCode( p, nInc ) 41*cdf0e10cSrcweir { 42*cdf0e10cSrcweir pParser = p; 43*cdf0e10cSrcweir bStmnt = sal_False; 44*cdf0e10cSrcweir nLine = 0; 45*cdf0e10cSrcweir nCol = 0; 46*cdf0e10cSrcweir nForLevel = 0; 47*cdf0e10cSrcweir } 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir sal_uInt32 SbiCodeGen::GetPC() 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir return aCode.GetSize(); 52*cdf0e10cSrcweir } 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir // Statement merken 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir void SbiCodeGen::Statement() 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir bStmnt = sal_True; 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir nLine = pParser->GetLine(); 61*cdf0e10cSrcweir nCol = pParser->GetCol1(); 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir // #29955 Information der for-Schleifen-Ebene 64*cdf0e10cSrcweir // in oberen Byte der Spalte speichern 65*cdf0e10cSrcweir nCol = (nCol & 0xff) + 0x100 * nForLevel; 66*cdf0e10cSrcweir } 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir // Anfang eines Statements markieren 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir void SbiCodeGen::GenStmnt() 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir if( bStmnt ) 73*cdf0e10cSrcweir { 74*cdf0e10cSrcweir bStmnt = sal_False; 75*cdf0e10cSrcweir Gen( _STMNT, nLine, nCol ); 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir } 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir // Die Gen-Routinen returnen den Offset des 1. Operanden, 80*cdf0e10cSrcweir // damit Jumps dort ihr Backchain versenken koennen 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode ) 83*cdf0e10cSrcweir { 84*cdf0e10cSrcweir #ifdef DBG_UTIL 85*cdf0e10cSrcweir if( eOpcode < SbOP0_START || eOpcode > SbOP0_END ) 86*cdf0e10cSrcweir pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE1" ); 87*cdf0e10cSrcweir #endif 88*cdf0e10cSrcweir GenStmnt(); 89*cdf0e10cSrcweir aCode += (sal_uInt8) eOpcode; 90*cdf0e10cSrcweir return GetPC(); 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode, sal_uInt32 nOpnd ) 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir #ifdef DBG_UTIL 96*cdf0e10cSrcweir if( eOpcode < SbOP1_START || eOpcode > SbOP1_END ) 97*cdf0e10cSrcweir pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE2" ); 98*cdf0e10cSrcweir #endif 99*cdf0e10cSrcweir GenStmnt(); 100*cdf0e10cSrcweir aCode += (sal_uInt8) eOpcode; 101*cdf0e10cSrcweir sal_uInt32 n = GetPC(); 102*cdf0e10cSrcweir aCode += nOpnd; 103*cdf0e10cSrcweir return n; 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode, sal_uInt32 nOpnd1, sal_uInt32 nOpnd2 ) 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir #ifdef DBG_UTIL 109*cdf0e10cSrcweir if( eOpcode < SbOP2_START || eOpcode > SbOP2_END ) 110*cdf0e10cSrcweir pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE3" ); 111*cdf0e10cSrcweir #endif 112*cdf0e10cSrcweir GenStmnt(); 113*cdf0e10cSrcweir aCode += (sal_uInt8) eOpcode; 114*cdf0e10cSrcweir sal_uInt32 n = GetPC(); 115*cdf0e10cSrcweir aCode += nOpnd1; 116*cdf0e10cSrcweir aCode += nOpnd2; 117*cdf0e10cSrcweir return n; 118*cdf0e10cSrcweir } 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir // Abspeichern des erzeugten Images im Modul 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir void SbiCodeGen::Save() 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir SbiImage* p = new SbiImage; 125*cdf0e10cSrcweir rMod.StartDefinitions(); 126*cdf0e10cSrcweir // OPTION BASE-Wert: 127*cdf0e10cSrcweir p->nDimBase = pParser->nBase; 128*cdf0e10cSrcweir // OPTION EXPLICIT-Flag uebernehmen 129*cdf0e10cSrcweir if( pParser->bExplicit ) 130*cdf0e10cSrcweir p->SetFlag( SBIMG_EXPLICIT ); 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir int nIfaceCount = 0; 133*cdf0e10cSrcweir if( rMod.mnType == com::sun::star::script::ModuleType::CLASS ) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir OSL_TRACE("COdeGen::save() classmodule processing"); 136*cdf0e10cSrcweir rMod.bIsProxyModule = true; 137*cdf0e10cSrcweir p->SetFlag( SBIMG_CLASSMODULE ); 138*cdf0e10cSrcweir pCLASSFAC->AddClassModule( &rMod ); 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir nIfaceCount = pParser->aIfaceVector.size(); 141*cdf0e10cSrcweir if( !rMod.pClassData ) 142*cdf0e10cSrcweir rMod.pClassData = new SbClassData; 143*cdf0e10cSrcweir if( nIfaceCount ) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir for( int i = 0 ; i < nIfaceCount ; i++ ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir const String& rIfaceName = pParser->aIfaceVector[i]; 148*cdf0e10cSrcweir SbxVariable* pIfaceVar = new SbxVariable( SbxVARIANT ); 149*cdf0e10cSrcweir pIfaceVar->SetName( rIfaceName ); 150*cdf0e10cSrcweir SbxArray* pIfaces = rMod.pClassData->mxIfaces; 151*cdf0e10cSrcweir pIfaces->Insert( pIfaceVar, pIfaces->Count() ); 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir rMod.pClassData->maRequiredTypes = pParser->aRequiredTypes; 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir else 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir pCLASSFAC->RemoveClassModule( &rMod ); 160*cdf0e10cSrcweir // Only a ClassModule can revert to Normal 161*cdf0e10cSrcweir if ( rMod.mnType == com::sun::star::script::ModuleType::CLASS ) 162*cdf0e10cSrcweir rMod.mnType = com::sun::star::script::ModuleType::NORMAL; 163*cdf0e10cSrcweir rMod.bIsProxyModule = false; 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir if( pParser->bText ) 167*cdf0e10cSrcweir p->SetFlag( SBIMG_COMPARETEXT ); 168*cdf0e10cSrcweir // GlobalCode-Flag 169*cdf0e10cSrcweir if( pParser->HasGlobalCode() ) 170*cdf0e10cSrcweir p->SetFlag( SBIMG_INITCODE ); 171*cdf0e10cSrcweir // Die Entrypoints: 172*cdf0e10cSrcweir for( SbiSymDef* pDef = pParser->aPublics.First(); pDef; 173*cdf0e10cSrcweir pDef = pParser->aPublics.Next() ) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir SbiProcDef* pProc = pDef->GetProcDef(); 176*cdf0e10cSrcweir if( pProc && pProc->IsDefined() ) 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir String aProcName = pProc->GetName(); 179*cdf0e10cSrcweir String aIfaceProcName; 180*cdf0e10cSrcweir String aIfaceName; 181*cdf0e10cSrcweir sal_uInt16 nPassCount = 1; 182*cdf0e10cSrcweir if( nIfaceCount ) 183*cdf0e10cSrcweir { 184*cdf0e10cSrcweir int nPropPrefixFound = 185*cdf0e10cSrcweir aProcName.Search( String( RTL_CONSTASCII_USTRINGPARAM("Property ") ) ); 186*cdf0e10cSrcweir String aPureProcName = aProcName; 187*cdf0e10cSrcweir String aPropPrefix; 188*cdf0e10cSrcweir if( nPropPrefixFound == 0 ) 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir aPropPrefix = aProcName.Copy( 0, 13 ); // 13 == Len( "Property ?et " ) 191*cdf0e10cSrcweir aPureProcName = aProcName.Copy( 13 ); 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir for( int i = 0 ; i < nIfaceCount ; i++ ) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir const String& rIfaceName = pParser->aIfaceVector[i]; 196*cdf0e10cSrcweir int nFound = aPureProcName.Search( rIfaceName ); 197*cdf0e10cSrcweir if( nFound == 0 && '_' == aPureProcName.GetChar( rIfaceName.Len() ) ) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir if( nPropPrefixFound == 0 ) 200*cdf0e10cSrcweir aIfaceProcName += aPropPrefix; 201*cdf0e10cSrcweir aIfaceProcName += aPureProcName.Copy( rIfaceName.Len() + 1 ); 202*cdf0e10cSrcweir aIfaceName = rIfaceName; 203*cdf0e10cSrcweir nPassCount = 2; 204*cdf0e10cSrcweir break; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir SbMethod* pMeth = NULL; 209*cdf0e10cSrcweir for( sal_uInt16 nPass = 0 ; nPass < nPassCount ; nPass++ ) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir if( nPass == 1 ) 212*cdf0e10cSrcweir aProcName = aIfaceProcName; 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir PropertyMode ePropMode = pProc->getPropertyMode(); 215*cdf0e10cSrcweir if( ePropMode != PROPERTY_MODE_NONE ) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir SbxDataType ePropType = SbxEMPTY; 218*cdf0e10cSrcweir switch( ePropMode ) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir case PROPERTY_MODE_GET: 221*cdf0e10cSrcweir ePropType = pProc->GetType(); 222*cdf0e10cSrcweir break; 223*cdf0e10cSrcweir case PROPERTY_MODE_LET: 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir // type == type of first parameter 226*cdf0e10cSrcweir ePropType = SbxVARIANT; // Default 227*cdf0e10cSrcweir SbiSymPool* pPool = &pProc->GetParams(); 228*cdf0e10cSrcweir if( pPool->GetSize() > 1 ) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir SbiSymDef* pPar = pPool->Get( 1 ); 231*cdf0e10cSrcweir if( pPar ) 232*cdf0e10cSrcweir ePropType = pPar->GetType(); 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir break; 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir case PROPERTY_MODE_SET: 237*cdf0e10cSrcweir ePropType = SbxOBJECT; 238*cdf0e10cSrcweir break; 239*cdf0e10cSrcweir case PROPERTY_MODE_NONE: 240*cdf0e10cSrcweir DBG_ERROR( "Illegal PropertyMode PROPERTY_MODE_NONE" ); 241*cdf0e10cSrcweir break; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir String aPropName = pProc->GetPropName(); 244*cdf0e10cSrcweir if( nPass == 1 ) 245*cdf0e10cSrcweir aPropName = aPropName.Copy( aIfaceName.Len() + 1 ); 246*cdf0e10cSrcweir SbProcedureProperty* pProcedureProperty = NULL; 247*cdf0e10cSrcweir pProcedureProperty = rMod.GetProcedureProperty( aPropName, ePropType ); 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir if( nPass == 1 ) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir SbIfaceMapperMethod* pMapperMeth = NULL; 252*cdf0e10cSrcweir pMapperMeth = rMod.GetIfaceMapperMethod( aProcName, pMeth ); 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir else 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir pMeth = rMod.GetMethod( aProcName, pProc->GetType() ); 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir // #110004 259*cdf0e10cSrcweir if( !pProc->IsPublic() ) 260*cdf0e10cSrcweir pMeth->SetFlag( SBX_PRIVATE ); 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir // Declare? -> Hidden 263*cdf0e10cSrcweir if( pProc->GetLib().Len() > 0 ) 264*cdf0e10cSrcweir pMeth->SetFlag( SBX_HIDDEN ); 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir pMeth->nStart = pProc->GetAddr(); 267*cdf0e10cSrcweir pMeth->nLine1 = pProc->GetLine1(); 268*cdf0e10cSrcweir pMeth->nLine2 = pProc->GetLine2(); 269*cdf0e10cSrcweir // Die Parameter: 270*cdf0e10cSrcweir SbxInfo* pInfo = pMeth->GetInfo(); 271*cdf0e10cSrcweir String aHelpFile, aComment; 272*cdf0e10cSrcweir sal_uIntPtr nHelpId = 0; 273*cdf0e10cSrcweir if( pInfo ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir // Die Zusatzdaten retten 276*cdf0e10cSrcweir aHelpFile = pInfo->GetHelpFile(); 277*cdf0e10cSrcweir aComment = pInfo->GetComment(); 278*cdf0e10cSrcweir nHelpId = pInfo->GetHelpId(); 279*cdf0e10cSrcweir } 280*cdf0e10cSrcweir // Und die Parameterliste neu aufbauen 281*cdf0e10cSrcweir pInfo = new SbxInfo( aHelpFile, nHelpId ); 282*cdf0e10cSrcweir pInfo->SetComment( aComment ); 283*cdf0e10cSrcweir SbiSymPool* pPool = &pProc->GetParams(); 284*cdf0e10cSrcweir // Das erste Element ist immer der Funktionswert! 285*cdf0e10cSrcweir for( sal_uInt16 i = 1; i < pPool->GetSize(); i++ ) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir SbiSymDef* pPar = pPool->Get( i ); 288*cdf0e10cSrcweir SbxDataType t = pPar->GetType(); 289*cdf0e10cSrcweir if( !pPar->IsByVal() ) 290*cdf0e10cSrcweir t = (SbxDataType) ( t | SbxBYREF ); 291*cdf0e10cSrcweir if( pPar->GetDims() ) 292*cdf0e10cSrcweir t = (SbxDataType) ( t | SbxARRAY ); 293*cdf0e10cSrcweir // #33677 Optional-Info durchreichen 294*cdf0e10cSrcweir sal_uInt16 nFlags = SBX_READ; 295*cdf0e10cSrcweir if( pPar->IsOptional() ) 296*cdf0e10cSrcweir nFlags |= SBX_OPTIONAL; 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir pInfo->AddParam( pPar->GetName(), t, nFlags ); 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir sal_uInt32 nUserData = 0; 301*cdf0e10cSrcweir sal_uInt16 nDefaultId = pPar->GetDefaultId(); 302*cdf0e10cSrcweir if( nDefaultId ) 303*cdf0e10cSrcweir nUserData |= nDefaultId; 304*cdf0e10cSrcweir if( pPar->IsParamArray() ) 305*cdf0e10cSrcweir nUserData |= PARAM_INFO_PARAMARRAY; 306*cdf0e10cSrcweir if( pPar->IsWithBrackets() ) 307*cdf0e10cSrcweir nUserData |= PARAM_INFO_WITHBRACKETS; 308*cdf0e10cSrcweir if( nUserData ) 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir SbxParamInfo* pParam = (SbxParamInfo*)pInfo->GetParam( i ); 311*cdf0e10cSrcweir pParam->nUserData = nUserData; 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir pMeth->SetInfo( pInfo ); 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir } // for( iPass... 318*cdf0e10cSrcweir } 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir // Der Code 321*cdf0e10cSrcweir p->AddCode( aCode.GetBuffer(), aCode.GetSize() ); 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir // Der globale StringPool. 0 ist nicht belegt. 324*cdf0e10cSrcweir SbiStringPool* pPool = &pParser->aGblStrings; 325*cdf0e10cSrcweir sal_uInt16 nSize = pPool->GetSize(); 326*cdf0e10cSrcweir p->MakeStrings( nSize ); 327*cdf0e10cSrcweir sal_uInt16 i; 328*cdf0e10cSrcweir for( i = 1; i <= nSize; i++ ) 329*cdf0e10cSrcweir p->AddString( pPool->Find( i ) ); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir // Typen einfuegen 332*cdf0e10cSrcweir sal_uInt16 nCount = pParser->rTypeArray->Count(); 333*cdf0e10cSrcweir for (i = 0; i < nCount; i++) 334*cdf0e10cSrcweir p->AddType((SbxObject *)pParser->rTypeArray->Get(i)); 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir // Insert enum objects 337*cdf0e10cSrcweir nCount = pParser->rEnumArray->Count(); 338*cdf0e10cSrcweir for (i = 0; i < nCount; i++) 339*cdf0e10cSrcweir p->AddEnum((SbxObject *)pParser->rEnumArray->Get(i)); 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir if( !p->IsError() ) 342*cdf0e10cSrcweir rMod.pImage = p; 343*cdf0e10cSrcweir else 344*cdf0e10cSrcweir delete p; 345*cdf0e10cSrcweir 346*cdf0e10cSrcweir rMod.EndDefinitions(); 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir template < class T > 350*cdf0e10cSrcweir class PCodeVisitor 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir public: 353*cdf0e10cSrcweir virtual ~PCodeVisitor(); 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir virtual void start( sal_uInt8* pStart ) = 0; 356*cdf0e10cSrcweir virtual void processOpCode0( SbiOpcode eOp ) = 0; 357*cdf0e10cSrcweir virtual void processOpCode1( SbiOpcode eOp, T nOp1 ) = 0; 358*cdf0e10cSrcweir virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 ) = 0; 359*cdf0e10cSrcweir virtual bool processParams() = 0; 360*cdf0e10cSrcweir virtual void end() = 0; 361*cdf0e10cSrcweir }; 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir template <class T> PCodeVisitor< T >::~PCodeVisitor() 364*cdf0e10cSrcweir {} 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir template <class T> 367*cdf0e10cSrcweir class PCodeBufferWalker 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir private: 370*cdf0e10cSrcweir T m_nBytes; 371*cdf0e10cSrcweir sal_uInt8* m_pCode; 372*cdf0e10cSrcweir T readParam( sal_uInt8*& pCode ) 373*cdf0e10cSrcweir { 374*cdf0e10cSrcweir short nBytes = sizeof( T ); 375*cdf0e10cSrcweir T nOp1=0; 376*cdf0e10cSrcweir for ( int i=0; i<nBytes; ++i ) 377*cdf0e10cSrcweir nOp1 |= *pCode++ << ( i * 8); 378*cdf0e10cSrcweir return nOp1; 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir public: 381*cdf0e10cSrcweir PCodeBufferWalker( sal_uInt8* pCode, T nBytes ): m_nBytes( nBytes ), m_pCode( pCode ) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir void visitBuffer( PCodeVisitor< T >& visitor ) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir sal_uInt8* pCode = m_pCode; 387*cdf0e10cSrcweir if ( !pCode ) 388*cdf0e10cSrcweir return; 389*cdf0e10cSrcweir sal_uInt8* pEnd = pCode + m_nBytes; 390*cdf0e10cSrcweir visitor.start( m_pCode ); 391*cdf0e10cSrcweir T nOp1 = 0, nOp2 = 0; 392*cdf0e10cSrcweir for( ; pCode < pEnd; ) 393*cdf0e10cSrcweir { 394*cdf0e10cSrcweir SbiOpcode eOp = (SbiOpcode)(*pCode++); 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir if ( eOp <= SbOP0_END ) 397*cdf0e10cSrcweir visitor.processOpCode0( eOp ); 398*cdf0e10cSrcweir else if( eOp >= SbOP1_START && eOp <= SbOP1_END ) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir if ( visitor.processParams() ) 401*cdf0e10cSrcweir nOp1 = readParam( pCode ); 402*cdf0e10cSrcweir else 403*cdf0e10cSrcweir pCode += sizeof( T ); 404*cdf0e10cSrcweir visitor.processOpCode1( eOp, nOp1 ); 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir else if( eOp >= SbOP2_START && eOp <= SbOP2_END ) 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir if ( visitor.processParams() ) 409*cdf0e10cSrcweir { 410*cdf0e10cSrcweir nOp1 = readParam( pCode ); 411*cdf0e10cSrcweir nOp2 = readParam( pCode ); 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir else 414*cdf0e10cSrcweir pCode += ( sizeof( T ) * 2 ); 415*cdf0e10cSrcweir visitor.processOpCode2( eOp, nOp1, nOp2 ); 416*cdf0e10cSrcweir } 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir visitor.end(); 419*cdf0e10cSrcweir } 420*cdf0e10cSrcweir }; 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir template < class T, class S > 423*cdf0e10cSrcweir class OffSetAccumulator : public PCodeVisitor< T > 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir T m_nNumOp0; 426*cdf0e10cSrcweir T m_nNumSingleParams; 427*cdf0e10cSrcweir T m_nNumDoubleParams; 428*cdf0e10cSrcweir public: 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir OffSetAccumulator() : m_nNumOp0(0), m_nNumSingleParams(0), m_nNumDoubleParams(0){} 431*cdf0e10cSrcweir virtual void start( sal_uInt8* /*pStart*/ ){} 432*cdf0e10cSrcweir virtual void processOpCode0( SbiOpcode /*eOp*/ ){ ++m_nNumOp0; } 433*cdf0e10cSrcweir virtual void processOpCode1( SbiOpcode /*eOp*/, T /*nOp1*/ ){ ++m_nNumSingleParams; } 434*cdf0e10cSrcweir virtual void processOpCode2( SbiOpcode /*eOp*/, T /*nOp1*/, T /*nOp2*/ ) { ++m_nNumDoubleParams; } 435*cdf0e10cSrcweir virtual void end(){} 436*cdf0e10cSrcweir S offset() 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir T result = 0 ; 439*cdf0e10cSrcweir static const S max = std::numeric_limits< S >::max(); 440*cdf0e10cSrcweir result = m_nNumOp0 + ( ( sizeof(S) + 1 ) * m_nNumSingleParams ) + ( (( sizeof(S) * 2 )+ 1 ) * m_nNumDoubleParams ); 441*cdf0e10cSrcweir if ( result > max ) 442*cdf0e10cSrcweir return max; 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir return static_cast<S>(result); 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir virtual bool processParams(){ return false; } 447*cdf0e10cSrcweir }; 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir 451*cdf0e10cSrcweir template < class T, class S > 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir class BufferTransformer : public PCodeVisitor< T > 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir sal_uInt8* m_pStart; 456*cdf0e10cSrcweir SbiBuffer m_ConvertedBuf; 457*cdf0e10cSrcweir public: 458*cdf0e10cSrcweir BufferTransformer():m_pStart(NULL), m_ConvertedBuf( NULL, 1024 ) {} 459*cdf0e10cSrcweir virtual void start( sal_uInt8* pStart ){ m_pStart = pStart; } 460*cdf0e10cSrcweir virtual void processOpCode0( SbiOpcode eOp ) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir m_ConvertedBuf += (sal_uInt8)eOp; 463*cdf0e10cSrcweir } 464*cdf0e10cSrcweir virtual void processOpCode1( SbiOpcode eOp, T nOp1 ) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir m_ConvertedBuf += (sal_uInt8)eOp; 467*cdf0e10cSrcweir switch( eOp ) 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir case _JUMP: 470*cdf0e10cSrcweir case _JUMPT: 471*cdf0e10cSrcweir case _JUMPF: 472*cdf0e10cSrcweir case _GOSUB: 473*cdf0e10cSrcweir case _CASEIS: 474*cdf0e10cSrcweir case _RETURN: 475*cdf0e10cSrcweir case _ERRHDL: 476*cdf0e10cSrcweir case _TESTFOR: 477*cdf0e10cSrcweir nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) ); 478*cdf0e10cSrcweir break; 479*cdf0e10cSrcweir case _RESUME: 480*cdf0e10cSrcweir if ( nOp1 > 1 ) 481*cdf0e10cSrcweir nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) ); 482*cdf0e10cSrcweir break; 483*cdf0e10cSrcweir default: 484*cdf0e10cSrcweir break; // 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir m_ConvertedBuf += (S)nOp1; 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 ) 490*cdf0e10cSrcweir { 491*cdf0e10cSrcweir m_ConvertedBuf += (sal_uInt8)eOp; 492*cdf0e10cSrcweir if ( eOp == _CASEIS ) 493*cdf0e10cSrcweir if ( nOp1 ) 494*cdf0e10cSrcweir nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) ); 495*cdf0e10cSrcweir m_ConvertedBuf += (S)nOp1; 496*cdf0e10cSrcweir m_ConvertedBuf += (S)nOp2; 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir virtual bool processParams(){ return true; } 500*cdf0e10cSrcweir virtual void end() {} 501*cdf0e10cSrcweir // yeuch, careful here, you can only call 502*cdf0e10cSrcweir // GetBuffer on the returned SbiBuffer once, also 503*cdf0e10cSrcweir // you (as the caller) get to own the memory 504*cdf0e10cSrcweir SbiBuffer& buffer() 505*cdf0e10cSrcweir { 506*cdf0e10cSrcweir return m_ConvertedBuf; 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir static S convertBufferOffSet( sal_uInt8* pStart, T nOp1 ) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir PCodeBufferWalker< T > aBuff( pStart, nOp1); 511*cdf0e10cSrcweir OffSetAccumulator< T, S > aVisitor; 512*cdf0e10cSrcweir aBuff.visitBuffer( aVisitor ); 513*cdf0e10cSrcweir return aVisitor.offset(); 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir }; 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir sal_uInt32 518*cdf0e10cSrcweir SbiCodeGen::calcNewOffSet( sal_uInt8* pCode, sal_uInt16 nOffset ) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir return BufferTransformer< sal_uInt16, sal_uInt32 >::convertBufferOffSet( pCode, nOffset ); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir sal_uInt16 524*cdf0e10cSrcweir SbiCodeGen::calcLegacyOffSet( sal_uInt8* pCode, sal_uInt32 nOffset ) 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir return BufferTransformer< sal_uInt32, sal_uInt16 >::convertBufferOffSet( pCode, nOffset ); 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir template <class T, class S> 530*cdf0e10cSrcweir void 531*cdf0e10cSrcweir PCodeBuffConvertor<T,S>::convert() 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir PCodeBufferWalker< T > aBuf( m_pStart, m_nSize ); 534*cdf0e10cSrcweir BufferTransformer< T, S > aTrnsfrmer; 535*cdf0e10cSrcweir aBuf.visitBuffer( aTrnsfrmer ); 536*cdf0e10cSrcweir m_pCnvtdBuf = (sal_uInt8*)aTrnsfrmer.buffer().GetBuffer(); 537*cdf0e10cSrcweir m_nCnvtdSize = static_cast<S>( aTrnsfrmer.buffer().GetSize() ); 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir template class PCodeBuffConvertor< sal_uInt16, sal_uInt32 >; 541*cdf0e10cSrcweir template class PCodeBuffConvertor< sal_uInt32, sal_uInt16 >; 542