xref: /trunk/main/basic/source/runtime/runtime.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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
10cdf0e10cSrcweir  *
11e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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;
73493ed1f29SArmin Le Grand         if (eOp < SbOP0_END)
735cdf0e10cSrcweir         {
736cdf0e10cSrcweir             (this->*( aStep0[ eOp ] ) )();
737cdf0e10cSrcweir         }
73893ed1f29SArmin 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         }
74493ed1f29SArmin 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;
780*07a3d7f1SPedro Giffuni             // An error occurred 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