xref: /AOO41X/main/basic/source/comp/codegen.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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