2000-09-18 15:18:56 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-29 15:17:05 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2005-09-29 11:49:04 +00:00
|
|
|
*
|
2005-09-29 15:17:05 +00:00
|
|
|
* $RCSfile: codegen.cxx,v $
|
2005-09-29 11:49:04 +00:00
|
|
|
*
|
2006-09-17 09:01:20 +00:00
|
|
|
* $Revision: 1.14 $
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
2006-09-17 09:01:20 +00:00
|
|
|
* last change: $Author: obo $ $Date: 2006-09-17 10:01:20 $
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
2005-09-29 15:17:05 +00:00
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
|
|
|
*
|
2005-09-29 15:17:05 +00:00
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
2005-09-29 15:17:05 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
2005-09-29 15:17:05 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
2005-09-29 15:17:05 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-17 09:01:20 +00:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_basic.hxx"
|
|
|
|
|
2005-04-13 08:10:55 +00:00
|
|
|
#include <sbx.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
#include "sbcomp.hxx"
|
|
|
|
#include "image.hxx"
|
|
|
|
|
|
|
|
// nInc ist die Inkrementgroesse der Puffer
|
|
|
|
|
|
|
|
SbiCodeGen::SbiCodeGen( SbModule& r, SbiParser* p, short nInc )
|
|
|
|
: rMod( r ), aCode( p, nInc )
|
|
|
|
{
|
|
|
|
pParser = p;
|
|
|
|
bStmnt = FALSE;
|
|
|
|
nLine = 0;
|
|
|
|
nCol = 0;
|
|
|
|
nForLevel = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
USHORT SbiCodeGen::GetPC()
|
|
|
|
{
|
|
|
|
return aCode.GetSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Statement merken
|
|
|
|
|
|
|
|
void SbiCodeGen::Statement()
|
|
|
|
{
|
|
|
|
bStmnt = TRUE;
|
|
|
|
|
|
|
|
nLine = pParser->GetLine();
|
|
|
|
nCol = pParser->GetCol1();
|
|
|
|
|
|
|
|
// #29955 Information der for-Schleifen-Ebene
|
|
|
|
// in oberen Byte der Spalte speichern
|
|
|
|
nCol = (nCol & 0xff) + 0x100 * nForLevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Anfang eines Statements markieren
|
|
|
|
|
|
|
|
void SbiCodeGen::GenStmnt()
|
|
|
|
{
|
|
|
|
if( bStmnt )
|
|
|
|
{
|
|
|
|
bStmnt = FALSE;
|
|
|
|
Gen( _STMNT, nLine, nCol );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Die Gen-Routinen returnen den Offset des 1. Operanden,
|
|
|
|
// damit Jumps dort ihr Backchain versenken koennen
|
|
|
|
|
|
|
|
USHORT SbiCodeGen::Gen( SbiOpcode eOpcode )
|
|
|
|
{
|
|
|
|
#ifndef PRODUCT
|
|
|
|
if( eOpcode < SbOP0_START || eOpcode > SbOP0_END )
|
|
|
|
pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE1" );
|
|
|
|
#endif
|
|
|
|
GenStmnt();
|
|
|
|
aCode += (UINT8) eOpcode;
|
|
|
|
return GetPC();
|
|
|
|
}
|
|
|
|
|
|
|
|
USHORT SbiCodeGen::Gen( SbiOpcode eOpcode, UINT16 nOpnd )
|
|
|
|
{
|
|
|
|
#ifndef PRODUCT
|
|
|
|
if( eOpcode < SbOP1_START || eOpcode > SbOP1_END )
|
|
|
|
pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE2" );
|
|
|
|
#endif
|
|
|
|
GenStmnt();
|
|
|
|
aCode += (UINT8) eOpcode;
|
|
|
|
USHORT n = GetPC();
|
|
|
|
aCode += nOpnd;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
USHORT SbiCodeGen::Gen( SbiOpcode eOpcode, UINT16 nOpnd1, UINT16 nOpnd2 )
|
|
|
|
{
|
|
|
|
#ifndef PRODUCT
|
|
|
|
if( eOpcode < SbOP2_START || eOpcode > SbOP2_END )
|
|
|
|
pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE3" );
|
|
|
|
#endif
|
|
|
|
GenStmnt();
|
|
|
|
aCode += (UINT8) eOpcode;
|
|
|
|
USHORT n = GetPC();
|
|
|
|
aCode += nOpnd1;
|
|
|
|
aCode += nOpnd2;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Abspeichern des erzeugten Images im Modul
|
|
|
|
|
|
|
|
void SbiCodeGen::Save()
|
|
|
|
{
|
|
|
|
SbiImage* p = new SbiImage;
|
|
|
|
rMod.StartDefinitions();
|
|
|
|
// OPTION BASE-Wert:
|
|
|
|
p->nDimBase = pParser->nBase;
|
|
|
|
// OPTION EXPLICIT-Flag uebernehmen
|
|
|
|
if( pParser->bExplicit )
|
|
|
|
p->SetFlag( SBIMG_EXPLICIT );
|
2006-05-05 09:11:35 +00:00
|
|
|
if( pParser->bVBASupportOn )
|
|
|
|
p->SetFlag( SBIMG_VBASUPPORT );
|
2005-03-29 10:48:48 +00:00
|
|
|
|
|
|
|
int nIfaceCount = 0;
|
2004-11-02 10:53:16 +00:00
|
|
|
if( pParser->bClassModule )
|
|
|
|
{
|
|
|
|
p->SetFlag( SBIMG_CLASSMODULE );
|
|
|
|
pCLASSFAC->AddClassModule( &rMod );
|
2005-03-29 10:48:48 +00:00
|
|
|
|
|
|
|
nIfaceCount = pParser->aIfaceVector.size();
|
|
|
|
if( nIfaceCount )
|
|
|
|
{
|
|
|
|
if( !rMod.pClassData )
|
|
|
|
rMod.pClassData = new SbClassData;
|
|
|
|
|
|
|
|
for( int i = 0 ; i < nIfaceCount ; i++ )
|
|
|
|
{
|
|
|
|
const String& rIfaceName = pParser->aIfaceVector[i];
|
|
|
|
SbxVariable* pIfaceVar = new SbxVariable( SbxVARIANT );
|
|
|
|
pIfaceVar->SetName( rIfaceName );
|
|
|
|
SbxArray* pIfaces = rMod.pClassData->mxIfaces;
|
|
|
|
pIfaces->Insert( pIfaceVar, pIfaces->Count() );
|
|
|
|
}
|
|
|
|
}
|
2004-11-02 10:53:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pCLASSFAC->RemoveClassModule( &rMod );
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
if( pParser->bText )
|
|
|
|
p->SetFlag( SBIMG_COMPARETEXT );
|
|
|
|
// GlobalCode-Flag
|
|
|
|
if( pParser->HasGlobalCode() )
|
|
|
|
p->SetFlag( SBIMG_INITCODE );
|
|
|
|
// Die Entrypoints:
|
|
|
|
for( SbiSymDef* pDef = pParser->aPublics.First(); pDef;
|
|
|
|
pDef = pParser->aPublics.Next() )
|
|
|
|
{
|
|
|
|
SbiProcDef* pProc = pDef->GetProcDef();
|
2004-03-17 12:32:41 +00:00
|
|
|
if( pProc && pProc->IsDefined() )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2005-03-29 10:48:48 +00:00
|
|
|
String aProcName = pProc->GetName();
|
|
|
|
String aIfaceProcName;
|
|
|
|
String aIfaceName;
|
|
|
|
USHORT nPassCount = 1;
|
|
|
|
if( nIfaceCount )
|
2004-11-02 10:53:16 +00:00
|
|
|
{
|
2005-03-29 10:48:48 +00:00
|
|
|
int nPropPrefixFound =
|
|
|
|
aProcName.Search( String( RTL_CONSTASCII_USTRINGPARAM("Property ") ) );
|
|
|
|
String aPureProcName = aProcName;
|
|
|
|
String aPropPrefix;
|
|
|
|
if( nPropPrefixFound == 0 )
|
|
|
|
{
|
|
|
|
aPropPrefix = aProcName.Copy( 0, 13 ); // 13 == Len( "Property ?et " )
|
|
|
|
aPureProcName = aProcName.Copy( 13 );
|
|
|
|
}
|
|
|
|
for( int i = 0 ; i < nIfaceCount ; i++ )
|
2004-11-02 10:53:16 +00:00
|
|
|
{
|
2005-03-29 10:48:48 +00:00
|
|
|
const String& rIfaceName = pParser->aIfaceVector[i];
|
|
|
|
int nFound = aPureProcName.Search( rIfaceName );
|
|
|
|
if( nFound == 0 && '_' == aPureProcName.GetChar( rIfaceName.Len() ) )
|
|
|
|
{
|
|
|
|
if( nPropPrefixFound == 0 )
|
|
|
|
aIfaceProcName += aPropPrefix;
|
|
|
|
aIfaceProcName += aPureProcName.Copy( rIfaceName.Len() + 1 );
|
|
|
|
aIfaceName = rIfaceName;
|
|
|
|
nPassCount = 2;
|
2004-11-02 10:53:16 +00:00
|
|
|
break;
|
2005-03-29 10:48:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-06-19 16:41:04 +00:00
|
|
|
SbMethod* pMeth = NULL;
|
2005-03-29 10:48:48 +00:00
|
|
|
for( USHORT nPass = 0 ; nPass < nPassCount ; nPass++ )
|
|
|
|
{
|
|
|
|
if( nPass == 1 )
|
|
|
|
aProcName = aIfaceProcName;
|
|
|
|
|
|
|
|
PropertyMode ePropMode = pProc->getPropertyMode();
|
|
|
|
if( ePropMode != PROPERTY_MODE_NONE )
|
|
|
|
{
|
2006-06-19 16:41:04 +00:00
|
|
|
SbxDataType ePropType = SbxEMPTY;
|
2005-03-29 10:48:48 +00:00
|
|
|
switch( ePropMode )
|
2004-11-02 10:53:16 +00:00
|
|
|
{
|
2005-03-29 10:48:48 +00:00
|
|
|
case PROPERTY_MODE_GET:
|
|
|
|
ePropType = pProc->GetType();
|
|
|
|
break;
|
|
|
|
case PROPERTY_MODE_LET:
|
2004-11-02 10:53:16 +00:00
|
|
|
{
|
2005-03-29 10:48:48 +00:00
|
|
|
// type == type of first parameter
|
|
|
|
ePropType = SbxVARIANT; // Default
|
|
|
|
SbiSymPool* pPool = &pProc->GetParams();
|
|
|
|
if( pPool->GetSize() > 1 )
|
|
|
|
{
|
|
|
|
SbiSymDef* pPar = pPool->Get( 1 );
|
|
|
|
if( pPar )
|
|
|
|
ePropType = pPar->GetType();
|
|
|
|
}
|
|
|
|
break;
|
2004-11-02 10:53:16 +00:00
|
|
|
}
|
2005-03-29 10:48:48 +00:00
|
|
|
case PROPERTY_MODE_SET:
|
|
|
|
ePropType = SbxOBJECT;
|
|
|
|
break;
|
2006-06-19 16:41:04 +00:00
|
|
|
case PROPERTY_MODE_NONE:
|
|
|
|
DBG_ERROR( "Illegal PropertyMode PROPERTY_MODE_NONE" );
|
|
|
|
break;
|
2004-11-02 10:53:16 +00:00
|
|
|
}
|
2005-03-29 10:48:48 +00:00
|
|
|
String aPropName = pProc->GetPropName();
|
|
|
|
if( nPass == 1 )
|
|
|
|
aPropName = aPropName.Copy( aIfaceName.Len() + 1 );
|
2006-06-19 16:41:04 +00:00
|
|
|
SbProcedureProperty* pProcedureProperty = NULL;
|
|
|
|
pProcedureProperty = rMod.GetProcedureProperty( aPropName, ePropType );
|
2004-11-02 10:53:16 +00:00
|
|
|
}
|
2005-03-29 10:48:48 +00:00
|
|
|
if( nPass == 1 )
|
|
|
|
{
|
2006-06-19 16:41:04 +00:00
|
|
|
SbIfaceMapperMethod* pMapperMeth = NULL;
|
|
|
|
pMapperMeth = rMod.GetIfaceMapperMethod( aProcName, pMeth );
|
2005-03-29 10:48:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMeth = rMod.GetMethod( aProcName, pProc->GetType() );
|
2004-03-17 12:32:41 +00:00
|
|
|
|
2005-03-29 10:48:48 +00:00
|
|
|
// #110004
|
|
|
|
if( !pProc->IsPublic() )
|
|
|
|
pMeth->SetFlag( SBX_PRIVATE );
|
2004-03-17 12:32:41 +00:00
|
|
|
|
2005-03-29 10:48:48 +00:00
|
|
|
pMeth->nStart = pProc->GetAddr();
|
|
|
|
pMeth->nLine1 = pProc->GetLine1();
|
|
|
|
pMeth->nLine2 = pProc->GetLine2();
|
|
|
|
// Die Parameter:
|
|
|
|
SbxInfo* pInfo = pMeth->GetInfo();
|
|
|
|
String aHelpFile, aComment;
|
|
|
|
ULONG nHelpId = 0;
|
|
|
|
if( pInfo )
|
|
|
|
{
|
|
|
|
// Die Zusatzdaten retten
|
|
|
|
aHelpFile = pInfo->GetHelpFile();
|
|
|
|
aComment = pInfo->GetComment();
|
|
|
|
nHelpId = pInfo->GetHelpId();
|
|
|
|
}
|
|
|
|
// Und die Parameterliste neu aufbauen
|
|
|
|
pInfo = new SbxInfo( aHelpFile, nHelpId );
|
|
|
|
pInfo->SetComment( aComment );
|
|
|
|
SbiSymPool* pPool = &pProc->GetParams();
|
|
|
|
// Das erste Element ist immer der Funktionswert!
|
|
|
|
for( USHORT i = 1; i < pPool->GetSize(); i++ )
|
|
|
|
{
|
|
|
|
SbiSymDef* pPar = pPool->Get( i );
|
|
|
|
SbxDataType t = pPar->GetType();
|
|
|
|
if( !pPar->IsByVal() )
|
|
|
|
t = (SbxDataType) ( t | SbxBYREF );
|
|
|
|
if( pPar->GetDims() )
|
|
|
|
t = (SbxDataType) ( t | SbxARRAY );
|
|
|
|
// #33677 Optional-Info durchreichen
|
|
|
|
USHORT nFlags = SBX_READ;
|
|
|
|
if( pPar->IsOptional() )
|
|
|
|
nFlags |= SBX_OPTIONAL;
|
2004-03-17 12:32:41 +00:00
|
|
|
|
2005-03-29 10:48:48 +00:00
|
|
|
pInfo->AddParam( pPar->GetName(), t, nFlags );
|
2005-01-28 15:05:45 +00:00
|
|
|
|
2005-03-29 10:48:48 +00:00
|
|
|
UINT32 nUserData = 0;
|
|
|
|
USHORT nDefaultId = pPar->GetDefaultId();
|
|
|
|
if( nDefaultId )
|
|
|
|
nUserData |= nDefaultId;
|
|
|
|
if( pPar->IsParamArray() )
|
|
|
|
nUserData |= PARAM_INFO_PARAMARRAY;
|
|
|
|
if( nUserData )
|
|
|
|
{
|
|
|
|
SbxParamInfo* pParam = (SbxParamInfo*)pInfo->GetParam( i );
|
|
|
|
pParam->nUserData = nUserData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pMeth->SetInfo( pInfo );
|
2004-03-17 12:32:41 +00:00
|
|
|
}
|
2005-03-29 10:48:48 +00:00
|
|
|
|
|
|
|
} // for( iPass...
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Der Code
|
|
|
|
p->AddCode( aCode.GetBuffer(), aCode.GetSize() );
|
|
|
|
|
|
|
|
// Der globale StringPool. 0 ist nicht belegt.
|
|
|
|
SbiStringPool* pPool = &pParser->aGblStrings;
|
|
|
|
USHORT nSize = pPool->GetSize();
|
|
|
|
p->MakeStrings( nSize );
|
|
|
|
USHORT i;
|
|
|
|
for( i = 1; i <= nSize; i++ )
|
|
|
|
p->AddString( pPool->Find( i ) );
|
|
|
|
|
|
|
|
// Typen einfuegen
|
|
|
|
USHORT nCount = pParser->rTypeArray->Count();
|
|
|
|
for (i = 0; i < nCount; i++)
|
|
|
|
p->AddType((SbxObject *)pParser->rTypeArray->Get(i));
|
|
|
|
|
2004-11-15 15:34:34 +00:00
|
|
|
// Insert enum objects
|
|
|
|
nCount = pParser->rEnumArray->Count();
|
|
|
|
for (i = 0; i < nCount; i++)
|
|
|
|
p->AddEnum((SbxObject *)pParser->rEnumArray->Get(i));
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
if( !p->IsError() )
|
|
|
|
rMod.pImage = p;
|
|
|
|
else
|
|
|
|
delete p;
|
|
|
|
|
|
|
|
rMod.EndDefinitions();
|
|
|
|
}
|
|
|
|
|