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