示例#1
0
  public void generate_code(CodeGeneratorState s) throws PlcException, IOException {
    if (code == null) {
      c.emitRet(); // empty function code
      return;
    }

    // ------------------------------------------
    // traverse tree to allocate automatic vars?
    // ------------------------------------------
    int n_auto_vars = svars.getUsedSlots();
    int n_int_auto_vars = isvars.getUsedSlots();
    // ------------------------------------------

    // ------------------------------------------
    // generate prologue code here
    // ------------------------------------------

    // check number of args
    int n_args = args_def.size();
    String good_args_label = c.getLabel();

    c.emitIConst_32bit(n_args);
    c.emitISubLU();
    c.emitJz(good_args_label);

    // wrong count - throw string
    // BUG! Need less consuming way of reporting this. Maybe by
    // calling class object Method? Or by summoning something?
    c.emitString("arg count: " + name + " in " + s.get_class().getName());
    c.emitThrow();

    c.markLabel(good_args_label);

    if (requestDebug) c.emitDebug((byte) 0x1, "Enabled debug");

    // push nulls to reserve stack space for autovars
    // BUG! We can execute vars initialization code here, can we?
    // We can if code does not depend on auto vars itself, or depends only on
    // previous ones.
    // TODO: BUG! autovars in arguments are already on stack, we don't have to reserve space
    for (int i = n_auto_vars; i > 0; i--) c.emitPushNull();

    // TODO introduce instruction to reserve o+i space in one step
    // Reserve integer stack place for int vars
    for (int i = n_int_auto_vars; i > 0; i--) c.emitIConst_0();

    // ------------------------------------------

    // ------------------------------------------
    // generate main code by descending the tree
    // ------------------------------------------
    code.generate_code(c, s);
    // ------------------------------------------

    // ------------------------------------------
    // generate epilogue code here
    // ------------------------------------------
    if (requestDebug) c.emitDebug((byte) 0x2, "Disabled debug");
    c.emitRet(); // catch the fall-out
    // ------------------------------------------

  }
示例#2
0
  public void generateLlvmCode(CodeGeneratorState s, BufferedWriter llvmFile)
      throws PlcException, IOException {

    LlvmCodegen llc = new LlvmCodegen(s.get_class(), this, llvmFile);

    StringBuilder argdef = new StringBuilder();

    boolean firstParm = true;
    for (ArgDefinition a : args_def) {
      if (!firstParm) argdef.append(", ");

      firstParm = false;

      argdef.append("i64 %" + a.getName());
    }

    String llvmMethodName = name;
    name = name.replaceAll("<init>", "_\\$_Constructor");

    llc.putln(String.format("define %s @%s(%s) {", llc.getObjectType(), name, argdef)); // function

    if (code != null) {

      // ------------------------------------------
      // traverse tree to allocate automatic vars?
      // ------------------------------------------
      // int n_auto_vars = svars.getUsedSlots();
      // int n_int_auto_vars = isvars.getUsedSlots();
      // ------------------------------------------

      // ------------------------------------------
      // generate prologue code here
      // ------------------------------------------

      /*
      // check number of args
      int n_args = args_def.size();
      String good_args_label = c.getLabel();

      c.emitIConst_32bit(n_args);
      c.emitISubLU();
      c.emitJz(good_args_label);

      // wrong count - throw string
      // BUG! Need less consuming way of reporting this. Maybe by
      // calling class object Method? Or by summoning something?
      c.emitString("arg count: "+name + " in " + s.get_class().getName());
      c.emitThrow();

      c.markLabel(good_args_label);
      	 */

      if (requestDebug) llc.emitDebug((byte) 0x1);
      // if(requestDebug) llc.emitDebug((byte)0x1,"Enabled debug");

      // push nulls to reserve stack space for autovars
      // BUG! We can execute vars initialization code here, can we?
      // We can if code does not depend on auto vars itself, or depends only on
      // previous ones.
      // 		for( int i = n_auto_vars; i > 0; i-- ) 			c.emitPushNull();

      // Reserve integer stack place for int vars 		for( int i = n_int_auto_vars; i > 0; i-- )
      //	c.emitIConst_0();

      // ------------------------------------------

      // ------------------------------------------
      // generate main code by descending the tree
      // ------------------------------------------
      code.generateLlvmCode(llc);
      // ------------------------------------------

      // ------------------------------------------
      // generate epilogue code here
      // ------------------------------------------

      // if(requestDebug) c.emitDebug((byte)0x2,"Disabled debug");
      if (requestDebug) llc.emitDebug((byte) 0x2);
    }

    // catch the fall-out
    llc.putln("ret " + llc.getObjectType() + " <{ i8* null, i8* null }> ;"); // empty function code
    llc.putln("}"); // end of function

    // ------------------------------------------
    // Part of code is generated to the buffer to
    // be emitted after the method code. Flush it
    // now.
    // ------------------------------------------

    llc.flushPostponedCode();
  }