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