public static void compileSortRecordFactory()

in xalan/src/main/java/org/apache/xalan/xsltc/compiler/Sort.java [303:444]


    public static void compileSortRecordFactory(Vector sortObjects,
	ClassGenerator classGen, MethodGenerator methodGen) 
    {
	String sortRecordClass = 
	    compileSortRecord(sortObjects, classGen, methodGen);

	boolean needsSortRecordFactory = false;
	final int nsorts = sortObjects.size();
	for (int i = 0; i < nsorts; i++) {
	    final Sort sort = (Sort) sortObjects.elementAt(i);
	    needsSortRecordFactory |= sort._needsSortRecordFactory;
	}

	String sortRecordFactoryClass = NODE_SORT_FACTORY;
	if (needsSortRecordFactory) {
	    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),
                                      null, 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);
	}
        sortOrderTemp.setStart(il.append(new ASTORE(sortOrderTemp.getIndex())));

        LocalVariableGen sortTypeTemp
                 = methodGen.addLocalVariable("sort_type_tmp",
                                      Util.getJCRefType("[" + STRING_SIG),
                                      null, 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);
	}
        sortTypeTemp.setStart(il.append(new ASTORE(sortTypeTemp.getIndex())));

        LocalVariableGen sortLangTemp
                 = methodGen.addLocalVariable("sort_lang_tmp",
                                      Util.getJCRefType("[" + STRING_SIG),
                                      null, 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);
        }
        sortLangTemp.setStart(il.append(new ASTORE(sortLangTemp.getIndex())));

        LocalVariableGen sortCaseOrderTemp
                 = methodGen.addLocalVariable("sort_case_order_tmp",
                                      Util.getJCRefType("[" + STRING_SIG),
                                      null, 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);
        }
        sortCaseOrderTemp.setStart(
                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());

        sortOrderTemp.setEnd(il.append(new ALOAD(sortOrderTemp.getIndex())));
        sortTypeTemp.setEnd(il.append(new ALOAD(sortTypeTemp.getIndex())));
        sortLangTemp.setEnd(il.append(new ALOAD(sortLangTemp.getIndex())));
        sortCaseOrderTemp.setEnd(
                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);
	    }
	}
    }