author | joehw |
Wed, 09 Mar 2016 16:09:55 -0800 | |
changeset 36486 | b84e564d2358 |
parent 25868 | 686eef1e7a79 |
child 42801 | b6efd9c4f416 |
permissions | -rw-r--r-- |
6 | 1 |
/* |
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
2 |
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. |
6 | 3 |
*/ |
4 |
/* |
|
5 |
* Copyright 2001-2004 The Apache Software Foundation. |
|
6 |
* |
|
7 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
8 |
* you may not use this file except in compliance with the License. |
|
9 |
* You may obtain a copy of the License at |
|
10 |
* |
|
11 |
* http://www.apache.org/licenses/LICENSE-2.0 |
|
12 |
* |
|
13 |
* Unless required by applicable law or agreed to in writing, software |
|
14 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
15 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
16 |
* See the License for the specific language governing permissions and |
|
17 |
* limitations under the License. |
|
18 |
*/ |
|
19 |
||
20 |
package com.sun.org.apache.xalan.internal.xsltc.compiler; |
|
21 |
||
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
22 |
import com.sun.org.apache.bcel.internal.generic.ALOAD; |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
23 |
import com.sun.org.apache.bcel.internal.generic.ASTORE; |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
24 |
import com.sun.org.apache.bcel.internal.generic.CHECKCAST; |
6 | 25 |
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; |
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
26 |
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; |
6 | 27 |
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; |
28 |
import com.sun.org.apache.bcel.internal.generic.InstructionList; |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
29 |
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; |
6 | 30 |
import com.sun.org.apache.bcel.internal.generic.PUSH; |
31 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; |
|
32 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; |
|
33 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; |
|
34 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType; |
|
35 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; |
|
36 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; |
|
37 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; |
|
38 |
import com.sun.org.apache.xml.internal.utils.XML11Char; |
|
39 |
||
40 |
/** |
|
41 |
* @author Jacek Ambroziak |
|
42 |
* @author Santiago Pericas-Geertsen |
|
43 |
* @author Morten Jorgensen |
|
44 |
* @author John Howard <JohnH@schemasoft.com> |
|
45 |
*/ |
|
46 |
final class WithParam extends Instruction { |
|
47 |
||
48 |
/** |
|
49 |
* Parameter's name. |
|
50 |
*/ |
|
51 |
private QName _name; |
|
52 |
||
53 |
/** |
|
54 |
* The escaped qname of the with-param. |
|
55 |
*/ |
|
56 |
protected String _escapedName; |
|
57 |
||
58 |
/** |
|
59 |
* Parameter's default value. |
|
60 |
*/ |
|
61 |
private Expression _select; |
|
62 |
||
63 |
/** |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
64 |
* Reference to JVM variable holding temporary result tree. |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
65 |
*/ |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
66 |
private LocalVariableGen _domAdapter; |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
67 |
|
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
68 |
/** |
6 | 69 |
* %OPT% This is set to true when the WithParam is used in a CallTemplate |
70 |
* for a simple named template. If this is true, the parameters are |
|
71 |
* passed to the named template through method arguments rather than |
|
72 |
* using the expensive Translet.addParameter() call. |
|
73 |
*/ |
|
74 |
private boolean _doParameterOptimization = false; |
|
75 |
||
76 |
/** |
|
77 |
* Displays the contents of this element |
|
78 |
*/ |
|
79 |
public void display(int indent) { |
|
80 |
indent(indent); |
|
81 |
Util.println("with-param " + _name); |
|
82 |
if (_select != null) { |
|
83 |
indent(indent + IndentIncrement); |
|
84 |
Util.println("select " + _select.toString()); |
|
85 |
} |
|
86 |
displayContents(indent + IndentIncrement); |
|
87 |
} |
|
88 |
||
89 |
/** |
|
90 |
* Returns the escaped qname of the parameter |
|
91 |
*/ |
|
92 |
public String getEscapedName() { |
|
93 |
return _escapedName; |
|
94 |
} |
|
95 |
||
96 |
/** |
|
97 |
* Return the name of this WithParam. |
|
98 |
*/ |
|
99 |
public QName getName() { |
|
100 |
return _name; |
|
101 |
} |
|
102 |
||
103 |
/** |
|
104 |
* Set the name of the variable or paremeter. Escape all special chars. |
|
105 |
*/ |
|
106 |
public void setName(QName name) { |
|
107 |
_name = name; |
|
108 |
_escapedName = Util.escape(name.getStringRep()); |
|
109 |
} |
|
110 |
||
111 |
/** |
|
112 |
* Set the do parameter optimization flag |
|
113 |
*/ |
|
114 |
public void setDoParameterOptimization(boolean flag) { |
|
115 |
_doParameterOptimization = flag; |
|
116 |
} |
|
117 |
||
118 |
/** |
|
119 |
* The contents of a <xsl:with-param> elements are either in the element's |
|
120 |
* 'select' attribute (this has precedence) or in the element body. |
|
121 |
*/ |
|
122 |
public void parseContents(Parser parser) { |
|
123 |
final String name = getAttribute("name"); |
|
124 |
if (name.length() > 0) { |
|
125 |
if (!XML11Char.isXML11ValidQName(name)) { |
|
126 |
ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, |
|
127 |
this); |
|
128 |
parser.reportError(Constants.ERROR, err); |
|
129 |
} |
|
130 |
setName(parser.getQNameIgnoreDefaultNs(name)); |
|
131 |
} |
|
132 |
else { |
|
133 |
reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name"); |
|
134 |
} |
|
135 |
||
136 |
final String select = getAttribute("select"); |
|
137 |
if (select.length() > 0) { |
|
138 |
_select = parser.parseExpression(this, "select", null); |
|
139 |
} |
|
140 |
||
141 |
parseChildren(parser); |
|
142 |
} |
|
143 |
||
144 |
/** |
|
145 |
* Type-check either the select attribute or the element body, depending |
|
146 |
* on which is in use. |
|
147 |
*/ |
|
148 |
public Type typeCheck(SymbolTable stable) throws TypeCheckError { |
|
149 |
if (_select != null) { |
|
150 |
final Type tselect = _select.typeCheck(stable); |
|
151 |
if (tselect instanceof ReferenceType == false) { |
|
152 |
_select = new CastExpr(_select, Type.Reference); |
|
153 |
} |
|
154 |
} |
|
155 |
else { |
|
156 |
typeCheckContents(stable); |
|
157 |
} |
|
158 |
return Type.Void; |
|
159 |
} |
|
160 |
||
161 |
/** |
|
162 |
* Compile the value of the parameter, which is either in an expression in |
|
163 |
* a 'select' attribute, or in the with-param element's body |
|
164 |
*/ |
|
165 |
public void translateValue(ClassGenerator classGen, |
|
166 |
MethodGenerator methodGen) { |
|
167 |
// Compile expression is 'select' attribute if present |
|
168 |
if (_select != null) { |
|
169 |
_select.translate(classGen, methodGen); |
|
170 |
_select.startIterator(classGen, methodGen); |
|
171 |
} |
|
172 |
// If not, compile result tree from parameter body if present. |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
173 |
// Store result tree into local variable for releasing it later |
6 | 174 |
else if (hasContents()) { |
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
175 |
final InstructionList il = methodGen.getInstructionList(); |
6 | 176 |
compileResultTree(classGen, methodGen); |
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
177 |
_domAdapter = methodGen.addLocalVariable2("@" + _escapedName, Type.ResultTree.toJCType(), il.getEnd()); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
178 |
il.append(DUP); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
179 |
il.append(new ASTORE(_domAdapter.getIndex())); |
6 | 180 |
} |
181 |
// If neither are present then store empty string in parameter slot |
|
182 |
else { |
|
183 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
184 |
final InstructionList il = methodGen.getInstructionList(); |
|
185 |
il.append(new PUSH(cpg, Constants.EMPTYSTRING)); |
|
186 |
} |
|
187 |
} |
|
188 |
||
189 |
/** |
|
190 |
* This code generates a sequence of bytecodes that call the |
|
191 |
* addParameter() method in AbstractTranslet. The method call will add |
|
192 |
* (or update) the parameter frame with the new parameter value. |
|
193 |
*/ |
|
194 |
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { |
|
195 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
196 |
final InstructionList il = methodGen.getInstructionList(); |
|
197 |
||
198 |
// Translate the value and put it on the stack |
|
199 |
if (_doParameterOptimization) { |
|
200 |
translateValue(classGen, methodGen); |
|
201 |
return; |
|
202 |
} |
|
203 |
||
204 |
// Make name acceptable for use as field name in class |
|
205 |
String name = Util.escape(getEscapedName()); |
|
206 |
||
207 |
// Load reference to the translet (method is in AbstractTranslet) |
|
208 |
il.append(classGen.loadTranslet()); |
|
209 |
||
210 |
// Load the name of the parameter |
|
211 |
il.append(new PUSH(cpg, name)); // TODO: namespace ? |
|
212 |
// Generete the value of the parameter (use value in 'select' by def.) |
|
213 |
translateValue(classGen, methodGen); |
|
214 |
// Mark this parameter value is not being the default value |
|
215 |
il.append(new PUSH(cpg, false)); |
|
216 |
// Pass the parameter to the template |
|
217 |
il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, |
|
218 |
ADD_PARAMETER, |
|
219 |
ADD_PARAMETER_SIG))); |
|
220 |
il.append(POP); // cleanup stack |
|
221 |
} |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
222 |
|
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
223 |
/** |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
224 |
* Release the compiled result tree. |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
225 |
*/ |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
226 |
public void releaseResultTree(ClassGenerator classGen, MethodGenerator methodGen) { |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
227 |
if (_domAdapter != null) { |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
228 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
229 |
final InstructionList il = methodGen.getInstructionList(); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
230 |
if (classGen.getStylesheet().callsNodeset() && classGen.getDOMClass().equals(MULTI_DOM_CLASS)) { |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
231 |
final int removeDA = cpg.addMethodref(MULTI_DOM_CLASS, "removeDOMAdapter", "(" + DOM_ADAPTER_SIG + ")V"); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
232 |
il.append(methodGen.loadDOM()); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
233 |
il.append(new CHECKCAST(cpg.addClass(MULTI_DOM_CLASS))); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
234 |
il.append(new ALOAD(_domAdapter.getIndex())); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
235 |
il.append(new CHECKCAST(cpg.addClass(DOM_ADAPTER_CLASS))); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
236 |
il.append(new INVOKEVIRTUAL(removeDA)); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
237 |
} |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
238 |
final int release = cpg.addInterfaceMethodref(DOM_IMPL_CLASS, "release", "()V"); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
239 |
il.append(new ALOAD(_domAdapter.getIndex())); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
240 |
il.append(new INVOKEINTERFACE(release, 1)); |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
241 |
_domAdapter = null; |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
242 |
} |
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
243 |
} |
6 | 244 |
} |