author | joehw |
Wed, 18 Oct 2017 13:25:49 -0700 | |
changeset 47359 | e1a6c0168741 |
parent 47216 | 71c04702a3d5 |
child 47712 | bde0215f1f70 |
permissions | -rw-r--r-- |
6 | 1 |
/* |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
3 |
* @LastModified: Oct 2017 |
6 | 4 |
*/ |
5 |
/* |
|
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
36486
diff
changeset
|
6 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
36486
diff
changeset
|
7 |
* contributor license agreements. See the NOTICE file distributed with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
36486
diff
changeset
|
8 |
* this work for additional information regarding copyright ownership. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
36486
diff
changeset
|
9 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
36486
diff
changeset
|
10 |
* (the "License"); you may not use this file except in compliance with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
36486
diff
changeset
|
11 |
* the License. You may obtain a copy of the License at |
6 | 12 |
* |
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
36486
diff
changeset
|
13 |
* http://www.apache.org/licenses/LICENSE-2.0 |
6 | 14 |
* |
15 |
* Unless required by applicable law or agreed to in writing, software |
|
16 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
17 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
18 |
* See the License for the specific language governing permissions and |
|
19 |
* limitations under the License. |
|
20 |
*/ |
|
21 |
||
22 |
package com.sun.org.apache.xalan.internal.xsltc.compiler; |
|
23 |
||
24 |
import com.sun.org.apache.bcel.internal.classfile.Field; |
|
25 |
import com.sun.org.apache.bcel.internal.generic.ALOAD; |
|
26 |
import com.sun.org.apache.bcel.internal.generic.ANEWARRAY; |
|
27 |
import com.sun.org.apache.bcel.internal.generic.ASTORE; |
|
28 |
import com.sun.org.apache.bcel.internal.generic.CHECKCAST; |
|
29 |
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; |
|
30 |
import com.sun.org.apache.bcel.internal.generic.GETFIELD; |
|
31 |
import com.sun.org.apache.bcel.internal.generic.ILOAD; |
|
32 |
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; |
|
33 |
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; |
|
34 |
import com.sun.org.apache.bcel.internal.generic.InstructionHandle; |
|
35 |
import com.sun.org.apache.bcel.internal.generic.InstructionList; |
|
36 |
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; |
|
37 |
import com.sun.org.apache.bcel.internal.generic.NEW; |
|
38 |
import com.sun.org.apache.bcel.internal.generic.NOP; |
|
39 |
import com.sun.org.apache.bcel.internal.generic.PUSH; |
|
40 |
import com.sun.org.apache.bcel.internal.generic.PUTFIELD; |
|
41 |
import com.sun.org.apache.bcel.internal.generic.TABLESWITCH; |
|
42 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; |
|
43 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.CompareGenerator; |
|
44 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; |
|
45 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.IntType; |
|
46 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; |
|
47 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSortRecordFactGenerator; |
|
48 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSortRecordGenerator; |
|
49 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.StringType; |
|
50 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; |
|
51 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; |
|
52 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; |
|
53 |
import com.sun.org.apache.xml.internal.dtm.Axis; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
54 |
import java.util.ArrayList; |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
55 |
import java.util.List; |
6 | 56 |
|
57 |
||
58 |
/** |
|
59 |
* @author Jacek Ambroziak |
|
60 |
* @author Santiago Pericas-Geertsen |
|
61 |
* @author Morten Jorgensen |
|
62 |
*/ |
|
63 |
final class Sort extends Instruction implements Closure { |
|
64 |
||
65 |
private Expression _select; |
|
66 |
private AttributeValue _order; |
|
67 |
private AttributeValue _caseOrder; |
|
68 |
private AttributeValue _dataType; |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
69 |
private String _lang; // bug! see 26869 |
6 | 70 |
|
71 |
private String _className = null; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
72 |
private List<VariableRefBase> _closureVars = null; |
6 | 73 |
private boolean _needsSortRecordFactory = false; |
74 |
||
75 |
// -- Begin Closure interface -------------------- |
|
76 |
||
77 |
/** |
|
78 |
* Returns true if this closure is compiled in an inner class (i.e. |
|
79 |
* if this is a real closure). |
|
80 |
*/ |
|
81 |
public boolean inInnerClass() { |
|
82 |
return (_className != null); |
|
83 |
} |
|
84 |
||
85 |
/** |
|
86 |
* Returns a reference to its parent closure or null if outermost. |
|
87 |
*/ |
|
88 |
public Closure getParentClosure() { |
|
89 |
return null; |
|
90 |
} |
|
91 |
||
92 |
/** |
|
93 |
* Returns the name of the auxiliary class or null if this predicate |
|
94 |
* is compiled inside the Translet. |
|
95 |
*/ |
|
96 |
public String getInnerClassName() { |
|
97 |
return _className; |
|
98 |
} |
|
99 |
||
100 |
/** |
|
101 |
* Add new variable to the closure. |
|
102 |
*/ |
|
103 |
public void addVariable(VariableRefBase variableRef) { |
|
104 |
if (_closureVars == null) { |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
105 |
_closureVars = new ArrayList<>(); |
6 | 106 |
} |
107 |
||
108 |
// Only one reference per variable |
|
109 |
if (!_closureVars.contains(variableRef)) { |
|
110 |
_closureVars.add(variableRef); |
|
111 |
_needsSortRecordFactory = true; |
|
112 |
} |
|
113 |
} |
|
114 |
||
115 |
// -- End Closure interface ---------------------- |
|
116 |
||
117 |
private void setInnerClassName(String className) { |
|
118 |
_className = className; |
|
119 |
} |
|
120 |
||
121 |
/** |
|
122 |
* Parse the attributes of the xsl:sort element |
|
123 |
*/ |
|
124 |
public void parseContents(Parser parser) { |
|
125 |
||
126 |
final SyntaxTreeNode parent = getParent(); |
|
127 |
if (!(parent instanceof ApplyTemplates) && |
|
128 |
!(parent instanceof ForEach)) { |
|
129 |
reportError(this, parser, ErrorMsg.STRAY_SORT_ERR, null); |
|
130 |
return; |
|
131 |
} |
|
132 |
||
133 |
// Parse the select expression (node string value if no expression) |
|
134 |
_select = parser.parseExpression(this, "select", "string(.)"); |
|
135 |
||
136 |
// Get the sort order; default is 'ascending' |
|
137 |
String val = getAttribute("order"); |
|
138 |
if (val.length() == 0) val = "ascending"; |
|
139 |
_order = AttributeValue.create(this, val, parser); |
|
140 |
||
141 |
// Get the sort data type; default is text |
|
142 |
val = getAttribute("data-type"); |
|
143 |
if (val.length() == 0) { |
|
144 |
try { |
|
145 |
final Type type = _select.typeCheck(parser.getSymbolTable()); |
|
146 |
if (type instanceof IntType) |
|
147 |
val = "number"; |
|
148 |
else |
|
149 |
val = "text"; |
|
150 |
} |
|
151 |
catch (TypeCheckError e) { |
|
152 |
val = "text"; |
|
153 |
} |
|
154 |
} |
|
155 |
_dataType = AttributeValue.create(this, val, parser); |
|
156 |
||
157 |
_lang = getAttribute("lang"); // bug! see 26869 |
|
158 |
// val = getAttribute("lang"); |
|
159 |
// _lang = AttributeValue.create(this, val, parser); |
|
160 |
// Get the case order; default is language dependant |
|
161 |
val = getAttribute("case-order"); |
|
162 |
_caseOrder = AttributeValue.create(this, val, parser); |
|
163 |
||
164 |
} |
|
165 |
||
166 |
/** |
|
167 |
* Run type checks on the attributes; expression must return a string |
|
168 |
* which we will use as a sort key |
|
169 |
*/ |
|
170 |
public Type typeCheck(SymbolTable stable) throws TypeCheckError { |
|
171 |
final Type tselect = _select.typeCheck(stable); |
|
172 |
||
173 |
// If the sort data-type is not set we use the natural data-type |
|
174 |
// of the data we will sort |
|
175 |
if (!(tselect instanceof StringType)) { |
|
176 |
_select = new CastExpr(_select, Type.String); |
|
177 |
} |
|
178 |
||
179 |
_order.typeCheck(stable); |
|
180 |
_caseOrder.typeCheck(stable); |
|
181 |
_dataType.typeCheck(stable); |
|
182 |
return Type.Void; |
|
183 |
} |
|
184 |
||
185 |
/** |
|
186 |
* These two methods are needed in the static methods that compile the |
|
187 |
* overloaded NodeSortRecord.compareType() and NodeSortRecord.sortOrder() |
|
188 |
*/ |
|
189 |
public void translateSortType(ClassGenerator classGen, |
|
190 |
MethodGenerator methodGen) { |
|
191 |
_dataType.translate(classGen, methodGen); |
|
192 |
} |
|
193 |
||
194 |
public void translateSortOrder(ClassGenerator classGen, |
|
195 |
MethodGenerator methodGen) { |
|
196 |
_order.translate(classGen, methodGen); |
|
197 |
} |
|
198 |
||
199 |
public void translateCaseOrder(ClassGenerator classGen, |
|
200 |
MethodGenerator methodGen) { |
|
201 |
_caseOrder.translate(classGen, methodGen); |
|
202 |
} |
|
203 |
||
204 |
public void translateLang(ClassGenerator classGen, |
|
205 |
MethodGenerator methodGen) { |
|
206 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
207 |
final InstructionList il = methodGen.getInstructionList(); |
|
208 |
il.append(new PUSH(cpg, _lang)); // bug! see 26869 |
|
209 |
} |
|
210 |
||
211 |
/** |
|
212 |
* This method compiles code for the select expression for this |
|
213 |
* xsl:sort element. The method is called from the static code-generating |
|
214 |
* methods in this class. |
|
215 |
*/ |
|
216 |
public void translateSelect(ClassGenerator classGen, |
|
217 |
MethodGenerator methodGen) { |
|
218 |
_select.translate(classGen,methodGen); |
|
219 |
} |
|
220 |
||
221 |
/** |
|
222 |
* This method should not produce any code |
|
223 |
*/ |
|
224 |
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { |
|
225 |
// empty |
|
226 |
} |
|
227 |
||
228 |
/** |
|
229 |
* Compiles code that instantiates a SortingIterator object. |
|
230 |
* This object's constructor needs referencdes to the current iterator |
|
231 |
* and a node sort record producing objects as its parameters. |
|
232 |
*/ |
|
233 |
public static void translateSortIterator(ClassGenerator classGen, |
|
234 |
MethodGenerator methodGen, |
|
235 |
Expression nodeSet, |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
236 |
List<Sort> sortObjects) |
6 | 237 |
{ |
238 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
239 |
final InstructionList il = methodGen.getInstructionList(); |
|
240 |
||
241 |
// SortingIterator.SortingIterator(NodeIterator,NodeSortRecordFactory); |
|
242 |
final int init = cpg.addMethodref(SORT_ITERATOR, "<init>", |
|
243 |
"(" |
|
244 |
+ NODE_ITERATOR_SIG |
|
245 |
+ NODE_SORT_FACTORY_SIG |
|
246 |
+ ")V"); |
|
247 |
||
248 |
// Backwards branches are prohibited if an uninitialized object is |
|
249 |
// on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. |
|
250 |
// We don't know whether this code might contain backwards branches |
|
251 |
// so we mustn't create the new object until after we've created |
|
252 |
// the suspect arguments to its constructor. Instead we calculate |
|
253 |
// the values of the arguments to the constructor first, store them |
|
254 |
// in temporary variables, create the object and reload the |
|
255 |
// arguments from the temporaries to avoid the problem. |
|
256 |
||
257 |
LocalVariableGen nodesTemp = |
|
258 |
methodGen.addLocalVariable("sort_tmp1", |
|
259 |
Util.getJCRefType(NODE_ITERATOR_SIG), |
|
12458 | 260 |
null, null); |
6 | 261 |
|
262 |
LocalVariableGen sortRecordFactoryTemp = |
|
263 |
methodGen.addLocalVariable("sort_tmp2", |
|
264 |
Util.getJCRefType(NODE_SORT_FACTORY_SIG), |
|
12458 | 265 |
null, null); |
6 | 266 |
|
267 |
// Get the current node iterator |
|
268 |
if (nodeSet == null) { // apply-templates default |
|
269 |
final int children = cpg.addInterfaceMethodref(DOM_INTF, |
|
270 |
"getAxisIterator", |
|
271 |
"(I)"+ |
|
272 |
NODE_ITERATOR_SIG); |
|
273 |
il.append(methodGen.loadDOM()); |
|
274 |
il.append(new PUSH(cpg, Axis.CHILD)); |
|
275 |
il.append(new INVOKEINTERFACE(children, 2)); |
|
276 |
} |
|
277 |
else { |
|
278 |
nodeSet.translate(classGen, methodGen); |
|
279 |
} |
|
280 |
||
12458 | 281 |
nodesTemp.setStart(il.append(new ASTORE(nodesTemp.getIndex()))); |
6 | 282 |
|
283 |
// Compile the code for the NodeSortRecord producing class and pass |
|
284 |
// that as the last argument to the SortingIterator constructor. |
|
285 |
compileSortRecordFactory(sortObjects, classGen, methodGen); |
|
12458 | 286 |
sortRecordFactoryTemp.setStart( |
287 |
il.append(new ASTORE(sortRecordFactoryTemp.getIndex()))); |
|
6 | 288 |
|
289 |
il.append(new NEW(cpg.addClass(SORT_ITERATOR))); |
|
290 |
il.append(DUP); |
|
12458 | 291 |
nodesTemp.setEnd(il.append(new ALOAD(nodesTemp.getIndex()))); |
292 |
sortRecordFactoryTemp.setEnd( |
|
293 |
il.append(new ALOAD(sortRecordFactoryTemp.getIndex()))); |
|
6 | 294 |
il.append(new INVOKESPECIAL(init)); |
295 |
} |
|
296 |
||
297 |
||
298 |
/** |
|
299 |
* Compiles code that instantiates a NodeSortRecordFactory object which |
|
300 |
* will produce NodeSortRecord objects of a specific type. |
|
301 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
302 |
public static void compileSortRecordFactory(List<Sort> sortObjects, |
6 | 303 |
ClassGenerator classGen, MethodGenerator methodGen) |
304 |
{ |
|
305 |
String sortRecordClass = |
|
306 |
compileSortRecord(sortObjects, classGen, methodGen); |
|
307 |
||
308 |
boolean needsSortRecordFactory = false; |
|
309 |
final int nsorts = sortObjects.size(); |
|
310 |
for (int i = 0; i < nsorts; i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
311 |
final Sort sort = sortObjects.get(i); |
6 | 312 |
needsSortRecordFactory |= sort._needsSortRecordFactory; |
313 |
} |
|
314 |
||
315 |
String sortRecordFactoryClass = NODE_SORT_FACTORY; |
|
316 |
if (needsSortRecordFactory) { |
|
317 |
sortRecordFactoryClass = |
|
318 |
compileSortRecordFactory(sortObjects, classGen, methodGen, |
|
319 |
sortRecordClass); |
|
320 |
} |
|
321 |
||
322 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
323 |
final InstructionList il = methodGen.getInstructionList(); |
|
324 |
||
325 |
// Backwards branches are prohibited if an uninitialized object is |
|
326 |
// on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. |
|
327 |
// We don't know whether this code might contain backwards branches |
|
328 |
// so we mustn't create the new object until after we've created |
|
329 |
// the suspect arguments to its constructor. Instead we calculate |
|
330 |
// the values of the arguments to the constructor first, store them |
|
331 |
// in temporary variables, create the object and reload the |
|
332 |
// arguments from the temporaries to avoid the problem. |
|
333 |
||
334 |
// Compile code that initializes the static _sortOrder |
|
335 |
LocalVariableGen sortOrderTemp |
|
336 |
= methodGen.addLocalVariable("sort_order_tmp", |
|
337 |
Util.getJCRefType("[" + STRING_SIG), |
|
12458 | 338 |
null, null); |
6 | 339 |
il.append(new PUSH(cpg, nsorts)); |
340 |
il.append(new ANEWARRAY(cpg.addClass(STRING))); |
|
341 |
for (int level = 0; level < nsorts; level++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
342 |
final Sort sort = sortObjects.get(level); |
6 | 343 |
il.append(DUP); |
344 |
il.append(new PUSH(cpg, level)); |
|
345 |
sort.translateSortOrder(classGen, methodGen); |
|
346 |
il.append(AASTORE); |
|
347 |
} |
|
12458 | 348 |
sortOrderTemp.setStart(il.append(new ASTORE(sortOrderTemp.getIndex()))); |
6 | 349 |
|
350 |
LocalVariableGen sortTypeTemp |
|
351 |
= methodGen.addLocalVariable("sort_type_tmp", |
|
352 |
Util.getJCRefType("[" + STRING_SIG), |
|
12458 | 353 |
null, null); |
6 | 354 |
il.append(new PUSH(cpg, nsorts)); |
355 |
il.append(new ANEWARRAY(cpg.addClass(STRING))); |
|
356 |
for (int level = 0; level < nsorts; level++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
357 |
final Sort sort = sortObjects.get(level); |
6 | 358 |
il.append(DUP); |
359 |
il.append(new PUSH(cpg, level)); |
|
360 |
sort.translateSortType(classGen, methodGen); |
|
361 |
il.append(AASTORE); |
|
362 |
} |
|
12458 | 363 |
sortTypeTemp.setStart(il.append(new ASTORE(sortTypeTemp.getIndex()))); |
6 | 364 |
|
365 |
LocalVariableGen sortLangTemp |
|
366 |
= methodGen.addLocalVariable("sort_lang_tmp", |
|
367 |
Util.getJCRefType("[" + STRING_SIG), |
|
12458 | 368 |
null, null); |
6 | 369 |
il.append(new PUSH(cpg, nsorts)); |
370 |
il.append(new ANEWARRAY(cpg.addClass(STRING))); |
|
371 |
for (int level = 0; level < nsorts; level++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
372 |
final Sort sort = sortObjects.get(level); |
6 | 373 |
il.append(DUP); |
374 |
il.append(new PUSH(cpg, level)); |
|
375 |
sort.translateLang(classGen, methodGen); |
|
376 |
il.append(AASTORE); |
|
377 |
} |
|
12458 | 378 |
sortLangTemp.setStart(il.append(new ASTORE(sortLangTemp.getIndex()))); |
6 | 379 |
|
380 |
LocalVariableGen sortCaseOrderTemp |
|
381 |
= methodGen.addLocalVariable("sort_case_order_tmp", |
|
382 |
Util.getJCRefType("[" + STRING_SIG), |
|
12458 | 383 |
null, null); |
6 | 384 |
il.append(new PUSH(cpg, nsorts)); |
385 |
il.append(new ANEWARRAY(cpg.addClass(STRING))); |
|
386 |
for (int level = 0; level < nsorts; level++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
387 |
final Sort sort = sortObjects.get(level); |
6 | 388 |
il.append(DUP); |
389 |
il.append(new PUSH(cpg, level)); |
|
390 |
sort.translateCaseOrder(classGen, methodGen); |
|
391 |
il.append(AASTORE); |
|
392 |
} |
|
12458 | 393 |
sortCaseOrderTemp.setStart( |
394 |
il.append(new ASTORE(sortCaseOrderTemp.getIndex()))); |
|
6 | 395 |
|
396 |
il.append(new NEW(cpg.addClass(sortRecordFactoryClass))); |
|
397 |
il.append(DUP); |
|
398 |
il.append(methodGen.loadDOM()); |
|
399 |
il.append(new PUSH(cpg, sortRecordClass)); |
|
400 |
il.append(classGen.loadTranslet()); |
|
401 |
||
12458 | 402 |
sortOrderTemp.setEnd(il.append(new ALOAD(sortOrderTemp.getIndex()))); |
403 |
sortTypeTemp.setEnd(il.append(new ALOAD(sortTypeTemp.getIndex()))); |
|
404 |
sortLangTemp.setEnd(il.append(new ALOAD(sortLangTemp.getIndex()))); |
|
405 |
sortCaseOrderTemp.setEnd( |
|
406 |
il.append(new ALOAD(sortCaseOrderTemp.getIndex()))); |
|
6 | 407 |
|
408 |
il.append(new INVOKESPECIAL( |
|
409 |
cpg.addMethodref(sortRecordFactoryClass, "<init>", |
|
410 |
"(" + DOM_INTF_SIG |
|
411 |
+ STRING_SIG |
|
412 |
+ TRANSLET_INTF_SIG |
|
413 |
+ "[" + STRING_SIG |
|
414 |
+ "[" + STRING_SIG |
|
415 |
+ "[" + STRING_SIG |
|
416 |
+ "[" + STRING_SIG + ")V"))); |
|
417 |
||
418 |
// Initialize closure variables in sortRecordFactory |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
419 |
final List<VariableRefBase> dups = new ArrayList<>(); |
6 | 420 |
|
421 |
for (int j = 0; j < nsorts; j++) { |
|
422 |
final Sort sort = (Sort) sortObjects.get(j); |
|
423 |
final int length = (sort._closureVars == null) ? 0 : |
|
424 |
sort._closureVars.size(); |
|
425 |
||
426 |
for (int i = 0; i < length; i++) { |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
427 |
VariableRefBase varRef = sort._closureVars.get(i); |
6 | 428 |
|
429 |
// Discard duplicate variable references |
|
430 |
if (dups.contains(varRef)) continue; |
|
431 |
||
432 |
final VariableBase var = varRef.getVariable(); |
|
433 |
||
434 |
// Store variable in new closure |
|
435 |
il.append(DUP); |
|
436 |
il.append(var.loadInstruction()); |
|
437 |
il.append(new PUTFIELD( |
|
438 |
cpg.addFieldref(sortRecordFactoryClass, var.getEscapedName(), |
|
439 |
var.getType().toSignature()))); |
|
440 |
dups.add(varRef); |
|
441 |
} |
|
442 |
} |
|
443 |
} |
|
444 |
||
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
445 |
public static String compileSortRecordFactory(List<Sort> sortObjects, |
6 | 446 |
ClassGenerator classGen, MethodGenerator methodGen, |
447 |
String sortRecordClass) |
|
448 |
{ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
449 |
final XSLTC xsltc = (sortObjects.get(0)).getXSLTC(); |
6 | 450 |
final String className = xsltc.getHelperClassName(); |
451 |
||
452 |
final NodeSortRecordFactGenerator sortRecordFactory = |
|
453 |
new NodeSortRecordFactGenerator(className, |
|
454 |
NODE_SORT_FACTORY, |
|
455 |
className + ".java", |
|
456 |
ACC_PUBLIC | ACC_SUPER | ACC_FINAL, |
|
457 |
new String[] {}, |
|
458 |
classGen.getStylesheet()); |
|
459 |
||
460 |
ConstantPoolGen cpg = sortRecordFactory.getConstantPool(); |
|
461 |
||
462 |
// Add a new instance variable for each var in closure |
|
463 |
final int nsorts = sortObjects.size(); |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
464 |
final List<VariableRefBase> dups = new ArrayList<>(); |
6 | 465 |
|
466 |
for (int j = 0; j < nsorts; j++) { |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
467 |
final Sort sort = sortObjects.get(j); |
6 | 468 |
final int length = (sort._closureVars == null) ? 0 : |
469 |
sort._closureVars.size(); |
|
470 |
||
471 |
for (int i = 0; i < length; i++) { |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
472 |
final VariableRefBase varRef = sort._closureVars.get(i); |
6 | 473 |
|
474 |
// Discard duplicate variable references |
|
475 |
if (dups.contains(varRef)) continue; |
|
476 |
||
477 |
final VariableBase var = varRef.getVariable(); |
|
478 |
sortRecordFactory.addField(new Field(ACC_PUBLIC, |
|
479 |
cpg.addUtf8(var.getEscapedName()), |
|
480 |
cpg.addUtf8(var.getType().toSignature()), |
|
481 |
null, cpg.getConstantPool())); |
|
482 |
dups.add(varRef); |
|
483 |
} |
|
484 |
} |
|
485 |
||
486 |
// Define a constructor for this class |
|
487 |
final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = |
|
488 |
new com.sun.org.apache.bcel.internal.generic.Type[7]; |
|
489 |
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG); |
|
490 |
argTypes[1] = Util.getJCRefType(STRING_SIG); |
|
491 |
argTypes[2] = Util.getJCRefType(TRANSLET_INTF_SIG); |
|
492 |
argTypes[3] = Util.getJCRefType("[" + STRING_SIG); |
|
493 |
argTypes[4] = Util.getJCRefType("[" + STRING_SIG); |
|
494 |
argTypes[5] = Util.getJCRefType("[" + STRING_SIG); |
|
495 |
argTypes[6] = Util.getJCRefType("[" + STRING_SIG); |
|
496 |
||
497 |
final String[] argNames = new String[7]; |
|
498 |
argNames[0] = DOCUMENT_PNAME; |
|
499 |
argNames[1] = "className"; |
|
500 |
argNames[2] = TRANSLET_PNAME; |
|
501 |
argNames[3] = "order"; |
|
502 |
argNames[4] = "type"; |
|
503 |
argNames[5] = "lang"; |
|
504 |
argNames[6] = "case_order"; |
|
505 |
||
506 |
||
507 |
InstructionList il = new InstructionList(); |
|
508 |
final MethodGenerator constructor = |
|
509 |
new MethodGenerator(ACC_PUBLIC, |
|
510 |
com.sun.org.apache.bcel.internal.generic.Type.VOID, |
|
511 |
argTypes, argNames, "<init>", |
|
512 |
className, il, cpg); |
|
513 |
||
514 |
// Push all parameters onto the stack and called super.<init>() |
|
515 |
il.append(ALOAD_0); |
|
516 |
il.append(ALOAD_1); |
|
517 |
il.append(ALOAD_2); |
|
518 |
il.append(new ALOAD(3)); |
|
519 |
il.append(new ALOAD(4)); |
|
520 |
il.append(new ALOAD(5)); |
|
521 |
il.append(new ALOAD(6)); |
|
522 |
il.append(new ALOAD(7)); |
|
523 |
il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY, |
|
524 |
"<init>", |
|
525 |
"(" + DOM_INTF_SIG |
|
526 |
+ STRING_SIG |
|
527 |
+ TRANSLET_INTF_SIG |
|
528 |
+ "[" + STRING_SIG |
|
529 |
+ "[" + STRING_SIG |
|
530 |
+ "[" + STRING_SIG |
|
531 |
+ "[" + STRING_SIG + ")V"))); |
|
532 |
il.append(RETURN); |
|
533 |
||
534 |
// Override the definition of makeNodeSortRecord() |
|
535 |
il = new InstructionList(); |
|
536 |
final MethodGenerator makeNodeSortRecord = |
|
537 |
new MethodGenerator(ACC_PUBLIC, |
|
538 |
Util.getJCRefType(NODE_SORT_RECORD_SIG), |
|
539 |
new com.sun.org.apache.bcel.internal.generic.Type[] { |
|
540 |
com.sun.org.apache.bcel.internal.generic.Type.INT, |
|
541 |
com.sun.org.apache.bcel.internal.generic.Type.INT }, |
|
542 |
new String[] { "node", "last" }, "makeNodeSortRecord", |
|
543 |
className, il, cpg); |
|
544 |
||
545 |
il.append(ALOAD_0); |
|
546 |
il.append(ILOAD_1); |
|
547 |
il.append(ILOAD_2); |
|
548 |
il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY, |
|
549 |
"makeNodeSortRecord", "(II)" + NODE_SORT_RECORD_SIG))); |
|
550 |
il.append(DUP); |
|
551 |
il.append(new CHECKCAST(cpg.addClass(sortRecordClass))); |
|
552 |
||
553 |
// Initialize closure in record class |
|
554 |
final int ndups = dups.size(); |
|
555 |
for (int i = 0; i < ndups; i++) { |
|
556 |
final VariableRefBase varRef = (VariableRefBase) dups.get(i); |
|
557 |
final VariableBase var = varRef.getVariable(); |
|
558 |
final Type varType = var.getType(); |
|
559 |
||
560 |
il.append(DUP); |
|
561 |
||
562 |
// Get field from factory class |
|
563 |
il.append(ALOAD_0); |
|
564 |
il.append(new GETFIELD( |
|
565 |
cpg.addFieldref(className, |
|
566 |
var.getEscapedName(), varType.toSignature()))); |
|
567 |
||
568 |
// Put field in record class |
|
569 |
il.append(new PUTFIELD( |
|
570 |
cpg.addFieldref(sortRecordClass, |
|
571 |
var.getEscapedName(), varType.toSignature()))); |
|
572 |
} |
|
573 |
il.append(POP); |
|
574 |
il.append(ARETURN); |
|
575 |
||
576 |
constructor.setMaxLocals(); |
|
577 |
constructor.setMaxStack(); |
|
12458 | 578 |
sortRecordFactory.addMethod(constructor); |
6 | 579 |
makeNodeSortRecord.setMaxLocals(); |
580 |
makeNodeSortRecord.setMaxStack(); |
|
12458 | 581 |
sortRecordFactory.addMethod(makeNodeSortRecord); |
6 | 582 |
xsltc.dumpClass(sortRecordFactory.getJavaClass()); |
583 |
||
584 |
return className; |
|
585 |
} |
|
586 |
||
587 |
/** |
|
588 |
* Create a new auxillary class extending NodeSortRecord. |
|
589 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
590 |
private static String compileSortRecord(List<Sort> sortObjects, |
6 | 591 |
ClassGenerator classGen, |
592 |
MethodGenerator methodGen) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
593 |
final XSLTC xsltc = sortObjects.get(0).getXSLTC(); |
6 | 594 |
final String className = xsltc.getHelperClassName(); |
595 |
||
596 |
// This generates a new class for handling this specific sort |
|
597 |
final NodeSortRecordGenerator sortRecord = |
|
598 |
new NodeSortRecordGenerator(className, |
|
599 |
NODE_SORT_RECORD, |
|
600 |
"sort$0.java", |
|
601 |
ACC_PUBLIC | ACC_SUPER | ACC_FINAL, |
|
602 |
new String[] {}, |
|
603 |
classGen.getStylesheet()); |
|
604 |
||
605 |
final ConstantPoolGen cpg = sortRecord.getConstantPool(); |
|
606 |
||
607 |
// Add a new instance variable for each var in closure |
|
608 |
final int nsorts = sortObjects.size(); |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
609 |
final List<VariableRefBase> dups = new ArrayList<>(); |
6 | 610 |
|
611 |
for (int j = 0; j < nsorts; j++) { |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
612 |
final Sort sort = sortObjects.get(j); |
6 | 613 |
|
614 |
// Set the name of the inner class in this sort object |
|
615 |
sort.setInnerClassName(className); |
|
616 |
||
617 |
final int length = (sort._closureVars == null) ? 0 : |
|
618 |
sort._closureVars.size(); |
|
619 |
for (int i = 0; i < length; i++) { |
|
620 |
final VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i); |
|
621 |
||
622 |
// Discard duplicate variable references |
|
623 |
if (dups.contains(varRef)) continue; |
|
624 |
||
625 |
final VariableBase var = varRef.getVariable(); |
|
626 |
sortRecord.addField(new Field(ACC_PUBLIC, |
|
627 |
cpg.addUtf8(var.getEscapedName()), |
|
628 |
cpg.addUtf8(var.getType().toSignature()), |
|
629 |
null, cpg.getConstantPool())); |
|
630 |
dups.add(varRef); |
|
631 |
} |
|
632 |
} |
|
633 |
||
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
634 |
MethodGenerator init = compileInit(sortRecord, cpg, className); |
12458 | 635 |
MethodGenerator extract = compileExtract(sortObjects, sortRecord, |
6 | 636 |
cpg, className); |
637 |
sortRecord.addMethod(init); |
|
638 |
sortRecord.addMethod(extract); |
|
639 |
||
640 |
xsltc.dumpClass(sortRecord.getJavaClass()); |
|
641 |
return className; |
|
642 |
} |
|
643 |
||
644 |
/** |
|
645 |
* Create a constructor for the new class. Updates the reference to the |
|
646 |
* collator in the super calls only when the stylesheet specifies a new |
|
647 |
* language in xsl:sort. |
|
648 |
*/ |
|
36486
b84e564d2358
8150704: XALAN: ERROR: 'No more DTM IDs are available' when transforming with lots of temporary result trees
joehw
parents:
25868
diff
changeset
|
649 |
private static MethodGenerator compileInit(NodeSortRecordGenerator sortRecord, |
6 | 650 |
ConstantPoolGen cpg, |
651 |
String className) |
|
652 |
{ |
|
653 |
final InstructionList il = new InstructionList(); |
|
654 |
final MethodGenerator init = |
|
655 |
new MethodGenerator(ACC_PUBLIC, |
|
656 |
com.sun.org.apache.bcel.internal.generic.Type.VOID, |
|
657 |
null, null, "<init>", className, |
|
658 |
il, cpg); |
|
659 |
||
660 |
// Call the constructor in the NodeSortRecord superclass |
|
661 |
il.append(ALOAD_0); |
|
662 |
il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_RECORD, |
|
663 |
"<init>", "()V"))); |
|
664 |
||
665 |
||
666 |
||
667 |
il.append(RETURN); |
|
668 |
||
12458 | 669 |
return init; |
6 | 670 |
} |
671 |
||
672 |
||
673 |
/** |
|
674 |
* Compiles a method that overloads NodeSortRecord.extractValueFromDOM() |
|
675 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
676 |
private static MethodGenerator compileExtract(List<Sort> sortObjects, |
6 | 677 |
NodeSortRecordGenerator sortRecord, |
678 |
ConstantPoolGen cpg, |
|
679 |
String className) { |
|
680 |
final InstructionList il = new InstructionList(); |
|
681 |
||
682 |
// String NodeSortRecord.extractValueFromDOM(dom,node,level); |
|
683 |
final CompareGenerator extractMethod = |
|
684 |
new CompareGenerator(ACC_PUBLIC | ACC_FINAL, |
|
685 |
com.sun.org.apache.bcel.internal.generic.Type.STRING, |
|
686 |
new com.sun.org.apache.bcel.internal.generic.Type[] { |
|
687 |
Util.getJCRefType(DOM_INTF_SIG), |
|
688 |
com.sun.org.apache.bcel.internal.generic.Type.INT, |
|
689 |
com.sun.org.apache.bcel.internal.generic.Type.INT, |
|
690 |
Util.getJCRefType(TRANSLET_SIG), |
|
691 |
com.sun.org.apache.bcel.internal.generic.Type.INT |
|
692 |
}, |
|
693 |
new String[] { "dom", |
|
694 |
"current", |
|
695 |
"level", |
|
696 |
"translet", |
|
697 |
"last" |
|
698 |
}, |
|
699 |
"extractValueFromDOM", className, il, cpg); |
|
700 |
||
701 |
// Values needed for the switch statement |
|
702 |
final int levels = sortObjects.size(); |
|
703 |
final int match[] = new int[levels]; |
|
704 |
final InstructionHandle target[] = new InstructionHandle[levels]; |
|
705 |
InstructionHandle tblswitch = null; |
|
706 |
||
707 |
// Compile switch statement only if the key has multiple levels |
|
708 |
if (levels > 1) { |
|
709 |
// Put the parameter to the swtich statement on the stack |
|
710 |
il.append(new ILOAD(extractMethod.getLocalIndex("level"))); |
|
711 |
// Append the switch statement here later on |
|
712 |
tblswitch = il.append(new NOP()); |
|
713 |
} |
|
714 |
||
715 |
// Append all the cases for the switch statment |
|
716 |
for (int level = 0; level < levels; level++) { |
|
717 |
match[level] = level; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
718 |
final Sort sort = sortObjects.get(level); |
6 | 719 |
target[level] = il.append(NOP); |
720 |
sort.translateSelect(sortRecord, extractMethod); |
|
721 |
il.append(ARETURN); |
|
722 |
} |
|
723 |
||
724 |
// Compile def. target for switch statement if key has multiple levels |
|
725 |
if (levels > 1) { |
|
726 |
// Append the default target - it will _NEVER_ be reached |
|
727 |
InstructionHandle defaultTarget = |
|
728 |
il.append(new PUSH(cpg, EMPTYSTRING)); |
|
729 |
il.insert(tblswitch,new TABLESWITCH(match, target, defaultTarget)); |
|
730 |
il.append(ARETURN); |
|
731 |
} |
|
732 |
||
12458 | 733 |
return extractMethod; |
6 | 734 |
} |
735 |
} |