/** * Translate a predicate expression. This translation pushes two references on the stack: a * reference to a newly created filter object and a reference to the predicate's closure. */ public void translateFilter(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Compile auxiliary class for filter compileFilter(classGen, methodGen); // Create new instance of filter il.append(new NEW(cpg.addClass(_className))); il.append(DUP); il.append(new INVOKESPECIAL(cpg.addMethodref(_className, "<init>", "()V"))); // Initialize closure variables final int length = (_closureVars == null) ? 0 : _closureVars.size(); for (int i = 0; i < length; i++) { VariableRefBase varRef = (VariableRefBase) _closureVars.get(i); VariableBase var = varRef.getVariable(); Type varType = var.getType(); il.append(DUP); // Find nearest closure implemented as an inner class Closure variableClosure = _parentClosure; while (variableClosure != null) { if (variableClosure.inInnerClass()) break; variableClosure = variableClosure.getParentClosure(); } // Use getfield if in an inner class if (variableClosure != null) { il.append(ALOAD_0); il.append( new GETFIELD( cpg.addFieldref( variableClosure.getInnerClassName(), var.getEscapedName(), varType.toSignature()))); } else { // Use a load of instruction if in translet class il.append(var.loadInstruction()); } // Store variable in new closure il.append( new PUTFIELD(cpg.addFieldref(_className, var.getEscapedName(), varType.toSignature()))); } }
/** * Compiles code that instantiates a NodeSortRecordFactory object which will produce * NodeSortRecord objects of a specific type. */ 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); } } }