reduce FormulaByteToken virtual calls

similar to
  commit f47fc9a67f16a3da1e5cbcc8b821682298ec90b3
  reduce ScRefListToken virtual calls

Push the Get/Set-Byte() methods down to the only subclasses
that actually use it.

Change-Id: I990e45baccb00657600ecf62004a67849ede2f62
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/1008
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
(cherry picked from commit d3ab7f03ee98fb23ab1b9c6a0e5f18874603f46d)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205601
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Tested-by: Julien Nabet <serval2412@yahoo.fr>
This commit is contained in:
Noel Grandin
2026-05-24 10:28:55 +02:00
committed by Julien Nabet
parent e22c8988d2
commit 8f6c2c38eb
9 changed files with 112 additions and 72 deletions
+16 -6
View File
@@ -1832,7 +1832,7 @@ void FormulaCompiler::Factor()
SetError( FormulaError::PairExpected);
else
NextToken();
pFacToken->SetByte( nSepCount );
static_cast<FormulaByteToken*>(&*pFacToken)->SetByte( nSepCount );
if (nSepCount == 2)
{
// An old mode!=1 indicates ISO week, remove argument if
@@ -1854,7 +1854,7 @@ void FormulaCompiler::Factor()
// the compiler local RPN array.
--mpCode; --mnPC;
(*mpCode)->DecRef(); // may be dead now
pFacToken->SetByte( nSepCount - 1 );
static_cast<FormulaByteToken*>(&*pFacToken)->SetByte( nSepCount - 1 );
}
else
{
@@ -1884,7 +1884,7 @@ void FormulaCompiler::Factor()
SetError( FormulaError::PairExpected);
else if ( mpArr->GetCodeError() == FormulaError::NONE )
{
pFacToken->SetByte( 1 );
static_cast<FormulaByteToken*>(&*pFacToken)->SetByte( 1 );
if (mbComputeII)
{
FormulaToken** pArg = mpCode - 1;
@@ -1976,8 +1976,12 @@ void FormulaCompiler::Factor()
// Jumps are just normal functions for the FunctionAutoPilot tree view
if (!mbJumpCommandReorder && pFacToken->GetType() == svJump)
pFacToken = new FormulaFAPToken( pFacToken->GetOpCode(), nSepCount, pFacToken );
else if (pFacToken->GetType() == svExternal)
static_cast<FormulaExternalToken*>(&*pFacToken)->SetByte( nSepCount );
else if (pFacToken->GetType() == svString)
static_cast<FormulaStringOpToken*>(&*pFacToken)->SetByte( nSepCount );
else
pFacToken->SetByte( nSepCount );
static_cast<FormulaByteToken*>(&*pFacToken)->SetByte( nSepCount );
PutCode( pFacToken );
if (bDone)
@@ -2353,7 +2357,7 @@ OpCode FormulaCompiler::Expression()
while (mpToken->GetOpCode() == ocAnd || mpToken->GetOpCode() == ocOr)
{
FormulaTokenRef p = mpToken;
mpToken->SetByte( 2 ); // 2 parameters!
static_cast<FormulaByteToken*>(mpToken.get())->SetByte( 2 ); // 2 parameters!
FormulaToken** pArgArray[2];
if (mbComputeII)
pArgArray[0] = mpCode - 1; // Add first argument
@@ -2669,7 +2673,13 @@ const FormulaToken* FormulaCompiler::CreateStringFromToken( OUStringBuffer& rBuf
if (bWriteSpaces)
{
// most times it's just one blank
sal_uInt8 n = t->GetByte();
sal_uInt8 n = 0;
if (t->GetOpCode() == ocWhitespace)
n = static_cast<const FormulaSpaceToken*>(t)->GetByte();
else if (t->GetOpCode() == ocSpaces)
n = static_cast<const FormulaByteToken*>(t)->GetByte();
else
assert(false);
for ( sal_uInt8 j=0; j<n; ++j )
{
if (eOp == ocWhitespace)
+44 -29
View File
@@ -70,11 +70,12 @@ FormulaToken::~FormulaToken()
bool FormulaToken::IsFunction() const
{
return (eOp != ocPush && eOp != ocBad && eOp != ocColRowName &&
if (!(eOp != ocPush && eOp != ocBad && eOp != ocColRowName &&
eOp != ocColRowNameAuto && eOp != ocName && eOp != ocDBArea &&
eOp != ocTableRef &&
(GetByte() != 0 // x parameters
|| (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) // no parameter
eOp != ocSep && eOp != ocDPFieldName && eOp != ocClose && eOp != ocOpen))
return false;
if ((SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) // no parameter
|| FormulaCompiler::IsOpCodeJumpCommand( eOp ) // @ jump commands
|| (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) // one parameter
|| (SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR) // x parameters (cByte==0 in
@@ -82,7 +83,11 @@ bool FormulaToken::IsFunction() const
|| eOp == ocMacro || eOp == ocExternal || eOp == ocUDExternal // macros, AddIns
|| eOp == ocAnd || eOp == ocOr // former binary, now x parameters
|| (eOp >= ocInternalBegin && eOp <= ocInternalEnd) // internal
));
)
return true;
if (eOp == ocWhitespace)
return (static_cast<const FormulaSpaceToken*>(this)->GetByte() != 0); // x parameters
return (static_cast<const FormulaByteToken*>(this)->GetByte() != 0); // x parameters
}
@@ -92,9 +97,6 @@ sal_uInt8 FormulaToken::GetParamCount() const
&& !FormulaCompiler::IsOpCodeJumpCommand(eOp) && eOp != ocPercentSign)
return 0; // parameters and specials
// ocIf... jump commands not for FAP, have cByte then
//2do: bool parameter whether FAP or not?
else if (GetByte())
return GetByte(); // all functions, also ocExternal and ocMacro
else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP && eOp != ocAnd && eOp != ocOr)
return 2; // binary operators, compiler checked; OR and AND legacy but are functions
else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP) || eOp == ocPercentSign)
@@ -103,9 +105,30 @@ sal_uInt8 FormulaToken::GetParamCount() const
return 0; // no parameter
else if (FormulaCompiler::IsOpCodeJumpCommand( eOp ))
return 1; // only the condition counts as parameter
else
return 0; // all the rest, no Parameter, or
// if so then it should be in cByte
//2do: bool parameter whether FAP or not?
if (GetType() == svByte)
{
if (auto n = static_cast<const FormulaByteToken*>(this)->GetByte())
return n; // all functions, also ocExternal and ocMacro
}
if (GetType() == svFAP)
{
if (auto n = static_cast<const FormulaFAPToken*>(this)->GetByte())
return n; // all functions, also ocExternal and ocMacro
}
if (GetType() == svExternal)
{
if (auto n = static_cast<const FormulaExternalToken*>(this)->GetByte())
return n;
}
if (GetType() == svString && (eOp == ocBad || eOp == ocStringXML || eOp == ocStringName || eOp == ocDPFieldName))
{
if (auto n = static_cast<const FormulaStringOpToken*>(this)->GetByte())
return n;
}
return 0; // all the rest, no Parameter, or
// if so then it should be in cByte
}
bool FormulaToken::IsExternalRef() const
@@ -158,17 +181,6 @@ bool FormulaToken::operator==( const FormulaToken& rToken ) const
// --- virtual dummy methods -------------------------------------------------
sal_uInt8 FormulaToken::GetByte() const
{
// ok to be called for any derived class
return 0;
}
void FormulaToken::SetByte( sal_uInt8 )
{
assert( !"virtual dummy called" );
}
ParamClass FormulaToken::GetInForceArray() const
{
// ok to be called for any derived class
@@ -194,18 +206,18 @@ sal_uInt8 FormulaSpaceToken::GetByte() const { return nByte; }
sal_Unicode FormulaSpaceToken::GetChar() const { return cChar; }
bool FormulaSpaceToken::operator==( const FormulaToken& r ) const
{
return FormulaToken::operator==( r ) && nByte == r.GetByte() &&
cChar == static_cast<const FormulaSpaceToken&>(r).GetChar();
return FormulaToken::operator==( r )
&& nByte == static_cast<const FormulaSpaceToken&>(r).GetByte()
&& cChar == static_cast<const FormulaSpaceToken&>(r).GetChar();
}
sal_uInt8 FormulaByteToken::GetByte() const { return nByte; }
void FormulaByteToken::SetByte( sal_uInt8 n ) { nByte = n; }
ParamClass FormulaByteToken::GetInForceArray() const { return eInForceArray; }
void FormulaByteToken::SetInForceArray( ParamClass c ) { eInForceArray = c; }
bool FormulaByteToken::operator==( const FormulaToken& r ) const
{
return FormulaToken::operator==( r ) && nByte == r.GetByte() &&
return FormulaToken::operator==( r )
&& mnByte == static_cast<const FormulaByteToken&>(r).mnByte &&
eInForceArray == r.GetInForceArray();
}
@@ -213,7 +225,8 @@ bool FormulaByteToken::operator==( const FormulaToken& r ) const
FormulaToken* FormulaFAPToken::GetFAPOrigToken() const { return pOrigToken.get(); }
bool FormulaFAPToken::operator==( const FormulaToken& r ) const
{
return FormulaByteToken::operator==( r )
return FormulaToken::operator==( r )
&& mnByte == static_cast<const FormulaFAPToken&>(r).mnByte
&& pOrigToken == static_cast<const FormulaFAPToken&>(r).GetFAPOrigToken();
}
@@ -1456,7 +1469,7 @@ FormulaTokenArray * FormulaTokenArray::RewriteMissing( const MissingConvention &
{
OpCode eOp = pCur->GetOpCode();
if ( ( eOp == ocCeil || eOp == ocFloor ||
( eOp == ocLogNormDist && pCur->GetByte() == 4 ) ) &&
( eOp == ocLogNormDist && static_cast<FormulaByteToken*>(pCur)->GetByte() == 4 ) ) &&
rConv.getConvention() == MissingConvention::FORMULA_MISSING_CONVENTION_OOXML )
{
switch ( eOp )
@@ -2024,7 +2037,9 @@ bool FormulaIndexToken::operator==( const FormulaToken& r ) const
const OUString& FormulaExternalToken::GetExternal() const { return aExternal; }
bool FormulaExternalToken::operator==( const FormulaToken& r ) const
{
return FormulaByteToken::operator==( r )
return FormulaToken::operator==( r )
&& mnByte == static_cast<const FormulaExternalToken&>(r).mnByte
&& eInForceArray == static_cast<const FormulaExternalToken&>(r).eInForceArray
&& aExternal == static_cast<const FormulaExternalToken&>(r).GetExternal();
}
+29 -23
View File
@@ -211,8 +211,6 @@ public:
Any other non-overridden method pops up an assertion.
*/
virtual sal_uInt8 GetByte() const;
virtual void SetByte( sal_uInt8 n );
virtual ParamClass GetInForceArray() const;
virtual void SetInForceArray( ParamClass c );
@@ -250,37 +248,37 @@ public:
nByte( r.nByte ), cChar( r.cChar ) {}
virtual FormulaToken* Clone() const override { return new FormulaSpaceToken(*this); }
virtual sal_uInt8 GetByte() const override;
sal_uInt8 GetByte() const;
sal_Unicode GetChar() const;
virtual bool operator==( const FormulaToken& rToken ) const override;
};
class FORMULA_DLLPUBLIC FormulaByteToken : public FormulaToken
class FORMULA_DLLPUBLIC FormulaByteToken final : public FormulaToken
{
private:
sal_uInt8 nByte;
sal_uInt8 mnByte;
ParamClass eInForceArray;
protected:
FormulaByteToken( OpCode e, sal_uInt8 n, StackVar v, ParamClass c ) :
FormulaToken( v,e ), nByte( n ),
FormulaToken( v,e ), mnByte( n ),
eInForceArray( c ) {}
public:
FormulaByteToken( OpCode e, sal_uInt8 n, ParamClass c ) :
FormulaToken( svByte,e ), nByte( n ),
FormulaToken( svByte,e ), mnByte( n ),
eInForceArray( c ) {}
FormulaByteToken( OpCode e, sal_uInt8 n ) :
FormulaToken( svByte,e ), nByte( n ),
FormulaToken( svByte,e ), mnByte( n ),
eInForceArray( ParamClass::Unknown ) {}
FormulaByteToken( OpCode e ) :
FormulaToken( svByte,e ), nByte( 0 ),
FormulaToken( svByte,e ), mnByte( 0 ),
eInForceArray( ParamClass::Unknown ) {}
FormulaByteToken( const FormulaByteToken& r ) :
FormulaToken( r ), nByte( r.nByte ),
FormulaToken( r ), mnByte( r.mnByte ),
eInForceArray( r.eInForceArray ) {}
virtual FormulaToken* Clone() const override { return new FormulaByteToken(*this); }
virtual sal_uInt8 GetByte() const override final;
virtual void SetByte( sal_uInt8 n ) override final;
sal_uInt8 GetByte() const { return mnByte; }
void SetByte( sal_uInt8 n ) { mnByte = n; }
virtual ParamClass GetInForceArray() const override final;
virtual void SetInForceArray( ParamClass c ) override final;
virtual bool operator==( const FormulaToken& rToken ) const override;
@@ -289,19 +287,21 @@ public:
// A special token for the FormulaAutoPilot only. Keeps a reference pointer of
// the token of which it was created for comparison.
class FORMULA_DLLPUBLIC FormulaFAPToken final : public FormulaByteToken
class FORMULA_DLLPUBLIC FormulaFAPToken final : public FormulaToken
{
private:
sal_uInt8 mnByte;
FormulaTokenRef pOrigToken;
public:
FormulaFAPToken( OpCode e, sal_uInt8 n, FormulaToken* p ) :
FormulaByteToken( e, n, svFAP, ParamClass::Unknown ),
pOrigToken( p ) {}
FormulaToken(svFAP, e), mnByte(n), pOrigToken( p ) {}
FormulaFAPToken( const FormulaFAPToken& r ) :
FormulaByteToken( r ), pOrigToken( r.pOrigToken ) {}
FormulaToken( r ), mnByte(r.mnByte), pOrigToken( r.pOrigToken ) {}
virtual FormulaToken* Clone() const override { return new FormulaFAPToken(*this); }
FormulaToken* GetFAPOrigToken() const;
sal_uInt8 GetByte() const { return mnByte; }
void SetByte( sal_uInt8 n ) { mnByte = n; }
virtual bool operator==( const FormulaToken& rToken ) const override;
};
@@ -370,8 +370,8 @@ public:
FormulaStringOpToken( const FormulaStringOpToken& r );
virtual FormulaToken* Clone() const override;
virtual sal_uInt8 GetByte() const override final { return nByte; }
virtual void SetByte( sal_uInt8 n ) override final { nByte = n; }
sal_uInt8 GetByte() const { return nByte; }
void SetByte( sal_uInt8 n ) { nByte = n; }
virtual ParamClass GetInForceArray() const override final { return eInForceArray; }
virtual void SetInForceArray( ParamClass c ) override final { eInForceArray = c; }
virtual bool operator==( const FormulaToken& rToken ) const override;
@@ -412,22 +412,28 @@ public:
};
class FORMULA_DLLPUBLIC FormulaExternalToken final : public FormulaByteToken
class FORMULA_DLLPUBLIC FormulaExternalToken final : public FormulaToken
{
private:
OUString aExternal;
sal_uInt8 mnByte;
ParamClass eInForceArray;
OUString aExternal;
public:
FormulaExternalToken( OpCode e, sal_uInt8 n, OUString r ) :
FormulaByteToken( e, n, svExternal, ParamClass::Unknown ),
FormulaToken( svExternal, e), mnByte(n), eInForceArray( ParamClass::Unknown ),
aExternal(std::move( r )) {}
FormulaExternalToken( OpCode e, OUString r ) :
FormulaByteToken( e, 0, svExternal, ParamClass::Unknown ),
FormulaToken( svExternal, e), mnByte(0), eInForceArray( ParamClass::Unknown ),
aExternal(std::move( r )) {}
FormulaExternalToken( const FormulaExternalToken& r ) :
FormulaByteToken( r ), aExternal( r.aExternal ) {}
FormulaToken( r ), mnByte(r.mnByte), eInForceArray(r.eInForceArray), aExternal( r.aExternal ) {}
virtual FormulaToken* Clone() const override { return new FormulaExternalToken(*this); }
const OUString& GetExternal() const;
sal_uInt8 GetByte() const { return mnByte; }
void SetByte( sal_uInt8 n ) { mnByte = n; }
virtual ParamClass GetInForceArray() const override final { return eInForceArray; }
virtual void SetInForceArray( ParamClass c ) override final { eInForceArray = c; }
virtual bool operator==( const FormulaToken& rToken ) const override;
};
+5 -5
View File
@@ -4217,17 +4217,17 @@ ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( const ScFormulaC
break;
case formula::svByte:
{
if(pThisTok->GetByte() != pOtherTok->GetByte())
if(static_cast<FormulaByteToken*>(pThisTok)->GetByte() != static_cast<FormulaByteToken*>(pOtherTok)->GetByte())
return NotEqual;
}
break;
case formula::svExternal:
{
if (static_cast<FormulaExternalToken*>(pThisTok)->GetExternal()
!= static_cast<FormulaExternalToken*>(pOtherTok)->GetExternal())
auto lhs = static_cast<FormulaExternalToken*>(pThisTok);
auto rhs = static_cast<FormulaExternalToken*>(pOtherTok);
if (lhs->GetExternal() != rhs->GetExternal())
return NotEqual;
if (pThisTok->GetByte() != pOtherTok->GetByte())
if (lhs->GetByte() != rhs->GetByte())
return NotEqual;
}
break;
+10 -1
View File
@@ -7045,7 +7045,16 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
// OpCode of the "root" operator (which is already in RPN array).
OpCode eOpCode = (*(mpCode - 1))->GetOpCode();
// Param number of the "root" operator (which is already in RPN array).
sal_uInt8 nRootParam = (*(mpCode - 1))->GetByte();
auto p = *(mpCode - 1);
sal_uInt8 nRootParam = 0;
if (p->GetType() == svExternal)
nRootParam = static_cast<FormulaExternalToken*>(p)->GetByte();
else if (eOpCode == ocBad)
nRootParam = static_cast<FormulaStringOpToken*>(p)->GetByte();
else if (p->GetType() == svFAP)
nRootParam = static_cast<FormulaFAPToken*>(p)->GetByte();
else if (p->GetType() == svByte)
nRootParam = static_cast<FormulaByteToken*>(p)->GetByte();
// eOpCode can be some operator which does not change with operands with or contains zero values.
if (eOpCode == ocSum)
{
+1 -1
View File
@@ -4042,7 +4042,7 @@ StackVar ScInterpreter::Interpret()
if (!pCur || (nGlobalError != FormulaError::NONE && nErrorFunction > nErrorFunctionCount) )
break;
eOp = pCur->GetOpCode();
cPar = pCur->GetByte();
cPar = pCur->GetParamCount();
if ( eOp == ocPush )
{
// RPN code push without error
+2 -2
View File
@@ -1694,7 +1694,7 @@ void ScTokenArray::GenHash()
case svByte:
{
// Constant value.
sal_uInt8 nVal = p->GetByte();
sal_uInt8 nVal = static_cast<const FormulaByteToken*>(p)->GetByte();
nHash += static_cast<size_t>(nVal);
}
break;
@@ -2336,7 +2336,7 @@ bool ScTokenArray::GetAdjacentExtendOfOuterFuncRefs( SCCOLROW& nExtend,
FormulaToken* t = pRPN[nRPN-1];
if ( t->GetType() == svByte )
{
sal_uInt8 nParamCount = t->GetByte();
sal_uInt8 nParamCount = static_cast<FormulaByteToken*>(t)->GetByte();
if ( nParamCount && nRPN > nParamCount )
{
bool bRet = false;
+1 -1
View File
@@ -846,7 +846,7 @@ bool XclExpFmlaCompImpl::GetNextToken( XclExpScToken& rTokData )
/* TODO: handle ocWhitespace characters? */
while (rTokData.GetOpCode() == ocSpaces || rTokData.GetOpCode() == ocWhitespace)
{
rTokData.mnSpaces += rTokData.mpScToken->GetByte();
rTokData.mnSpaces += static_cast<const FormulaByteToken*>(rTokData.mpScToken)->GetByte();
rTokData.mpScToken = GetNextRawToken();
}
return rTokData.Is();
+4 -4
View File
@@ -402,17 +402,17 @@ void ScTokenConversion::ConvertToTokenSequence( const ScDocument& rDoc,
case svByte:
// Only the count of spaces is stored as "long". Parameter count is ignored.
if ( eOpCode == ocSpaces )
rAPI.Data <<= static_cast<sal_Int32>(rToken.GetByte());
rAPI.Data <<= static_cast<sal_Int32>(static_cast<const FormulaByteToken&>(rToken).GetByte());
else if (eOpCode == ocWhitespace)
{
auto const & rSToken = static_cast<const FormulaSpaceToken&>(rToken);
// Convention is one character repeated.
if (rToken.GetByte() == 1)
if (rSToken.GetByte() == 1)
rAPI.Data <<= OUString( rSToken.GetChar());
else
{
OUStringBuffer aBuf( rToken.GetByte());
comphelper::string::padToLength( aBuf, rToken.GetByte(), rSToken.GetChar());
OUStringBuffer aBuf(rSToken.GetByte());
comphelper::string::padToLength( aBuf, rSToken.GetByte(), rSToken.GetChar());
rAPI.Data <<= aBuf.makeStringAndClear();
}
}