You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by db...@apache.org on 2001/04/11 04:21:51 UTC
cvs commit: xml-xalan/c/src/XPath XPath.cpp XPath.hpp XPathExpression.cpp XPathExpression.hpp XPathProcessorImpl.cpp
dbertoni 01/04/10 19:21:51
Modified: c/src/XPath XPath.cpp XPath.hpp XPathExpression.cpp
XPathExpression.hpp XPathProcessorImpl.cpp
Log:
When possible, encode numbers directly into the op map. Short-cut the normal evaluation process when such a situation is encountered during expression evalution. Changes for OS/390 port.
Revision Changes Path
1.48 +87 -135 xml-xalan/c/src/XPath/XPath.cpp
Index: XPath.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.cpp,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- XPath.cpp 2001/03/29 22:17:46 1.47
+++ XPath.cpp 2001/04/11 02:21:50 1.48
@@ -199,16 +199,14 @@
{
assert(context != 0);
- XObjectPtr result;
-
switch(m_expression.m_opMap[opPos])
{
case XPathExpression::eOP_XPATH:
- result = executeMore(context, opPos + 2, executionContext);
+ return executeMore(context, opPos + 2, executionContext);
break;
case XPathExpression::eOP_MATCHPATTERN:
- result = matchPattern(context, opPos + 2, executionContext);
+ return matchPattern(context, opPos + 2, executionContext);
break;
case XPathExpression::eEMPTY:
@@ -216,199 +214,121 @@
break;
case XPathExpression::eOP_OR:
- result = Or(context, opPos, executionContext);
+ return Or(context, opPos, executionContext);
break;
case XPathExpression::eOP_AND:
- result = And(context, opPos, executionContext);
+ return And(context, opPos, executionContext);
break;
case XPathExpression::eOP_NOTEQUALS:
- result = notequals(context, opPos, executionContext);
+ return notequals(context, opPos, executionContext);
break;
case XPathExpression::eOP_EQUALS:
- result = equals(context, opPos, executionContext);
+ return equals(context, opPos, executionContext);
break;
case XPathExpression::eOP_LTE:
- result = lte(context, opPos, executionContext);
+ return lte(context, opPos, executionContext);
break;
case XPathExpression::eOP_LT:
- result = lt(context, opPos, executionContext);
+ return lt(context, opPos, executionContext);
break;
case XPathExpression::eOP_GTE:
- result = gte(context, opPos, executionContext);
+ return gte(context, opPos, executionContext);
break;
case XPathExpression::eOP_GT:
- result = gt(context, opPos, executionContext);
+ return gt(context, opPos, executionContext);
break;
case XPathExpression::eOP_PLUS:
- result = plus(context, opPos, executionContext);
+ return plus(context, opPos, executionContext);
break;
case XPathExpression::eOP_MINUS:
- result = minus(context, opPos, executionContext);
+ return minus(context, opPos, executionContext);
break;
case XPathExpression::eOP_MULT:
- result = mult(context, opPos, executionContext);
+ return mult(context, opPos, executionContext);
break;
case XPathExpression::eOP_DIV:
- result = div(context, opPos, executionContext);
+ return div(context, opPos, executionContext);
break;
case XPathExpression::eOP_MOD:
- result = mod(context, opPos, executionContext);
+ return mod(context, opPos, executionContext);
break;
case XPathExpression::eOP_QUO:
- result = quo(context, opPos, executionContext);
+ return quo(context, opPos, executionContext);
break;
case XPathExpression::eOP_NEG:
- result = neg(context, opPos, executionContext);
+ return neg(context, opPos, executionContext);
break;
case XPathExpression::eOP_STRING:
- result = string(context, opPos, executionContext);
+ return string(context, opPos, executionContext);
break;
case XPathExpression::eOP_BOOL:
- result = boolean(context, opPos, executionContext);
+ return boolean(context, opPos, executionContext);
break;
case XPathExpression::eOP_NUMBER:
- result = number(context, opPos, executionContext);
+ return number(context, opPos, executionContext);
break;
case XPathExpression::eOP_UNION:
- result = Union(context, opPos, executionContext);
+ return Union(context, opPos, executionContext);
break;
case XPathExpression::eOP_LITERAL:
- result = literal(context, opPos, executionContext);
+ return literal(context, opPos, executionContext);
break;
case XPathExpression::eOP_VARIABLE:
- result = variable(context, opPos, executionContext);
+ return variable(context, opPos, executionContext);
break;
case XPathExpression::eOP_GROUP:
- result = group(context, opPos, executionContext);
+ return group(context, opPos, executionContext);
break;
case XPathExpression::eOP_NUMBERLIT:
- result = numberlit(context, opPos, executionContext);
+ return numberlit(context, opPos, executionContext);
+ break;
+
+ case XPathExpression::eOP_INLINE_NUMBERLIT:
+ return inlineNumberlit(context, opPos, executionContext);
break;
case XPathExpression::eOP_ARGUMENT:
- result = arg(context, opPos, executionContext);
+ return arg(context, opPos, executionContext);
break;
case XPathExpression::eOP_EXTFUNCTION:
- result = runExtFunction(context, opPos, executionContext);
+ return runExtFunction(context, opPos, executionContext);
break;
case XPathExpression::eOP_FUNCTION:
- result = runFunction(context, opPos, executionContext);
+ return runFunction(context, opPos, executionContext);
break;
case XPathExpression::eOP_LOCATIONPATH:
- result = locationPath(context, opPos, executionContext);
+ return locationPath(context, opPos, executionContext);
break;
case XPathExpression::eOP_LOCATIONPATHPATTERN:
- result = locationPathPattern(context, opPos, executionContext);
- break;
-
-/*
- case XPathExpression::eOP_PREDICATE:
- break;
-
- case XPathExpression::XPathExpression::eFROM_ANCESTORS:
- break;
-
- case XPathExpression::eFROM_ANCESTORS_OR_SELF:
- break;
-
- case XPathExpression::eFROM_ATTRIBUTES:
- break;
-
- case XPathExpression::eFROM_CHILDREN:
- break;
-
- case XPathExpression::eFROM_DESCENDANTS:
- break;
-
- case XPathExpression::eFROM_DESCENDANTS_OR_SELF:
- break;
-
- case XPathExpression::eFROM_FOLLOWING:
- break;
-
- case XPathExpression::eFROM_FOLLOWING_SIBLINGS:
- break;
-
- case XPathExpression::eFROM_PARENT:
- break;
-
- case XPathExpression::eFROM_PRECEDING:
- break;
-
- case XPathExpression::eFROM_PRECEDING_SIBLINGS:
- break;
-
- case XPathExpression::eFROM_SELF:
- break;
-
- case XPathExpression::eFROM_NAMESPACE:
- break;
-
- case XPathExpression::eFROM_ATTRIBUTE:
- break;
-
- case XPathExpression::eFROM_DOC:
- break;
-
- case XPathExpression::eFROM_DOCREF:
- break;
-
- case XPathExpression::eFROM_ID:
- break;
- case XPathExpression::eFROM_IDREF:
- break;
-
- case XPathExpression::eFROM_ROOT:
- break;
-
- case eNODETYPE_COMMENT:
- break;
-
- case eNODETYPE_TEXT:
- break;
-
- case eNODETYPE_PI:
- break;
-
- case eNODETYPE_NODE:
- break;
-
- case eNODETYPE_ROOT:
- break;
-
- case eNODETYPE_ANYELEMENT:
+ return locationPathPattern(context, opPos, executionContext);
break;
- case eNODENAME:
- break;
-*/
-
default:
{
const XalanDOMString theOpCode = LongToDOMString(m_expression.m_opMap[opPos]);
@@ -419,7 +339,7 @@
break;
}
- return result;
+ return XObjectPtr();
}
@@ -870,6 +790,33 @@
+double
+XPath::getNumericOperand(
+ XalanNode* context,
+ int opPos,
+ XPathExecutionContext& executionContext) const
+{
+ if (m_expression.m_opMap[opPos] == XPathExpression::eOP_INLINE_NUMBERLIT)
+ {
+ assert(m_expression.m_opMap.size() > unsigned(opPos + 2));
+
+ return double(m_expression.m_opMap[opPos + 2]);
+ }
+ else if (m_expression.m_opMap[opPos] == XPathExpression::eOP_NUMBERLIT)
+ {
+ assert(m_expression.m_opMap.size() > unsigned(opPos + 2));
+ assert(m_expression.m_tokenQueue.size() > unsigned(m_expression.m_opMap[opPos + 2]));
+
+ return m_expression.m_tokenQueue[m_expression.m_opMap[opPos + 2]].num();
+ }
+ else
+ {
+ return executeMore(context, opPos, executionContext)->num();
+ }
+}
+
+
+
const XObjectPtr
XPath::plus(
XalanNode* context,
@@ -878,15 +825,13 @@
{
opPos += 2;
- const XObjectPtr expr1(executeMore(context, opPos, executionContext));
- assert(expr1.get() != 0);
+ const double expr1 = getNumericOperand(context, opPos, executionContext);
const int expr2Pos = m_expression.getNextOpCodePosition(opPos);
- const XObjectPtr expr2(executeMore(context, expr2Pos, executionContext));
- assert(expr2.get() != 0);
+ const double expr2 = getNumericOperand(context, expr2Pos, executionContext);
- return executionContext.getXObjectFactory().createNumber(DoubleSupport::add(expr1->num(), expr2->num()));
+ return executionContext.getXObjectFactory().createNumber(DoubleSupport::add(expr1, expr2));
}
@@ -899,15 +844,13 @@
{
opPos += 2;
- const XObjectPtr expr1(executeMore(context, opPos, executionContext));
- assert(expr1.get() != 0);
+ const double expr1 = getNumericOperand(context, opPos, executionContext);
const int expr2Pos = m_expression.getNextOpCodePosition(opPos);
- const XObjectPtr expr2(executeMore(context, expr2Pos, executionContext));
- assert(expr2.get() != 0);
+ const double expr2 = getNumericOperand(context, expr2Pos, executionContext);
- return executionContext.getXObjectFactory().createNumber(DoubleSupport::subtract(expr1->num(), expr2->num()));
+ return executionContext.getXObjectFactory().createNumber(DoubleSupport::subtract(expr1, expr2));
}
@@ -920,15 +863,13 @@
{
opPos += 2;
- const XObjectPtr expr1(executeMore(context, opPos, executionContext));
- assert(expr1.get() != 0);
+ const double expr1 = getNumericOperand(context, opPos, executionContext);
const int expr2Pos = m_expression.getNextOpCodePosition(opPos);
- const XObjectPtr expr2(executeMore(context, expr2Pos, executionContext));
- assert(expr2.get() != 0);
+ const double expr2 = getNumericOperand(context, expr2Pos, executionContext);
- return executionContext.getXObjectFactory().createNumber(DoubleSupport::multiply(expr1->num(), expr2->num()));
+ return executionContext.getXObjectFactory().createNumber(DoubleSupport::multiply(expr1, expr2));
}
@@ -941,15 +882,13 @@
{
opPos += 2;
- const XObjectPtr expr1(executeMore(context, opPos, executionContext));
- assert(expr1.get() != 0);
+ const double expr1 = getNumericOperand(context, opPos, executionContext);
const int expr2Pos = m_expression.getNextOpCodePosition(opPos);
- const XObjectPtr expr2(executeMore(context, expr2Pos, executionContext));
- assert(expr2.get() != 0);
+ const double expr2 = getNumericOperand(context, expr2Pos, executionContext);
- return executionContext.getXObjectFactory().createNumber(DoubleSupport::divide(expr1->num(), expr2->num()));
+ return executionContext.getXObjectFactory().createNumber(DoubleSupport::divide(expr1, expr2));
}
@@ -1191,6 +1130,19 @@
{
return executionContext.getXObjectFactory().createNumber(theLiteral.num());
}
+}
+
+
+
+const XObjectPtr
+XPath::inlineNumberlit(
+ XalanNode* /* context */,
+ int opPos,
+ XPathExecutionContext& executionContext) const
+{
+ assert(m_expression.m_opMap.size() > unsigned(opPos + 2));
+
+ return executionContext.getXObjectFactory().createNumber(m_expression.m_opMap[opPos + 2]);
}
1.22 +20 -1 xml-xalan/c/src/XPath/XPath.hpp
Index: XPath.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.hpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- XPath.hpp 2001/03/29 22:17:46 1.21
+++ XPath.hpp 2001/04/11 02:21:50 1.22
@@ -772,7 +772,20 @@
XalanNode* context,
int opPos,
XPathExecutionContext& executionContext) const;
-
+
+ /**
+ * Get a literal value that has been placed directly in
+ * the op code map of the expression
+ * @param context The current source tree context node.
+ * @param opPos The current position in the m_opMap array.
+ * @return an XObject object.
+ */
+ const XObjectPtr
+ inlineNumberlit(
+ XalanNode* context,
+ int opPos,
+ XPathExecutionContext& executionContext) const;
+
/**
* Execute a function argument.
* @param context The current source tree context node.
@@ -838,6 +851,12 @@
int funcID,
const Function::XObjectArgVectorType& argVec,
XPathExecutionContext& executionContext) const;
+
+ double
+ getNumericOperand(
+ XalanNode* context,
+ int opPos,
+ XPathExecutionContext& executionContext) const;
private:
1.27 +1 -0 xml-xalan/c/src/XPath/XPathExpression.cpp
Index: XPathExpression.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathExpression.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- XPathExpression.cpp 2001/02/05 22:47:44 1.26
+++ XPathExpression.cpp 2001/04/11 02:21:50 1.27
@@ -859,6 +859,7 @@
theMap[eMATCH_IMMEDIATE_ANCESTOR] = 1 + s__opCodeMapLengthIndex;
theMap[eMATCH_ANY_ANCESTOR_WITH_PREDICATE] = 2 + s__opCodeMapLengthIndex;
theMap[eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL] = 2 + s__opCodeMapLengthIndex;
+ theMap[eOP_INLINE_NUMBERLIT] = 1 + s__opCodeMapLengthIndex;
return theMap;
}
1.16 +26 -2 xml-xalan/c/src/XPath/XPathExpression.hpp
Index: XPathExpression.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathExpression.hpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- XPathExpression.hpp 2001/02/05 22:47:44 1.15
+++ XPathExpression.hpp 2001/04/11 02:21:50 1.16
@@ -598,6 +598,14 @@
eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 97,
eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 98,
+ /**
+ * [OP_INLINE_NUMBERLIT] (Number literal.)
+ * [3]
+ * [value]
+ *
+ */
+ eOP_INLINE_NUMBERLIT = 99,
+
// Always add _before_ this one.
eOpCodeNextAvailable
}; // enum eOpCodes
@@ -745,7 +753,7 @@
#if defined(XALAN_NO_NAMESPACES)
typedef vector<int> OpCodeMapType;
- typedef deque<XToken> TokenQueueType;
+ typedef vector<XToken> TokenQueueType;
typedef vector<int> PatternMapType;
typedef map<int, int, less<int> > OpCodeLengthMapType;
@@ -760,7 +768,7 @@
#else
typedef std::vector<int> OpCodeMapType;
- typedef std::deque<XToken> TokenQueueType;
+ typedef std::vector<XToken> TokenQueueType;
typedef std::vector<int> PatternMapType;
typedef std::map<int, int> OpCodeLengthMapType;
@@ -1299,6 +1307,22 @@
#else
dumpRemainingTokenQueue(std::ostream& theStream) const;
#endif
+
+ /**
+ * Push a value onto the operations code
+ * map.
+ *
+ * @param theToken string value of the token to push
+ */
+ void
+ pushValueOnOpCodeMap(const OpCodeMapType::value_type& theValue)
+ {
+ // Push the index onto the op map.
+ m_opMap.push_back(theValue);
+
+ // Update the op map length.
+ m_opMap[s__opCodeMapLengthIndex]++;
+ }
/**
* Push a token onto the token queue and its index onto the operations code
1.36 +32 -5 xml-xalan/c/src/XPath/XPathProcessorImpl.cpp
Index: XPathProcessorImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathProcessorImpl.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- XPathProcessorImpl.cpp 2001/02/09 19:29:15 1.35
+++ XPathProcessorImpl.cpp 2001/04/11 02:21:50 1.36
@@ -1611,12 +1611,39 @@
XalanXMLChar::isDigit(charAt(m_token, 1)) == true) ||
XalanXMLChar::isDigit(m_tokenChar) == true)
{
- m_expression->appendOpCode(XPathExpression::eOP_NUMBERLIT);
+ // We're going to try to save as much time as possible by encoding
+ // some things directly into the op map, instead of encoding the
+ // index into the token queue.
+ const double num = DoubleSupport::toDouble(m_token);
- Number();
+ const XPathExpression::OpCodeMapType::value_type numAsValue =
+ XPathExpression::OpCodeMapType::value_type(num);
- m_expression->updateOpCodeLength(XPathExpression::eOP_NUMBERLIT,
- opPos);
+ if (numAsValue == num)
+ {
+ // The value will fit directly into the token queue, so
+ // put it there.
+ m_expression->appendOpCode(XPathExpression::eOP_INLINE_NUMBERLIT);
+
+ m_expression->pushValueOnOpCodeMap(numAsValue);
+
+ m_expression->updateOpCodeLength(XPathExpression::eOP_INLINE_NUMBERLIT,
+ opPos);
+ }
+ else
+ {
+ // Won't fit, so use the token to represent the number. One way
+ // to avoid this would be to use a union for the entries in the
+ // token queue, so that we can represent all numbers in-line.
+ m_expression->appendOpCode(XPathExpression::eOP_NUMBERLIT);
+
+ m_expression->pushArgumentOnOpCodeMap(num);
+
+ m_expression->updateOpCodeLength(XPathExpression::eOP_NUMBERLIT,
+ opPos);
+ }
+
+ nextToken();
}
else if(lookahead(XalanUnicode::charLeftParenthesis, 1) == true ||
(lookahead(XalanUnicode::charColon, 1) == true && lookahead(XalanUnicode::charLeftParenthesis, 3) == true))
@@ -2114,7 +2141,7 @@
assert(m_expression != 0);
// If there is no prefix, we have to fake things out...
- if (lookahead(':', 1) == false)
+ if (lookahead(XalanUnicode::charColon, 1) == false)
{
m_expression->insertToken(XalanDOMString());
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org