private static void catchBody(
      BytecodeContext bc,
      GeneratorAdapter adapter,
      Catch ct,
      int pe,
      int lRef,
      boolean caugth,
      boolean store)
      throws BytecodeException {
    // pc.setCatch(pe,true);
    adapter.loadArg(0);
    adapter.loadLocal(pe);
    adapter.push(caugth);
    adapter.push(store);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.SET_CATCH3);

    // ref=
    ct.name.writeOut(bc, Expression.MODE_REF);
    adapter.storeLocal(lRef);

    adapter.loadLocal(lRef);
    adapter.loadArg(0);
    adapter.loadLocal(pe); // (...,pe.getCatchBlock(pc))
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_EXCEPTION, GET_CATCH_BLOCK);
    adapter.invokeInterface(Types.REFERENCE, SET);
    adapter.pop();

    ct.body.writeOut(bc);
  }
Beispiel #2
0
  public static void main(final String args[]) throws Exception {

    // Generates the bytecode corresponding to the following Java class:
    //
    // public class Example {
    // public static void main (String[] args) {
    // System.out.println("Hello world!");
    // }
    // }

    // creates a ClassWriter for the Example public class,
    // which inherits from Object
    ClassWriter cw = new ClassWriter(0);
    cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

    // creates a MethodWriter for the (implicit) constructor
    MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    // pushes the 'this' variable
    mw.visitVarInsn(ALOAD, 0);
    // invokes the super class constructor
    mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
    mw.visitInsn(RETURN);
    // this code uses a maximum of one stack element and one local variable
    mw.visitMaxs(1, 1);
    mw.visitEnd();

    // creates a MethodWriter for the 'main' method
    mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
    // pushes the 'out' field (of type PrintStream) of the System class
    mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
    // pushes the "Hello World!" String constant
    mw.visitLdcInsn("Hello world!");
    // invokes the 'println' method (defined in the PrintStream class)
    mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
    mw.visitInsn(RETURN);
    // this code uses a maximum of two stack elements and two local
    // variables
    mw.visitMaxs(2, 2);
    mw.visitEnd();

    // gets the bytecode of the Example class, and loads it dynamically
    byte[] code = cw.toByteArray();

    FileOutputStream fos = new FileOutputStream("Example.class");
    fos.write(code);
    fos.close();

    Helloworld loader = new Helloworld();
    Class<?> exampleClass = loader.defineClass("Example", code, 0, code.length);

    // uses the dynamically generated class to print 'Helloworld'
    exampleClass.getMethods()[0].invoke(null, new Object[] {null});

    // ------------------------------------------------------------------------
    // Same example with a GeneratorAdapter (more convenient but slower)
    // ------------------------------------------------------------------------

    cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

    // creates a GeneratorAdapter for the (implicit) constructor
    Method m = Method.getMethod("void <init> ()");
    GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
    mg.loadThis();
    mg.invokeConstructor(Type.getType(Object.class), m);
    mg.returnValue();
    mg.endMethod();

    // creates a GeneratorAdapter for the 'main' method
    m = Method.getMethod("void main (String[])");
    mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
    mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
    mg.push("Hello world!");
    mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println (String)"));
    mg.returnValue();
    mg.endMethod();

    cw.visitEnd();

    code = cw.toByteArray();
    loader = new Helloworld();
    exampleClass = loader.defineClass("Example", code, 0, code.length);

    // uses the dynamically generated class to print 'Helloworld'
    exampleClass.getMethods()[0].invoke(null, new Object[] {null});
  }
  private void _writeOutCatch(BytecodeContext bc, int lRef, int lThrow) throws BytecodeException {
    GeneratorAdapter adapter = bc.getAdapter();
    int pe = adapter.newLocal(Types.PAGE_EXCEPTION);

    // instance of Abort
    Label abortEnd = new Label();
    adapter.loadLocal(lThrow);
    adapter.invokeStatic(Types.ABORT, TryCatchFinally.IS_ABORT);
    // adapter.instanceOf(Types.ABORT);
    adapter.ifZCmp(Opcodes.IFEQ, abortEnd);
    adapter.loadLocal(lThrow);
    adapter.throwException();
    adapter.visitLabel(abortEnd);

    // PageExceptionImpl old=pc.getCatch();
    int old = adapter.newLocal(Types.PAGE_EXCEPTION);
    adapter.loadArg(0);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.GET_CATCH);
    adapter.storeLocal(old);

    // cast to PageException  Caster.toPagException(t);
    adapter.loadLocal(lThrow);
    adapter.invokeStatic(Types.CASTER, TO_PAGE_EXCEPTION);

    // PageException pe=...
    adapter.storeLocal(pe);

    // catch loop
    Label endAllIf = new Label();
    Iterator<Catch> it = catches.iterator();
    Catch ctElse = null;
    while (it.hasNext()) {
      Catch ct = it.next();
      // store any for else
      if (ct.type != null
          && ct.type instanceof LitString
          && ((LitString) ct.type).getString().equalsIgnoreCase("any")) {
        ctElse = ct;
        continue;
      }

      ExpressionUtil.visitLine(bc, ct.line);

      // pe.typeEqual(type)
      if (ct.type == null) {
        LitBoolean.TRUE.writeOut(bc, Expression.MODE_VALUE);
      } else {
        adapter.loadLocal(pe);
        ct.type.writeOut(bc, Expression.MODE_REF);
        adapter.invokeVirtual(Types.PAGE_EXCEPTION, TYPE_EQUAL);
      }

      Label endIf = new Label();
      adapter.ifZCmp(Opcodes.IFEQ, endIf);

      catchBody(bc, adapter, ct, pe, lRef, true, true);

      adapter.visitJumpInsn(Opcodes.GOTO, endAllIf);
      adapter.visitLabel(endIf);
    }

    if (ctElse != null) {
      catchBody(bc, adapter, ctElse, pe, lRef, true, true);
    } else {
      // pc.setCatch(pe,true);
      adapter.loadArg(0);
      adapter.loadLocal(pe);
      adapter.push(false);
      adapter.push(false);
      adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.SET_CATCH3);

      adapter.loadLocal(pe);
      adapter.throwException();
    }
    adapter.visitLabel(endAllIf);

    // PageExceptionImpl old=pc.setCatch(old);
    adapter.loadArg(0);
    adapter.loadLocal(old);
    adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.SET_CATCH_PE);
  }
Beispiel #4
0
 public static void invokeMethod(GeneratorAdapter adapter, Type type, Method method) {
   if (type.getClass().isInterface()) adapter.invokeInterface(type, method);
   else adapter.invokeVirtual(type, method);
 }
  @Override
  public Type load(Context ctx) {
    GeneratorAdapter g = ctx.getGeneratorAdapter();

    owner.load(ctx);

    List<Class<?>> argumentClasses = new ArrayList<>();
    List<Type> argumentTypes = new ArrayList<>();
    for (Expression argument : arguments) {
      argument.load(ctx);
      argumentTypes.add(argument.type(ctx));
      argumentClasses.add(getJavaType(ctx.getClassLoader(), argument.type(ctx)));
    }

    Type returnType;
    try {
      if (ctx.getThisType().equals(owner.type(ctx))) {
        org.objectweb.asm.commons.Method method = null;
        for (org.objectweb.asm.commons.Method m : ctx.getMethods().keySet()) {
          if (m.getName().equals(methodName)) {
            if (m.getArgumentTypes().length == arguments.size()) {
              Type[] methodTypes = m.getArgumentTypes();
              boolean isSame = true;
              for (int i = 0; i < arguments.size(); i++) {
                if (!methodTypes[i].equals(argumentTypes.get(i))) {
                  isSame = false;
                  break;
                }
              }
              if (isSame) {
                method = m;
                break;
              }
            }
          }
        }
        if (method == null) throw new NoSuchMethodException();
        g.invokeVirtual(owner.type(ctx), method);
        return method.getReturnType();
      }
      Class<?> ownerJavaType = getJavaType(ctx.getClassLoader(), owner.type(ctx));
      Method method =
          ownerJavaType.getMethod(methodName, argumentClasses.toArray(new Class<?>[] {}));
      Class<?> returnClass = method.getReturnType();
      returnType = getType(returnClass);

      invokeVirtualOrInterface(
          g,
          ownerJavaType,
          new org.objectweb.asm.commons.Method(
              methodName, returnType, argumentTypes.toArray(new Type[] {})));

    } catch (NoSuchMethodException e) {
      throw new RuntimeException(
          format(
              "No method %s.%s(%s). %s",
              owner.type(ctx).getClassName(),
              methodName,
              (!argumentClasses.isEmpty() ? argsToString(argumentClasses) : ""),
              exceptionInGeneratedClass(ctx)));
    }
    return returnType;
  }
Beispiel #6
0
 public static Type invokeScope(GeneratorAdapter adapter, Method m, Type type) {
   if (type == null) type = Types.PAGE_CONTEXT;
   adapter.invokeVirtual(type, m);
   return m.getReturnType();
 }