/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"
#include <tools/fsys.hxx>
#include <vcl/svapp.hxx>
#include <tools/wldcrd.hxx>
#include <svl/zforlist.hxx>
#include <unotools/syslocale.hxx>
#include "runtime.hxx"
#include "sbintern.hxx"
#include "opcodes.hxx"
#include "codegen.hxx"
#include "iosys.hxx"
#include "image.hxx"
#include "ddectrl.hxx"
#include "dllmgr.hxx"
#include <comphelper/processfactory.hxx>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include "sbunoobj.hxx"
#include "errobject.hxx"
#include "sbtrace.hxx"
#include "comenumwrapper.hxx"

using namespace ::com::sun::star;

bool SbiRuntime::isVBAEnabled()
{
	bool result = false;
	SbiInstance* pInst = pINST;
	if ( pInst && pINST->pRun )
		result = pInst->pRun->bVBAEnabled;
	return result;
}

// #91147 Global reschedule flag
static sal_Bool bStaticGlobalEnableReschedule = sal_True;

void StarBASIC::StaticEnableReschedule( sal_Bool bReschedule )
{
    bStaticGlobalEnableReschedule = bReschedule;
}
void StarBASIC::SetVBAEnabled( sal_Bool bEnabled )
{
    if ( bDocBasic )
    {
        bVBAEnabled = bEnabled;
    }
}

sal_Bool StarBASIC::isVBAEnabled()
{
    if ( bDocBasic )
    {
        if( SbiRuntime::isVBAEnabled() )
            return sal_True;
        return bVBAEnabled;
    }
    return sal_False;
}


struct SbiArgvStack {					// Argv stack:
	SbiArgvStack*  pNext;	   			// Stack Chain
	SbxArrayRef    refArgv;	 			// Argv
	short nArgc;						// Argc
};

SbiRuntime::pStep0 SbiRuntime::aStep0[] = {	// Alle Opcodes ohne Operanden
	&SbiRuntime::StepNOP,
	&SbiRuntime::StepEXP,
	&SbiRuntime::StepMUL,
	&SbiRuntime::StepDIV,
	&SbiRuntime::StepMOD,
	&SbiRuntime::StepPLUS,
	&SbiRuntime::StepMINUS,
	&SbiRuntime::StepNEG,
	&SbiRuntime::StepEQ,
	&SbiRuntime::StepNE,
	&SbiRuntime::StepLT,
	&SbiRuntime::StepGT,
	&SbiRuntime::StepLE,
	&SbiRuntime::StepGE,
	&SbiRuntime::StepIDIV,
	&SbiRuntime::StepAND,
	&SbiRuntime::StepOR,
	&SbiRuntime::StepXOR,
	&SbiRuntime::StepEQV,
	&SbiRuntime::StepIMP,
	&SbiRuntime::StepNOT,
	&SbiRuntime::StepCAT,

	&SbiRuntime::StepLIKE,
	&SbiRuntime::StepIS,
	// Laden/speichern
	&SbiRuntime::StepARGC,		// neuen Argv einrichten
	&SbiRuntime::StepARGV,		// TOS ==> aktueller Argv
	&SbiRuntime::StepINPUT,	 	// Input ==> TOS
	&SbiRuntime::StepLINPUT,	 	// Line Input ==> TOS
	&SbiRuntime::StepGET,        // TOS anfassen
	&SbiRuntime::StepSET,        // Speichern Objekt TOS ==> TOS-1
	&SbiRuntime::StepPUT,		// TOS ==> TOS-1
	&SbiRuntime::StepPUTC,		// TOS ==> TOS-1, dann ReadOnly
	&SbiRuntime::StepDIM,		// DIM
	&SbiRuntime::StepREDIM, 		// REDIM
	&SbiRuntime::StepREDIMP,		// REDIM PRESERVE
	&SbiRuntime::StepERASE, 		// TOS loeschen
	// Verzweigen
	&SbiRuntime::StepSTOP,  	  	// Programmende
	&SbiRuntime::StepINITFOR,  	// FOR-Variable initialisieren
	&SbiRuntime::StepNEXT,	  	// FOR-Variable inkrementieren
	&SbiRuntime::StepCASE,	  	// Anfang CASE
	&SbiRuntime::StepENDCASE,  	// Ende CASE
	&SbiRuntime::StepSTDERROR,  	// Standard-Fehlerbehandlung
	&SbiRuntime::StepNOERROR,  	// keine Fehlerbehandlung
	&SbiRuntime::StepLEAVE,		// UP verlassen
	// E/A
	&SbiRuntime::StepCHANNEL,  	// TOS = Kanalnummer
	&SbiRuntime::StepPRINT,	  	// print TOS
	&SbiRuntime::StepPRINTF,	  	// print TOS in field
	&SbiRuntime::StepWRITE,	  	// write TOS
	&SbiRuntime::StepRENAME,	  	// Rename Tos+1 to Tos
	&SbiRuntime::StepPROMPT,	  	// Input Prompt aus TOS definieren
	&SbiRuntime::StepRESTART,  	// Set restart point
	&SbiRuntime::StepCHANNEL0,	// E/A-Kanal 0 einstellen
	&SbiRuntime::StepEMPTY,		// Leeren Ausdruck auf Stack
	&SbiRuntime::StepERROR,	  	// TOS = Fehlercode
	&SbiRuntime::StepLSET,		// Speichern Objekt TOS ==> TOS-1
	&SbiRuntime::StepRSET,		// Speichern Objekt TOS ==> TOS-1
	&SbiRuntime::StepREDIMP_ERASE,// Copy array object for REDIMP
	&SbiRuntime::StepINITFOREACH,// Init for each loop
	&SbiRuntime::StepVBASET,// vba-like set statement
	&SbiRuntime::StepERASE_CLEAR,// vba-like set statement
	&SbiRuntime::StepARRAYACCESS,// access TOS as array
	&SbiRuntime::StepBYVAL,     // access TOS as array
};

SbiRuntime::pStep1 SbiRuntime::aStep1[] = {	// Alle Opcodes mit einem Operanden
	&SbiRuntime::StepLOADNC,	  	// Laden einer numerischen Konstanten (+ID)
	&SbiRuntime::StepLOADSC,	  	// Laden einer Stringkonstanten (+ID)
	&SbiRuntime::StepLOADI,	  	// Immediate Load (+Wert)
	&SbiRuntime::StepARGN,		// Speichern eines named Args in Argv (+StringID)
	&SbiRuntime::StepPAD,	  	// String auf feste Laenge bringen (+Laenge)
	// Verzweigungen
	&SbiRuntime::StepJUMP,	  	// Sprung (+Target)
	&SbiRuntime::StepJUMPT,	  	// TOS auswerten), bedingter Sprung (+Target)
	&SbiRuntime::StepJUMPF,	  	// TOS auswerten), bedingter Sprung (+Target)
	&SbiRuntime::StepONJUMP,	  	// TOS auswerten), Sprung in JUMP-Tabelle (+MaxVal)
	&SbiRuntime::StepGOSUB,		// UP-Aufruf (+Target)
	&SbiRuntime::StepRETURN,		// UP-Return (+0 oder Target)
	&SbiRuntime::StepTESTFOR,	// FOR-Variable testen), inkrementieren (+Endlabel)
	&SbiRuntime::StepCASETO,		// Tos+1 <= Case <= Tos), 2xremove (+Target)
	&SbiRuntime::StepERRHDL,		// Fehler-Handler (+Offset)
	&SbiRuntime::StepRESUME,		// Resume nach Fehlern (+0 or 1 or Label)
	// E/A
	&SbiRuntime::StepCLOSE,		// (+Kanal/0)
	&SbiRuntime::StepPRCHAR,		// (+char)
	// Verwaltung
	&SbiRuntime::StepSETCLASS,	// Set + Klassennamen testen (+StringId)
	&SbiRuntime::StepTESTCLASS,	// Check TOS class (+StringId)
	&SbiRuntime::StepLIB,  		// Lib fuer Declare-Call (+StringId)
	&SbiRuntime::StepBASED,	  	// TOS wird um BASE erhoeht, BASE davor gepusht
	&SbiRuntime::StepARGTYP,	  	// Letzten Parameter in Argv konvertieren (+Typ)
	&SbiRuntime::StepVBASETCLASS,// vba-like set statement
};

SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// Alle Opcodes mit zwei Operanden
	&SbiRuntime::StepRTL,  	    // Laden aus RTL (+StringID+Typ)
	&SbiRuntime::StepFIND,	    // Laden (+StringID+Typ)
	&SbiRuntime::StepELEM,  		// Laden Element (+StringID+Typ)
	&SbiRuntime::StepPARAM,		// Parameter (+Offset+Typ)
	// Verzweigen
	&SbiRuntime::StepCALL,	  	// Declare-Call (+StringID+Typ)
	&SbiRuntime::StepCALLC,	  	// CDecl-Declare-Call (+StringID+Typ)
	&SbiRuntime::StepCASEIS,		// Case-Test (+Test-Opcode+False-Target)
	// Verwaltung
	&SbiRuntime::StepSTMNT, 		// Beginn eines Statements (+Line+Col)
	// E/A
	&SbiRuntime::StepOPEN,  		// (+SvStreamFlags+Flags)
	// Objekte
	&SbiRuntime::StepLOCAL,		// Lokale Variable definieren (+StringId+Typ)
	&SbiRuntime::StepPUBLIC,		// Modulglobale Variable (+StringID+Typ)
	&SbiRuntime::StepGLOBAL,	  	// Globale Variable definieren (+StringID+Typ)
	&SbiRuntime::StepCREATE,		// Objekt kreieren (+StringId+StringId)
	&SbiRuntime::StepSTATIC,     // Statische Variable (+StringId+StringId)
	&SbiRuntime::StepTCREATE,    // User Defined Objekte (+StringId+StringId)
	&SbiRuntime::StepDCREATE,    // Objekt-Array kreieren (+StringID+StringID)
	&SbiRuntime::StepGLOBAL_P,   // Globale Variable definieren, die beim Neustart
                                        // von Basic nicht ueberschrieben wird (+StringID+Typ)
	&SbiRuntime::StepFIND_G,    	// Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
	&SbiRuntime::StepDCREATE_REDIMP, // Objekt-Array redimensionieren (+StringID+StringID)
	&SbiRuntime::StepFIND_CM,    // Search inside a class module (CM) to enable global search in time
	&SbiRuntime::StepPUBLIC_P,    // Search inside a class module (CM) to enable global search in time
	&SbiRuntime::StepFIND_STATIC,    // Search inside a class module (CM) to enable global search in time
};


//////////////////////////////////////////////////////////////////////////
//								SbiRTLData								//
//////////////////////////////////////////////////////////////////////////

SbiRTLData::SbiRTLData()
{
	pDir		= 0;
	nDirFlags	= 0;
	nCurDirPos	= 0;
	pWildCard	= NULL;
}

SbiRTLData::~SbiRTLData()
{
	delete pDir;
	pDir = 0;
	delete pWildCard;
}

//////////////////////////////////////////////////////////////////////////
//								SbiInstance								//
//////////////////////////////////////////////////////////////////////////

// 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
// Die Entscheidung, ob StepPoint aufgerufen werden soll, wird anhand des
// CallLevels getroffen. Angehalten wird, wenn der aktuelle CallLevel <=
// nBreakCallLvl ist. Der aktuelle CallLevel kann niemals kleiner als 1
// sein, da er beim Aufruf einer Methode (auch main) inkrementiert wird.
// Daher bedeutet ein BreakCallLvl von 0, dass das Programm gar nicht
// angehalten wird.
// (siehe auch step2.cxx, SbiRuntime::StepSTMNT() )

// Hilfsfunktion, um den BreakCallLevel gemaess der der Debug-Flags zu ermitteln
void SbiInstance::CalcBreakCallLevel( sal_uInt16 nFlags )
{
	// Break-Flag wegfiltern
	nFlags &= ~((sal_uInt16)SbDEBUG_BREAK);

	sal_uInt16 nRet;
	switch( nFlags )
	{
		case SbDEBUG_STEPINTO:
			nRet = nCallLvl + 1;	// CallLevel+1 wird auch angehalten
			break;
		case SbDEBUG_STEPOVER | SbDEBUG_STEPINTO:
			nRet = nCallLvl;		// Aktueller CallLevel wird angehalten
			break;
		case SbDEBUG_STEPOUT:
			nRet = nCallLvl - 1;	// Kleinerer CallLevel wird angehalten
			break;
		case SbDEBUG_CONTINUE:
		// Basic-IDE liefert 0 statt SbDEBUG_CONTINUE, also auch default=continue
		default:
			nRet = 0;				// CallLevel ist immer >0 -> kein StepPoint
	}
	nBreakCallLvl = nRet;			// Ergebnis uebernehmen
}

SbiInstance::SbiInstance( StarBASIC* p )
{
	pBasic   = p;
	pNext    = NULL;
	pRun     = NULL;
	pIosys   = new SbiIoSystem;
	pDdeCtrl = new SbiDdeControl;
	pDllMgr	 = 0; // on demand
	pNumberFormatter = 0; // on demand
	nCallLvl = 0;
	nBreakCallLvl = 0;
	nErr	 =
	nErl	 = 0;
	bReschedule = sal_True;
	bCompatibility = sal_False;
}

SbiInstance::~SbiInstance()
{
	while( pRun )
	{
		SbiRuntime* p = pRun->pNext;
		delete pRun;
		pRun = p;
	}
	delete pIosys;
	delete pDdeCtrl;
	delete pDllMgr;
	delete pNumberFormatter;

	try
	{
		int nSize = ComponentVector.size();
		if( nSize )
		{
			for( int i = nSize - 1 ; i >= 0 ; --i )
			{
				Reference< XComponent > xDlgComponent = ComponentVector[i];
				if( xDlgComponent.is() )
					xDlgComponent->dispose();
			}
		}
	}
	catch( const Exception& )
	{
		DBG_ERROR( "SbiInstance::~SbiInstance: caught an exception while disposing the components!" );
	}

    ComponentVector.clear();
}

SbiDllMgr* SbiInstance::GetDllMgr()
{
	if( !pDllMgr )
		pDllMgr = new SbiDllMgr;
	return pDllMgr;
}

// #39629 NumberFormatter jetzt ueber statische Methode anlegen
SvNumberFormatter* SbiInstance::GetNumberFormatter()
{
    LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
    SvtSysLocale aSysLocale;
    DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
	if( pNumberFormatter )
    {
        if( eLangType != meFormatterLangType ||
            eDate != meFormatterDateFormat )
        {
            delete pNumberFormatter;
            pNumberFormatter = NULL;
        }
    }
    meFormatterLangType = eLangType;
    meFormatterDateFormat = eDate;
	if( !pNumberFormatter )
		PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx,
        &meFormatterLangType, &meFormatterDateFormat );
	return pNumberFormatter;
}

// #39629 NumberFormatter auch statisch anbieten
void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
	sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
    LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat )
{
	com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
		xFactory = comphelper::getProcessServiceFactory();

    LanguageType eLangType;
    if( peFormatterLangType )
        eLangType = *peFormatterLangType;
    else
        eLangType = GetpApp()->GetSettings().GetLanguage();

    DateFormat eDate;
    if( peFormatterDateFormat )
        eDate = *peFormatterDateFormat;
    else
    {
        SvtSysLocale aSysLocale;
        eDate = aSysLocale.GetLocaleData().getDateFormat();
    }

    rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType );

	xub_StrLen nCheckPos = 0; short nType;
	rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType );

	// Standard-Vorlagen des Formatters haben nur zweistellige
	// Jahreszahl. Deshalb eigenes Format registrieren

	// HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
	// fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
	// austauscht. Problem: Print Year(Date) unter engl. BS
	// siehe auch svtools\source\sbx\sbxdate.cxx

	String aDateStr;
	switch( eDate )
	{
		case MDY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") ); break;
		case DMY: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("TT.MM.JJJJ") ); break;
		case YMD: aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("JJJJ.MM.TT") ); break;
		default:  aDateStr = String( RTL_CONSTASCII_USTRINGPARAM("MM.TT.JJJJ") );
	}
	String aStr( aDateStr );
	rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
		rnStdDateIdx, LANGUAGE_GERMAN, eLangType );
	nCheckPos = 0;
	String aStrHHMMSS( RTL_CONSTASCII_USTRINGPARAM(" HH:MM:SS") );
	aStr = aDateStr;
	aStr += aStrHHMMSS;
	rpNumberFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
		rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType );
}



// Engine laufenlassen. Falls Flags == SbDEBUG_CONTINUE, Flags uebernehmen

void SbiInstance::Stop()
{
	for( SbiRuntime* p = pRun; p; p = p->pNext )
		p->Stop();
}

// Allows Basic IDE to set watch mode to suppress errors
static bool bWatchMode = false;

void setBasicWatchMode( bool bOn )
{
	bWatchMode = bOn;
}

void SbiInstance::Error( SbError n )
{
	Error( n, String() );
}

void SbiInstance::Error( SbError n, const String& rMsg )
{
	if( !bWatchMode )
	{
		aErrorMsg = rMsg;
		pRun->Error( n );
	}
}

void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const String& rMsg )
{
	if( !bWatchMode )
	{
		SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
		if ( !n )
			n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors

		aErrorMsg = rMsg;
		SbiRuntime::translateErrorToVba( n, aErrorMsg );

		bool bVBATranslationAlreadyDone = true;
		pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone );
	}
}

void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const String& rMsg )
{
	SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
	if( !n )
		n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors

	aErrorMsg = rMsg;
	SbiRuntime::translateErrorToVba( n, aErrorMsg );

	nErr = n;
}


void SbiInstance::FatalError( SbError n )
{
	pRun->FatalError( n );
}

void SbiInstance::FatalError( SbError _errCode, const String& _details )
{
	pRun->FatalError( _errCode, _details );
}

void SbiInstance::Abort()
{
	// Basic suchen, in dem der Fehler auftrat
	StarBASIC* pErrBasic = GetCurrentBasic( pBasic );
	pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 );
	pBasic->Stop();
}

// Hilfsfunktion, um aktives Basic zu finden, kann ungleich pRTBasic sein
StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic )
{
	StarBASIC* pCurBasic = pRTBasic;
	SbModule* pActiveModule = pRTBasic->GetActiveModule();
	if( pActiveModule )
	{
		SbxObject* pParent = pActiveModule->GetParent();
		if( pParent && pParent->ISA(StarBASIC) )
			pCurBasic = (StarBASIC*)pParent;
	}
	return pCurBasic;
}

SbModule* SbiInstance::GetActiveModule()
{
	if( pRun )
		return pRun->GetModule();
	else
		return NULL;
}

SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel )
{
	SbiRuntime* p = pRun;
	while( nLevel-- && p )
		p = p->pNext;
	if( p )
		return p->GetCaller();
	else
		return NULL;
}

SbxArray* SbiInstance::GetLocals( SbMethod* pMeth )
{
	SbiRuntime* p = pRun;
	while( p && p->GetMethod() != pMeth )
		p = p->pNext;
	if( p )
		return p->GetLocals();
	else
		return NULL;
}

//////////////////////////////////////////////////////////////////////////
//								SbiInstance								//
//////////////////////////////////////////////////////////////////////////

// Achtung: pMeth kann auch NULL sein (beim Aufruf des Init-Codes)

SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart )
		 : rBasic( *(StarBASIC*)pm->pParent ), pInst( pINST ),
		   pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), m_nLastTime(0)
{
	nFlags	  = pe ? pe->GetDebugFlags() : 0;
	pIosys	  = pInst->pIosys;
	pArgvStk  = NULL;
	pGosubStk = NULL;
	pForStk   = NULL;
	pError    = NULL;
	pErrCode  =
	pErrStmnt =
	pRestart  = NULL;
	pNext     = NULL;
	pCode     =
	pStmnt    = (const sal_uInt8* ) pImg->GetCode() + nStart;
	bRun      =
	bError    = sal_True;
	bInError  = sal_False;
	bBlocked  = sal_False;
	nLine	  = 0;
	nCol1	  = 0;
	nCol2	  = 0;
	nExprLvl  = 0;
	nArgc     = 0;
	nError	  = 0;
	nGosubLvl = 0;
	nForLvl   = 0;
	nOps	  = 0;
	refExprStk = new SbxArray;
	SetVBAEnabled( pMod->IsVBACompat() );
#if defined GCC
	SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL );
#else
	SetParameters( pe ? pe->GetParameters() : NULL );
#endif
	pRefSaveList = NULL;
	pItemStoreList = NULL;
}

SbiRuntime::~SbiRuntime()
{
	ClearGosubStack();
	ClearArgvStack();
	ClearForStack();

	// #74254 Items zum Sichern temporaere Referenzen freigeben
	ClearRefs();
	while( pItemStoreList )
	{
		RefSaveItem* pToDeleteItem = pItemStoreList;
		pItemStoreList = pToDeleteItem->pNext;
		delete pToDeleteItem;
	}
}

void SbiRuntime::SetVBAEnabled(bool bEnabled )
{
	bVBAEnabled = bEnabled;
}

// Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt
// uebernommen; von ByVal-Parametern werden Kopien angelegt. Falls
// ein bestimmter Datentyp verlangt wird, wird konvertiert.

void SbiRuntime::SetParameters( SbxArray* pParams )
{
	refParams = new SbxArray;
	// fuer den Returnwert
	refParams->Put( pMeth, 0 );

	SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL;
	sal_uInt16 nParamCount = pParams ? pParams->Count() : 1;
	if( nParamCount > 1 )
	{
		for( sal_uInt16 i = 1 ; i < nParamCount ; i++ )
		{
			const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL;

			// #111897 ParamArray
			if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
			{
				SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
				sal_uInt16 nParamArrayParamCount = nParamCount - i;
				pArray->unoAddDim( 0, nParamArrayParamCount - 1 );
				for( sal_uInt16 j = i ; j < nParamCount ; j++ )
				{
					SbxVariable* v = pParams->Get( j );
					short nDimIndex = j - i;
					pArray->Put( v, &nDimIndex );
				}
				SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
				pArrayVar->SetFlag( SBX_READWRITE );
				pArrayVar->PutObject( pArray );
				refParams->Put( pArrayVar, i );

				// Block ParamArray for missing parameter
				pInfo = NULL;
				break;
			}

			SbxVariable* v = pParams->Get( i );
			// Methoden sind immer byval!
			sal_Bool bByVal = v->IsA( TYPE(SbxMethod) );
			SbxDataType t = v->GetType();
			bool bTargetTypeIsArray = false;
			if( p )
			{
				bByVal |= sal_Bool( ( p->eType & SbxBYREF ) == 0 );
				t = (SbxDataType) ( p->eType & 0x0FFF );

				if( !bByVal && t != SbxVARIANT &&
					(!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) )
						bByVal = sal_True;

				bTargetTypeIsArray = (p->nUserData & PARAM_INFO_WITHBRACKETS) != 0;
			}
			if( bByVal )
			{
				if( bTargetTypeIsArray )
					t = SbxOBJECT;
				SbxVariable* v2 = new SbxVariable( t );
				v2->SetFlag( SBX_READWRITE );
				*v2 = *v;
				refParams->Put( v2, i );
			}
			else
			{
				if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) )
				{
					// Array konvertieren??
					if( p && (p->eType & SbxARRAY) )
						Error( SbERR_CONVERSION );
					else
						v->Convert( t );
				}
				refParams->Put( v, i );
			}
			if( p )
				refParams->PutAlias( p->aName, i );
		}
	}

	// ParamArray for missing parameter
	if( pInfo )
	{
		// #111897 Check first missing parameter for ParamArray
		const SbxParamInfo* p = pInfo->GetParam( nParamCount );
		if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
		{
			SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
			pArray->unoAddDim( 0, -1 );
			SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
			pArrayVar->SetFlag( SBX_READWRITE );
			pArrayVar->PutObject( pArray );
			refParams->Put( pArrayVar, nParamCount );
		}
	}
}


// Einen P-Code ausfuehren

sal_Bool SbiRuntime::Step()
{
	if( bRun )
	{
		// Unbedingt gelegentlich die Kontrolle abgeben!
		if( !( ++nOps & 0xF ) && pInst->IsReschedule() && bStaticGlobalEnableReschedule )
		{
			sal_uInt32 nTime = osl_getGlobalTimer();
			if (nTime - m_nLastTime > 5 ) // 20 ms
			{
				Application::Reschedule();
				m_nLastTime = nTime;
			}
		}

		// #i48868 blocked by next call level?
		while( bBlocked )
		{
			if( pInst->IsReschedule() && bStaticGlobalEnableReschedule )
				Application::Reschedule();
		}

#ifdef DBG_TRACE_BASIC
		sal_uInt32 nPC = ( pCode - (const sal_uInt8* )pImg->GetCode() );
		dbg_traceStep( pMod, nPC, pINST->nCallLvl );
#endif

		SbiOpcode eOp = (SbiOpcode ) ( *pCode++ );
		sal_uInt32 nOp1, nOp2;
        if (eOp < SbOP0_END)
		{
			(this->*( aStep0[ eOp ] ) )();
		}
        else if (eOp >= SbOP1_START && eOp < SbOP1_END)
		{
			nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;

			(this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 );
		}
        else if (eOp >= SbOP2_START && eOp < SbOP2_END)
		{
			nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
			nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24;
			(this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 );
		}
		else
			StarBASIC::FatalError( SbERR_INTERNAL_ERROR );

		// SBX-Fehler aufgetreten?
		SbError nSbError = SbxBase::GetError();
		Error( ERRCODE_TOERROR(nSbError) );			// Warnings rausfiltern

		// AB 13.2.1997, neues Error-Handling:
		// ACHTUNG: Hier kann nError auch dann gesetzt sein, wenn !nSbError,
		// da nError jetzt auch von anderen RT-Instanzen gesetzt werden kann

		if( nError )
			SbxBase::ResetError();

		// AB,15.3.96: Fehler nur anzeigen, wenn BASIC noch aktiv
		// (insbesondere nicht nach Compiler-Fehlern zur Laufzeit)
		if( nError && bRun )
		{
#ifdef DBG_TRACE_BASIC
			SbError nTraceErr = nError;
			String aTraceErrMsg = GetSbData()->aErrMsg;
			bool bTraceErrHandled = true;
#endif
			SbError err = nError;
			ClearExprStack();
			nError = 0;
			pInst->nErr = err;
			pInst->nErl = nLine;
			pErrCode    = pCode;
			pErrStmnt   = pStmnt;
			// An error occurred in an error handler
			// force parent handler ( if there is one )
			// to handle the error
			bool bLetParentHandleThis = false;

			// Im Error Handler? Dann Std-Error
			if ( !bInError )
			{
				bInError = sal_True;

				if( !bError )			// On Error Resume Next
					StepRESUME( 1 );
				else if( pError )		// On Error Goto ...
					pCode = pError;
				else
					bLetParentHandleThis = true;
            }
			else
			{
				bLetParentHandleThis = true;
				pError = NULL; //terminate the handler
			}
			if ( bLetParentHandleThis )
			{
				// AB 13.2.1997, neues Error-Handling:
				// Uebergeordnete Error-Handler beruecksichtigen

				// Wir haben keinen Error-Handler -> weiter oben suchen
				SbiRuntime* pRtErrHdl = NULL;
				SbiRuntime* pRt = this;
				while( NULL != (pRt = pRt->pNext) )
				{
					// Gibt es einen Error-Handler?
					if( pRt->bError == sal_False || pRt->pError != NULL )
					{
						pRtErrHdl = pRt;
						break;
					}
				}

				// Error-Hdl gefunden?
				if( pRtErrHdl )
				{
					// (Neuen) Error-Stack anlegen
					SbErrorStack*& rErrStack = GetSbData()->pErrStack;
					if( rErrStack )
						delete rErrStack;
					rErrStack = new SbErrorStack();

					// Alle im Call-Stack darunter stehenden RTs manipulieren
					pRt = this;
					do
					{
						// Fehler setzen
						pRt->nError = err;
						if( pRt != pRtErrHdl )
							pRt->bRun = sal_False;

						// In Error-Stack eintragen
						SbErrorStackEntry *pEntry = new SbErrorStackEntry
							( pRt->pMeth, pRt->nLine, pRt->nCol1, pRt->nCol2 );
						rErrStack->C40_INSERT(SbErrorStackEntry, pEntry, rErrStack->Count() );

						// Nach RT mit Error-Handler aufhoeren
						if( pRt == pRtErrHdl )
							break;
                           pRt = pRt->pNext;
					}
					while( pRt );
				}
				// Kein Error-Hdl gefunden -> altes Vorgehen
				else
				{
#ifdef DBG_TRACE_BASIC
					bTraceErrHandled = false;
#endif
					pInst->Abort();
				}

				// ALT: Nur
				// pInst->Abort();
			}

#ifdef DBG_TRACE_BASIC
			dbg_traceNotifyError( nTraceErr, aTraceErrMsg, bTraceErrHandled, pINST->nCallLvl );
#endif
		}
	}
	return bRun;
}

void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone )
{
	if( n )
	{
		nError = n;
		if( isVBAEnabled() && !bVBATranslationAlreadyDone )
		{
			String aMsg = pInst->GetErrorMsg();
			sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg );
			SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject();
			SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar );
			if( pGlobErr != NULL )
				pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg );

			pInst->aErrorMsg = aMsg;
			nError = SbERR_BASIC_COMPAT;
		}
	}
}

void SbiRuntime::Error( SbError _errCode, const String& _details )
{
    if ( _errCode )
    {
		// Not correct for class module usage, remove for now
        //OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" );
        if ( pInst->pRun == this )
        {
            pInst->Error( _errCode, _details );
            //OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" );
        }
        else
        {
            nError = _errCode;
        }
    }
}

void SbiRuntime::FatalError( SbError n )
{
	StepSTDERROR();
	Error( n );
}

void SbiRuntime::FatalError( SbError _errCode, const String& _details )
{
	StepSTDERROR();
	Error( _errCode, _details );
}

sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg )
{
	// If a message is defined use that ( in preference to
	// the defined one for the error ) NB #TODO
	// if there is an error defined it more than likely
	// is not the one you want ( some are the same though )
	// we really need a new vba compatible error list
	if ( !rMsg.Len() )
	{
		// TEST, has to be vb here always
#ifdef DBG_UTIL
		SbError nTmp = StarBASIC::GetSfxFromVBError( (sal_uInt16)nError );
		DBG_ASSERT( nTmp, "No VB error!" );
#endif

		StarBASIC::MakeErrorText( nError, rMsg );
		rMsg = StarBASIC::GetErrorText();
		if ( !rMsg.Len() ) // no message for err no, need localized resource here
			rMsg = String( RTL_CONSTASCII_USTRINGPARAM("Internal Object Error:") );
	}
	// no num? most likely then it *is* really a vba err
	sal_uInt16 nVBErrorCode = StarBASIC::GetVBErrorCode( nError );
	sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode;
	return nVBAErrorNumber;
}

//////////////////////////////////////////////////////////////////////////
//
//	Parameter, Locals, Caller
//
//////////////////////////////////////////////////////////////////////////

SbMethod* SbiRuntime::GetCaller()
{
	return pMeth;
}

SbxArray* SbiRuntime::GetLocals()
{
	return refLocals;
}

SbxArray* SbiRuntime::GetParams()
{
	return refParams;
}

//////////////////////////////////////////////////////////////////////////
//
//	Stacks
//
//////////////////////////////////////////////////////////////////////////

// Der Expression-Stack steht fuer die laufende Auswertung von Expressions
// zur Verfuegung.

void SbiRuntime::PushVar( SbxVariable* pVar )
{
	if( pVar )
		refExprStk->Put( pVar, nExprLvl++ );
}

SbxVariableRef SbiRuntime::PopVar()
{
#ifdef DBG_UTIL
	if( !nExprLvl )
	{
		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
		return new SbxVariable;
	}
#endif
	SbxVariableRef xVar = refExprStk->Get( --nExprLvl );
#ifdef DBG_UTIL
	if ( xVar->GetName().EqualsAscii( "Cells" ) )
		DBG_TRACE( "" );
#endif
	// Methods halten im 0.Parameter sich selbst, also weghauen
	if( xVar->IsA( TYPE(SbxMethod) ) )
		xVar->SetParameters(0);
	return xVar;
}

sal_Bool SbiRuntime::ClearExprStack()
{
	// Achtung: Clear() reicht nicht, da Methods geloescht werden muessen
	while ( nExprLvl )
	{
		PopVar();
	}
	refExprStk->Clear();
	return sal_False;
}

// Variable auf dem Expression-Stack holen, ohne sie zu entfernen
// n zaehlt ab 0.

SbxVariable* SbiRuntime::GetTOS( short n )
{
	n = nExprLvl - n - 1;
#ifdef DBG_UTIL
	if( n < 0 )
	{
		StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
		return new SbxVariable;
	}
#endif
	return refExprStk->Get( (sal_uInt16) n );
}

// Sicherstellen, dass TOS eine temporaere Variable ist

void SbiRuntime::TOSMakeTemp()
{
	SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
	if( p->GetRefCount() != 1 )
	{
		SbxVariable* pNew = new SbxVariable( *p );
		pNew->SetFlag( SBX_READWRITE );
		refExprStk->Put( pNew, nExprLvl - 1 );
	}
}

// Der GOSUB-Stack nimmt Returnadressen fuer GOSUBs auf

void SbiRuntime::PushGosub( const sal_uInt8* pc )
{
	if( ++nGosubLvl > MAXRECURSION )
		StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
	SbiGosubStack* p = new SbiGosubStack;
	p->pCode  = pc;
	p->pNext  = pGosubStk;
	p->nStartForLvl = nForLvl;
	pGosubStk = p;
}

void SbiRuntime::PopGosub()
{
	if( !pGosubStk )
		Error( SbERR_NO_GOSUB );
	else
	{
		SbiGosubStack* p = pGosubStk;
		pCode = p->pCode;
		pGosubStk = p->pNext;
		delete p;
		nGosubLvl--;
	}
}

// Entleeren des GOSUB-Stacks

void SbiRuntime::ClearGosubStack()
{
	SbiGosubStack* p;
	while(( p = pGosubStk ) != NULL )
		pGosubStk = p->pNext, delete p;
	nGosubLvl = 0;
}

// Der Argv-Stack nimmt aktuelle Argument-Vektoren auf

void SbiRuntime::PushArgv()
{
	SbiArgvStack* p = new SbiArgvStack;
	p->refArgv = refArgv;
	p->nArgc = nArgc;
	nArgc = 1;
	refArgv.Clear();
	p->pNext = pArgvStk;
	pArgvStk = p;
}

void SbiRuntime::PopArgv()
{
	if( pArgvStk )
	{
		SbiArgvStack* p = pArgvStk;
		pArgvStk = p->pNext;
		refArgv = p->refArgv;
		nArgc = p->nArgc;
		delete p;
	}
}

// Entleeren des Argv-Stacks

void SbiRuntime::ClearArgvStack()
{
	while( pArgvStk )
		PopArgv();
}

// Push des For-Stacks. Der Stack hat Inkrement, Ende, Beginn und Variable.
// Nach Aufbau des Stack-Elements ist der Stack leer.

void SbiRuntime::PushFor()
{
	SbiForStack* p = new SbiForStack;
	p->eForType = FOR_TO;
	p->pNext = pForStk;
	pForStk = p;
	// Der Stack ist wie folgt aufgebaut:
	p->refInc = PopVar();
	p->refEnd = PopVar();
	SbxVariableRef xBgn = PopVar();
	p->refVar = PopVar();
	*(p->refVar) = *xBgn;
	nForLvl++;
}

void SbiRuntime::PushForEach()
{
	SbiForStack* p = new SbiForStack;
	p->pNext = pForStk;
	pForStk = p;

	SbxVariableRef xObjVar = PopVar();
	SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL;
	if( pObj == NULL )
	{
		Error( SbERR_NO_OBJECT );
		return;
	}

	bool bError_ = false;
	BasicCollection* pCollection;
	SbxDimArray* pArray;
	SbUnoObject* pUnoObj;
	if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL )
	{
		p->eForType = FOR_EACH_ARRAY;
		p->refEnd = (SbxVariable*)pArray;

		short nDims = pArray->GetDims();
		p->pArrayLowerBounds = new sal_Int32[nDims];
		p->pArrayUpperBounds = new sal_Int32[nDims];
		p->pArrayCurIndices  = new sal_Int32[nDims];
		sal_Int32 lBound, uBound;
		for( short i = 0 ; i < nDims ; i++ )
		{
			pArray->GetDim32( i+1, lBound, uBound );
			p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound;
			p->pArrayUpperBounds[i] = uBound;
		}
	}
	else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL )
	{
		p->eForType = FOR_EACH_COLLECTION;
		p->refEnd = pCollection;
		p->nCurCollectionIndex = 0;
	}
	else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
	{
		// XEnumerationAccess?
		Any aAny = pUnoObj->getUnoAny();
		Reference< XEnumerationAccess > xEnumerationAccess;
		if( (aAny >>= xEnumerationAccess) )
		{
			p->xEnumeration = xEnumerationAccess->createEnumeration();
			p->eForType = FOR_EACH_XENUMERATION;
		}
		else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() )
        {
            uno::Reference< script::XInvocation > xInvocation;
            if ( ( aAny >>= xInvocation ) && xInvocation.is() )
            {
                try
                {
                    p->xEnumeration = new ComEnumerationWrapper( xInvocation );
                    p->eForType = FOR_EACH_XENUMERATION;
                }
                catch( uno::Exception& )
                {}
            }

            if ( !p->xEnumeration.is() )
                bError_ = true;
        }
        else
		{
			bError_ = true;
		}
	}
	else
	{
		bError_ = true;
	}

	if( bError_ )
	{
		Error( SbERR_CONVERSION );
		return;
	}

	// Container variable
	p->refVar = PopVar();
	nForLvl++;
}

// Poppen des FOR-Stacks

void SbiRuntime::PopFor()
{
	if( pForStk )
	{
		SbiForStack* p = pForStk;
		pForStk = p->pNext;
		delete p;
		nForLvl--;
	}
}

// Entleeren des FOR-Stacks

void SbiRuntime::ClearForStack()
{
	while( pForStk )
		PopFor();
}

SbiForStack* SbiRuntime::FindForStackItemForCollection( class BasicCollection* pCollection )
{
	SbiForStack* pRet = NULL;

	SbiForStack* p = pForStk;
	while( p )
	{
		SbxVariable* pVar = p->refEnd.Is() ? (SbxVariable*)p->refEnd : NULL;
		if( p->eForType == FOR_EACH_COLLECTION && pVar != NULL &&
			(pCollection = PTR_CAST(BasicCollection,pVar)) == pCollection )
		{
			pRet = p;
			break;
		}
	}

	return pRet;
}


//////////////////////////////////////////////////////////////////////////
//
//	DLL-Aufrufe
//
//////////////////////////////////////////////////////////////////////////

void SbiRuntime::DllCall
	( const String& aFuncName,	// Funktionsname
	  const String& aDLLName,	// Name der DLL
	  SbxArray* pArgs,			// Parameter (ab Index 1, kann NULL sein)
	  SbxDataType eResType,		// Returnwert
	  sal_Bool bCDecl )				// sal_True: nach C-Konventionen
{
	// No DllCall for "virtual" portal users
	if( needSecurityRestrictions() )
	{
		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
		return;
	}

	// MUSS NOCH IMPLEMENTIERT WERDEN
	/*
	String aMsg;
	aMsg = "FUNC=";
	aMsg += pFunc;
	aMsg += " DLL=";
	aMsg += pDLL;
	MessBox( NULL, WB_OK, String( "DLL-CALL" ), aMsg ).Execute();
	Error( SbERR_NOT_IMPLEMENTED );
	*/

	SbxVariable* pRes = new SbxVariable( eResType );
	SbiDllMgr* pDllMgr = pInst->GetDllMgr();
	SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
	if( nErr )
		Error( nErr );
	PushVar( pRes );
}

sal_uInt16 SbiRuntime::GetImageFlag( sal_uInt16 n ) const
{
	return pImg->GetFlag( n );
}

sal_uInt16 SbiRuntime::GetBase()
{
	return pImg->GetBase();
}
