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 [EMAIL PROTECTED] 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: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>