xref: /aoo41x/main/basic/source/runtime/runtime.cxx (revision 93ed1f29)
1e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e1f63238SAndrew Rist  * distributed with this work for additional information
6e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10e1f63238SAndrew Rist  *
11e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12e1f63238SAndrew Rist  *
13e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17e1f63238SAndrew Rist  * specific language governing permissions and limitations
18e1f63238SAndrew Rist  * under the License.
19e1f63238SAndrew Rist  *
20e1f63238SAndrew Rist  *************************************************************/
21e1f63238SAndrew Rist 
22e1f63238SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basic.hxx"
26cdf0e10cSrcweir #include <tools/fsys.hxx>
27cdf0e10cSrcweir #include <vcl/svapp.hxx>
28cdf0e10cSrcweir #include <tools/wldcrd.hxx>
29cdf0e10cSrcweir #include <svl/zforlist.hxx>
30cdf0e10cSrcweir #include <unotools/syslocale.hxx>
31cdf0e10cSrcweir #include "runtime.hxx"
32cdf0e10cSrcweir #include "sbintern.hxx"
33cdf0e10cSrcweir #include "opcodes.hxx"
34cdf0e10cSrcweir #include "codegen.hxx"
35cdf0e10cSrcweir #include "iosys.hxx"
36cdf0e10cSrcweir #include "image.hxx"
37cdf0e10cSrcweir #include "ddectrl.hxx"
38cdf0e10cSrcweir #include "dllmgr.hxx"
39cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
40cdf0e10cSrcweir #include <com/sun/star/container/XEnumerationAccess.hpp>
41cdf0e10cSrcweir #include "sbunoobj.hxx"
42cdf0e10cSrcweir #include "errobject.hxx"
43cdf0e10cSrcweir #include "sbtrace.hxx"
44cdf0e10cSrcweir #include "comenumwrapper.hxx"
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using namespace ::com::sun::star;
47cdf0e10cSrcweir 
isVBAEnabled()48cdf0e10cSrcweir bool SbiRuntime::isVBAEnabled()
49cdf0e10cSrcweir {
50cdf0e10cSrcweir 	bool result = false;
51cdf0e10cSrcweir 	SbiInstance* pInst = pINST;
52cdf0e10cSrcweir 	if ( pInst && pINST->pRun )
53cdf0e10cSrcweir 		result = pInst->pRun->bVBAEnabled;
54cdf0e10cSrcweir 	return result;
55cdf0e10cSrcweir }
56cdf0e10cSrcweir 
57cdf0e10cSrcweir // #91147 Global reschedule flag
58cdf0e10cSrcweir static sal_Bool bStaticGlobalEnableReschedule = sal_True;
59cdf0e10cSrcweir 
StaticEnableReschedule(sal_Bool bReschedule)60cdf0e10cSrcweir void StarBASIC::StaticEnableReschedule( sal_Bool bReschedule )
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     bStaticGlobalEnableReschedule = bReschedule;
63cdf0e10cSrcweir }
SetVBAEnabled(sal_Bool bEnabled)64cdf0e10cSrcweir void StarBASIC::SetVBAEnabled( sal_Bool bEnabled )
65cdf0e10cSrcweir {
66cdf0e10cSrcweir     if ( bDocBasic )
67cdf0e10cSrcweir     {
68cdf0e10cSrcweir         bVBAEnabled = bEnabled;
69cdf0e10cSrcweir     }
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
isVBAEnabled()72cdf0e10cSrcweir sal_Bool StarBASIC::isVBAEnabled()
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     if ( bDocBasic )
75cdf0e10cSrcweir     {
76cdf0e10cSrcweir         if( SbiRuntime::isVBAEnabled() )
77cdf0e10cSrcweir             return sal_True;
78cdf0e10cSrcweir         return bVBAEnabled;
79cdf0e10cSrcweir     }
80cdf0e10cSrcweir     return sal_False;
81cdf0e10cSrcweir }
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 
84cdf0e10cSrcweir struct SbiArgvStack {					// Argv stack:
85cdf0e10cSrcweir 	SbiArgvStack*  pNext;	   			// Stack Chain
86cdf0e10cSrcweir 	SbxArrayRef    refArgv;	 			// Argv
87cdf0e10cSrcweir 	short nArgc;						// Argc
88cdf0e10cSrcweir };
89cdf0e10cSrcweir 
90cdf0e10cSrcweir SbiRuntime::pStep0 SbiRuntime::aStep0[] = {	// Alle Opcodes ohne Operanden
91cdf0e10cSrcweir 	&SbiRuntime::StepNOP,
92cdf0e10cSrcweir 	&SbiRuntime::StepEXP,
93cdf0e10cSrcweir 	&SbiRuntime::StepMUL,
94cdf0e10cSrcweir 	&SbiRuntime::StepDIV,
95cdf0e10cSrcweir 	&SbiRuntime::StepMOD,
96cdf0e10cSrcweir 	&SbiRuntime::StepPLUS,
97cdf0e10cSrcweir 	&SbiRuntime::StepMINUS,
98cdf0e10cSrcweir 	&SbiRuntime::StepNEG,
99cdf0e10cSrcweir 	&SbiRuntime::StepEQ,
100cdf0e10cSrcweir 	&SbiRuntime::StepNE,
101cdf0e10cSrcweir 	&SbiRuntime::StepLT,
102cdf0e10cSrcweir 	&SbiRuntime::StepGT,
103cdf0e10cSrcweir 	&SbiRuntime::StepLE,
104cdf0e10cSrcweir 	&SbiRuntime::StepGE,
105cdf0e10cSrcweir 	&SbiRuntime::StepIDIV,
106cdf0e10cSrcweir 	&SbiRuntime::StepAND,
107cdf0e10cSrcweir 	&SbiRuntime::StepOR,
108cdf0e10cSrcweir 	&SbiRuntime::StepXOR,
109cdf0e10cSrcweir 	&SbiRuntime::StepEQV,
110cdf0e10cSrcweir 	&SbiRuntime::StepIMP,
111cdf0e10cSrcweir 	&SbiRuntime::StepNOT,
112cdf0e10cSrcweir 	&SbiRuntime::StepCAT,
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	&SbiRuntime::StepLIKE,
115cdf0e10cSrcweir 	&SbiRuntime::StepIS,
116cdf0e10cSrcweir 	// Laden/speichern
117cdf0e10cSrcweir 	&SbiRuntime::StepARGC,		// neuen Argv einrichten
118cdf0e10cSrcweir 	&SbiRuntime::StepARGV,		// TOS ==> aktueller Argv
119cdf0e10cSrcweir 	&SbiRuntime::StepINPUT,	 	// Input ==> TOS
120cdf0e10cSrcweir 	&SbiRuntime::StepLINPUT,	 	// Line Input ==> TOS
121cdf0e10cSrcweir 	&SbiRuntime::StepGET,        // TOS anfassen
122cdf0e10cSrcweir 	&SbiRuntime::StepSET,        // Speichern Objekt TOS ==> TOS-1
123cdf0e10cSrcweir 	&SbiRuntime::StepPUT,		// TOS ==> TOS-1
124cdf0e10cSrcweir 	&SbiRuntime::StepPUTC,		// TOS ==> TOS-1, dann ReadOnly
125cdf0e10cSrcweir 	&SbiRuntime::StepDIM,		// DIM
126cdf0e10cSrcweir 	&SbiRuntime::StepREDIM, 		// REDIM
127cdf0e10cSrcweir 	&SbiRuntime::StepREDIMP,		// REDIM PRESERVE
128cdf0e10cSrcweir 	&SbiRuntime::StepERASE, 		// TOS loeschen
129cdf0e10cSrcweir 	// Verzweigen
130cdf0e10cSrcweir 	&SbiRuntime::StepSTOP,  	  	// Programmende
131cdf0e10cSrcweir 	&SbiRuntime::StepINITFOR,  	// FOR-Variable initialisieren
132cdf0e10cSrcweir 	&SbiRuntime::StepNEXT,	  	// FOR-Variable inkrementieren
133cdf0e10cSrcweir 	&SbiRuntime::StepCASE,	  	// Anfang CASE
134cdf0e10cSrcweir 	&SbiRuntime::StepENDCASE,  	// Ende CASE
135cdf0e10cSrcweir 	&SbiRuntime::StepSTDERROR,  	// Standard-Fehlerbehandlung
136cdf0e10cSrcweir 	&SbiRuntime::StepNOERROR,  	// keine Fehlerbehandlung
137cdf0e10cSrcweir 	&SbiRuntime::StepLEAVE,		// UP verlassen
138cdf0e10cSrcweir 	// E/A
139cdf0e10cSrcweir 	&SbiRuntime::StepCHANNEL,  	// TOS = Kanalnummer
140cdf0e10cSrcweir 	&SbiRuntime::StepPRINT,	  	// print TOS
141cdf0e10cSrcweir 	&SbiRuntime::StepPRINTF,	  	// print TOS in field
142cdf0e10cSrcweir 	&SbiRuntime::StepWRITE,	  	// write TOS
143cdf0e10cSrcweir 	&SbiRuntime::StepRENAME,	  	// Rename Tos+1 to Tos
144cdf0e10cSrcweir 	&SbiRuntime::StepPROMPT,	  	// Input Prompt aus TOS definieren
145cdf0e10cSrcweir 	&SbiRuntime::StepRESTART,  	// Set restart point
146cdf0e10cSrcweir 	&SbiRuntime::StepCHANNEL0,	// E/A-Kanal 0 einstellen
147cdf0e10cSrcweir 	&SbiRuntime::StepEMPTY,		// Leeren Ausdruck auf Stack
148cdf0e10cSrcweir 	&SbiRuntime::StepERROR,	  	// TOS = Fehlercode
149cdf0e10cSrcweir 	&SbiRuntime::StepLSET,		// Speichern Objekt TOS ==> TOS-1
150cdf0e10cSrcweir 	&SbiRuntime::StepRSET,		// Speichern Objekt TOS ==> TOS-1
151cdf0e10cSrcweir 	&SbiRuntime::StepREDIMP_ERASE,// Copy array object for REDIMP
152cdf0e10cSrcweir 	&SbiRuntime::StepINITFOREACH,// Init for each loop
153cdf0e10cSrcweir 	&SbiRuntime::StepVBASET,// vba-like set statement
154cdf0e10cSrcweir 	&SbiRuntime::StepERASE_CLEAR,// vba-like set statement
155cdf0e10cSrcweir 	&SbiRuntime::StepARRAYACCESS,// access TOS as array
156cdf0e10cSrcweir 	&SbiRuntime::StepBYVAL,     // access TOS as array
157cdf0e10cSrcweir };
158cdf0e10cSrcweir 
159cdf0e10cSrcweir SbiRuntime::pStep1 SbiRuntime::aStep1[] = {	// Alle Opcodes mit einem Operanden
160cdf0e10cSrcweir 	&SbiRuntime::StepLOADNC,	  	// Laden einer numerischen Konstanten (+ID)
161cdf0e10cSrcweir 	&SbiRuntime::StepLOADSC,	  	// Laden einer Stringkonstanten (+ID)
162cdf0e10cSrcweir 	&SbiRuntime::StepLOADI,	  	// Immediate Load (+Wert)
163cdf0e10cSrcweir 	&SbiRuntime::StepARGN,		// Speichern eines named Args in Argv (+StringID)
164cdf0e10cSrcweir 	&SbiRuntime::StepPAD,	  	// String auf feste Laenge bringen (+Laenge)
165cdf0e10cSrcweir 	// Verzweigungen
166cdf0e10cSrcweir 	&SbiRuntime::StepJUMP,	  	// Sprung (+Target)
167cdf0e10cSrcweir 	&SbiRuntime::StepJUMPT,	  	// TOS auswerten), bedingter Sprung (+Target)
168cdf0e10cSrcweir 	&SbiRuntime::StepJUMPF,	  	// TOS auswerten), bedingter Sprung (+Target)
169cdf0e10cSrcweir 	&SbiRuntime::StepONJUMP,	  	// TOS auswerten), Sprung in JUMP-Tabelle (+MaxVal)
170cdf0e10cSrcweir 	&SbiRuntime::StepGOSUB,		// UP-Aufruf (+Target)
171cdf0e10cSrcweir 	&SbiRuntime::StepRETURN,		// UP-Return (+0 oder Target)
172cdf0e10cSrcweir 	&SbiRuntime::StepTESTFOR,	// FOR-Variable testen), inkrementieren (+Endlabel)
173cdf0e10cSrcweir 	&SbiRuntime::StepCASETO,		// Tos+1 <= Case <= Tos), 2xremove (+Target)
174cdf0e10cSrcweir 	&SbiRuntime::StepERRHDL,		// Fehler-Handler (+Offset)
175cdf0e10cSrcweir 	&SbiRuntime::StepRESUME,		// Resume nach Fehlern (+0 or 1 or Label)
176cdf0e10cSrcweir 	// E/A
177cdf0e10cSrcweir 	&SbiRuntime::StepCLOSE,		// (+Kanal/0)
178cdf0e10cSrcweir 	&SbiRuntime::StepPRCHAR,		// (+char)
179cdf0e10cSrcweir 	// Verwaltung
180cdf0e10cSrcweir 	&SbiRuntime::StepSETCLASS,	// Set + Klassennamen testen (+StringId)
181cdf0e10cSrcweir 	&SbiRuntime::StepTESTCLASS,	// Check TOS class (+StringId)
182cdf0e10cSrcweir 	&SbiRuntime::StepLIB,  		// Lib fuer Declare-Call (+StringId)
183cdf0e10cSrcweir 	&SbiRuntime::StepBASED,	  	// TOS wird um BASE erhoeht, BASE davor gepusht
184cdf0e10cSrcweir 	&SbiRuntime::StepARGTYP,	  	// Letzten Parameter in Argv konvertieren (+Typ)
185cdf0e10cSrcweir 	&SbiRuntime::StepVBASETCLASS,// vba-like set statement
186cdf0e10cSrcweir };
187cdf0e10cSrcweir 
188cdf0e10cSrcweir SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// Alle Opcodes mit zwei Operanden
189cdf0e10cSrcweir 	&SbiRuntime::StepRTL,  	    // Laden aus RTL (+StringID+Typ)
190cdf0e10cSrcweir 	&SbiRuntime::StepFIND,	    // Laden (+StringID+Typ)
191cdf0e10cSrcweir 	&SbiRuntime::StepELEM,  		// Laden Element (+StringID+Typ)
192cdf0e10cSrcweir 	&SbiRuntime::StepPARAM,		// Parameter (+Offset+Typ)
193cdf0e10cSrcweir 	// Verzweigen
194cdf0e10cSrcweir 	&SbiRuntime::StepCALL,	  	// Declare-Call (+StringID+Typ)
195cdf0e10cSrcweir 	&SbiRuntime::StepCALLC,	  	// CDecl-Declare-Call (+StringID+Typ)
196cdf0e10cSrcweir 	&SbiRuntime::StepCASEIS,		// Case-Test (+Test-Opcode+False-Target)
197cdf0e10cSrcweir 	// Verwaltung
198cdf0e10cSrcweir 	&SbiRuntime::StepSTMNT, 		// Beginn eines Statements (+Line+Col)
199cdf0e10cSrcweir 	// E/A
200cdf0e10cSrcweir 	&SbiRuntime::StepOPEN,  		// (+SvStreamFlags+Flags)
201cdf0e10cSrcweir 	// Objekte
202cdf0e10cSrcweir 	&SbiRuntime::StepLOCAL,		// Lokale Variable definieren (+StringId+Typ)
203cdf0e10cSrcweir 	&SbiRuntime::StepPUBLIC,		// Modulglobale Variable (+StringID+Typ)
204cdf0e10cSrcweir 	&SbiRuntime::StepGLOBAL,	  	// Globale Variable definieren (+StringID+Typ)
205cdf0e10cSrcweir 	&SbiRuntime::StepCREATE,		// Objekt kreieren (+StringId+StringId)
206cdf0e10cSrcweir 	&SbiRuntime::StepSTATIC,     // Statische Variable (+StringId+StringId)
207cdf0e10cSrcweir 	&SbiRuntime::StepTCREATE,    // User Defined Objekte (+StringId+StringId)
208cdf0e10cSrcweir 	&SbiRuntime::StepDCREATE,    // Objekt-Array kreieren (+StringID+StringID)
209cdf0e10cSrcweir 	&SbiRuntime::StepGLOBAL_P,   // Globale Variable definieren, die beim Neustart
210cdf0e10cSrcweir                                         // von Basic nicht ueberschrieben wird (+StringID+Typ)
211cdf0e10cSrcweir 	&SbiRuntime::StepFIND_G,    	// Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
212cdf0e10cSrcweir 	&SbiRuntime::StepDCREATE_REDIMP, // Objekt-Array redimensionieren (+StringID+StringID)
213cdf0e10cSrcweir 	&SbiRuntime::StepFIND_CM,    // Search inside a class module (CM) to enable global search in time
214cdf0e10cSrcweir 	&SbiRuntime::StepPUBLIC_P,    // Search inside a class module (CM) to enable global search in time
215cdf0e10cSrcweir 	&SbiRuntime::StepFIND_STATIC,    // Search inside a class module (CM) to enable global search in time
216cdf0e10cSrcweir };
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 
219cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
220cdf0e10cSrcweir //								SbiRTLData								//
221cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
222cdf0e10cSrcweir 
SbiRTLData()223cdf0e10cSrcweir SbiRTLData::SbiRTLData()
224cdf0e10cSrcweir {
225cdf0e10cSrcweir 	pDir		= 0;
226cdf0e10cSrcweir 	nDirFlags	= 0;
227cdf0e10cSrcweir 	nCurDirPos	= 0;
228cdf0e10cSrcweir 	pWildCard	= NULL;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir 
~SbiRTLData()231cdf0e10cSrcweir SbiRTLData::~SbiRTLData()
232cdf0e10cSrcweir {
233cdf0e10cSrcweir 	delete pDir;
234cdf0e10cSrcweir 	pDir = 0;
235cdf0e10cSrcweir 	delete pWildCard;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
239cdf0e10cSrcweir //								SbiInstance								//
240cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
241cdf0e10cSrcweir 
242cdf0e10cSrcweir // 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
243cdf0e10cSrcweir // Die Entscheidung, ob StepPoint aufgerufen werden soll, wird anhand des
244cdf0e10cSrcweir // CallLevels getroffen. Angehalten wird, wenn der aktuelle CallLevel <=
245cdf0e10cSrcweir // nBreakCallLvl ist. Der aktuelle CallLevel kann niemals kleiner als 1
246cdf0e10cSrcweir // sein, da er beim Aufruf einer Methode (auch main) inkrementiert wird.
247cdf0e10cSrcweir // Daher bedeutet ein BreakCallLvl von 0, dass das Programm gar nicht
248cdf0e10cSrcweir // angehalten wird.
249cdf0e10cSrcweir // (siehe auch step2.cxx, SbiRuntime::StepSTMNT() )
250cdf0e10cSrcweir 
251cdf0e10cSrcweir // Hilfsfunktion, um den BreakCallLevel gemaess der der Debug-Flags zu ermitteln
CalcBreakCallLevel(sal_uInt16 nFlags)252cdf0e10cSrcweir void SbiInstance::CalcBreakCallLevel( sal_uInt16 nFlags )
253cdf0e10cSrcweir {
254cdf0e10cSrcweir 	// Break-Flag wegfiltern
255cdf0e10cSrcweir 	nFlags &= ~((sal_uInt16)SbDEBUG_BREAK);
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	sal_uInt16 nRet;
258cdf0e10cSrcweir 	switch( nFlags )
259cdf0e10cSrcweir 	{
260cdf0e10cSrcweir 		case SbDEBUG_STEPINTO:
261cdf0e10cSrcweir 			nRet = nCallLvl + 1;	// CallLevel+1 wird auch angehalten
262cdf0e10cSrcweir 			break;
263cdf0e10cSrcweir 		case SbDEBUG_STEPOVER | SbDEBUG_STEPINTO:
264cdf0e10cSrcweir 			nRet = nCallLvl;		// Aktueller CallLevel wird angehalten
265cdf0e10cSrcweir 			break;
266cdf0e10cSrcweir 		case SbDEBUG_STEPOUT:
267cdf0e10cSrcweir 			nRet = nCallLvl - 1;	// Kleinerer CallLevel wird angehalten
268cdf0e10cSrcweir 			break;
269cdf0e10cSrcweir 		case SbDEBUG_CONTINUE:
270cdf0e10cSrcweir 		// Basic-IDE liefert 0 statt SbDEBUG_CONTINUE, also auch default=continue
271cdf0e10cSrcweir 		default:
272cdf0e10cSrcweir 			nRet = 0;				// CallLevel ist immer >0 -> kein StepPoint
273cdf0e10cSrcweir 	}
274cdf0e10cSrcweir 	nBreakCallLvl = nRet;			// Ergebnis uebernehmen
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
SbiInstance(StarBASIC * p)277cdf0e10cSrcweir SbiInstance::SbiInstance( StarBASIC* p )
278cdf0e10cSrcweir {
279cdf0e10cSrcweir 	pBasic   = p;
280cdf0e10cSrcweir 	pNext    = NULL;
281cdf0e10cSrcweir 	pRun     = NULL;
282cdf0e10cSrcweir 	pIosys   = new SbiIoSystem;
283cdf0e10cSrcweir 	pDdeCtrl = new SbiDdeControl;
284cdf0e10cSrcweir 	pDllMgr	 = 0; // on demand
285cdf0e10cSrcweir 	pNumberFormatter = 0; // on demand
286cdf0e10cSrcweir 	nCallLvl = 0;
287cdf0e10cSrcweir 	nBreakCallLvl = 0;
288cdf0e10cSrcweir 	nErr	 =
289cdf0e10cSrcweir 	nErl	 = 0;
290cdf0e10cSrcweir 	bReschedule = sal_True;
291cdf0e10cSrcweir 	bCompatibility = sal_False;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
~SbiInstance()294cdf0e10cSrcweir SbiInstance::~SbiInstance()
295cdf0e10cSrcweir {
296cdf0e10cSrcweir 	while( pRun )
297cdf0e10cSrcweir 	{
298cdf0e10cSrcweir 		SbiRuntime* p = pRun->pNext;
299cdf0e10cSrcweir 		delete pRun;
300cdf0e10cSrcweir 		pRun = p;
301cdf0e10cSrcweir 	}
302cdf0e10cSrcweir 	delete pIosys;
303cdf0e10cSrcweir 	delete pDdeCtrl;
304cdf0e10cSrcweir 	delete pDllMgr;
305cdf0e10cSrcweir 	delete pNumberFormatter;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 	try
308cdf0e10cSrcweir 	{
309cdf0e10cSrcweir 		int nSize = ComponentVector.size();
310cdf0e10cSrcweir 		if( nSize )
311cdf0e10cSrcweir 		{
312cdf0e10cSrcweir 			for( int i = nSize - 1 ; i >= 0 ; --i )
313cdf0e10cSrcweir 			{
314cdf0e10cSrcweir 				Reference< XComponent > xDlgComponent = ComponentVector[i];
315cdf0e10cSrcweir 				if( xDlgComponent.is() )
316cdf0e10cSrcweir 					xDlgComponent->dispose();
317cdf0e10cSrcweir 			}
318cdf0e10cSrcweir 		}
319cdf0e10cSrcweir 	}
320cdf0e10cSrcweir 	catch( const Exception& )
321cdf0e10cSrcweir 	{
322cdf0e10cSrcweir 		DBG_ERROR( "SbiInstance::~SbiInstance: caught an exception while disposing the components!" );
323cdf0e10cSrcweir 	}
324cdf0e10cSrcweir 
325cdf0e10cSrcweir     ComponentVector.clear();
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
GetDllMgr()328cdf0e10cSrcweir SbiDllMgr* SbiInstance::GetDllMgr()
329cdf0e10cSrcweir {
330cdf0e10cSrcweir 	if( !pDllMgr )
331cdf0e10cSrcweir 		pDllMgr = new SbiDllMgr;
332cdf0e10cSrcweir 	return pDllMgr;
333cdf0e10cSrcweir }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir // #39629 NumberFormatter jetzt ueber statische Methode anlegen
GetNumberFormatter()336cdf0e10cSrcweir SvNumberFormatter* SbiInstance::GetNumberFormatter()
337cdf0e10cSrcweir {
338cdf0e10cSrcweir     LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
339cdf0e10cSrcweir     SvtSysLocale aSysLocale;
340cdf0e10cSrcweir     DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
341cdf0e10cSrcweir 	if( pNumberFormatter )
342cdf0e10cSrcweir     {
343cdf0e10cSrcweir         if( eLangType != meFormatterLangType ||
344cdf0e10cSrcweir             eDate != meFormatterDateFormat )
345cdf0e10cSrcweir         {
346cdf0e10cSrcweir             delete pNumberFormatter;
347cdf0e10cSrcweir             pNumberFormatter = NULL;
348cdf0e10cSrcweir         }
349cdf0e10cSrcweir     }
350cdf0e10cSrcweir     meFormatterLangType = eLangType;
351cdf0e10cSrcweir     meFormatterDateFormat = eDate;
352cdf0e10cSrcweir 	if( !pNumberFormatter )
353cdf0e10cSrcweir 		PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx,
354cdf0e10cSrcweir         &meFormatterLangType, &meFormatterDateFormat );
355cdf0e10cSrcweir 	return pNumberFormatter;
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir // #39629 NumberFormatter auch statisch anbieten
PrepareNumberFormatter(SvNumberFormatter * & rpNumberFormatter,sal_uInt32 & rnStdDateIdx,sal_uInt32 & rnStdTimeIdx,sal_uInt32 & rnStdDateTimeIdx,LanguageType * peFormatterLangType,DateFormat * peFormatterDateFormat)359cdf0e10cSrcweir void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
360cdf0e10cSrcweir 	sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
361cdf0e10cSrcweir     LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat )
362cdf0e10cSrcweir {
363cdf0e10cSrcweir 	com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
364cdf0e10cSrcweir 		xFactory = comphelper::getProcessServiceFactory();
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     LanguageType eLangType;
367cdf0e10cSrcweir     if( peFormatterLangType )
368cdf0e10cSrcweir         eLangType = *peFormatterLangType;
369cdf0e10cSrcweir     else
370cdf0e10cSrcweir         eLangType = GetpApp()->GetSettings().GetLanguage();
371cdf0e10cSrcweir 
372cdf0e10cSrcweir     DateFormat eDate;
373cdf0e10cSrcweir     if( peFormatterDateFormat )
374cdf0e10cSrcweir         eDate = *peFormatterDateFormat;
375cdf0e10cSrcweir     else
376cdf0e10cSrcweir     {
377cdf0e10cSrcweir         SvtSysLocale aSysLocale;
378cdf0e10cSrcweir         eDate = aSysLocale.GetLocaleData().getDateFormat();
379cdf0e10cSrcweir     }
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType );
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 	xub_StrLen nCheckPos = 0; short nType;
384cdf0e10cSrcweir 	rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir 	// Standard-Vorlagen des Formatters haben nur zweistellige
387cdf0e10cSrcweir 	// Jahreszahl. Deshalb eigenes Format registrieren
388cdf0e10cSrcweir 
389cdf0e10cSrcweir 	// HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
390cdf0e10cSrcweir 	// fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
391cdf0e10cSrcweir 	// austauscht. Problem: Print Year(Date) unter engl. BS
392cdf0e10cSrcweir 	// siehe auch svtools\source\sbx\sbxdate.cxx
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	String aDateStr;
395cdf0e10cSrcweir 	switch( eDate )
396cdf0e10cSrcweir 	{
397cdf0e10cSrcweir 		case MDY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") ); break;
398cdf0e10cSrcweir 		case DMY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("TT.MM.JJJJ") ); break;
399cdf0e10cSrcweir 		case YMD: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("JJJJ.MM.TT") ); break;
400cdf0e10cSrcweir 		default:  aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") );
401cdf0e10cSrcweir 	}
402cdf0e10cSrcweir 	String aStr( aDateStr );
403cdf0e10cSrcweir 	rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
404cdf0e10cSrcweir 		rnStdDateIdx, LANGUAGE_GERMAN, eLangType );
405cdf0e10cSrcweir 	nCheckPos = 0;
406cdf0e10cSrcweir 	String aStrHHMMSS( RTL_CONSTASCII_USTRINGPARAM(" HH:MM:SS") );
407cdf0e10cSrcweir 	aStr = aDateStr;
408cdf0e10cSrcweir 	aStr += aStrHHMMSS;
409cdf0e10cSrcweir 	rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
410cdf0e10cSrcweir 		rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType );
411cdf0e10cSrcweir }
412cdf0e10cSrcweir 
413cdf0e10cSrcweir 
414cdf0e10cSrcweir 
415cdf0e10cSrcweir // Engine laufenlassen. Falls Flags == SbDEBUG_CONTINUE, Flags uebernehmen
416cdf0e10cSrcweir 
Stop()417cdf0e10cSrcweir void SbiInstance::Stop()
418cdf0e10cSrcweir {
419cdf0e10cSrcweir 	for( SbiRuntime* p = pRun; p; p = p->pNext )
420cdf0e10cSrcweir 		p->Stop();
421cdf0e10cSrcweir }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir // Allows Basic IDE to set watch mode to suppress errors
424cdf0e10cSrcweir static bool bWatchMode = false;
425cdf0e10cSrcweir 
setBasicWatchMode(bool bOn)426cdf0e10cSrcweir void setBasicWatchMode( bool bOn )
427cdf0e10cSrcweir {
428cdf0e10cSrcweir 	bWatchMode = bOn;
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
Error(SbError n)431cdf0e10cSrcweir void SbiInstance::Error( SbError n )
432cdf0e10cSrcweir {
433cdf0e10cSrcweir 	Error( n, String() );
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
Error(SbError n,const String & rMsg)436cdf0e10cSrcweir void SbiInstance::Error( SbError n, const String& rMsg )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir 	if( !bWatchMode )
439cdf0e10cSrcweir 	{
440cdf0e10cSrcweir 		aErrorMsg = rMsg;
441cdf0e10cSrcweir 		pRun->Error( n );
442cdf0e10cSrcweir 	}
443cdf0e10cSrcweir }
444cdf0e10cSrcweir 
ErrorVB(sal_Int32 nVBNumber,const String & rMsg)445cdf0e10cSrcweir void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const String& rMsg )
446cdf0e10cSrcweir {
447cdf0e10cSrcweir 	if( !bWatchMode )
448cdf0e10cSrcweir 	{
449cdf0e10cSrcweir 		SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
450cdf0e10cSrcweir 		if ( !n )
451cdf0e10cSrcweir 			n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 		aErrorMsg = rMsg;
454cdf0e10cSrcweir 		SbiRuntime::translateErrorToVba( n, aErrorMsg );
455cdf0e10cSrcweir 
456cdf0e10cSrcweir 		bool bVBATranslationAlreadyDone = true;
457cdf0e10cSrcweir 		pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone );
458cdf0e10cSrcweir 	}
459cdf0e10cSrcweir }
460cdf0e10cSrcweir 
setErrorVB(sal_Int32 nVBNumber,const String & rMsg)461cdf0e10cSrcweir void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const String& rMsg )
462cdf0e10cSrcweir {
463cdf0e10cSrcweir 	SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
464cdf0e10cSrcweir 	if( !n )
465cdf0e10cSrcweir 		n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
466cdf0e10cSrcweir 
467cdf0e10cSrcweir 	aErrorMsg = rMsg;
468cdf0e10cSrcweir 	SbiRuntime::translateErrorToVba( n, aErrorMsg );
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	nErr = n;
471cdf0e10cSrcweir }
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 
FatalError(SbError n)474cdf0e10cSrcweir void SbiInstance::FatalError( SbError n )
475cdf0e10cSrcweir {
476cdf0e10cSrcweir 	pRun->FatalError( n );
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
FatalError(SbError _errCode,const String & _details)479cdf0e10cSrcweir void SbiInstance::FatalError( SbError _errCode, const String& _details )
480cdf0e10cSrcweir {
481cdf0e10cSrcweir 	pRun->FatalError( _errCode, _details );
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
Abort()484cdf0e10cSrcweir void SbiInstance::Abort()
485cdf0e10cSrcweir {
486cdf0e10cSrcweir 	// Basic suchen, in dem der Fehler auftrat
487cdf0e10cSrcweir 	StarBASIC* pErrBasic = GetCurrentBasic( pBasic );
488cdf0e10cSrcweir 	pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 );
489cdf0e10cSrcweir 	pBasic->Stop();
490cdf0e10cSrcweir }
491cdf0e10cSrcweir 
492cdf0e10cSrcweir // Hilfsfunktion, um aktives Basic zu finden, kann ungleich pRTBasic sein
GetCurrentBasic(StarBASIC * pRTBasic)493cdf0e10cSrcweir StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic )
494cdf0e10cSrcweir {
495cdf0e10cSrcweir 	StarBASIC* pCurBasic = pRTBasic;
496cdf0e10cSrcweir 	SbModule* pActiveModule = pRTBasic->GetActiveModule();
497cdf0e10cSrcweir 	if( pActiveModule )
498cdf0e10cSrcweir 	{
499cdf0e10cSrcweir 		SbxObject* pParent = pActiveModule->GetParent();
500cdf0e10cSrcweir 		if( pParent && pParent->ISA(StarBASIC) )
501cdf0e10cSrcweir 			pCurBasic = (StarBASIC*)pParent;
502cdf0e10cSrcweir 	}
503cdf0e10cSrcweir 	return pCurBasic;
504cdf0e10cSrcweir }
505cdf0e10cSrcweir 
GetActiveModule()506cdf0e10cSrcweir SbModule* SbiInstance::GetActiveModule()
507cdf0e10cSrcweir {
508cdf0e10cSrcweir 	if( pRun )
509cdf0e10cSrcweir 		return pRun->GetModule();
510cdf0e10cSrcweir 	else
511cdf0e10cSrcweir 		return NULL;
512cdf0e10cSrcweir }
513cdf0e10cSrcweir 
GetCaller(sal_uInt16 nLevel)514cdf0e10cSrcweir SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel )
515cdf0e10cSrcweir {
516cdf0e10cSrcweir 	SbiRuntime* p = pRun;
517cdf0e10cSrcweir 	while( nLevel-- && p )
518cdf0e10cSrcweir 		p = p->pNext;
519cdf0e10cSrcweir 	if( p )
520cdf0e10cSrcweir 		return p->GetCaller();
521cdf0e10cSrcweir 	else
522cdf0e10cSrcweir 		return NULL;
523cdf0e10cSrcweir }
524cdf0e10cSrcweir 
GetLocals(SbMethod * pMeth)525cdf0e10cSrcweir SbxArray* SbiInstance::GetLocals( SbMethod* pMeth )
526cdf0e10cSrcweir {
527cdf0e10cSrcweir 	SbiRuntime* p = pRun;
528cdf0e10cSrcweir 	while( p && p->GetMethod() != pMeth )
529cdf0e10cSrcweir 		p = p->pNext;
530cdf0e10cSrcweir 	if( p )
531cdf0e10cSrcweir 		return p->GetLocals();
532cdf0e10cSrcweir 	else
533cdf0e10cSrcweir 		return NULL;
534cdf0e10cSrcweir }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
537cdf0e10cSrcweir //								SbiInstance								//
538cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
539cdf0e10cSrcweir 
540cdf0e10cSrcweir // Achtung: pMeth kann auch NULL sein (beim Aufruf des Init-Codes)
541cdf0e10cSrcweir 
SbiRuntime(SbModule * pm,SbMethod * pe,sal_uInt32 nStart)542cdf0e10cSrcweir SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart )
543cdf0e10cSrcweir 		 : rBasic( *(StarBASIC*)pm->pParent ), pInst( pINST ),
544cdf0e10cSrcweir 		   pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), m_nLastTime(0)
545cdf0e10cSrcweir {
546cdf0e10cSrcweir 	nFlags	  = pe ? pe->GetDebugFlags() : 0;
547cdf0e10cSrcweir 	pIosys	  = pInst->pIosys;
548cdf0e10cSrcweir 	pArgvStk  = NULL;
549cdf0e10cSrcweir 	pGosubStk = NULL;
550cdf0e10cSrcweir 	pForStk   = NULL;
551cdf0e10cSrcweir 	pError    = NULL;
552cdf0e10cSrcweir 	pErrCode  =
553cdf0e10cSrcweir 	pErrStmnt =
554cdf0e10cSrcweir 	pRestart  = NULL;
555cdf0e10cSrcweir 	pNext     = NULL;
556cdf0e10cSrcweir 	pCode     =
557cdf0e10cSrcweir 	pStmnt    = (const sal_uInt8* ) pImg->GetCode() + nStart;
558cdf0e10cSrcweir 	bRun      =
559cdf0e10cSrcweir 	bError    = sal_True;
560cdf0e10cSrcweir 	bInError  = sal_False;
561cdf0e10cSrcweir 	bBlocked  = sal_False;
562cdf0e10cSrcweir 	nLine	  = 0;
563cdf0e10cSrcweir 	nCol1	  = 0;
564cdf0e10cSrcweir 	nCol2	  = 0;
565cdf0e10cSrcweir 	nExprLvl  = 0;
566cdf0e10cSrcweir 	nArgc     = 0;
567cdf0e10cSrcweir 	nError	  = 0;
568cdf0e10cSrcweir 	nGosubLvl = 0;
569cdf0e10cSrcweir 	nForLvl   = 0;
570cdf0e10cSrcweir 	nOps	  = 0;
571cdf0e10cSrcweir 	refExprStk = new SbxArray;
572cdf0e10cSrcweir 	SetVBAEnabled( pMod->IsVBACompat() );
573cdf0e10cSrcweir #if defined GCC
574cdf0e10cSrcweir 	SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL );
575cdf0e10cSrcweir #else
576cdf0e10cSrcweir 	SetParameters( pe ? pe->GetParameters() : NULL );
577cdf0e10cSrcweir #endif
578cdf0e10cSrcweir 	pRefSaveList = NULL;
579cdf0e10cSrcweir 	pItemStoreList = NULL;
580cdf0e10cSrcweir }
581cdf0e10cSrcweir 
~SbiRuntime()582cdf0e10cSrcweir SbiRuntime::~SbiRuntime()
583cdf0e10cSrcweir {
584cdf0e10cSrcweir 	ClearGosubStack();
585cdf0e10cSrcweir 	ClearArgvStack();
586cdf0e10cSrcweir 	ClearForStack();
587cdf0e10cSrcweir 
588cdf0e10cSrcweir 	// #74254 Items zum Sichern temporaere Referenzen freigeben
589cdf0e10cSrcweir 	ClearRefs();
590cdf0e10cSrcweir 	while( pItemStoreList )
591cdf0e10cSrcweir 	{
592cdf0e10cSrcweir 		RefSaveItem* pToDeleteItem = pItemStoreList;
593cdf0e10cSrcweir 		pItemStoreList = pToDeleteItem->pNext;
594cdf0e10cSrcweir 		delete pToDeleteItem;
595cdf0e10cSrcweir 	}
596cdf0e10cSrcweir }
597cdf0e10cSrcweir 
SetVBAEnabled(bool bEnabled)598cdf0e10cSrcweir void SbiRuntime::SetVBAEnabled(bool bEnabled )
599cdf0e10cSrcweir {
600cdf0e10cSrcweir 	bVBAEnabled = bEnabled;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir 
603cdf0e10cSrcweir // Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt
604cdf0e10cSrcweir // uebernommen; von ByVal-Parametern werden Kopien angelegt. Falls
605cdf0e10cSrcweir // ein bestimmter Datentyp verlangt wird, wird konvertiert.
606cdf0e10cSrcweir 
SetParameters(SbxArray * pParams)607cdf0e10cSrcweir void SbiRuntime::SetParameters( SbxArray* pParams )
608cdf0e10cSrcweir {
609cdf0e10cSrcweir 	refParams = new SbxArray;
610cdf0e10cSrcweir 	// fuer den Returnwert
611cdf0e10cSrcweir 	refParams->Put( pMeth, 0 );
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 	SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL;
614cdf0e10cSrcweir 	sal_uInt16 nParamCount = pParams ? pParams->Count() : 1;
615cdf0e10cSrcweir 	if( nParamCount > 1 )
616cdf0e10cSrcweir 	{
617cdf0e10cSrcweir 		for( sal_uInt16 i = 1 ; i < nParamCount ; i++ )
618cdf0e10cSrcweir 		{
619cdf0e10cSrcweir 			const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL;
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 			// #111897 ParamArray
622cdf0e10cSrcweir 			if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
623cdf0e10cSrcweir 			{
624cdf0e10cSrcweir 				SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
625cdf0e10cSrcweir 				sal_uInt16 nParamArrayParamCount = nParamCount - i;
626cdf0e10cSrcweir 				pArray->unoAddDim( 0, nParamArrayParamCount - 1 );
627cdf0e10cSrcweir 				for( sal_uInt16 j = i ; j < nParamCount ; j++ )
628cdf0e10cSrcweir 				{
629cdf0e10cSrcweir 					SbxVariable* v = pParams->Get( j );
630cdf0e10cSrcweir 					short nDimIndex = j - i;
631cdf0e10cSrcweir 					pArray->Put( v, &nDimIndex );
632cdf0e10cSrcweir 				}
633cdf0e10cSrcweir 				SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
634cdf0e10cSrcweir 				pArrayVar->SetFlag( SBX_READWRITE );
635cdf0e10cSrcweir 				pArrayVar->PutObject( pArray );
636cdf0e10cSrcweir 				refParams->Put( pArrayVar, i );
637cdf0e10cSrcweir 
638cdf0e10cSrcweir 				// Block ParamArray for missing parameter
639cdf0e10cSrcweir 				pInfo = NULL;
640cdf0e10cSrcweir 				break;
641cdf0e10cSrcweir 			}
642cdf0e10cSrcweir 
643cdf0e10cSrcweir 			SbxVariable* v = pParams->Get( i );
644cdf0e10cSrcweir 			// Methoden sind immer byval!
645cdf0e10cSrcweir 			sal_Bool bByVal = v->IsA( TYPE(SbxMethod) );
646cdf0e10cSrcweir 			SbxDataType t = v->GetType();
647cdf0e10cSrcweir 			bool bTargetTypeIsArray = false;
648cdf0e10cSrcweir 			if( p )
649cdf0e10cSrcweir 			{
650cdf0e10cSrcweir 				bByVal |= sal_Bool( ( p->eType & SbxBYREF ) == 0 );
651cdf0e10cSrcweir 				t = (SbxDataType) ( p->eType & 0x0FFF );
652cdf0e10cSrcweir 
653cdf0e10cSrcweir 				if( !bByVal && t != SbxVARIANT &&
654cdf0e10cSrcweir 					(!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) )
655cdf0e10cSrcweir 						bByVal = sal_True;
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 				bTargetTypeIsArray = (p->nUserData & PARAM_INFO_WITHBRACKETS) != 0;
658cdf0e10cSrcweir 			}
659cdf0e10cSrcweir 			if( bByVal )
660cdf0e10cSrcweir 			{
661cdf0e10cSrcweir 				if( bTargetTypeIsArray )
662cdf0e10cSrcweir 					t = SbxOBJECT;
663cdf0e10cSrcweir 				SbxVariable* v2 = new SbxVariable( t );
664cdf0e10cSrcweir 				v2->SetFlag( SBX_READWRITE );
665cdf0e10cSrcweir 				*v2 = *v;
666cdf0e10cSrcweir 				refParams->Put( v2, i );
667cdf0e10cSrcweir 			}
668cdf0e10cSrcweir 			else
669cdf0e10cSrcweir 			{
670cdf0e10cSrcweir 				if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) )
671cdf0e10cSrcweir 				{
672cdf0e10cSrcweir 					// Array konvertieren??
673cdf0e10cSrcweir 					if( p && (p->eType & SbxARRAY) )
674cdf0e10cSrcweir 						Error( SbERR_CONVERSION );
675cdf0e10cSrcweir 					else
676cdf0e10cSrcweir 						v->Convert( t );
677cdf0e10cSrcweir 				}
678cdf0e10cSrcweir 				refParams->Put( v, i );
679cdf0e10cSrcweir 			}
680cdf0e10cSrcweir 			if( p )
681cdf0e10cSrcweir 				refParams->PutAlias( p->aName, i );
682cdf0e10cSrcweir 		}
683cdf0e10cSrcweir 	}
684cdf0e10cSrcweir 
685cdf0e10cSrcweir 	// ParamArray for missing parameter
686cdf0e10cSrcweir 	if( pInfo )
687cdf0e10cSrcweir 	{
688cdf0e10cSrcweir 		// #111897 Check first missing parameter for ParamArray
689cdf0e10cSrcweir 		const SbxParamInfo* p = pInfo->GetParam( nParamCount );
690cdf0e10cSrcweir 		if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
691cdf0e10cSrcweir 		{
692cdf0e10cSrcweir 			SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
693cdf0e10cSrcweir 			pArray->unoAddDim( 0, -1 );
694cdf0e10cSrcweir 			SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
695cdf0e10cSrcweir 			pArrayVar->SetFlag( SBX_READWRITE );
696cdf0e10cSrcweir 			pArrayVar->PutObject( pArray );
697cdf0e10cSrcweir 			refParams->Put( pArrayVar, nParamCount );
698cdf0e10cSrcweir 		}
699cdf0e10cSrcweir 	}
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
702cdf0e10cSrcweir 
703cdf0e10cSrcweir // Einen P-Code ausfuehren
704cdf0e10cSrcweir 
Step()705cdf0e10cSrcweir sal_Bool SbiRuntime::Step()
706cdf0e10cSrcweir {
707cdf0e10cSrcweir 	if( bRun )
708cdf0e10cSrcweir 	{
709cdf0e10cSrcweir 		// Unbedingt gelegentlich die Kontrolle abgeben!
710cdf0e10cSrcweir 		if( !( ++nOps & 0xF ) && pInst->IsReschedule() && bStaticGlobalEnableReschedule )
711cdf0e10cSrcweir 		{
712cdf0e10cSrcweir 			sal_uInt32 nTime = osl_getGlobalTimer();
713cdf0e10cSrcweir 			if (nTime - m_nLastTime > 5 ) // 20 ms
714cdf0e10cSrcweir 			{
715cdf0e10cSrcweir 				Application::Reschedule();
716cdf0e10cSrcweir 				m_nLastTime = nTime;
717cdf0e10cSrcweir 			}
718cdf0e10cSrcweir 		}
719cdf0e10cSrcweir 
720cdf0e10cSrcweir 		// #i48868 blocked by next call level?
721cdf0e10cSrcweir 		while( bBlocked )
722cdf0e10cSrcweir 		{
723cdf0e10cSrcweir 			if( pInst->IsReschedule() && bStaticGlobalEnableReschedule )
724cdf0e10cSrcweir 				Application::Reschedule();
725cdf0e10cSrcweir 		}
726cdf0e10cSrcweir 
727cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
728cdf0e10cSrcweir 		sal_uInt32 nPC = ( pCode - (const sal_uInt8* )pImg->GetCode() );
729cdf0e10cSrcweir 		dbg_traceStep( pMod, nPC, pINST->nCallLvl );
730cdf0e10cSrcweir #endif
731cdf0e10cSrcweir 
732cdf0e10cSrcweir 		SbiOpcode eOp = (SbiOpcode ) ( *pCode++ );
733cdf0e10cSrcweir 		sal_uInt32 nOp1, nOp2;
734*93ed1f29SArmin Le Grand         if (eOp < SbOP0_END)
735cdf0e10cSrcweir 		{
736cdf0e10cSrcweir 			(this->*( aStep0[ eOp ] ) )();
737cdf0e10cSrcweir 		}
738*93ed1f29SArmin Le Grand         else if (eOp >= SbOP1_START && eOp < SbOP1_END)
739cdf0e10cSrcweir 		{
740cdf0e10cSrcweir 			nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
741cdf0e10cSrcweir 
742cdf0e10cSrcweir 			(this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 );
743cdf0e10cSrcweir 		}
744*93ed1f29SArmin Le Grand         else if (eOp >= SbOP2_START && eOp < SbOP2_END)
745cdf0e10cSrcweir 		{
746cdf0e10cSrcweir 			nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
747cdf0e10cSrcweir 			nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24;
748cdf0e10cSrcweir 			(this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 );
749cdf0e10cSrcweir 		}
750cdf0e10cSrcweir 		else
751cdf0e10cSrcweir 			StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
752cdf0e10cSrcweir 
753cdf0e10cSrcweir 		// SBX-Fehler aufgetreten?
754cdf0e10cSrcweir 		SbError nSbError = SbxBase::GetError();
755cdf0e10cSrcweir 		Error( ERRCODE_TOERROR(nSbError) );			// Warnings rausfiltern
756cdf0e10cSrcweir 
757cdf0e10cSrcweir 		// AB 13.2.1997, neues Error-Handling:
758cdf0e10cSrcweir 		// ACHTUNG: Hier kann nError auch dann gesetzt sein, wenn !nSbError,
759cdf0e10cSrcweir 		// da nError jetzt auch von anderen RT-Instanzen gesetzt werden kann
760cdf0e10cSrcweir 
761cdf0e10cSrcweir 		if( nError )
762cdf0e10cSrcweir 			SbxBase::ResetError();
763cdf0e10cSrcweir 
764cdf0e10cSrcweir 		// AB,15.3.96: Fehler nur anzeigen, wenn BASIC noch aktiv
765cdf0e10cSrcweir 		// (insbesondere nicht nach Compiler-Fehlern zur Laufzeit)
766cdf0e10cSrcweir 		if( nError && bRun )
767cdf0e10cSrcweir 		{
768cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
769cdf0e10cSrcweir 			SbError nTraceErr = nError;
770cdf0e10cSrcweir 			String aTraceErrMsg = GetSbData()->aErrMsg;
771cdf0e10cSrcweir 			bool bTraceErrHandled = true;
772cdf0e10cSrcweir #endif
773cdf0e10cSrcweir 			SbError err = nError;
774cdf0e10cSrcweir 			ClearExprStack();
775cdf0e10cSrcweir 			nError = 0;
776cdf0e10cSrcweir 			pInst->nErr = err;
777cdf0e10cSrcweir 			pInst->nErl = nLine;
778cdf0e10cSrcweir 			pErrCode    = pCode;
779cdf0e10cSrcweir 			pErrStmnt   = pStmnt;
780cdf0e10cSrcweir 			// An error occured in an error handler
781cdf0e10cSrcweir 			// force parent handler ( if there is one )
782cdf0e10cSrcweir 			// to handle the error
783cdf0e10cSrcweir 			bool bLetParentHandleThis = false;
784cdf0e10cSrcweir 
785cdf0e10cSrcweir 			// Im Error Handler? Dann Std-Error
786cdf0e10cSrcweir 			if ( !bInError )
787cdf0e10cSrcweir 			{
788cdf0e10cSrcweir 				bInError = sal_True;
789cdf0e10cSrcweir 
790cdf0e10cSrcweir 				if( !bError )			// On Error Resume Next
791cdf0e10cSrcweir 					StepRESUME( 1 );
792cdf0e10cSrcweir 				else if( pError )		// On Error Goto ...
793cdf0e10cSrcweir 					pCode = pError;
794cdf0e10cSrcweir 				else
795cdf0e10cSrcweir 					bLetParentHandleThis = true;
796cdf0e10cSrcweir             }
797cdf0e10cSrcweir 			else
798cdf0e10cSrcweir 			{
799cdf0e10cSrcweir 				bLetParentHandleThis = true;
800cdf0e10cSrcweir 				pError = NULL; //terminate the handler
801cdf0e10cSrcweir 			}
802cdf0e10cSrcweir 			if ( bLetParentHandleThis )
803cdf0e10cSrcweir 			{
804cdf0e10cSrcweir 				// AB 13.2.1997, neues Error-Handling:
805cdf0e10cSrcweir 				// Uebergeordnete Error-Handler beruecksichtigen
806cdf0e10cSrcweir 
807cdf0e10cSrcweir 				// Wir haben keinen Error-Handler -> weiter oben suchen
808cdf0e10cSrcweir 				SbiRuntime* pRtErrHdl = NULL;
809cdf0e10cSrcweir 				SbiRuntime* pRt = this;
810cdf0e10cSrcweir 				while( NULL != (pRt = pRt->pNext) )
811cdf0e10cSrcweir 				{
812cdf0e10cSrcweir 					// Gibt es einen Error-Handler?
813cdf0e10cSrcweir 					if( pRt->bError == sal_False || pRt->pError != NULL )
814cdf0e10cSrcweir 					{
815cdf0e10cSrcweir 						pRtErrHdl = pRt;
816cdf0e10cSrcweir 						break;
817cdf0e10cSrcweir 					}
818cdf0e10cSrcweir 				}
819cdf0e10cSrcweir 
820cdf0e10cSrcweir 				// Error-Hdl gefunden?
821cdf0e10cSrcweir 				if( pRtErrHdl )
822cdf0e10cSrcweir 				{
823cdf0e10cSrcweir 					// (Neuen) Error-Stack anlegen
824cdf0e10cSrcweir 					SbErrorStack*& rErrStack = GetSbData()->pErrStack;
825cdf0e10cSrcweir 					if( rErrStack )
826cdf0e10cSrcweir 						delete rErrStack;
827cdf0e10cSrcweir 					rErrStack = new SbErrorStack();
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 					// Alle im Call-Stack darunter stehenden RTs manipulieren
830cdf0e10cSrcweir 					pRt = this;
831cdf0e10cSrcweir 					do
832cdf0e10cSrcweir 					{
833cdf0e10cSrcweir 						// Fehler setzen
834cdf0e10cSrcweir 						pRt->nError = err;
835cdf0e10cSrcweir 						if( pRt != pRtErrHdl )
836cdf0e10cSrcweir 							pRt->bRun = sal_False;
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 						// In Error-Stack eintragen
839cdf0e10cSrcweir 						SbErrorStackEntry *pEntry = new SbErrorStackEntry
840cdf0e10cSrcweir 							( pRt->pMeth, pRt->nLine, pRt->nCol1, pRt->nCol2 );
841cdf0e10cSrcweir 						rErrStack->C40_INSERT(SbErrorStackEntry, pEntry, rErrStack->Count() );
842cdf0e10cSrcweir 
843cdf0e10cSrcweir 						// Nach RT mit Error-Handler aufhoeren
844cdf0e10cSrcweir 						if( pRt == pRtErrHdl )
845cdf0e10cSrcweir 							break;
846cdf0e10cSrcweir                            pRt = pRt->pNext;
847cdf0e10cSrcweir 					}
848cdf0e10cSrcweir 					while( pRt );
849cdf0e10cSrcweir 				}
850cdf0e10cSrcweir 				// Kein Error-Hdl gefunden -> altes Vorgehen
851cdf0e10cSrcweir 				else
852cdf0e10cSrcweir 				{
853cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
854cdf0e10cSrcweir 					bTraceErrHandled = false;
855cdf0e10cSrcweir #endif
856cdf0e10cSrcweir 					pInst->Abort();
857cdf0e10cSrcweir 				}
858cdf0e10cSrcweir 
859cdf0e10cSrcweir 				// ALT: Nur
860cdf0e10cSrcweir 				// pInst->Abort();
861cdf0e10cSrcweir 			}
862cdf0e10cSrcweir 
863cdf0e10cSrcweir #ifdef DBG_TRACE_BASIC
864cdf0e10cSrcweir 			dbg_traceNotifyError( nTraceErr, aTraceErrMsg, bTraceErrHandled, pINST->nCallLvl );
865cdf0e10cSrcweir #endif
866cdf0e10cSrcweir 		}
867cdf0e10cSrcweir 	}
868cdf0e10cSrcweir 	return bRun;
869cdf0e10cSrcweir }
870cdf0e10cSrcweir 
Error(SbError n,bool bVBATranslationAlreadyDone)871cdf0e10cSrcweir void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone )
872cdf0e10cSrcweir {
873cdf0e10cSrcweir 	if( n )
874cdf0e10cSrcweir 	{
875cdf0e10cSrcweir 		nError = n;
876cdf0e10cSrcweir 		if( isVBAEnabled() && !bVBATranslationAlreadyDone )
877cdf0e10cSrcweir 		{
878cdf0e10cSrcweir 			String aMsg = pInst->GetErrorMsg();
879cdf0e10cSrcweir 			sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg );
880cdf0e10cSrcweir 			SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject();
881cdf0e10cSrcweir 			SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar );
882cdf0e10cSrcweir 			if( pGlobErr != NULL )
883cdf0e10cSrcweir 				pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg );
884cdf0e10cSrcweir 
885cdf0e10cSrcweir 			pInst->aErrorMsg = aMsg;
886cdf0e10cSrcweir 			nError = SbERR_BASIC_COMPAT;
887cdf0e10cSrcweir 		}
888cdf0e10cSrcweir 	}
889cdf0e10cSrcweir }
890cdf0e10cSrcweir 
Error(SbError _errCode,const String & _details)891cdf0e10cSrcweir void SbiRuntime::Error( SbError _errCode, const String& _details )
892cdf0e10cSrcweir {
893cdf0e10cSrcweir     if ( _errCode )
894cdf0e10cSrcweir     {
895cdf0e10cSrcweir 		// Not correct for class module usage, remove for now
896cdf0e10cSrcweir         //OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" );
897cdf0e10cSrcweir         if ( pInst->pRun == this )
898cdf0e10cSrcweir         {
899cdf0e10cSrcweir             pInst->Error( _errCode, _details );
900cdf0e10cSrcweir             //OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" );
901cdf0e10cSrcweir         }
902cdf0e10cSrcweir         else
903cdf0e10cSrcweir         {
904cdf0e10cSrcweir             nError = _errCode;
905cdf0e10cSrcweir         }
906cdf0e10cSrcweir     }
907cdf0e10cSrcweir }
908cdf0e10cSrcweir 
FatalError(SbError n)909cdf0e10cSrcweir void SbiRuntime::FatalError( SbError n )
910cdf0e10cSrcweir {
911cdf0e10cSrcweir 	StepSTDERROR();
912cdf0e10cSrcweir 	Error( n );
913cdf0e10cSrcweir }
914cdf0e10cSrcweir 
FatalError(SbError _errCode,const String & _details)915cdf0e10cSrcweir void SbiRuntime::FatalError( SbError _errCode, const String& _details )
916cdf0e10cSrcweir {
917cdf0e10cSrcweir 	StepSTDERROR();
918cdf0e10cSrcweir 	Error( _errCode, _details );
919cdf0e10cSrcweir }
920cdf0e10cSrcweir 
translateErrorToVba(SbError nError,String & rMsg)921cdf0e10cSrcweir sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg )
922cdf0e10cSrcweir {
923cdf0e10cSrcweir 	// If a message is defined use that ( in preference to
924cdf0e10cSrcweir 	// the defined one for the error ) NB #TODO
925cdf0e10cSrcweir 	// if there is an error defined it more than likely
926cdf0e10cSrcweir 	// is not the one you want ( some are the same though )
927cdf0e10cSrcweir 	// we really need a new vba compatible error list
928cdf0e10cSrcweir 	if ( !rMsg.Len() )
929cdf0e10cSrcweir 	{
930cdf0e10cSrcweir 		// TEST, has to be vb here always
931cdf0e10cSrcweir #ifdef DBG_UTIL
932cdf0e10cSrcweir 		SbError nTmp = StarBASIC::GetSfxFromVBError( (sal_uInt16)nError );
933cdf0e10cSrcweir 		DBG_ASSERT( nTmp, "No VB error!" );
934cdf0e10cSrcweir #endif
935cdf0e10cSrcweir 
936cdf0e10cSrcweir 		StarBASIC::MakeErrorText( nError, rMsg );
937cdf0e10cSrcweir 		rMsg = StarBASIC::GetErrorText();
938cdf0e10cSrcweir 		if ( !rMsg.Len() ) // no message for err no, need localized resource here
939cdf0e10cSrcweir 			rMsg = String( RTL_CONSTASCII_USTRINGPARAM("Internal Object Error:") );
940cdf0e10cSrcweir 	}
941cdf0e10cSrcweir 	// no num? most likely then it *is* really a vba err
942cdf0e10cSrcweir 	sal_uInt16 nVBErrorCode = StarBASIC::GetVBErrorCode( nError );
943cdf0e10cSrcweir 	sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode;
944cdf0e10cSrcweir 	return nVBAErrorNumber;
945cdf0e10cSrcweir }
946cdf0e10cSrcweir 
947cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
948cdf0e10cSrcweir //
949cdf0e10cSrcweir //	Parameter, Locals, Caller
950cdf0e10cSrcweir //
951cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
952cdf0e10cSrcweir 
GetCaller()953cdf0e10cSrcweir SbMethod* SbiRuntime::GetCaller()
954cdf0e10cSrcweir {
955cdf0e10cSrcweir 	return pMeth;
956cdf0e10cSrcweir }
957cdf0e10cSrcweir 
GetLocals()958cdf0e10cSrcweir SbxArray* SbiRuntime::GetLocals()
959cdf0e10cSrcweir {
960cdf0e10cSrcweir 	return refLocals;
961cdf0e10cSrcweir }
962cdf0e10cSrcweir 
GetParams()963cdf0e10cSrcweir SbxArray* SbiRuntime::GetParams()
964cdf0e10cSrcweir {
965cdf0e10cSrcweir 	return refParams;
966cdf0e10cSrcweir }
967cdf0e10cSrcweir 
968cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
969cdf0e10cSrcweir //
970cdf0e10cSrcweir //	Stacks
971cdf0e10cSrcweir //
972cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
973cdf0e10cSrcweir 
974cdf0e10cSrcweir // Der Expression-Stack steht fuer die laufende Auswertung von Expressions
975cdf0e10cSrcweir // zur Verfuegung.
976cdf0e10cSrcweir 
PushVar(SbxVariable * pVar)977cdf0e10cSrcweir void SbiRuntime::PushVar( SbxVariable* pVar )
978cdf0e10cSrcweir {
979cdf0e10cSrcweir 	if( pVar )
980cdf0e10cSrcweir 		refExprStk->Put( pVar, nExprLvl++ );
981cdf0e10cSrcweir }
982cdf0e10cSrcweir 
PopVar()983cdf0e10cSrcweir SbxVariableRef SbiRuntime::PopVar()
984cdf0e10cSrcweir {
985cdf0e10cSrcweir #ifdef DBG_UTIL
986cdf0e10cSrcweir 	if( !nExprLvl )
987cdf0e10cSrcweir 	{
988cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
989cdf0e10cSrcweir 		return new SbxVariable;
990cdf0e10cSrcweir 	}
991cdf0e10cSrcweir #endif
992cdf0e10cSrcweir 	SbxVariableRef xVar = refExprStk->Get( --nExprLvl );
993cdf0e10cSrcweir #ifdef DBG_UTIL
994cdf0e10cSrcweir 	if ( xVar->GetName().EqualsAscii( "Cells" ) )
995cdf0e10cSrcweir 		DBG_TRACE( "" );
996cdf0e10cSrcweir #endif
997cdf0e10cSrcweir 	// Methods halten im 0.Parameter sich selbst, also weghauen
998cdf0e10cSrcweir 	if( xVar->IsA( TYPE(SbxMethod) ) )
999cdf0e10cSrcweir 		xVar->SetParameters(0);
1000cdf0e10cSrcweir 	return xVar;
1001cdf0e10cSrcweir }
1002cdf0e10cSrcweir 
ClearExprStack()1003cdf0e10cSrcweir sal_Bool SbiRuntime::ClearExprStack()
1004cdf0e10cSrcweir {
1005cdf0e10cSrcweir 	// Achtung: Clear() reicht nicht, da Methods geloescht werden muessen
1006cdf0e10cSrcweir 	while ( nExprLvl )
1007cdf0e10cSrcweir 	{
1008cdf0e10cSrcweir 		PopVar();
1009cdf0e10cSrcweir 	}
1010cdf0e10cSrcweir 	refExprStk->Clear();
1011cdf0e10cSrcweir 	return sal_False;
1012cdf0e10cSrcweir }
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir // Variable auf dem Expression-Stack holen, ohne sie zu entfernen
1015cdf0e10cSrcweir // n zaehlt ab 0.
1016cdf0e10cSrcweir 
GetTOS(short n)1017cdf0e10cSrcweir SbxVariable* SbiRuntime::GetTOS( short n )
1018cdf0e10cSrcweir {
1019cdf0e10cSrcweir 	n = nExprLvl - n - 1;
1020cdf0e10cSrcweir #ifdef DBG_UTIL
1021cdf0e10cSrcweir 	if( n < 0 )
1022cdf0e10cSrcweir 	{
1023cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1024cdf0e10cSrcweir 		return new SbxVariable;
1025cdf0e10cSrcweir 	}
1026cdf0e10cSrcweir #endif
1027cdf0e10cSrcweir 	return refExprStk->Get( (sal_uInt16) n );
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir // Sicherstellen, dass TOS eine temporaere Variable ist
1031cdf0e10cSrcweir 
TOSMakeTemp()1032cdf0e10cSrcweir void SbiRuntime::TOSMakeTemp()
1033cdf0e10cSrcweir {
1034cdf0e10cSrcweir 	SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
1035cdf0e10cSrcweir 	if( p->GetRefCount() != 1 )
1036cdf0e10cSrcweir 	{
1037cdf0e10cSrcweir 		SbxVariable* pNew = new SbxVariable( *p );
1038cdf0e10cSrcweir 		pNew->SetFlag( SBX_READWRITE );
1039cdf0e10cSrcweir 		refExprStk->Put( pNew, nExprLvl - 1 );
1040cdf0e10cSrcweir 	}
1041cdf0e10cSrcweir }
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir // Der GOSUB-Stack nimmt Returnadressen fuer GOSUBs auf
1044cdf0e10cSrcweir 
PushGosub(const sal_uInt8 * pc)1045cdf0e10cSrcweir void SbiRuntime::PushGosub( const sal_uInt8* pc )
1046cdf0e10cSrcweir {
1047cdf0e10cSrcweir 	if( ++nGosubLvl > MAXRECURSION )
1048cdf0e10cSrcweir 		StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
1049cdf0e10cSrcweir 	SbiGosubStack* p = new SbiGosubStack;
1050cdf0e10cSrcweir 	p->pCode  = pc;
1051cdf0e10cSrcweir 	p->pNext  = pGosubStk;
1052cdf0e10cSrcweir 	p->nStartForLvl = nForLvl;
1053cdf0e10cSrcweir 	pGosubStk = p;
1054cdf0e10cSrcweir }
1055cdf0e10cSrcweir 
PopGosub()1056cdf0e10cSrcweir void SbiRuntime::PopGosub()
1057cdf0e10cSrcweir {
1058cdf0e10cSrcweir 	if( !pGosubStk )
1059cdf0e10cSrcweir 		Error( SbERR_NO_GOSUB );
1060cdf0e10cSrcweir 	else
1061cdf0e10cSrcweir 	{
1062cdf0e10cSrcweir 		SbiGosubStack* p = pGosubStk;
1063cdf0e10cSrcweir 		pCode = p->pCode;
1064cdf0e10cSrcweir 		pGosubStk = p->pNext;
1065cdf0e10cSrcweir 		delete p;
1066cdf0e10cSrcweir 		nGosubLvl--;
1067cdf0e10cSrcweir 	}
1068cdf0e10cSrcweir }
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir // Entleeren des GOSUB-Stacks
1071cdf0e10cSrcweir 
ClearGosubStack()1072cdf0e10cSrcweir void SbiRuntime::ClearGosubStack()
1073cdf0e10cSrcweir {
1074cdf0e10cSrcweir 	SbiGosubStack* p;
1075cdf0e10cSrcweir 	while(( p = pGosubStk ) != NULL )
1076cdf0e10cSrcweir 		pGosubStk = p->pNext, delete p;
1077cdf0e10cSrcweir 	nGosubLvl = 0;
1078cdf0e10cSrcweir }
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir // Der Argv-Stack nimmt aktuelle Argument-Vektoren auf
1081cdf0e10cSrcweir 
PushArgv()1082cdf0e10cSrcweir void SbiRuntime::PushArgv()
1083cdf0e10cSrcweir {
1084cdf0e10cSrcweir 	SbiArgvStack* p = new SbiArgvStack;
1085cdf0e10cSrcweir 	p->refArgv = refArgv;
1086cdf0e10cSrcweir 	p->nArgc = nArgc;
1087cdf0e10cSrcweir 	nArgc = 1;
1088cdf0e10cSrcweir 	refArgv.Clear();
1089cdf0e10cSrcweir 	p->pNext = pArgvStk;
1090cdf0e10cSrcweir 	pArgvStk = p;
1091cdf0e10cSrcweir }
1092cdf0e10cSrcweir 
PopArgv()1093cdf0e10cSrcweir void SbiRuntime::PopArgv()
1094cdf0e10cSrcweir {
1095cdf0e10cSrcweir 	if( pArgvStk )
1096cdf0e10cSrcweir 	{
1097cdf0e10cSrcweir 		SbiArgvStack* p = pArgvStk;
1098cdf0e10cSrcweir 		pArgvStk = p->pNext;
1099cdf0e10cSrcweir 		refArgv = p->refArgv;
1100cdf0e10cSrcweir 		nArgc = p->nArgc;
1101cdf0e10cSrcweir 		delete p;
1102cdf0e10cSrcweir 	}
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir // Entleeren des Argv-Stacks
1106cdf0e10cSrcweir 
ClearArgvStack()1107cdf0e10cSrcweir void SbiRuntime::ClearArgvStack()
1108cdf0e10cSrcweir {
1109cdf0e10cSrcweir 	while( pArgvStk )
1110cdf0e10cSrcweir 		PopArgv();
1111cdf0e10cSrcweir }
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir // Push des For-Stacks. Der Stack hat Inkrement, Ende, Beginn und Variable.
1114cdf0e10cSrcweir // Nach Aufbau des Stack-Elements ist der Stack leer.
1115cdf0e10cSrcweir 
PushFor()1116cdf0e10cSrcweir void SbiRuntime::PushFor()
1117cdf0e10cSrcweir {
1118cdf0e10cSrcweir 	SbiForStack* p = new SbiForStack;
1119cdf0e10cSrcweir 	p->eForType = FOR_TO;
1120cdf0e10cSrcweir 	p->pNext = pForStk;
1121cdf0e10cSrcweir 	pForStk = p;
1122cdf0e10cSrcweir 	// Der Stack ist wie folgt aufgebaut:
1123cdf0e10cSrcweir 	p->refInc = PopVar();
1124cdf0e10cSrcweir 	p->refEnd = PopVar();
1125cdf0e10cSrcweir 	SbxVariableRef xBgn = PopVar();
1126cdf0e10cSrcweir 	p->refVar = PopVar();
1127cdf0e10cSrcweir 	*(p->refVar) = *xBgn;
1128cdf0e10cSrcweir 	nForLvl++;
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir 
PushForEach()1131cdf0e10cSrcweir void SbiRuntime::PushForEach()
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir 	SbiForStack* p = new SbiForStack;
1134cdf0e10cSrcweir 	p->pNext = pForStk;
1135cdf0e10cSrcweir 	pForStk = p;
1136cdf0e10cSrcweir 
1137cdf0e10cSrcweir 	SbxVariableRef xObjVar = PopVar();
1138cdf0e10cSrcweir 	SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL;
1139cdf0e10cSrcweir 	if( pObj == NULL )
1140cdf0e10cSrcweir 	{
1141cdf0e10cSrcweir 		Error( SbERR_NO_OBJECT );
1142cdf0e10cSrcweir 		return;
1143cdf0e10cSrcweir 	}
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir 	bool bError_ = false;
1146cdf0e10cSrcweir 	BasicCollection* pCollection;
1147cdf0e10cSrcweir 	SbxDimArray* pArray;
1148cdf0e10cSrcweir 	SbUnoObject* pUnoObj;
1149cdf0e10cSrcweir 	if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL )
1150cdf0e10cSrcweir 	{
1151cdf0e10cSrcweir 		p->eForType = FOR_EACH_ARRAY;
1152cdf0e10cSrcweir 		p->refEnd = (SbxVariable*)pArray;
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir 		short nDims = pArray->GetDims();
1155cdf0e10cSrcweir 		p->pArrayLowerBounds = new sal_Int32[nDims];
1156cdf0e10cSrcweir 		p->pArrayUpperBounds = new sal_Int32[nDims];
1157cdf0e10cSrcweir 		p->pArrayCurIndices  = new sal_Int32[nDims];
1158cdf0e10cSrcweir 		sal_Int32 lBound, uBound;
1159cdf0e10cSrcweir 		for( short i = 0 ; i < nDims ; i++ )
1160cdf0e10cSrcweir 		{
1161cdf0e10cSrcweir 			pArray->GetDim32( i+1, lBound, uBound );
1162cdf0e10cSrcweir 			p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound;
1163cdf0e10cSrcweir 			p->pArrayUpperBounds[i] = uBound;
1164cdf0e10cSrcweir 		}
1165cdf0e10cSrcweir 	}
1166cdf0e10cSrcweir 	else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL )
1167cdf0e10cSrcweir 	{
1168cdf0e10cSrcweir 		p->eForType = FOR_EACH_COLLECTION;
1169cdf0e10cSrcweir 		p->refEnd = pCollection;
1170cdf0e10cSrcweir 		p->nCurCollectionIndex = 0;
1171cdf0e10cSrcweir 	}
1172cdf0e10cSrcweir 	else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
1173cdf0e10cSrcweir 	{
1174cdf0e10cSrcweir 		// XEnumerationAccess?
1175cdf0e10cSrcweir 		Any aAny = pUnoObj->getUnoAny();
1176cdf0e10cSrcweir 		Reference< XEnumerationAccess > xEnumerationAccess;
1177cdf0e10cSrcweir 		if( (aAny >>= xEnumerationAccess) )
1178cdf0e10cSrcweir 		{
1179cdf0e10cSrcweir 			p->xEnumeration = xEnumerationAccess->createEnumeration();
1180cdf0e10cSrcweir 			p->eForType = FOR_EACH_XENUMERATION;
1181cdf0e10cSrcweir 		}
1182cdf0e10cSrcweir 		else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() )
1183cdf0e10cSrcweir         {
1184cdf0e10cSrcweir             uno::Reference< script::XInvocation > xInvocation;
1185cdf0e10cSrcweir             if ( ( aAny >>= xInvocation ) && xInvocation.is() )
1186cdf0e10cSrcweir             {
1187cdf0e10cSrcweir                 try
1188cdf0e10cSrcweir                 {
1189cdf0e10cSrcweir                     p->xEnumeration = new ComEnumerationWrapper( xInvocation );
1190cdf0e10cSrcweir                     p->eForType = FOR_EACH_XENUMERATION;
1191cdf0e10cSrcweir                 }
1192cdf0e10cSrcweir                 catch( uno::Exception& )
1193cdf0e10cSrcweir                 {}
1194cdf0e10cSrcweir             }
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir             if ( !p->xEnumeration.is() )
1197cdf0e10cSrcweir                 bError_ = true;
1198cdf0e10cSrcweir         }
1199cdf0e10cSrcweir         else
1200cdf0e10cSrcweir 		{
1201cdf0e10cSrcweir 			bError_ = true;
1202cdf0e10cSrcweir 		}
1203cdf0e10cSrcweir 	}
1204cdf0e10cSrcweir 	else
1205cdf0e10cSrcweir 	{
1206cdf0e10cSrcweir 		bError_ = true;
1207cdf0e10cSrcweir 	}
1208cdf0e10cSrcweir 
1209cdf0e10cSrcweir 	if( bError_ )
1210cdf0e10cSrcweir 	{
1211cdf0e10cSrcweir 		Error( SbERR_CONVERSION );
1212cdf0e10cSrcweir 		return;
1213cdf0e10cSrcweir 	}
1214cdf0e10cSrcweir 
1215cdf0e10cSrcweir 	// Container variable
1216cdf0e10cSrcweir 	p->refVar = PopVar();
1217cdf0e10cSrcweir 	nForLvl++;
1218cdf0e10cSrcweir }
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir // Poppen des FOR-Stacks
1221cdf0e10cSrcweir 
PopFor()1222cdf0e10cSrcweir void SbiRuntime::PopFor()
1223cdf0e10cSrcweir {
1224cdf0e10cSrcweir 	if( pForStk )
1225cdf0e10cSrcweir 	{
1226cdf0e10cSrcweir 		SbiForStack* p = pForStk;
1227cdf0e10cSrcweir 		pForStk = p->pNext;
1228cdf0e10cSrcweir 		delete p;
1229cdf0e10cSrcweir 		nForLvl--;
1230cdf0e10cSrcweir 	}
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir // Entleeren des FOR-Stacks
1234cdf0e10cSrcweir 
ClearForStack()1235cdf0e10cSrcweir void SbiRuntime::ClearForStack()
1236cdf0e10cSrcweir {
1237cdf0e10cSrcweir 	while( pForStk )
1238cdf0e10cSrcweir 		PopFor();
1239cdf0e10cSrcweir }
1240cdf0e10cSrcweir 
FindForStackItemForCollection(class BasicCollection * pCollection)1241cdf0e10cSrcweir SbiForStack* SbiRuntime::FindForStackItemForCollection( class BasicCollection* pCollection )
1242cdf0e10cSrcweir {
1243cdf0e10cSrcweir 	SbiForStack* pRet = NULL;
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir 	SbiForStack* p = pForStk;
1246cdf0e10cSrcweir 	while( p )
1247cdf0e10cSrcweir 	{
1248cdf0e10cSrcweir 		SbxVariable* pVar = p->refEnd.Is() ? (SbxVariable*)p->refEnd : NULL;
1249cdf0e10cSrcweir 		if( p->eForType == FOR_EACH_COLLECTION && pVar != NULL &&
1250cdf0e10cSrcweir 			(pCollection = PTR_CAST(BasicCollection,pVar)) == pCollection )
1251cdf0e10cSrcweir 		{
1252cdf0e10cSrcweir 			pRet = p;
1253cdf0e10cSrcweir 			break;
1254cdf0e10cSrcweir 		}
1255cdf0e10cSrcweir 	}
1256cdf0e10cSrcweir 
1257cdf0e10cSrcweir 	return pRet;
1258cdf0e10cSrcweir }
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir 
1261cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
1262cdf0e10cSrcweir //
1263cdf0e10cSrcweir //	DLL-Aufrufe
1264cdf0e10cSrcweir //
1265cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
1266cdf0e10cSrcweir 
DllCall(const String & aFuncName,const String & aDLLName,SbxArray * pArgs,SbxDataType eResType,sal_Bool bCDecl)1267cdf0e10cSrcweir void SbiRuntime::DllCall
1268cdf0e10cSrcweir 	( const String& aFuncName,	// Funktionsname
1269cdf0e10cSrcweir 	  const String& aDLLName,	// Name der DLL
1270cdf0e10cSrcweir 	  SbxArray* pArgs,			// Parameter (ab Index 1, kann NULL sein)
1271cdf0e10cSrcweir 	  SbxDataType eResType,		// Returnwert
1272cdf0e10cSrcweir 	  sal_Bool bCDecl )				// sal_True: nach C-Konventionen
1273cdf0e10cSrcweir {
1274cdf0e10cSrcweir 	// No DllCall for "virtual" portal users
1275cdf0e10cSrcweir 	if( needSecurityRestrictions() )
1276cdf0e10cSrcweir 	{
1277cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
1278cdf0e10cSrcweir 		return;
1279cdf0e10cSrcweir 	}
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir 	// MUSS NOCH IMPLEMENTIERT WERDEN
1282cdf0e10cSrcweir 	/*
1283cdf0e10cSrcweir 	String aMsg;
1284cdf0e10cSrcweir 	aMsg = "FUNC=";
1285cdf0e10cSrcweir 	aMsg += pFunc;
1286cdf0e10cSrcweir 	aMsg += " DLL=";
1287cdf0e10cSrcweir 	aMsg += pDLL;
1288cdf0e10cSrcweir 	MessBox( NULL, WB_OK, String( "DLL-CALL" ), aMsg ).Execute();
1289cdf0e10cSrcweir 	Error( SbERR_NOT_IMPLEMENTED );
1290cdf0e10cSrcweir 	*/
1291cdf0e10cSrcweir 
1292cdf0e10cSrcweir 	SbxVariable* pRes = new SbxVariable( eResType );
1293cdf0e10cSrcweir 	SbiDllMgr* pDllMgr = pInst->GetDllMgr();
1294cdf0e10cSrcweir 	SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
1295cdf0e10cSrcweir 	if( nErr )
1296cdf0e10cSrcweir 		Error( nErr );
1297cdf0e10cSrcweir 	PushVar( pRes );
1298cdf0e10cSrcweir }
1299cdf0e10cSrcweir 
GetImageFlag(sal_uInt16 n) const1300cdf0e10cSrcweir sal_uInt16 SbiRuntime::GetImageFlag( sal_uInt16 n ) const
1301cdf0e10cSrcweir {
1302cdf0e10cSrcweir 	return pImg->GetFlag( n );
1303cdf0e10cSrcweir }
1304cdf0e10cSrcweir 
GetBase()1305cdf0e10cSrcweir sal_uInt16 SbiRuntime::GetBase()
1306cdf0e10cSrcweir {
1307cdf0e10cSrcweir 	return pImg->GetBase();
1308cdf0e10cSrcweir }
1309