summaryrefslogtreecommitdiff
path: root/basic/source/runtime/step0.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'basic/source/runtime/step0.cxx')
-rw-r--r--basic/source/runtime/step0.cxx99
1 files changed, 51 insertions, 48 deletions
diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx
index 06a8bb19af00..e184d8928f3f 100644
--- a/basic/source/runtime/step0.cxx
+++ b/basic/source/runtime/step0.cxx
@@ -48,6 +48,11 @@ Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::
#include <algorithm>
+// for a patch forward declaring these methods below makes sense
+// but, #FIXME lets really just move the methods to the top
+void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType );
+void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled );
+
SbxVariable* getDefaultProp( SbxVariable* pRef );
void SbiRuntime::StepNOP()
@@ -59,34 +64,6 @@ void SbiRuntime::StepArith( SbxOperator eOp )
TOSMakeTemp();
SbxVariable* p2 = GetTOS();
-
- // This could & should be moved to the MakeTempTOS() method in runtime.cxx
- // In the code which this is cut'npaste from there is a check for a ref
- // count != 1 based on which the copy of the SbxVariable is done.
- // see orig code in MakeTempTOS ( and I'm not sure what the significance,
- // of that is )
- // here we alway seem to have a refcount of 1. Also it seems that
- // MakeTempTOS is called for other operation, so I hold off for now
- // until I have a better idea
- if ( bVBAEnabled
- && ( p2->GetType() == SbxOBJECT || p2->GetType() == SbxVARIANT )
- )
- {
- SbxVariable* pDflt = getDefaultProp( p2 );
- if ( pDflt )
- {
- pDflt->Broadcast( SBX_HINT_DATAWANTED );
- // replacing new p2 on stack causes object pointed by
- // pDft->pParent to be deleted, when p2->Compute() is
- // called below pParent is accessed ( but its deleted )
- // so set it to NULL now
- pDflt->SetParent( NULL );
- p2 = new SbxVariable( *pDflt );
- p2->SetFlag( SBX_READWRITE );
- refExprStk->Put( p2, nExprLvl - 1 );
- }
- }
-
p2->ResetFlag( SBX_FIXED );
p2->Compute( eOp, *p1 );
@@ -109,19 +86,24 @@ void SbiRuntime::StepCompare( SbxOperator eOp )
// values ( and type ) set as appropriate
SbxDataType p1Type = p1->GetType();
SbxDataType p2Type = p2->GetType();
+ if ( p1Type == SbxEMPTY )
+ {
+ p1->Broadcast( SBX_HINT_DATAWANTED );
+ p1Type = p1->GetType();
+ }
+ if ( p2Type == SbxEMPTY )
+ {
+ p2->Broadcast( SBX_HINT_DATAWANTED );
+ p2Type = p2->GetType();
+ }
if ( p1Type == p2Type )
{
- if ( p1Type == SbxEMPTY )
- {
- p1->Broadcast( SBX_HINT_DATAWANTED );
- p2->Broadcast( SBX_HINT_DATAWANTED );
- }
// if both sides are an object and have default props
// then we need to use the default props
// we don't need to worry if only one side ( lhs, rhs ) is an
// object ( object side will get coerced to correct type in
// Compare )
- else if ( p1Type == SbxOBJECT )
+ if ( p1Type == SbxOBJECT )
{
SbxVariable* pDflt = getDefaultProp( p1 );
if ( pDflt )
@@ -141,8 +123,21 @@ void SbiRuntime::StepCompare( SbxOperator eOp )
#ifndef WIN
static SbxVariable* pTRUE = NULL;
static SbxVariable* pFALSE = NULL;
-
- if( p2->Compare( eOp, *p1 ) )
+ static SbxVariable* pNULL = NULL;
+ // why do this on non-windows ?
+ // why do this at all ?
+ // I dumbly follow the pattern :-/
+ if ( bVBAEnabled && ( p1->IsNull() || p2->IsNull() ) )
+ {
+ if( !pNULL )
+ {
+ pNULL = new SbxVariable;
+ pNULL->PutNull();
+ pNULL->AddRef();
+ }
+ PushVar( pNULL );
+ }
+ else if( p2->Compare( eOp, *p1 ) )
{
if( !pTRUE )
{
@@ -163,9 +158,14 @@ void SbiRuntime::StepCompare( SbxOperator eOp )
PushVar( pFALSE );
}
#else
- BOOL bRes = p2->Compare( eOp, *p1 );
SbxVariable* pRes = new SbxVariable;
- pRes->PutBool( bRes );
+ if ( bVBAEnabled && ( p1->IsNull() || p2->IsNull() ) )
+ pRes->PutNull();
+ else
+ {
+ BOOL bRes = p2->Compare( eOp, *p1 );
+ pRes->PutBool( bRes );
+ }
PushVar( pRes );
#endif
}
@@ -679,6 +679,17 @@ void SbiRuntime::StepDIM()
// #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx)
void SbiRuntime::DimImpl( SbxVariableRef refVar )
{
+ // If refDim then this DIM statement is terminating a ReDIM and
+ // previous StepERASE_CLEAR for an array, the following actions have
+ // been delayed from ( StepERASE_CLEAR ) 'till here
+ if ( refRedim )
+ {
+ if ( !refRedimpArray ) // only erase the array not ReDim Preserve
+ lcl_eraseImpl( refVar, bVBAEnabled );
+ SbxDataType eType = refVar->GetType();
+ lcl_clearImpl( refVar, eType );
+ refRedim = NULL;
+ }
SbxArray* pDims = refVar->GetParameters();
// Muss eine gerade Anzahl Argumente haben
// Man denke daran, dass Arg[0] nicht zaehlt!
@@ -844,6 +855,7 @@ void SbiRuntime::StepREDIMP()
void SbiRuntime::StepREDIMP_ERASE()
{
SbxVariableRef refVar = PopVar();
+ refRedim = refVar;
SbxDataType eType = refVar->GetType();
if( eType & SbxARRAY )
{
@@ -854,12 +866,6 @@ void SbiRuntime::StepREDIMP_ERASE()
refRedimpArray = pDimArray;
}
- // As in ERASE
- USHORT nSavFlags = refVar->GetFlags();
- refVar->ResetFlag( SBX_FIXED );
- refVar->SetType( SbxDataType(eType & 0x0FFF) );
- refVar->SetFlags( nSavFlags );
- refVar->Clear();
}
else
if( refVar->IsFixed() )
@@ -932,10 +938,7 @@ void SbiRuntime::StepERASE()
void SbiRuntime::StepERASE_CLEAR()
{
- SbxVariableRef refVar = PopVar();
- lcl_eraseImpl( refVar, bVBAEnabled );
- SbxDataType eType = refVar->GetType();
- lcl_clearImpl( refVar, eType );
+ refRedim = PopVar();
}
void SbiRuntime::StepARRAYACCESS()