sortRecordFactoryClass =
compileSortRecordFactory(sortObjects, classGen, methodGen,
sortRecordClass);
}
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
// Backwards branches are prohibited if an uninitialized object is
// on the stack by section 4.9.4 of the JVM Specification, 2nd Ed.
// We don't know whether this code might contain backwards branches
// so we mustn't create the new object until after we've created
// the suspect arguments to its constructor. Instead we calculate
// the values of the arguments to the constructor first, store them
// in temporary variables, create the object and reload the
// arguments from the temporaries to avoid the problem.
// Compile code that initializes the static _sortOrder
LocalVariableGen sortOrderTemp
= methodGen.addLocalVariable("sort_order_tmp",
Util.getJCRefType("[" + STRING_SIG),
il.getEnd(), null);
il.append(new PUSH(cpg, nsorts));
il.append(new ANEWARRAY(cpg.addClass(STRING)));
for (int level = 0; level < nsorts; level++) {
final Sort sort = (Sort)sortObjects.elementAt(level);
il.append(DUP);
il.append(new PUSH(cpg, level));
sort.translateSortOrder(classGen, methodGen);
il.append(AASTORE);
}
il.append(new ASTORE(sortOrderTemp.getIndex()));
LocalVariableGen sortTypeTemp
= methodGen.addLocalVariable("sort_type_tmp",
Util.getJCRefType("[" + STRING_SIG),
il.getEnd(), null);
il.append(new PUSH(cpg, nsorts));
il.append(new ANEWARRAY(cpg.addClass(STRING)));
for (int level = 0; level < nsorts; level++) {
final Sort sort = (Sort)sortObjects.elementAt(level);
il.append(DUP);
il.append(new PUSH(cpg, level));
sort.translateSortType(classGen, methodGen);
il.append(AASTORE);
}
il.append(new ASTORE(sortTypeTemp.getIndex()));
LocalVariableGen sortLangTemp
= methodGen.addLocalVariable("sort_lang_tmp",
Util.getJCRefType("[" + STRING_SIG),
il.getEnd(), null);
il.append(new PUSH(cpg, nsorts));
il.append(new ANEWARRAY(cpg.addClass(STRING)));
for (int level = 0; level < nsorts; level++) {
final Sort sort = (Sort)sortObjects.elementAt(level);
il.append(DUP);
il.append(new PUSH(cpg, level));
sort.translateLang(classGen, methodGen);
il.append(AASTORE);
}
il.append(new ASTORE(sortLangTemp.getIndex()));
LocalVariableGen sortCaseOrderTemp
= methodGen.addLocalVariable("sort_case_order_tmp",
Util.getJCRefType("[" + STRING_SIG),
il.getEnd(), null);
il.append(new PUSH(cpg, nsorts));
il.append(new ANEWARRAY(cpg.addClass(STRING)));
for (int level = 0; level < nsorts; level++) {
final Sort sort = (Sort)sortObjects.elementAt(level);
il.append(DUP);
il.append(new PUSH(cpg, level));
sort.translateCaseOrder(classGen, methodGen);
il.append(AASTORE);
}
il.append(new ASTORE(sortCaseOrderTemp.getIndex()));
il.append(new NEW(cpg.addClass(sortRecordFactoryClass)));
il.append(DUP);
il.append(methodGen.loadDOM());
il.append(new PUSH(cpg, sortRecordClass));
il.append(classGen.loadTranslet());
il.append(new ALOAD(sortOrderTemp.getIndex()));
il.append(new ALOAD(sortTypeTemp.getIndex()));
il.append(new ALOAD(sortLangTemp.getIndex()));
il.append(new ALOAD(sortCaseOrderTemp.getIndex()));
il.append(new INVOKESPECIAL(
cpg.addMethodref(sortRecordFactoryClass, "<init>",
"(" + DOM_INTF_SIG
+ STRING_SIG
+ TRANSLET_INTF_SIG
+ "[" + STRING_SIG
+ "[" + STRING_SIG
+ "[" + STRING_SIG
+ "[" + STRING_SIG + ")V")));
// Initialize closure variables in sortRecordFactory
final ArrayList dups = new ArrayList();
for (int j = 0; j < nsorts; j++) {
final Sort sort = (Sort) sortObjects.get(j);
final int length = (sort._closureVars == null) ? 0 :
sort._closureVars.size();
for (int i = 0; i < length; i++) {
VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i);
// Discard duplicate variable references
if (dups.contains(varRef)) continue;
final VariableBase var = varRef.getVariable();
// Store variable in new closure
il.append(DUP);
il.append(var.loadInstruction());
il.append(new PUTFIELD(
cpg.addFieldref(sortRecordFactoryClass, var.getEscapedName(),
var.getType().toSignature())));
dups.add(varRef);
}
}
}