Create abstract class CXFA_FMChainableExpression
Create the abstract class CXFA_FMChainableExpression, which is derived
from CXFA_FMSimpleExpression, as a base class for expression classes
that chain two CXFA_FMSimpleExpression objects.
This change sets up another change that would allow for space-efficient
destruction of chainable expressions.
Bug: chromium:1052724
Change-Id: I47d015e4c458611261a95920b2dbd3d6b163bcfa
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67090
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Daniel Hosseinian <dhoss@chromium.org>
diff --git a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp
index e94f55a..ac91d94 100644
--- a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.cpp
@@ -70,12 +70,35 @@
} // namespace
-CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(XFA_FM_TOKEN op) : m_op(op) {}
+CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(XFA_FM_TOKEN op)
+ : m_op(op), m_bChainable(false) {}
+
+CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(XFA_FM_TOKEN op,
+ bool chainable)
+ : m_op(op), m_bChainable(chainable) {}
XFA_FM_TOKEN CXFA_FMSimpleExpression::GetOperatorToken() const {
return m_op;
}
+CXFA_FMChainableExpression::CXFA_FMChainableExpression(
+ XFA_FM_TOKEN op,
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
+ : CXFA_FMSimpleExpression(op, /*chainable=*/true),
+ m_pExp1(std::move(pExp1)),
+ m_pExp2(std::move(pExp2)) {}
+
+CXFA_FMChainableExpression::~CXFA_FMChainableExpression() = default;
+
+CXFA_FMSimpleExpression* CXFA_FMChainableExpression::GetFirstExpression() {
+ return m_pExp1.get();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMChainableExpression::GetSecondExpression() {
+ return m_pExp2.get();
+}
+
CXFA_FMNullExpression::CXFA_FMNullExpression()
: CXFA_FMSimpleExpression(TOKnull) {}
@@ -182,9 +205,7 @@
XFA_FM_TOKEN op,
std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
- : CXFA_FMSimpleExpression(op),
- m_pExp1(std::move(pExp1)),
- m_pExp2(std::move(pExp2)) {}
+ : CXFA_FMChainableExpression(op, std::move(pExp1), std::move(pExp2)) {}
CXFA_FMAssignExpression::~CXFA_FMAssignExpression() = default;
@@ -195,7 +216,8 @@
return false;
CFX_WideTextBuf tempExp1;
- if (!m_pExp1->ToJavaScript(&tempExp1, ReturnType::kInfered))
+ CXFA_FMSimpleExpression* exp1 = GetFirstExpression();
+ if (!exp1->ToJavaScript(&tempExp1, ReturnType::kInfered))
return false;
*js << "if (pfm_rt.is_obj(" << tempExp1 << "))\n{\n";
@@ -203,12 +225,13 @@
*js << "pfm_ret = ";
CFX_WideTextBuf tempExp2;
- if (!m_pExp2->ToJavaScript(&tempExp2, ReturnType::kInfered))
+ CXFA_FMSimpleExpression* exp2 = GetSecondExpression();
+ if (!exp2->ToJavaScript(&tempExp2, ReturnType::kInfered))
return false;
*js << "pfm_rt.asgn_val_op(" << tempExp1 << ", " << tempExp2 << ");\n}\n";
- if (m_pExp1->GetOperatorToken() == TOKidentifier &&
+ if (exp1->GetOperatorToken() == TOKidentifier &&
!tempExp1.AsStringView().EqualsASCII("this")) {
*js << "else\n{\n";
if (type == ReturnType::kImplied)
@@ -226,10 +249,8 @@
XFA_FM_TOKEN op,
std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
std::unique_ptr<CXFA_FMSimpleExpression> pExp2)
- : CXFA_FMSimpleExpression(op),
- m_OpName(opName),
- m_pExp1(std::move(pExp1)),
- m_pExp2(std::move(pExp2)) {}
+ : CXFA_FMChainableExpression(op, std::move(pExp1), std::move(pExp2)),
+ m_OpName(opName) {}
CXFA_FMBinExpression::~CXFA_FMBinExpression() = default;
@@ -239,10 +260,10 @@
return false;
*js << "pfm_rt." << m_OpName << "(";
- if (!m_pExp1->ToJavaScript(js, ReturnType::kInfered))
+ if (!GetFirstExpression()->ToJavaScript(js, ReturnType::kInfered))
return false;
*js << ", ";
- if (!m_pExp2->ToJavaScript(js, ReturnType::kInfered))
+ if (!GetSecondExpression()->ToJavaScript(js, ReturnType::kInfered))
return false;
*js << ")";
return !CXFA_IsTooBig(js);
@@ -530,10 +551,10 @@
XFA_FM_TOKEN op,
WideStringView wsIdentifier,
std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp)
- : CXFA_FMSimpleExpression(op),
- m_wsIdentifier(wsIdentifier),
- m_pExp1(std::move(pAccessor)),
- m_pExp2(std::move(pIndexExp)) {}
+ : CXFA_FMChainableExpression(op,
+ std::move(pAccessor),
+ std::move(pIndexExp)),
+ m_wsIdentifier(wsIdentifier) {}
CXFA_FMDotAccessorExpression::~CXFA_FMDotAccessorExpression() = default;
@@ -546,8 +567,9 @@
*js << "pfm_rt.dot_acc(";
CFX_WideTextBuf tempExp1;
- if (m_pExp1) {
- if (!m_pExp1->ToJavaScript(&tempExp1, ReturnType::kInfered))
+ CXFA_FMSimpleExpression* exp1 = GetFirstExpression();
+ if (exp1) {
+ if (!exp1->ToJavaScript(&tempExp1, ReturnType::kInfered))
return false;
*js << tempExp1;
@@ -556,7 +578,7 @@
}
*js << ", \"";
- if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier)
+ if (exp1 && exp1->GetOperatorToken() == TOKidentifier)
*js << tempExp1;
*js << "\", ";
@@ -569,7 +591,8 @@
else
*js << "\"" << m_wsIdentifier << "\", ";
- if (!m_pExp2->ToJavaScript(js, ReturnType::kInfered))
+ CXFA_FMSimpleExpression* exp2 = GetSecondExpression();
+ if (!exp2->ToJavaScript(js, ReturnType::kInfered))
return false;
*js << ")";
@@ -627,10 +650,10 @@
XFA_FM_TOKEN op,
WideStringView wsIdentifier,
std::unique_ptr<CXFA_FMSimpleExpression> pIndexExp)
- : CXFA_FMSimpleExpression(op),
- m_wsIdentifier(wsIdentifier),
- m_pExp1(std::move(pAccessor)),
- m_pExp2(std::move(pIndexExp)) {}
+ : CXFA_FMChainableExpression(op,
+ std::move(pAccessor),
+ std::move(pIndexExp)),
+ m_wsIdentifier(wsIdentifier) {}
CXFA_FMDotDotAccessorExpression::~CXFA_FMDotDotAccessorExpression() = default;
@@ -640,18 +663,20 @@
if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
return false;
+ CXFA_FMSimpleExpression* exp1 = GetFirstExpression();
*js << "pfm_rt.dotdot_acc(";
- if (!m_pExp1->ToJavaScript(js, ReturnType::kInfered))
+ if (!exp1->ToJavaScript(js, ReturnType::kInfered))
return false;
*js << ", "
<< "\"";
- if (m_pExp1->GetOperatorToken() == TOKidentifier) {
- if (!m_pExp1->ToJavaScript(js, ReturnType::kInfered))
+ if (exp1->GetOperatorToken() == TOKidentifier) {
+ if (!exp1->ToJavaScript(js, ReturnType::kInfered))
return false;
}
+ CXFA_FMSimpleExpression* exp2 = GetSecondExpression();
*js << "\", \"" << m_wsIdentifier << "\", ";
- if (!m_pExp2->ToJavaScript(js, ReturnType::kInfered))
+ if (!exp2->ToJavaScript(js, ReturnType::kInfered))
return false;
*js << ")";
return !CXFA_IsTooBig(js);
@@ -660,9 +685,9 @@
CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression(
std::unique_ptr<CXFA_FMSimpleExpression> pAccessorExp1,
std::unique_ptr<CXFA_FMSimpleExpression> pCallExp)
- : CXFA_FMSimpleExpression(TOKdot),
- m_pExp1(std::move(pAccessorExp1)),
- m_pExp2(std::move(pCallExp)) {}
+ : CXFA_FMChainableExpression(TOKdot,
+ std::move(pAccessorExp1),
+ std::move(pCallExp)) {}
CXFA_FMMethodCallExpression::~CXFA_FMMethodCallExpression() = default;
@@ -673,13 +698,13 @@
return false;
CFX_WideTextBuf buf;
- if (!m_pExp1->ToJavaScript(&buf, ReturnType::kInfered))
+ if (!GetFirstExpression()->ToJavaScript(&buf, ReturnType::kInfered))
return false;
*js << "(function() {\n";
*js << " return pfm_method_runner(" << buf << ", function(obj) {\n";
*js << " return obj.";
- if (!m_pExp2->ToJavaScript(js, ReturnType::kInfered))
+ if (!GetSecondExpression()->ToJavaScript(js, ReturnType::kInfered))
return false;
*js << ";\n";
*js << " });\n";
diff --git a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h
index ae8f38e..49e2560 100644
--- a/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h
+++ b/xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h
@@ -29,11 +29,33 @@
virtual bool ToJavaScript(CFX_WideTextBuf* js, ReturnType type) = 0;
XFA_FM_TOKEN GetOperatorToken() const;
+ bool chainable() const { return m_bChainable; }
protected:
explicit CXFA_FMSimpleExpression(XFA_FM_TOKEN op);
+ CXFA_FMSimpleExpression(XFA_FM_TOKEN op, bool chainable);
const XFA_FM_TOKEN m_op;
+
+ private:
+ const bool m_bChainable;
+};
+
+class CXFA_FMChainableExpression : public CXFA_FMSimpleExpression {
+ public:
+ ~CXFA_FMChainableExpression() override;
+
+ protected:
+ CXFA_FMChainableExpression(XFA_FM_TOKEN op,
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
+ std::unique_ptr<CXFA_FMSimpleExpression> pExp2);
+
+ CXFA_FMSimpleExpression* GetFirstExpression();
+ CXFA_FMSimpleExpression* GetSecondExpression();
+
+ private:
+ std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
+ std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
};
class CXFA_FMNullExpression final : public CXFA_FMSimpleExpression {
@@ -77,7 +99,7 @@
WideStringView m_wsIdentifier;
};
-class CXFA_FMAssignExpression final : public CXFA_FMSimpleExpression {
+class CXFA_FMAssignExpression final : public CXFA_FMChainableExpression {
public:
CXFA_FMAssignExpression(XFA_FM_TOKEN op,
std::unique_ptr<CXFA_FMSimpleExpression> pExp1,
@@ -85,13 +107,9 @@
~CXFA_FMAssignExpression() override;
bool ToJavaScript(CFX_WideTextBuf* js, ReturnType type) override;
-
- private:
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
};
-class CXFA_FMBinExpression : public CXFA_FMSimpleExpression {
+class CXFA_FMBinExpression : public CXFA_FMChainableExpression {
public:
~CXFA_FMBinExpression() override;
@@ -105,8 +123,6 @@
private:
WideString m_OpName;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
};
class CXFA_FMLogicalOrExpression final : public CXFA_FMBinExpression {
@@ -257,7 +273,7 @@
std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> m_Arguments;
};
-class CXFA_FMDotAccessorExpression final : public CXFA_FMSimpleExpression {
+class CXFA_FMDotAccessorExpression final : public CXFA_FMChainableExpression {
public:
CXFA_FMDotAccessorExpression(
std::unique_ptr<CXFA_FMSimpleExpression> pAccessor,
@@ -270,8 +286,6 @@
private:
WideStringView m_wsIdentifier;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
};
class CXFA_FMIndexExpression final : public CXFA_FMSimpleExpression {
@@ -289,7 +303,8 @@
bool m_bIsStarIndex;
};
-class CXFA_FMDotDotAccessorExpression final : public CXFA_FMSimpleExpression {
+class CXFA_FMDotDotAccessorExpression final
+ : public CXFA_FMChainableExpression {
public:
CXFA_FMDotDotAccessorExpression(
std::unique_ptr<CXFA_FMSimpleExpression> pAccessor,
@@ -302,11 +317,9 @@
private:
WideStringView m_wsIdentifier;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
};
-class CXFA_FMMethodCallExpression final : public CXFA_FMSimpleExpression {
+class CXFA_FMMethodCallExpression final : public CXFA_FMChainableExpression {
public:
CXFA_FMMethodCallExpression(
std::unique_ptr<CXFA_FMSimpleExpression> pAccessorExp1,
@@ -314,10 +327,6 @@
~CXFA_FMMethodCallExpression() override;
bool ToJavaScript(CFX_WideTextBuf* js, ReturnType type) override;
-
- private:
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
- std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
};
bool CXFA_IsTooBig(const CFX_WideTextBuf* js);