You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Denis Benoit <De...@fbn.ca> on 2002/05/21 15:36:42 UTC
[PATCH] Stack based "finallies" in Generator.java
Hi Kin-Man,
Here is the patch as promised.
. It follows what we agreed about the "two arrays" simulating stacks;
. It prevents generating any extra code if there is no Tags in the JSP,
now this case is easy to determine thanks to pageInfo.getMaxTagNesting :)
This is a first draft, I'll continue testing it, if you see something you
don't like just give tell me so, and I'll correct it.
Thanks!
Index: jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v
retrieving revision 1.14
diff -c -r1.14 Generator.java
*** jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java 15 May 2002 20:42:03 -0000 1.14
--- jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java 21 May 2002 01:08:45 -0000
***************
*** 94,102 ****
private JspCompilationContext ctxt;
private boolean breakAtLF;
private PageInfo pageInfo;
! private FinallyApplyer finallies;
! private int tryBit;
! private Stack tryStack;
/**
* @param s the input string
--- 94,101 ----
private JspCompilationContext ctxt;
private boolean breakAtLF;
private PageInfo pageInfo;
! private int maxTagNesting;
!
/**
* @param s the input string
***************
*** 226,231 ****
--- 225,256 ----
out.println();
out.println();
}
+
+ maxTagNesting = pageInfo.getMaxTagNesting();
+ if (maxTagNesting >= 0) {
+ out.printil("private static final int RELEASE_ACTION = 0;");
+ out.printil("private static final int POP_AND_RELEASE_ACTION = 1;");
+ out.println();
+ out.println();
+ }
+
+
+ // Class fields declarations
+
+ // pseudo "Finally" state stack objects
+
+ if (maxTagNesting >= 0) {
+ String depth = Integer.toString(maxTagNesting + 1);
+ out.printil("int finallyStackIndex = -1;");
+ out.printin("int[] finallyStackActions = new int[");
+ out.print(depth);
+ out.println("];");
+ out.printin("javax.servlet.jsp.tagext.Tag[] finallyStackTags = new javax.servlet.jsp.tagext.Tag[");
+ out.print(depth);
+ out.println("];");
+ out.println();
+ out.println();
+ }
// Constructor (empty so far) here
***************
*** 238,255 ****
out.println();
out.println();
- out.printil("private void addTagToVector(java.util.Vector tags, int index, Object tag) {");
- out.pushIndent();
- out.printil("if (index + 1 > tags.size())");
- out.pushIndent();
- out.printil("tags.setSize(index + 1);");
- out.popIndent();
- out.printil("tags.setElementAt(tag, index);");
- out.popIndent();
- out.printil("}");
- out.println();
- out.println();
-
// Now the service method
out.printin("public void ");
out.print (serviceMethodName);
--- 263,268 ----
***************
*** 977,998 ****
declareTagVariableInfos(tagVarInfos, n.getTagData(),
VariableInfo.AT_BEGIN);
! if (implementsTryCatchFinally) {
! out.printil("try {");
! out.pushIndent();
! } else {
! out.printil("// try {");
! out.printin("bitmask.set(");
! Integer tryBitVal = new Integer(tryBit++);
! tryStack.push(tryBitVal);
! out.print(tryBitVal.toString());
! out.println(");");
! out.printin("addTagToVector(tags, ");
! out.print(tryBitVal.toString());
! out.print(", ");
! out.print(tagHandlerVar);
! out.println(");");
! }
out.printin("int ");
out.print(tagEvalVar);
out.print(" = ");
--- 990,1006 ----
declareTagVariableInfos(tagVarInfos, n.getTagData(),
VariableInfo.AT_BEGIN);
! if (implementsTryCatchFinally) {
! out.printil("try {");
! out.pushIndent();
! } else {
! out.printil("// try {");
! out.printil("finallyStackActions[++finallyStackIndex] = RELEASE_ACTION;");
! out.printin("finallyStackTags[finallyStackIndex] = ");
! out.print(tagHandlerVar);
! out.println(";");
! }
!
out.printin("int ");
out.print(tagEvalVar);
out.print(" = ");
***************
*** 1008,1050 ****
VariableInfo.AT_BEGIN, false);
if (n.getBody() != null) {
- out.printin("if (");
- out.print(tagEvalVar);
- out.println(" != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {");
- out.pushIndent();
-
- if (isBodyTag) {
- out.printil("// try {");
- out.printin("bitmask.set(");
- Integer tryBitVal = new Integer(tryBit++);
- tryStack.push(tryBitVal);
- out.print(tryBitVal.toString());
- out.println(");");
- out.printin("addTagToVector(tags, ");
- out.print(tryBitVal.toString());
- out.print(", new Integer(");
- out.print(tagEvalVar);
- out.println("));");
out.printin("if (");
out.print(tagEvalVar);
! out.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) {");
! // Assume EVAL_BODY_BUFFERED
out.pushIndent();
! out.printil("out = pageContext.pushBody();");
! out.printin(tagHandlerVar);
! out.println(".setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);");
! out.printin(tagHandlerVar);
! out.println(".doInitBody();");
! out.popIndent();
! out.printil("}");
! }
! if (IterationTag.class.isAssignableFrom(tagHandlerClass)) {
! out.printil("do {");
! out.pushIndent();
! }
}
// Declare and update NESTED variables
--- 1016,1051 ----
VariableInfo.AT_BEGIN, false);
if (n.getBody() != null) {
out.printin("if (");
out.print(tagEvalVar);
! out.println(" != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {");
out.pushIndent();
+
+ if (isBodyTag) {
+ out.printil("// try {");
+ out.printin("if (");
+ out.print(tagEvalVar);
+ out.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) {");
+ // Assume EVAL_BODY_BUFFERED
+ out.pushIndent();
! out.printil("out = pageContext.pushBody();");
! if (!implementsTryCatchFinally) {
! out.printil("finallyStackActions[finallyStackIndex] = POP_AND_RELEASE_ACTION;");
! }
! out.printin(tagHandlerVar);
! out.println(".setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);");
! out.printin(tagHandlerVar);
! out.println(".doInitBody();");
! out.popIndent();
! out.printil("}");
! }
! if (IterationTag.class.isAssignableFrom(tagHandlerClass)) {
! out.printil("do {");
! out.pushIndent();
! }
}
// Declare and update NESTED variables
***************
*** 1085,1118 ****
VariableInfo.AT_BEGIN, false);
if (n.getBody() != null) {
! if (implementsBodyTag) {
! Integer tryBitVal = (Integer)tryStack.pop();
! out.printil("// } finally {");
! out.printin("bitmask.clear(");
! out.print(tryBitVal.toString());
! out.println(");");
!
! out.printin("if (");
! out.print(tagEvalVar);
! out.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)");
! out.pushIndent();
! out.printil("out = pageContext.popBody();");
! out.popIndent();
!
! finallies.beginPartMethod(tryBitVal.intValue());
! finallies.print(" if (");
! finallies.print("((Integer)tags.elementAt(");
! finallies.print(tryBitVal.toString());
! finallies.print(")).intValue()");
! finallies.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)");
! finallies.println(" out = pageContext.popBody();");
!
! finallies.endPartMethod();
! out.printil("// }");
! }
! out.popIndent(); // EVAL_BODY
! out.printil("}");
}
out.printin("if (");
--- 1086,1108 ----
VariableInfo.AT_BEGIN, false);
if (n.getBody() != null) {
! if (implementsBodyTag) {
! out.printil("// } finally {");
! if (!implementsTryCatchFinally) {
! out.printil("finallyStackActions[finallyStackIndex] = RELEASE_ACTION;");
! }
! out.printin("if (");
! out.print(tagEvalVar);
! out.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)");
! out.pushIndent();
! out.printil("out = pageContext.popBody();");
! out.printil("");
! out.popIndent();
! out.printil("// }");
! }
! out.popIndent(); // EVAL_BODY
! out.printil("}");
}
out.printin("if (");
***************
*** 1124,1158 ****
// TryCatchFinally
if (implementsTryCatchFinally) {
! out.popIndent(); // try
! out.printil("} catch (Throwable _jspx_exception) {");
! out.pushIndent();
! out.printin(tagHandlerVar);
! out.println(".doCatch(_jspx_exception);");
! out.popIndent();
! out.printil("} finally {");
! out.pushIndent();
! out.printin(tagHandlerVar);
! out.println(".doFinally();");
! out.printin(tagHandlerVar);
! out.println(".release();");
! out.popIndent();
! out.printil("}");
! } else {
! Integer tryBitVal = (Integer)tryStack.pop();
! out.printil("// } finally {");
! out.printin("bitmask.clear(");
! out.print(tryBitVal.toString());
! out.println(");");
! out.printin(tagHandlerVar);
! out.println(".release();");
! out.printil("// }");
! finallies.beginPartMethod(tryBitVal.intValue());
! finallies.printin("((javax.servlet.jsp.tagext.Tag)tags.elementAt(");
! finallies.print(tryBitVal.toString());
! finallies.print("))");
! finallies.println(".release();");
! finallies.endPartMethod();
}
// Declare and update AT_END variables
--- 1114,1139 ----
// TryCatchFinally
if (implementsTryCatchFinally) {
! out.popIndent(); // try
! out.printil("} catch (Throwable _jspx_exception) {");
! out.pushIndent();
! out.printin(tagHandlerVar);
! out.println(".doCatch(_jspx_exception);");
! out.popIndent();
! out.printil("} finally {");
! out.pushIndent();
! out.printin(tagHandlerVar);
! out.println(".doFinally();");
! out.printin(tagHandlerVar);
! out.println(".release();");
! out.popIndent();
! out.printil("}");
! } else {
! out.printil("// } finally {");
! out.printil("finallyStackIndex--;");
! out.printin(tagHandlerVar);
! out.println(".release();");
! out.printil("// }");
}
// Declare and update AT_END variables
***************
*** 1419,1424 ****
--- 1400,1416 ----
out.popIndent();
out.printil("} catch (Throwable t) {");
out.pushIndent();
+ if (maxTagNesting >= 0) {
+ out.printil("while (finallyStackIndex >= 0) {");
+ out.pushIndent();
+ out.printil("if (POP_AND_RELEASE_ACTION == finallyStackActions[finallyStackIndex])");
+ out.pushIndent();
+ out.printil("out = pageContext.popBody();");
+ out.popIndent();
+ out.printil("finallyStackTags[finallyStackIndex--].release();");
+ out.popIndent();
+ out.printil("}");
+ }
out.printil("if (out != null && out.getBufferSize() != 0)");
out.pushIndent();
out.printil("out.clearBuffer();");
***************
*** 1427,1446 ****
out.popIndent();
out.printil("} finally {");
out.pushIndent();
-
- // Do stuff here for finally actions...
-
- out.printil("try {");
- out.pushIndent();
- out.printil("finallies(bitmask, out, tags, pageContext);");
- out.popIndent();
- out.printil("} catch (javax.servlet.jsp.JspException e) {");
- out.pushIndent();
- out.printil("if (pageContext != null) pageContext.handlePageException(e);");
- out.popIndent();
- out.printil("}");
out.printil("if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);");
-
out.popIndent();
out.printil("}");
--- 1419,1425 ----
***************
*** 1448,1457 ****
out.popIndent();
out.printil("}");
- // Call the final method
- finallies.done();
- out.printil(finallies.toString());
-
// Close the class definition
out.popIndent();
out.printil("}");
--- 1427,1432 ----
***************
*** 1467,1474 ****
pageInfo = compiler.getPageInfo();
beanInfo = pageInfo.getBeanRepository();
breakAtLF = ctxt.getOptions().getMappedFile();
- finallies = new FinallyApplyer();
- tryStack = new Stack();
}
/**
--- 1442,1447 ----
***************
*** 1562,1616 ****
public Class getTagHandlerClass() {
return tagHandlerClass;
}
- }
-
- private static class FinallyApplyer {
- private PrintStream finalOutput;
- private ByteArrayOutputStream rawOutput;
-
- FinallyApplyer() {
- rawOutput = new ByteArrayOutputStream();
- finalOutput = new PrintStream(rawOutput, true);
-
- finalOutput.println();
- finalOutput.println(" private void finallies(java.util.BitSet bitmask, JspWriter out, java.util.Vector tags, PageContext pageContext)");
- finalOutput.println(" throws javax.servlet.jsp.JspException {");
- }
-
- public void done() {
- finalOutput.println(" }");
- }
-
- public void beginPartMethod(int bit) {
- finalOutput.print(" if (bitmask.get(");
- finalOutput.print(bit);
- finalOutput.println(")) {");
- }
-
- public void endPartMethod() {
- finalOutput.println(" }");
- finalOutput.println();
- }
-
- public void println(String aLine) {
- if (null != aLine) {
- finalOutput.print(aLine);
- }
- finalOutput.println();
- }
-
- public void printin(String partLine) {
- finalOutput.print(" ");
- finalOutput.print(partLine);
- }
-
- public void print(String partLine) {
- finalOutput.print(partLine);
- }
-
- public String toString() {
- return rawOutput.toString();
- }
}
}
--- 1535,1540 ----
--
Denis Benoit
Denis.Benoit@fbn.ca
Tél: (514)879-5168
**********************************************************************
Financière Banque Nationale et NBCN n'assument
aucune responsabilité quant à la confidentialité et l'intégrité du
présent courriel en raison des risques d'interception inhérents à l'Internet.
Pour cette raison, toute opinion exprimée au terme des présentes
ne reflète pas nécessairement celle de Financière Banque Nationale
et de NBCN.
**********************************************************************
Due to the security risks involved in sending information over the
Internet, National Bank Financial and NBCN cannot
be held responsible for ensuring the confidentiality and integrity
of the present e-mail. For this reason, the opinions expressed herein
do not necessarily reflect those of National Bank Financial
and NBCN.
**********************************************************************
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>