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