morten 01/09/19 04:50:31
Modified: java/src/org/apache/xalan/xsltc/compiler Predicate.java
StepPattern.java TestSeq.java
Log:
Fix for predicates used in complex match patterns. The compiler failed to
produce code that would match on patterns like "blob/[EMAIL
PROTECTED]'str']". It
would also fail to identify some position predicates such as "blob[$param]".
Nested parameters were not handled properly either. A pattern such as
"foo[bar[starts-with(@attr, 'baz')]]" would be broken up and actually
compiled twice - the outer predicate would be compiled first and the inner
one after that. This fix makes sure that the predicates are handled together
as one test, and not as two separate tests.
PR: bugzilla 1376 (was an id/key problem, now predicates)
Obtained from: n/a
Submitted by: [EMAIL PROTECTED]
Reviewed by: [EMAIL PROTECTED]
Revision Changes Path
1.12 +8 -3
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Predicate.java
Index: Predicate.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Predicate.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Predicate.java 2001/09/17 14:29:54 1.11
+++ Predicate.java 2001/09/19 11:50:31 1.12
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: Predicate.java,v 1.11 2001/09/17 14:29:54 morten Exp $
+ * @(#)$Id: Predicate.java,v 1.12 2001/09/19 11:50:31 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -94,6 +94,12 @@
}
public boolean isNthPositionFilter() {
+ if (_exp instanceof EqualityExpr) {
+ EqualityExpr eq = (EqualityExpr)_exp;
+ if ((eq.getLeft() instanceof PositionCall) &&
+ (eq.getRight() instanceof IntExpr))
+ _nthPositionFilter = true;
+ }
return _nthPositionFilter;
}
@@ -216,6 +222,7 @@
}
_nthPositionFilter = false;
+
return _type = Type.Boolean;
}
@@ -285,7 +292,6 @@
testGen.setMaxLocals();
testGen.setMaxStack();
testGen.removeNOPs();
-
filterGen.addEmptyConstructor(ACC_PUBLIC);
filterGen.addMethod(testGen.getMethod());
@@ -375,7 +381,6 @@
if (right instanceof CastExpr) right = ((CastExpr)right).getExpr();
if (right instanceof Step) _step = (Step)right;
}
- //if ((_step != null) && (_step.isAbbreviatedDot())) _step = null;
return _step;
}
1.6 +31 -19
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/StepPattern.java
Index: StepPattern.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/StepPattern.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- StepPattern.java 2001/09/12 14:30:46 1.5
+++ StepPattern.java 2001/09/19 11:50:31 1.6
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: StepPattern.java,v 1.5 2001/09/12 14:30:46 morten Exp $
+ * @(#)$Id: StepPattern.java,v 1.6 2001/09/19 11:50:31 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -65,6 +65,7 @@
package org.apache.xalan.xsltc.compiler;
import java.util.Vector;
+import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.dom.Axis;
import org.apache.xalan.xsltc.compiler.util.Type;
import de.fub.bytecode.generic.*;
@@ -190,10 +191,12 @@
// Create an instance of Step to do the translation
if (_contextCase == SIMPLE_CONTEXT) {
_step = new Step(_axis, _nodeType, null);
+ _step.setParser(getParser());
_step.typeCheck(stable);
}
else if (_contextCase == GENERAL_CONTEXT) {
_step = new Step(_axis, _nodeType, _predicates);
+ _step.setParser(getParser());
_step.typeCheck(stable);
}
}
@@ -205,19 +208,28 @@
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
- // context node is on the stack
- final int getType = cpg.addInterfaceMethodref(DOM_INTF,
- "getType", "(I)I");
- il.append(methodGen.loadDOM());
- il.append(SWAP);
- il.append(new INVOKEINTERFACE(getType, 2));
- il.append(new PUSH(cpg, _nodeType));
+ if ((_nodeType == DOM.ELEMENT) && (hasPredicates())) {
+ // TODO: insert check to see if current node is element
+ il.append(POP);
+ }
+ else if ((_nodeType == DOM.ATTRIBUTE) && (hasPredicates())) {
+ // TODO: insert check to see if current node is attribute
+ il.append(POP);
+ }
+ else {
+ // context node is on the stack
+ final int getType = cpg.addInterfaceMethodref(DOM_INTF,
+ "getType", "(I)I");
+ il.append(methodGen.loadDOM());
+ il.append(SWAP);
+ il.append(new INVOKEINTERFACE(getType, 2));
+ il.append(new PUSH(cpg, _nodeType));
- // Need to allow for long jumps here - don't know if 100% correct
- //_falseList.add(il.append(new IF_ICMPNE(null)));
- final BranchHandle icmp = il.append(new IF_ICMPEQ(null));
- _falseList.add(il.append(new GOTO_W(null)));
- icmp.setTarget(il.append(NOP));
+ // Need to allow for long jumps here
+ final BranchHandle icmp = il.append(new IF_ICMPEQ(null));
+ _falseList.add(il.append(new GOTO_W(null)));
+ icmp.setTarget(il.append(NOP));
+ }
}
private void translateNoContext(ClassGenerator classGen,
@@ -241,8 +253,8 @@
// Compile the expressions within the predicates
final int n = _predicates.size();
for (int i = 0; i < n; i++) {
- final Predicate pred = (Predicate)_predicates.elementAt(i);
- final Expression exp = pred.getExpr();
+ Predicate pred = (Predicate)_predicates.elementAt(i);
+ Expression exp = pred.getExpr();
exp.translateDesynthesized(classGen, methodGen);
_trueList.append(exp._trueList);
_falseList.append(exp._falseList);
@@ -309,14 +321,14 @@
il.append(new ILOAD(match.getIndex()));
il.append(methodGen.storeCurrentNode());
+
// Translate the expression of the predicate
- final Predicate pred = (Predicate) _predicates.elementAt(0);
- final Expression exp = pred.getExpr();
+ Predicate pred = (Predicate) _predicates.elementAt(0);
+ Expression exp = pred.getExpr();
exp.translateDesynthesized(classGen, methodGen);
// Backpatch true list and restore current iterator/node
- InstructionHandle restore;
- restore = il.append(methodGen.storeIterator());
+ InstructionHandle restore = il.append(methodGen.storeIterator());
il.append(methodGen.storeCurrentNode());
exp.backPatchTrueList(restore);
BranchHandle skipFalse = il.append(new GOTO(null));
1.5 +8 -3
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/TestSeq.java
Index: TestSeq.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/TestSeq.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- TestSeq.java 2001/08/27 09:07:19 1.4
+++ TestSeq.java 2001/09/19 11:50:31 1.5
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: TestSeq.java,v 1.4 2001/08/27 09:07:19 morten Exp $
+ * @(#)$Id: TestSeq.java,v 1.5 2001/09/19 11:50:31 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -202,6 +202,9 @@
return (LocationPathPattern)_patterns.elementAt(n);
}
+
+ private InstructionHandle _start = null;
+
/**
* Copile the code for this test sequence. The code will first test for
* the pattern with the highest priority, then go on to the next ones,
@@ -212,6 +215,8 @@
InstructionHandle continuation) {
final int count = _patterns.size();
+
+ if (_start != null) return(_start);
// EZ DC if there is only one (default) pattern
if (count == 0) getTemplateHandle(_default);
@@ -220,7 +225,7 @@
// test fails. It is updated in each iteration, so that the tests
// are linked together in the if-elseif-elseif-else fashion.
InstructionHandle fail;
-
+
// Initialize 'fail' to either the code for the default template
if (_default != null)
fail = getTemplateHandle(_default);
@@ -254,7 +259,7 @@
// Set current instruction list to be this one.
_instructionList = il;
}
- return fail;
+ return(_start = fail);
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]