@Override
  public void parse(
      final BytecodeArtifact bytecodeArtifact, final IPathResolver directoryResolver) {
    assert null != bytecodeArtifact
        : "Parameter 'bytecodeArtifact' of method 'parse' must not be null";

    /** (1) */
    final ClassReader cr = new ClassReader(bytecodeArtifact.getBytesOriginal());

    /** (2) */
    // cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
    final ClassWriter cw = new ClassWriter(cr, 0);

    /** (3) */
    final ASMClassInstrumentor ca = constructSelf(cw);

    /** (4) */
    cr.accept(ca, ClassReader.EXPAND_FRAMES);

    assert null != ca : "'ca' of method 'parse' must not be null";
    assert null != cw : "'cw' of method 'parse' must not be null";

    final String fileAbsolutePath = bytecodeArtifact.absolutePath();
    this.benchmark.addBytecodeArtificatAnalysed(
        ca.className,
        cw.toByteArray(),
        fileAbsolutePath,
        directoryResolver,
        bytecodeArtifact.isClassFile(),
        this.isInterface);
  }
Exemple #2
0
  public static void main(String[] args)
      throws NoSuchMethodException, SecurityException, IllegalArgumentException,
          InvocationTargetException {
    try {
      ClassReader classReader = new ClassReader("com/asm/Before_Demo1");
      ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);

      ClassAdapter ca = new AopClassAdapter(cw);

      classReader.accept(ca, ClassReader.SKIP_DEBUG);

      byte[] byteArray = cw.toByteArray();

      MyClassLoader myClassLoader = new MyClassLoader();
      Class<?> clazz = myClassLoader.myDefineClass(byteArray, "com.asm.Before_Demo1");
      Method method = clazz.getMethod("sayHello");
      method.invoke(clazz.newInstance());

    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (InstantiationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
Exemple #3
0
 public static byte[] getBytesFromClassNode(ClassNode c) {
   ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
   c.accept(w);
   byte[] b = w.toByteArray();
   SquidAPIPlugin.LOGGER.info("Successfully transformed " + c.name.replace("/", "."), ".");
   return b;
 }
  /**
   * Generates interface class using collection of rules.
   *
   * @param className name of result class
   * @param rules collection of rules what will be used as interface methods
   * @param classLoader class loader what will be used to load generated interface
   * @return generated interface
   * @throws Exception if an error has occurred
   */
  public static Class<?> generateInterface(
      String className, RuleInfo[] rules, ClassLoader classLoader) throws Exception {

    ClassWriter classWriter = new ClassWriter(0);

    String name = className.replace('.', '/');

    classWriter.visit(Opcodes.V1_5, PUBLIC_ABSTRACT_INTERFACE, name, null, JAVA_LANG_OBJECT, null);

    for (RuleInfo ruleInfo : rules) {

      String ruleName = ruleInfo.getName();
      classWriter.visitMethod(PUBLIC_ABSTRACT, ruleName, getMethodTypes(ruleInfo), null, null);
    }

    classWriter.visitEnd();

    // Create class object.
    //
    ReflectUtils.defineClass(className, classWriter.toByteArray(), classLoader);

    // Return loaded to classpath class object.
    //
    return Class.forName(className, true, classLoader);
  }
 public void test() throws Exception {
   ClassWriter cw = new ClassWriter(0);
   CheckClassAdapter ca = new CheckClassAdapter(cw);
   ClassVisitor cv = getClassAdapter(ca);
   generateBasicClass(cv);
   checkClass(defineClass("C", cw.toByteArray()));
 }
  public void toAsm(JarOutputStream jos) {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    //        ClassWriter cw = new ClassWriter(0);
    CheckClassAdapter cca = new CheckClassAdapter(cw);

    cca.visit(version, access, name, sig, superName, interfaces);
    Iterator it = fieldVisitors.entrySet().iterator();

    while (it.hasNext()) {
      Map.Entry pairs = (Map.Entry) it.next();
      ByteCodeFieldVisitor fv = (ByteCodeFieldVisitor) pairs.getValue();
      fv.toAsm(cca);
    }

    it = methodVisitors.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry pairs = (Map.Entry) it.next();
      ByteCodeMethodVisitor mv = (ByteCodeMethodVisitor) pairs.getValue();
      mv.toAsm(cca);
    }

    byte[] bytes = cw.toByteArray();
    if (ProjectProperties.getBoolean("fortress.bytecode.verify", false)) {
      PrintWriter pw = new PrintWriter(System.out);
      CheckClassAdapter.verify(new ClassReader(bytes), true, pw);
    }
    System.out.println("About to write " + name);
    ByteCodeWriter.writeJarredClass(jos, name, bytes);
  }
    public Class<? extends T> generate() {
      visitor.visitEnd();

      byte[] bytecode = visitor.toByteArray();
      return DEFINE_CLASS_METHOD.invoke(
          type.getClassLoader(), typeName, bytecode, 0, bytecode.length);
    }
  /**
   * Chain together a ClassReader than will read the given class and a ClassWriter to write out a
   * new class with an adapter in the middle to add annotations
   *
   * @param fromName the name of the class we're coming from
   */
  private static void adaptClass(String fromName) {
    if (VERBOSE) System.out.println("Adding annotations to class: " + fromName);

    // gets an input stream to read the bytecode of the class
    String resource = fromName.replace('.', '/') + ".class";
    InputStream is = BootstrapClassLoader.getBootstrapClassLoader().getResourceAsStream(resource);
    byte[] b;

    // adapts the class on the fly
    try {
      ClassReader cr = new ClassReader(is);
      ClassWriter cw = new ClassWriter(0);
      ClassVisitor cv = new AddAnnotationClassAdapter(cw, fromName);
      cr.accept(cv, 0);
      b = cw.toByteArray();
    } catch (Exception e) {
      throw new Error("Couldn't find class " + fromName + " (" + resource + ")", e);
    }

    // store the adapted class on disk
    try {
      File file = new File(destinationDir + resource);
      new File(file.getParent()).mkdirs(); // ensure we have a directory to write to
      FileOutputStream fos = new FileOutputStream(file);
      fos.write(b);
      fos.close();
    } catch (Exception e) {
      throw new Error("Error writing to " + destinationDir + resource + " to disk", e);
    }
  }
    @SuppressWarnings("unused")
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
      try {
        return super.findClass(name);
      } catch (ClassNotFoundException e) {

        byte[] def = mClassDefs.get(name);
        if (def != null) {
          // Load the modified ClassWithNative from its bytes representation.
          return defineClass(name, def, 0, def.length);
        }

        try {
          // Load everything else from the original definition into the new class loader.
          ClassReader cr = new ClassReader(name);
          ClassWriter cw = new ClassWriter(0);
          cr.accept(cw, 0);
          byte[] bytes = cw.toByteArray();
          return defineClass(name, bytes, 0, bytes.length);

        } catch (IOException ioe) {
          throw new RuntimeException(ioe);
        }
      }
    }
  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);
  }
Exemple #11
0
  private static byte[] visitEnd() {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, RubyIDClassName, null, "java/lang/Object", null);
    Method staticBlock = Method.getMethod("void <clinit> ()V");
    GeneratorAdapter staticBlockMg =
        new GeneratorAdapter(Opcodes.ACC_STATIC, staticBlock, null, null, cw);

    for (Map.Entry<String, String> e : idMap.entrySet()) {
      cw.visitField(
          Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
          e.getValue(),
          Types.RUBY_ID_TYPE.getDescriptor(),
          null,
          null);

      staticBlockMg.push(e.getKey());
      staticBlockMg.invokeStatic(
          Type.getType(RubyID.class),
          Method.getMethod("com.xruby.runtime.lang.RubyID intern(String)"));
      staticBlockMg.putStatic(
          Type.getType("L" + RubyIDClassName + ";"), e.getValue(), Types.RUBY_ID_TYPE);
    }

    staticBlockMg.returnValue();
    staticBlockMg.endMethod();
    cw.visitEnd();

    return cw.toByteArray();
  }
  @Override
  public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (transformedName.equals("net.minecraft.block.BlockDynamicLiquid")
        && CoreLoadingPlugin.util.getBoolean("FiniteWater", false)) {
      ClassReader reader = new ClassReader(bytes);
      ClassNode node = new ClassNode();
      reader.accept(node, 0);
      InsnList getSmallestFlowDecay = new InsnList();

      getSmallestFlowDecay.add(new VarInsnNode(ALOAD, 0));
      getSmallestFlowDecay.add(new InsnNode(ICONST_0));
      getSmallestFlowDecay.add(
          new FieldInsnNode(
              PUTFIELD, "net/minecraft/block/BlockDynamicLiquid", "field_149815_a", "I"));

      for (MethodNode method : node.methods)
        if ("func_149810_a"
            .equals(
                FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(name, method.name, method.desc)))
          method.instructions.insertBefore(method.instructions.getFirst(), getSmallestFlowDecay);

      ClassWriter writer = new ClassWriter(0);
      node.accept(writer);
      return writer.toByteArray();
    }

    return bytes;
  }
  private static void transformIfNeccessary(File file) throws IOException {
    InputStream is = new FileInputStream(file);
    ClassNode cn;
    try {
      ClassReader cr = new ClassReader(is);
      cn = new ClassNode();
      cr.accept(cn, 0);
    } finally {
      is.close();
    }

    if (!isAlreadyTransformed(cn) && isAnnotationPresent(cn)) {
      System.out.println("Transforming file " + file);
      ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
      ClassVisitor ca = new CheckClassAdapter(cw);
      ClassVisitor cv = new PropertyChangeSupportAdapter(ca);
      cn.accept(cv);
      FileOutputStream os = new FileOutputStream(file);
      try {
        os.write(cw.toByteArray());
      } finally {
        os.close();
      }
    }
  }
Exemple #14
0
  private static Map<String, Class<?>> defineClasses(
      List<ClassDefinition> classDefinitions, DynamicClassLoader classLoader) {
    ClassInfoLoader classInfoLoader =
        ClassInfoLoader.createClassInfoLoader(classDefinitions, classLoader);

    if (DUMP_BYTE_CODE_TREE) {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      DumpByteCodeVisitor dumpByteCode = new DumpByteCodeVisitor(new PrintStream(out));
      for (ClassDefinition classDefinition : classDefinitions) {
        dumpByteCode.visitClass(classDefinition);
      }
      System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8));
    }

    Map<String, byte[]> byteCodes = new LinkedHashMap<>();
    for (ClassDefinition classDefinition : classDefinitions) {
      ClassWriter cw = new SmartClassWriter(classInfoLoader);
      classDefinition.visit(cw);
      byte[] byteCode = cw.toByteArray();
      if (RUN_ASM_VERIFIER) {
        ClassReader reader = new ClassReader(byteCode);
        CheckClassAdapter.verify(reader, classLoader, true, new PrintWriter(System.out));
      }
      byteCodes.put(classDefinition.getType().getJavaClassName(), byteCode);
    }

    String dumpClassPath = DUMP_CLASS_FILES_TO.get();
    if (dumpClassPath != null) {
      for (Map.Entry<String, byte[]> entry : byteCodes.entrySet()) {
        File file =
            new File(
                dumpClassPath,
                ParameterizedType.typeFromJavaClassName(entry.getKey()).getClassName() + ".class");
        try {
          log.debug("ClassFile: " + file.getAbsolutePath());
          Files.createParentDirs(file);
          Files.write(entry.getValue(), file);
        } catch (IOException e) {
          log.error(e, "Failed to write generated class file to: %s" + file.getAbsolutePath());
        }
      }
    }
    if (DUMP_BYTE_CODE_RAW) {
      for (byte[] byteCode : byteCodes.values()) {
        ClassReader classReader = new ClassReader(byteCode);
        classReader.accept(
            new TraceClassVisitor(new PrintWriter(System.err)), ClassReader.SKIP_FRAMES);
      }
    }
    Map<String, Class<?>> classes = classLoader.defineClasses(byteCodes);
    try {
      for (Class<?> clazz : classes.values()) {
        Reflection.initialize(clazz);
      }
    } catch (VerifyError e) {
      throw new RuntimeException(e);
    }
    return classes;
  }
 public void test() throws Exception {
   ClassWriter cw = new ClassWriter(0);
   CheckClassAdapter ca = new CheckClassAdapter(cw);
   RemoveAnnotationAdapter ra = new RemoveAnnotationAdapter(ca, "Ljava/lang/Deprecated;");
   AddAnnotationAdapter aa = new AddAnnotationAdapter(ra, "Ljava/lang/Deprecated;");
   generateBasicClass(aa);
   checkClass(defineClass("C", cw.toByteArray()));
 }
 public byte[] genEABytecode() throws Exception {
   byte[] bytecodes = null;
   if (createBody) {
     eaCW.visitEnd();
     bytecodes = eaCW.toByteArray();
   }
   return bytecodes;
 }
 @Override
 public byte[] transform(String className, String transformedClassName, byte[] bytes) {
   String methodName;
   if (className.equals(OBF_CLASS)) {
     methodName = SRG_METHOD;
   } else if (className.equals(MCP_CLASS)) {
     methodName = MCP_METHOD;
   } else {
     return bytes;
   }
   ClassNode classNode = new ClassNode();
   ClassReader classReader = new ClassReader(bytes);
   classReader.accept(classNode, 0);
   for (MethodNode method : classNode.methods) {
     if (method.name.equals(methodName) && method.desc.equals(METHOD_DESC)) {
       logger.info("CraftingTweaks will now patch {} in {}...", methodName, className);
       MethodNode mn = new MethodNode();
       Label notClicked = new Label();
       // mn.visitMethodInsn(Opcodes.INVOKESTATIC, "org/lwjgl/input/Mouse", "getEventButtonState",
       // "()Z", false);
       // mn.visitJumpInsn(Opcodes.IFEQ, notClicked); // if getEventButtonState false, continue
       // after
       mn.visitVarInsn(Opcodes.ILOAD, 1); // push mouseX
       mn.visitVarInsn(Opcodes.ILOAD, 2); // push mouseY
       mn.visitVarInsn(Opcodes.ILOAD, 3); // push button
       mn.visitMethodInsn(
           Opcodes.INVOKESTATIC,
           "net/blay09/mods/craftingtweaks/CraftingTweaks",
           "onGuiClick",
           "(III)Z",
           false); // call onGuiClick
       mn.visitJumpInsn(Opcodes.IFEQ, notClicked); // if onGuiClick false, continue after
       mn.visitInsn(Opcodes.RETURN); // otherwise stop here
       mn.visitLabel(notClicked); // continue from here
       AbstractInsnNode insertAfter = null;
       for (int i = 0; i < method.instructions.size(); i++) {
         AbstractInsnNode node = method.instructions.get(i);
         if (node instanceof VarInsnNode) {
           if (node.getOpcode() == Opcodes.ISTORE && ((VarInsnNode) node).var == 3) { // ISTORE 3
             insertAfter = node;
             break;
           }
         }
       }
       if (insertAfter != null) {
         method.instructions.insert(insertAfter, mn.instructions);
         logger.info("CraftingTweaks successfully patched {} in {}!", methodName, className);
       } else {
         logger.warn(
             "CraftingTweaks failed to patch {0}::{1} ({2} not found) - transfering into crafting grids will not work!",
             className, methodName, "ISTORE 3");
       }
     }
   }
   ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
   classNode.accept(writer);
   return writer.toByteArray();
 }
  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());
  }
  @Override
  public byte[] transform(String name, String transformedName, byte[] basicClass) {
    if (!"net.minecraft.item.ItemStack".equals(name)) return basicClass;
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);

    FieldNode itemField = null;
    for (FieldNode f : classNode.fields) {
      if (ITEM_TYPE.equals(f.desc) && itemField == null) {
        itemField = f;
      } else if (ITEM_TYPE.equals(f.desc)) {
        throw new RuntimeException("Error processing ItemStack - found a duplicate Item field");
      }
    }
    if (itemField == null) {
      throw new RuntimeException(
          "Error processing ItemStack - no Item field declared (is the code somehow obfuscated?)");
    }

    MethodNode getItemMethod = null;
    for (MethodNode m : classNode.methods) {
      if (GETITEM_DESC.equals(m.desc) && getItemMethod == null) {
        getItemMethod = m;
      } else if (GETITEM_DESC.equals(m.desc)) {
        throw new RuntimeException("Error processing ItemStack - duplicate getItem method found");
      }
    }
    if (getItemMethod == null) {
      throw new RuntimeException(
          "Error processing ItemStack - no getItem method found (is the code somehow obfuscated?)");
    }

    for (MethodNode m : classNode.methods) {
      for (ListIterator<AbstractInsnNode> it = m.instructions.iterator(); it.hasNext(); ) {
        AbstractInsnNode insnNode = it.next();
        if (insnNode.getType() == AbstractInsnNode.FIELD_INSN) {
          FieldInsnNode fi = (FieldInsnNode) insnNode;
          if (itemField.name.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD) {
            it.remove();
            MethodInsnNode replace =
                new MethodInsnNode(
                    Opcodes.INVOKEVIRTUAL,
                    "net/minecraft/item/ItemStack",
                    getItemMethod.name,
                    getItemMethod.desc,
                    false);
            it.add(replace);
          }
        }
      }
    }
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
  }
  private void build() {
    ClassWriter cw = new ClassWriter(0);
    final ClassLoader cl = getClass().getClassLoader();
    for (SVDBItemType t : SVDBItemType.values()) {
      Class cls = null;
      for (String pkg : fTargetPkgList) {
        try {
          cls = cl.loadClass(pkg + ".SVDB" + t.name());
        } catch (Exception e) {
        }

        if (cls != null) {
          break;
        }
      }

      if (cls != null) {
        // Found a class to process
        fTypeClassMap.put(t, cls);
      } else {
        System.out.println("Error: Failed to find item " + t.name());
      }
    }

    //		long start = System.currentTimeMillis();
    build_boilerplate(cw);

    for (SVDBItemType t : fTypeClassMap.keySet()) {
      Class cls = fTypeClassMap.get(t);
      buildItemAccessor(cw, t, cls);
    }

    for (Class c : fClassList) {
      buildObjectAccessor(cw, c);
    }

    cw.visitEnd();

    JITClassLoader jit_cl = new JITClassLoader(cl, cw.toByteArray());
    try {
      fDelegateCls =
          (Class<JITPersistenceDelegateBase>)
              jit_cl.loadClass(fTargetPkg + ".SVDBPersistenceDelegate");
    } catch (Exception e) {
      e.printStackTrace();
    }

    /*
    long end = System.currentTimeMillis();

    System.out.println("Class-build time: " + (end-start));
    System.out.println("Size: " + cw.toByteArray().length);
     */
  }
 protected Class findClass(String name) {
   ClassWriter writer = new ClassWriter(true);
   writer.visit(
       Constants.ACC_PUBLIC | Constants.ACC_INTERFACE,
       name.replace('.', '/'),
       "java/lang/Object",
       null,
       null);
   byte[] b = writer.toByteArray();
   return defineClass(name, b, 0, b.length);
 }
Exemple #22
0
  @Override
  public byte[] transform(String name, String transformedName, byte[] basicClass) {
    if (basicClass == null) return null;
    ClassReader reader = new ClassReader(basicClass);
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);

    ClassVisitor visitor = writer;
    visitor = new ExitVisitor(visitor);

    reader.accept(visitor, 0);
    return writer.toByteArray();
  }
  @Override
  public void compile(boolean result, IEnvironmentMethod environment) {
    if (!result) return;

    Method method = interfaceClass.getMethods()[0];

    // generate class
    String clsName = environment.makeClassName();

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    cw.visit(
        Opcodes.V1_6,
        Opcodes.ACC_PUBLIC,
        clsName,
        null,
        "java/lang/Object",
        new String[] {internal(interfaceClass)});

    MethodOutput constructor =
        new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    constructor.start();
    constructor.loadObject(0);
    constructor.invokeSpecial("java/lang/Object", "<init>", "()V");
    constructor.ret();
    constructor.end();

    MethodOutput output =
        new MethodOutput(cw, Opcodes.ACC_PUBLIC, method.getName(), descriptor(method), null, null);

    IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment);
    IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass);

    for (int i = 0; i < arguments.size(); i++) {
      environmentMethod.putValue(
          arguments.get(i).getName(),
          new SymbolArgument(i + 1, environment.getType(method.getGenericParameterTypes()[i])),
          getPosition());
    }

    output.start();
    for (Statement statement : statements) {
      statement.compile(environmentMethod);
    }
    output.ret();
    output.end();

    environment.putClass(clsName, cw.toByteArray());

    // make class instance
    environment.getOutput().newObject(clsName);
    environment.getOutput().dup();
    environment.getOutput().construct(clsName);
  }
Exemple #24
0
  public static byte[] dump1() {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    FieldVisitor fv;
    MethodVisitor mv;

    cw.visit(V1_4, ACC_SUPER, "pkg/Outer$1", null, "pkg/Outer", null);

    cw.visitOuterClass("pkg/Outer", "m", "()V");
    cw.visitInnerClass("pkg/Outer$1", null, null, 0);

    fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null);
    fv.visitEnd();

    mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitFieldInsn(PUTFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer", "<init>", "()V");
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
    mv.visitCode();
    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;");
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        "java/lang/StringBuilder",
        "append",
        "(Ljava/lang/Object;)Ljava/lang/StringBuilder;");
    mv.visitLdcInsn(" ");
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        "java/lang/StringBuilder",
        "append",
        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;");
    mv.visitMethodInsn(INVOKESTATIC, "pkg/Outer", "access$000", "(Lpkg/Outer;)I");
    mv.visitMethodInsn(
        INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;");
    mv.visitMethodInsn(
        INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    cw.visitEnd();

    return cw.toByteArray();
  }
  private byte[] transformEntitySheep(byte[] bytes) {
    System.out.println("Transforming EntitySheep...");
    ClassNode cn = new ClassNode();
    ClassReader cr = new ClassReader(bytes);
    cr.accept(cn, 0);

    Iterator<MethodNode> methods = cn.methods.iterator();
    while (methods.hasNext()) {
      MethodNode m = methods.next();

      if (m.name.equals(names.get("entitySheep_setColour_func"))
          && m.desc.equals(names.get("entitySheep_setColour_desc"))) {
        System.out.println("Found target method: " + m.name + m.desc + "! Inserting call...");

        for (int idx = 0; idx < m.instructions.size(); idx++) {
          if (m.instructions.get(idx).getOpcode() == Opcodes.ISTORE) {
            System.out.println("Found ISTORE at index " + idx + ", inserting code afterwards...");
            idx++; // AFTERwards, not before ;)

            InsnList toAdd = new InsnList();

            // to mark the end of the code
            LabelNode lmmnode = new LabelNode(new Label());
            // load this
            toAdd.add(new VarInsnNode(Opcodes.ALOAD, 0));
            // new fleece colour
            toAdd.add(new VarInsnNode(Opcodes.ILOAD, 1));
            // old fleece colour
            toAdd.add(new VarInsnNode(Opcodes.ILOAD, 2));
            toAdd.add(
                new MethodInsnNode(
                    Opcodes.INVOKESTATIC,
                    "keepcalm/mods/events/ForgeEventHelper",
                    "onSheepDye",
                    "(L" + names.get("entitySheep_javaName") + ";II)Z"));
            LabelNode endIf = new LabelNode(new Label());
            toAdd.add(new JumpInsnNode(Opcodes.IFEQ, endIf));
            toAdd.add(new InsnNode(Opcodes.RETURN));
            toAdd.add(endIf);
            toAdd.add(lmmnode);

            m.instructions.insertBefore(m.instructions.get(idx), toAdd);
            break;
          }
        }
      }
    }

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cn.accept(cw);
    return cw.toByteArray();
  }
 public static Class<?> malform(Class<?> type) throws Exception {
   ClassReader classReader = new ClassReader(type.getName());
   ClassWriter classWriter = new ClassWriter(classReader, 0);
   classReader.accept(new SignatureMalformer(classWriter), 0);
   ClassLoader classLoader =
       new ByteArrayClassLoader(
           null,
           Collections.singletonMap(type.getName(), classWriter.toByteArray()),
           null,
           ByteArrayClassLoader.PersistenceHandler.MANIFEST,
           PackageDefinitionStrategy.NoOp.INSTANCE);
   return classLoader.loadClass(type.getName());
 }
 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;
 }
 @Override
 public Object visitVarDec(VarDec varDec, Object arg) throws Exception {
   // System.out.println(varDec.type.getJVMType());
   if (varDec.type.getJVMType().startsWith("Ljava/util/List"))
     fv = cw.visitField(ACC_STATIC, varDec.identToken.getText(), emptyList, null, null);
   else
     fv =
         cw.visitField(
             ACC_STATIC, varDec.identToken.getText(), varDec.type.getJVMType(), null, null);
   fv.visitEnd();
   return null;
   // throw new UnsupportedOperationException("code generation not yet implemented");
 }
  private void buildObjectAccessor(ClassWriter cw, Class cls) {
    MethodVisitor mv;

    if (fDebugEn) {
      debug("--> buildAccessor cls=" + cls.getName());
    }

    // Constructor
    String tgt_clsname = getClassName(cls);
    String cls_name = getClassLeafName(cls);

    // Read method
    //
    // 0 - this
    // 1 - parent
    // 2 - object
    mv =
        cw.visitMethod(
            ACC_PRIVATE,
            "read" + cls_name,
            "(L" + fChildItem + ";" + "L" + tgt_clsname + ";)V",
            null,
            new String[] {fDBFormatException});
    mv.visitCode();
    visit(false, tgt_clsname, mv, cls);
    mv.visitInsn(RETURN);
    mv.visitMaxs(3, 3);
    mv.visitEnd();

    // Write method
    //
    // 0 - this
    // 1 - object
    mv =
        cw.visitMethod(
            ACC_PRIVATE,
            "write" + cls_name,
            // "(L" + tgt_clsname + ";)V",
            "(L" + tgt_clsname + ";)V",
            null,
            new String[] {fDBWriteException});
    mv.visitCode();
    visit(true, tgt_clsname, mv, cls);
    mv.visitInsn(RETURN);
    mv.visitMaxs(3, 3);
    mv.visitEnd();

    if (fDebugEn) {
      debug("<-- buildAccessor cls=" + cls.getName());
    }
  }
  protected byte[] transformClass(byte[] bytes, String clssname) {
    InputStream is = getClass().getResourceAsStream("/" + clssname.replace('.', '/') + ".class");

    ClassReader orig = null;
    try {
      ClassReader crRepl = new ClassReader(is);
      ClassNode cnRepl = new ClassNode(Opcodes.ASM4);
      crRepl.accept(cnRepl, ClassReader.SKIP_FRAMES);

      ClassReader crOrig = new ClassReader(bytes);
      ClassNode cnOrig = new ClassNode(Opcodes.ASM4);
      crOrig.accept(cnOrig, ClassReader.SKIP_FRAMES);

      for (Object ofnRepl : cnRepl.fields) {
        FieldNode fnRepl = (FieldNode) ofnRepl;

        if (hasReplaceAnnotation(fnRepl.visibleAnnotations)) {
          FieldNode fnOrig = findField(cnOrig.fields, fnRepl);
          if (fnOrig != null) {
            cnOrig.fields.remove(fnOrig);
            cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl));
          }
        } else if (hasAddAnnotation(fnRepl.visibleAnnotations)) {
          cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl));
        }
      }

      for (Object omnRepl : cnRepl.methods) {
        MethodNode mnRepl = (MethodNode) omnRepl;

        if (hasReplaceAnnotation(mnRepl.visibleAnnotations)) {
          MethodNode mnOrig = findMethod(cnOrig.methods, mnRepl);
          if (mnOrig != null) {
            cnOrig.methods.remove(mnOrig);
            cnOrig.methods.add(cnOrig.methods.size(), scrubMethod(cnOrig, cnRepl, mnRepl));
          }
        } else if (hasAddAnnotation(mnRepl.visibleAnnotations)) {
          cnOrig.methods.add(cnOrig.methods.size() + 1, scrubMethod(cnOrig, cnRepl, mnRepl));
        }
      }

      ClassWriter cwNew = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
      cnOrig.accept(cwNew);
      return cwNew.toByteArray();
    } catch (IOException e) {
      e.printStackTrace(); // To change body of catch statement use File | Settings | File
      // Templates.
    }

    return bytes;
  }