summaryrefslogtreecommitdiff
path: root/basic/source
diff options
context:
space:
mode:
authorJohn <jbt@gmx.us>2021-03-04 01:50:25 -0500
committerMike Kaganski <mike.kaganski@collabora.com>2021-03-21 21:54:11 +0100
commitb80069e133d30e80e50a792b2bc1d0c2f9a31bfa (patch)
treeca579f9e2ef140cff39004199191de9ce286e857 /basic/source
parentf2c457c99ae3f0e364830a7642b4db9e7fb4c586 (diff)
tdf#88442 SBasic: Don't double-initialize a Global ... As New ...
"As New" variables use lazy instantiation, but that should not re-apply each time one re-enters the module. If the object is still there, don't replace it. Change-Id: Ic568a56b93db9bc9139d434d97a4a4deb05840df Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112018 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'basic/source')
-rw-r--r--basic/source/comp/dim.cxx27
-rw-r--r--basic/source/inc/runtime.hxx1
-rw-r--r--basic/source/runtime/runtime.cxx34
3 files changed, 56 insertions, 6 deletions
diff --git a/basic/source/comp/dim.cxx b/basic/source/comp/dim.cxx
index 20396cd729ad..cf14d1c7818c 100644
--- a/basic/source/comp/dim.cxx
+++ b/basic/source/comp/dim.cxx
@@ -446,12 +446,39 @@ void SbiParser::DefVar( SbiOpcode eOp, bool bStatic )
{
SbiExpression aExpr( this, *pDef );
aExpr.Gen();
+
+ /* tdf#88442
+ * Don't initialize a
+ * Global X as New SomeObjectType
+ * if it has already been initialized.
+ * This approach relies on JUMPT evaluating Object->NULL as being 'false'
+ * But the effect of this code is similar to inserting
+ * If IsNull(YourGlobal)
+ * Set YourGlobal = ' new obj
+ * End If ' If IsNull(YourGlobal)
+ * Only for globals. For locals that check is skipped as it's unnecessary
+ */
+ sal_uInt32 come_from = 0;
+ if ( pDef->GetScope() == SbGLOBAL )
+ {
+ come_from = aGen.Gen( SbiOpcode::JUMPT_, 0 );
+ aGen.Gen( SbiOpcode::FIND_, pDef->GetId(), pDef->GetTypeId() );
+ }
+
SbiOpcode eOp_ = pDef->IsNew() ? SbiOpcode::CREATE_ : SbiOpcode::TCREATE_;
aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() );
if ( bVBASupportOn )
aGen.Gen( SbiOpcode::VBASET_ );
else
aGen.Gen( SbiOpcode::SET_ );
+
+ if ( come_from )
+ {
+ // See other tdf#88442 comment above where come_from is
+ // initialized. This is effectively 'inserting' the
+ // End If ' If IsNull(YourGlobal)
+ aGen.BackChain( come_from );
+ }
}
}
else
diff --git a/basic/source/inc/runtime.hxx b/basic/source/inc/runtime.hxx
index 1169820e753b..73e56838e2aa 100644
--- a/basic/source/inc/runtime.hxx
+++ b/basic/source/inc/runtime.hxx
@@ -288,6 +288,7 @@ class SbiRuntime
// #56204 swap out DIM-functionality into help method (step0.cxx)
void DimImpl(const SbxVariableRef& refVar);
+ bool EvaluateTopOfStackAsBool();
static bool implIsClass( SbxObject const * pObj, const OUString& aClass );
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
index 9de5da64d5f2..d1dcd3d74502 100644
--- a/basic/source/runtime/runtime.cxx
+++ b/basic/source/runtime/runtime.cxx
@@ -2975,24 +2975,46 @@ void SbiRuntime::StepJUMP( sal_uInt32 nOp1 )
pCode = pImg->GetCode() + nOp1;
}
+bool SbiRuntime::EvaluateTopOfStackAsBool()
+{
+ SbxVariableRef tos = PopVar();
+ // In a test e.g. If Null then
+ // will evaluate Null will act as if False
+ if ( bVBAEnabled && tos->IsNull() )
+ {
+ return false;
+ }
+ if ( tos->IsObject() )
+ {
+ //GetBool applied to an Object attempts to dereference and evaluate
+ //the underlying value as Bool. Here, we're checking rather that
+ //it is not null
+ return tos->GetObject();
+ }
+ else
+ {
+ return tos->GetBool();
+ }
+}
+
// evaluate TOS, conditional jump (+target)
void SbiRuntime::StepJUMPT( sal_uInt32 nOp1 )
{
- SbxVariableRef p = PopVar();
- if( p->GetBool() )
+ if ( EvaluateTopOfStackAsBool() )
+ {
StepJUMP( nOp1 );
+ }
}
// evaluate TOS, conditional jump (+target)
void SbiRuntime::StepJUMPF( sal_uInt32 nOp1 )
{
- SbxVariableRef p = PopVar();
- // In a test e.g. If Null then
- // will evaluate Null will act as if False
- if( ( bVBAEnabled && p->IsNull() ) || !p->GetBool() )
+ if ( !EvaluateTopOfStackAsBool() )
+ {
StepJUMP( nOp1 );
+ }
}
// evaluate TOS, jump into JUMP-table (+MaxVal)