Esempio n. 1
0
  /**
   * 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);
      }
    }
  }