@Override
  public void generate(GenScope scope) {
    InstructionList il = scope.getInstructionList();
    InstructionFactory ifact = scope.getInstructionFactory();
    ConstantPoolGen cpg = scope.getConstantPool();

    String transformationName = this.getTransformationName();
    String entryPointName = this.getEntryPointName();

    LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT);

    // Probably this could be improved, but for the moment a transformation
    // object will provide a facility to instantiate another transformation

    // Create the new transformation
    // [This_Transformation, "TransformationName"] -> instantiateTransformation ->
    // [Created_Transformation]
    scope.generateGetTransformation();
    il.append(ifact.createConstant(transformationName));
    il.append(
        ifact.createInvoke(
            DefaultTypes.IdcTransformation.getClassName(),
            "instantiateTransformation",
            DefaultTypes.IdcTransformation,
            new Type[] {Type.STRING},
            Constants.INVOKEVIRTUAL));

    // There are two cases
    //
    // 1. Explicit invocation of a transformation rule

    if (entryPointName != null) {
      generateInvokeEntryPoint(scope, il, ifact, transformationName, entryPointName, lvg);
    } else {
      generateInvokeTransformation(scope, il, ifact, transformationName, lvg);
    }
  }
  private void generateInvokeEntryPoint(
      GenScope scope,
      InstructionList il,
      InstructionFactory ifact,
      String transformationName,
      String entryPointName,
      LocalVariableGen lvg) {

    // Configure the transformation
    il.append(InstructionFactory.DUP);
    il.append(
        ifact.createInvoke(
            DefaultTypes.IdcTransformation.getClassName(),
            "configure_",
            Type.VOID,
            new Type[] {},
            Constants.INVOKEVIRTUAL));
    // TODO: Configure the models properly, not as I'm doing directly in instantiateTransformation
    // directly

    // Put the params into the stack and invoke, but first check the type of the transformation
    // object
    ObjectType transformationType = new ObjectType(transformationName);
    il.append(ifact.createCheckCast(transformationType));
    // [Transformation, param1, ..., paramN]
    EList<Variable> params = this.getEntryPointParameters();
    Type[] types = new Type[params.size()];
    int i = 0;
    for (Variable variable : params) {
      scope.loadVariable(variable, il);
      types[i++] = Type.OBJECT;
    }
    il.append(
        ifact.createInvoke(
            transformationType.getClassName(),
            entryPointName,
            Type.OBJECT,
            types,
            Constants.INVOKEVIRTUAL));

    il.append(new ASTORE(lvg.getIndex()));
  }
  private void generateInvokeTransformation(
      GenScope scope,
      InstructionList il,
      InstructionFactory ifact,
      String transformationName,
      LocalVariableGen lvg) {
    il.append(InstructionFactory.DUP);
    il.append(InstructionFactory.DUP);
    il.append(InstructionFactory.DUP);

    // Configure the invoked transformation: view filter
    scope.loadVariable(this.getInputViewFilter(), il);
    il.append(
        ifact.createInvoke(
            DefaultTypes.IdcTransformation.getClassName(),
            "configure_invocation_",
            Type.VOID,
            new Type[] {DefaultTypes.RunnableClosure},
            Constants.INVOKEVIRTUAL));

    // Configure the transformation
    il.append(InstructionFactory.DUP);
    il.append(
        ifact.createInvoke(
            DefaultTypes.IdcTransformation.getClassName(),
            "configure_",
            Type.VOID,
            new Type[] {},
            Constants.INVOKEVIRTUAL));

    // Set parameters
    for (NamedInvocationParameter p : this.getParameters()) {
      il.append(InstructionFactory.DUP);
      il.append(ifact.createConstant(p.getFormalName()));
      scope.loadVariable(p.getResult(), il);
      il.append(
          ifact.createInvoke(
              DefaultTypes.IdcTransformation.getClassName(),
              "setParameterValue",
              Type.VOID,
              new Type[] {Type.STRING, Type.OBJECT},
              Constants.INVOKEVIRTUAL));
    }

    // Start the transformation
    il.append(
        ifact.createInvoke(
            DefaultTypes.IdcTransformation.getClassName(),
            "start_",
            Type.VOID,
            new Type[] {},
            Constants.INVOKEVIRTUAL));

    // Get a target element from a trace
    if (this.getOutputResolutionSourceElement() != null) {
      scope.loadVariable(this.getOutputResolutionSourceElement(), il);
      il.append(ifact.createConstant(this.getQueueName()));
      il.append(ifact.createConstant(this.getSrcTraceAttributeName()));
      il.append(ifact.createConstant(this.getTgtTraceAttributeName()));
      il.append(
          ifact.createInvoke(
              DefaultTypes.IdcTransformation.getClassName(),
              "retrieve_from_invocation_",
              Type.OBJECT,
              new Type[] {Type.OBJECT, Type.STRING, Type.STRING, Type.STRING},
              Constants.INVOKEVIRTUAL));
    } else {
      il.append(InstructionFactory.ACONST_NULL);
    }

    il.append(new ASTORE(lvg.getIndex()));
  }
Exemple #4
0
  @Override
  public void generate(GenScope scope) {
    InstructionList il = scope.getInstructionList();
    InstructionFactory ifact = scope.getInstructionFactory();
    ConstantPoolGen cpg = scope.getConstantPool();

    LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT);

    // TODO: I'm going to assume that there is an optional kindOf and
    //       and p() predicate.
    if (this.getPredicates().size() > 2)
      throw new UnsupportedOperationException("QMatchJVMGen. Only 2 fixed predicates implemented.");

    KindOfPredicate kindOf = null;
    PropertyEqualsPredicate prop = null;

    if (getPredicates().get(0) instanceof KindOfPredicate) {
      kindOf = (KindOfPredicate) getPredicates().get(0);
      prop = (PropertyEqualsPredicate) getPredicates().get(1);
    } else {
      prop = (PropertyEqualsPredicate) getPredicates().get(0);
    }

    // Create the object, then the parameters of the constructor
    String requestClass = "org.eclectic.idc.jvm.runtime.RequestKindProperty";
    il.append(ifact.createNew(requestClass));
    il.append(InstructionConstants.DUP);

    scope.generateGetModelManager();
    if (kindOf == null) {
      il.append(InstructionConstants.ACONST_NULL);
    } else {
      ReadMetaJVMGen readMeta = new ReadMetaJVMGen();
      readMeta.setClassName(kindOf.getClassName());
      readMeta.setModel(kindOf.getModel());
      readMeta.setName("_readMeta_for" + getName());

      readMeta.setFile(this.getFile());
      readMeta.setColumn(this.getColumn());
      readMeta.setRow(this.getRow());

      readMeta.generate(scope);
      scope.loadVariable(readMeta, il);
    }

    il.append(ifact.createConstant(prop.getPropertyName()));
    scope.loadVariable(prop.getValue(), il);
    // In the stack: IdcMetaclass, featureName, value + receptor x 2

    il.append(
        ifact.createInvoke(
            requestClass,
            "<init>",
            Type.VOID,
            new Type[] {
              DefaultTypes.ModelManager, DefaultTypes.IdcMetaclass, Type.STRING, Type.OBJECT
            },
            Constants.INVOKESPECIAL));

    if (getGetterClosure() != null) {
      il.append(InstructionConstants.DUP);
      scope.loadVariable(getGetterClosure(), il);
      il.append(
          ifact.createInvoke(
              requestClass,
              "setGetterClosure",
              Type.VOID,
              new Type[] {DefaultTypes.IClosure},
              Constants.INVOKEVIRTUAL));
    }

    // Generate debug info
    il.append(InstructionConstants.DUP);
    if (getFile() == null) {
      il.append(InstructionConstants.ACONST_NULL);
    } else {
      il.append(ifact.createConstant(getFile()));
    }
    il.append(ifact.createConstant(getRow()));
    il.append(ifact.createConstant(getColumn()));
    il.append(
        ifact.createInvoke(
            requestClass,
            "setDebugInfo",
            Type.VOID,
            new Type[] {Type.STRING, Type.INT, Type.INT},
            Constants.INVOKEVIRTUAL));
    // End-of debug info

    QueueJVMGen jvmQ = (QueueJVMGen) getQueue();
    CommonGen.generateGetQueue(scope, jvmQ);
    il.append(InstructionConstants.SWAP);

    il.append(
        ifact.createInvoke(
            DefaultTypes.ContinuationResolverHelper.getClassName(),
            "requestAndWait",
            Type.OBJECT,
            new Type[] {DefaultTypes.HistoryQueue, DefaultTypes.IRequest},
            Constants.INVOKESTATIC));

    // il.append(ifact.createInvoke(jvmQ.getClassName(),
    //		"requestAndWait", Type.OBJECT, new Type[] { DefaultTypes.IRequest },
    // Constants.INVOKEVIRTUAL));

    // il.append(InstructionConstants.DUP);
    // CommonGen.print(il, ifact);

    il.append(new ASTORE(lvg.getIndex()));
  }