private void build_boilerplate(ClassWriter cw) {
    String classname = "SVDBPersistenceDelegate";
    String full_classname = transform_cls(fTargetPkg) + "/" + classname;

    cw.visit(
        Opcodes.V1_5,
        ACC_PROTECTED + ACC_PUBLIC + ACC_SUPER,
        full_classname,
        null,
        fBaseClass,
        null);
    cw.visitSource(classname + ".java", null);

    MethodVisitor mv;

    // Constructor
    mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, fBaseClass, "<init>", "()V");
    mv.visitInsn(RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();

    buildItemDispatchMethods(cw);
    buildObjectDispatchMethods(cw);
  }
  public void startScript(StaticScope scope) {
    classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);

    // Create the class with the appropriate class name and source file
    classWriter.visit(
        javaVersion == null ? RubyInstanceConfig.JAVA_VERSION : javaVersion,
        ACC_PUBLIC + ACC_SUPER,
        getClassname(),
        null,
        p(AbstractScript.class),
        null);

    // add setPosition impl, which stores filename as constant to speed updates
    SkinnyMethodAdapter method =
        new SkinnyMethodAdapter(
            getClassVisitor(),
            ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
            "setPosition",
            sig(Void.TYPE, params(ThreadContext.class, int.class)),
            null,
            null);
    method.start();

    method.aload(0); // thread context
    method.ldc(sourcename);
    method.iload(1); // line number
    method.invokevirtual(
        p(ThreadContext.class), "setFileAndLine", sig(void.class, String.class, int.class));
    method.voidreturn();
    method.end();

    topLevelScope = scope;

    beginInit();

    cacheCompiler = OptoFactory.newCacheCompiler(this);

    // This code was originally used to provide debugging info using JSR-45
    // "SMAP" format. However, it breaks using normal Java traces to
    // generate Ruby traces, since the original path is lost. Reverting
    // to full path for now.
    //        String sourceNoPath;
    //        if (sourcename.indexOf("/") >= 0) {
    //            String[] pathElements = sourcename.split("/");
    //            sourceNoPath = pathElements[pathElements.length - 1];
    //        } else if (sourcename.indexOf("\\") >= 0) {
    //            String[] pathElements = sourcename.split("\\\\");
    //            sourceNoPath = pathElements[pathElements.length - 1];
    //        } else {
    //            sourceNoPath = sourcename;
    //        }

    final File sourceFile = new File(getSourcename());
    // Revert to using original sourcename here, so that jitted traces match
    // interpreted traces.
    classWriter.visitSource(sourcename, sourceFile.getAbsolutePath());
  }
Exemplo n.º 3
0
  public Class<?> createWrapper(Method callback) {
    ClassWriter cw = new ClassWriter(0);
    MethodVisitor mv;

    String name = getUniqueName(callback);
    String desc = name.replace('.', '/');
    String instType = Type.getInternalName(callback.getDeclaringClass());
    String eventType = Type.getInternalName(callback.getParameterTypes()[0]);

    /*
    System.out.println("Name:     " + name);
    System.out.println("Desc:     " + desc);
    System.out.println("InstType: " + instType);
    System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback));
    System.out.println("Event:    " + eventType);
    */

    cw.visit(
        V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[] {HANDLER_DESC});

    cw.visitSource(".dynamic", null);
    {
      cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd();
    }
    {
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;");
      mv.visitInsn(RETURN);
      mv.visitMaxs(2, 2);
      mv.visitEnd();
    }
    {
      mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;");
      mv.visitTypeInsn(CHECKCAST, instType);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitTypeInsn(CHECKCAST, eventType);
      mv.visitMethodInsn(
          INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback));
      mv.visitInsn(RETURN);
      mv.visitMaxs(2, 2);
      mv.visitEnd();
    }
    cw.visitEnd();
    return LOADER.define(name, cw.toByteArray());
  }
Exemplo n.º 4
0
 protected static ClassWriter createClassWriter(String internalName, AccessorType accessorType) {
   ClassWriter classWriter =
       new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
   classWriter.visit(
       V1_6,
       ACC_PUBLIC + ACC_SUPER,
       internalName,
       null,
       "java/lang/Object",
       new String[] {getInternalName(accessorType.getAccessorType().getName())});
   classWriter.visitSource(getExternalName(internalName), null);
   return classWriter;
 }
    public static byte[] dump() throws Exception {

      ClassWriter cw = new ClassWriter(0);
      MethodVisitor mv;

      cw.visit(52, ACC_PUBLIC + ACC_SUPER, "DummyBundleClass", null, "java/lang/Object", null);

      cw.visitSource("DummyBundleClass.java", null);

      {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLineNumber(1, l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "LDummyBundleClass;", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
      }
      {
        mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLineNumber(4, l0);
        mv.visitInsn(RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("args", "[Ljava/lang/String;", null, l0, l1, 0);
        mv.visitMaxs(0, 1);
        mv.visitEnd();
      }
      cw.visitEnd();

      return cw.toByteArray();
    }
Exemplo n.º 6
0
  private static byte[] compileBytes(
      Rule rule,
      Class helperClass,
      String helperName,
      String compiledHelperName,
      boolean compileToBytecode)
      throws Exception {
    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;
    MethodVisitor mv;
    AnnotationVisitor av0;
    // create the class as a subclass of the rule helper class, appending Compiled to the front
    // of the class name and a unique number to the end of the class helperName
    // also ensure it implements the HelperAdapter interface
    //
    // public class foo.bar.Compiled_<helper>_<NNN> extends foo.bar.<helper> implements
    // HelperAdapter

    cw.visit(
        V1_5,
        ACC_PUBLIC + ACC_SUPER,
        compiledHelperName,
        null,
        helperName,
        new String[] {"org/jboss/byteman/rule/helper/HelperAdapter"});
    // we need to install the source file name
    {
      String fullFileName = rule.getFile();
      int idx = fullFileName.lastIndexOf(java.io.File.separatorChar);
      String basicFileName = (idx < 0 ? fullFileName : fullFileName.substring(idx + 1));
      String debug = "// compiled from: " + fullFileName + "\n// generated by Byteman\n";
      cw.visitSource(basicFileName, debug);
    }
    {
      // we need a Hashmap field to hold the bindings
      //
      // private HashMap<String, Object> bindingMap;

      fv =
          cw.visitField(
              ACC_PRIVATE,
              "bindingMap",
              "Ljava/util/HashMap;",
              "Ljava/util/HashMap<Ljava/lang/String;Ljava/lang/Object;>;",
              null);
      fv.visitEnd();
    }
    {
      // and a rule field to hold the rule
      //
      // private Rule rule;

      fv =
          cw.visitField(
              ACC_PRIVATE,
              "rule",
              "Lorg/jboss/byteman/rule/Rule;",
              "Lorg/jboss/byteman/rule/Rule;",
              null);
      fv.visitEnd();
    }
    {
      // we need a constructor which takes a Rule as argument
      // if the helper implements a constructor which takes a Rule as argument then we invoke it
      // otherwise we invoke the empty helper constructor

      Constructor superConstructor = null;
      try {
        superConstructor = helperClass.getDeclaredConstructor(Rule.class);
      } catch (NoSuchMethodException e) {
        // hmm, ok see if there is an empty constructor
      } catch (SecurityException e) {
        throw new CompileException(
            "Compiler.compileBytes : unable to access constructor for helper class "
                + helperClass.getCanonicalName());
      }
      boolean superWantsRule = (superConstructor != null);
      if (!superWantsRule) {
        try {
          superConstructor = helperClass.getDeclaredConstructor();
        } catch (NoSuchMethodException e) {
          throw new CompileException(
              "Compiler.compileBytes : no valid constructor found for helper class "
                  + helperClass.getCanonicalName());
        } catch (SecurityException e) {
          throw new CompileException(
              "Compiler.compileBytes : unable to access constructor for helper class "
                  + helperClass.getCanonicalName());
        }
      }
      //
      //  public Compiled<helper>_<NNN>()Rule rule)
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V", null, null);
      mv.visitCode();
      // super();
      //
      // or
      //
      // super(Rule);
      if (superWantsRule) {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V");
      } else {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "()V");
      }
      // bindingMap = new HashMap<String, Object);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitTypeInsn(NEW, "java/util/HashMap");
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V");
      mv.visitFieldInsn(PUTFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
      // this.rule = rule
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitFieldInsn(PUTFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      // return;
      mv.visitInsn(RETURN);
      mv.visitMaxs(3, 2);
      mv.visitEnd();
    }
    {
      // create the execute method
      //
      // public void execute(Bindings bindings, Object recipient, Object[] args) throws
      // ExecuteException
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "execute",
              "(Ljava/lang/Object;[Ljava/lang/Object;)V",
              null,
              new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
      mv.visitCode();
      // if (Transformer.isVerbose())
      mv.visitMethodInsn(INVOKESTATIC, "org/jboss/byteman/agent/Transformer", "isVerbose", "()Z");
      Label l0 = new Label();
      mv.visitJumpInsn(IFEQ, l0);
      // then
      // System.out.println(rule.getName() + " execute");
      mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
      mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
      mv.visitLdcInsn(" execute()");
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
      mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
      // end if
      mv.visitLabel(l0);

      Bindings bindings = rule.getBindings();
      Iterator<Binding> iterator = bindings.iterator();

      while (iterator.hasNext()) {
        Binding binding = iterator.next();
        String name = binding.getName();
        if (binding.isAlias()) {
          // lookups and updates will use the aliased name
          continue;
        }
        if (binding.isHelper()) {
          // bindingMap.put(name, this);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
          mv.visitLdcInsn(name);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitMethodInsn(
              INVOKEVIRTUAL,
              "java/util/HashMap",
              "put",
              "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
          mv.visitInsn(POP);
        } else if (binding.isRecipient()) {
          // bindingMap.put(name, recipient);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
          mv.visitLdcInsn(name);
          mv.visitVarInsn(ALOAD, 1);
          mv.visitMethodInsn(
              INVOKEVIRTUAL,
              "java/util/HashMap",
              "put",
              "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
          mv.visitInsn(POP);
          // } else if (binding.isParam() || binding.isLocalVar() || binding.isReturn() ||
          //             binding.isThrowable() || binding.isParamCount() || binding.isParamArray())
          // {
        } else if (!binding.isBindVar()) {
          // bindingMap.put(name, args[binding.getCallArrayIndex()]);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
          mv.visitLdcInsn(name);
          mv.visitVarInsn(ALOAD, 2);
          mv.visitLdcInsn(binding.getCallArrayIndex());
          mv.visitInsn(AALOAD);
          mv.visitMethodInsn(
              INVOKEVIRTUAL,
              "java/util/HashMap",
              "put",
              "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
          mv.visitInsn(POP);
        }
      }

      // execute0()
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKEVIRTUAL, compiledHelperName, "execute0", "()V");

      // now restore update bindings

      iterator = bindings.iterator();

      while (iterator.hasNext()) {
        Binding binding = iterator.next();
        if (binding.isAlias()) {
          continue;
        }
        String name = binding.getName();

        if (binding.isUpdated()) {
          // if (binding.isParam() || binding.isLocalVar() || binding.isReturn()) {
          if (!binding.isBindVar()) {
            int idx = binding.getCallArrayIndex();
            // Object value = bindingMap.get(name);
            // args[idx] = value;
            mv.visitVarInsn(ALOAD, 2); // args
            mv.visitLdcInsn(idx);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
            mv.visitLdcInsn(name);
            mv.visitMethodInsn(
                INVOKEVIRTUAL,
                "java/util/HashMap",
                "get",
                "(Ljava/lang/Object;)Ljava/lang/Object;");
            mv.visitInsn(AASTORE);
          }
        }
      }

      // return
      mv.visitInsn(RETURN);
      mv.visitMaxs(4, 3);
      mv.visitEnd();
    }
    {
      // create the setBinding method
      //
      // public void setBinding(String name, Object value)
      mv =
          cw.visitMethod(
              ACC_PUBLIC, "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
      mv.visitCode();
      //  bindingMap.put(name, value);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/util/HashMap",
          "put",
          "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
      mv.visitInsn(POP);
      // return
      mv.visitInsn(RETURN);
      mv.visitMaxs(3, 3);
      mv.visitEnd();
    }
    {
      // create the getBinding method
      //
      // public Object getBinding(String name)
      mv =
          cw.visitMethod(
              ACC_PUBLIC, "getBinding", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);
      mv.visitCode();
      // {TOS} <== bindingMap.get(name);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(2, 2);
      mv.visitEnd();
    }
    {
      // create the getName method
      //
      // public String getName()
      mv = cw.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null);
      mv.visitCode();
      // {TOS} <== rule.getName()
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(1, 1);
      mv.visitEnd();
    }
    // create the getAccessibleField method
    //
    // public Object getAccessibleField(Object owner, int fieldIndex)
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "getAccessibleField",
              "(Ljava/lang/Object;I)Ljava/lang/Object;",
              null,
              null);
      mv.visitCode();
      // {TOS} <== rule.getAccessibleField(owner, fieldIndex);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ILOAD, 2);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "org/jboss/byteman/rule/Rule",
          "getAccessibleField",
          "(Ljava/lang/Object;I)Ljava/lang/Object;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(3, 3);
      mv.visitEnd();
    }

    // create the setAccessibleField method
    //
    // public void setAccessibleField(Object owner, Object value, int fieldIndex)
    // rule.setAccessibleField(owner, value, fieldIndex);
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "setAccessibleField",
              "(Ljava/lang/Object;Ljava/lang/Object;I)V",
              null,
              null);
      mv.visitCode();
      // rule.setAccessibleField(owner, value, fieldIndex);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitVarInsn(ILOAD, 3);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "org/jboss/byteman/rule/Rule",
          "setAccessibleField",
          "(Ljava/lang/Object;Ljava/lang/Object;I)V");
      // return
      mv.visitInsn(RETURN);
      mv.visitMaxs(4, 4);
      mv.visitEnd();
    }

    // create the invokeAccessibleMethod method
    //
    // public Object invokeAccessibleMethod(Object target, Object[] args, int methodIndex)
    // {TOS} <==  rule.invokeAccessibleMethod(target, args, methodIndex);
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "invokeAccessibleMethod",
              "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;",
              null,
              null);
      mv.visitCode();
      // rule.invokeAccessibleMethod(target, args, fieldIndex);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitVarInsn(ILOAD, 3);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "org/jboss/byteman/rule/Rule",
          "invokeAccessibleMethod",
          "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(4, 4);
      mv.visitEnd();
    }
    if (compileToBytecode) {
      // we generate a single execute0 method if we want to run compiled and get
      // the event, condiiton and action to insert the relevant bytecode to implement
      // bind(), test() and fire()

      {
        // create the execute0() method
        //
        // private void execute0()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "execute0",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        CompileContext compileContext = new CompileContext(mv);
        // make sure we set the first line number before generating any code
        compileContext.notifySourceLine(rule.getLine());
        compileContext.addLocalCount(3); // for this and 2 object args
        // bind();
        rule.getEvent().compile(mv, compileContext);
        // if (test())
        rule.getCondition().compile(mv, compileContext);
        Label l0 = new Label();
        mv.visitJumpInsn(IFEQ, l0);
        compileContext.addStackCount(-1);
        // then
        rule.getAction().compile(mv, compileContext);
        // fire();
        // end if
        mv.visitLabel(l0);
        // this will match the ENDRULE line
        compileContext.notifySourceEnd();
        // return
        mv.visitInsn(RETURN);
        // need to specify correct Maxs values
        mv.visitMaxs(compileContext.getStackMax(), compileContext.getLocalMax());
        mv.visitEnd();
      }
    } else {
      // we generate the following methods if we want to run interpreted
      {
        // create the execute0() method
        //
        // private void execute0()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "execute0",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // bind();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "bind", "()V");
        // if (test())
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "test", "()Z");
        Label l0 = new Label();
        mv.visitJumpInsn(IFEQ, l0);
        // then
        // fire();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "fire", "()V");
        // end if
        mv.visitLabel(l0);
        // return
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
      }
      {
        // create the bind method
        //
        // private void bind()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "bind",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // rule.getEvent().interpret(this);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Rule",
            "getEvent",
            "()Lorg/jboss/byteman/rule/Event;");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Event",
            "interpret",
            "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;");
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
      }
      {
        // create the test method
        //
        // private boolean test()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "test",
                "()Z",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // {TOS} <== rule.getCondition().interpret(this);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Rule",
            "getCondition",
            "()Lorg/jboss/byteman/rule/Condition;");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Condition",
            "interpret",
            "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;");
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean");
        // unbox the returned Boolean
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
        // return {TOS}
        mv.visitInsn(IRETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
      }
      {
        // create the fire method
        //
        // private void fire()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "fire",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // rule.getAction().interpret(this);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Rule",
            "getAction",
            "()Lorg/jboss/byteman/rule/Action;");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Action",
            "interpret",
            "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;");
        // return
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
      }
    }

    cw.visitEnd();

    return cw.toByteArray();
  }
Exemplo n.º 7
0
  @Override
  public Object visitProgram(Program program, Object arg) throws Exception {
    className = program.JVMName;
    classDescriptor = 'L' + className + ';';
    cw.visit(
        52, // version
        ACC_PUBLIC + ACC_SUPER, // access codes
        className, // fully qualified classname
        null, // signature
        "java/lang/Object", // superclass
        new String[] {"cop5555sp15/Codelet"} // implemented interfaces
        );
    cw.visitSource(null, null); // maybe replace first argument with source
    // file name

    // create init method
    {
      MethodVisitor mv;
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitLineNumber(3, l0);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
      mv.visitInsn(RETURN);
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitLocalVariable("this", classDescriptor, null, l0, l1, 0);
      mv.visitMaxs(1, 1);
      mv.visitEnd();
    }

    // generate the execute method
    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC,
            "execute", // name of top
            // level
            // method
            "()V", // descriptor: this method is parameterless with no
            // return value
            null, // signature.  This is null for us, it has to do with generic types
            null // array of strings containing exceptions
            );
    mv.visitCode();
    Label lbeg = new Label();
    mv.visitLabel(lbeg);
    mv.visitLineNumber(program.firstToken.lineNumber, lbeg);
    program.block.visit(this, new InheritedAttributes(mv));
    mv.visitInsn(RETURN);
    Label lend = new Label();
    mv.visitLabel(lend);
    mv.visitLocalVariable("this", classDescriptor, null, lbeg, lend, 0);
    mv.visitMaxs(0, 0); // this is required just before the end of a method.
    // It causes asm to calculate information about the
    // stack usage of this method.
    mv.visitEnd();

    cw.visitEnd();
    return cw.toByteArray();
  }