Package com.artemis.weaver.optimizer

Source Code of com.artemis.weaver.optimizer.ProcessEntitiesInjector

package com.artemis.weaver.optimizer;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import com.artemis.meta.ClassMetadata;
import com.artemis.meta.ClassMetadata.OptimizationType;

public final class ProcessEntitiesInjector implements Opcodes {

  private final ClassReader cr;
  private final ClassMetadata meta;
  private final ClassWriter cw;

  public ProcessEntitiesInjector(ClassReader cr, ClassMetadata meta) {
    this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    this.cr = cr;
    this.meta = meta;
  }

  public ClassReader transform() {
    return new ClassReader(injectMethods());
  }

  private byte[] injectMethods() {
    injectProcessEntities();
    cr.accept(cw, 0);
    return cw.toByteArray();
  }
 
  private void injectProcessEntities() {
    String owner = meta.type.getInternalName();
   
    MethodVisitor mv = cw.visitMethod(ACC_PROTECTED + ACC_FINAL, "processEntities", "(Lcom/artemis/utils/ImmutableBag;)V", "(Lcom/artemis/utils/ImmutableBag<Lcom/artemis/Entity;>;)V", null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);

    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, "com/artemis/utils/Bag");
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/artemis/utils/Bag", "getData", "()[Ljava/lang/Object;");
    mv.visitVarInsn(ASTORE, 2);
    Label l1 = new Label();
    mv.visitLabel(l1);

    mv.visitInsn(ICONST_0);
    mv.visitVarInsn(ISTORE, 3);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEINTERFACE, "com/artemis/utils/ImmutableBag", "size", "()I");
    mv.visitVarInsn(ISTORE, 4);
    Label l3 = new Label();
    mv.visitLabel(l3);
    Label l4 = new Label();
    mv.visitJumpInsn(GOTO, l4);
    Label l5 = new Label();
    mv.visitLabel(l5);

    mv.visitFrame(Opcodes.F_APPEND,3, new Object[] {"[Ljava/lang/Object;", Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitVarInsn(ILOAD, 3);
    mv.visitInsn(AALOAD);
    mv.visitTypeInsn(CHECKCAST, "com/artemis/Entity");
//    mv.visitMethodInsn(INVOKEVIRTUAL, owner, "process", "(Lcom/artemis/Entity;)V");
    mv.visitMethodInsn(invocation(meta.sysetemOptimizable), owner, "process", "(Lcom/artemis/Entity;)V");
    Label l6 = new Label();
    mv.visitLabel(l6);

    mv.visitIincInsn(3, 1);
    mv.visitLabel(l4);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ILOAD, 4);
    mv.visitVarInsn(ILOAD, 3);
    mv.visitJumpInsn(IF_ICMPGT, l5);
    Label l7 = new Label();
    mv.visitLabel(l7);

    mv.visitInsn(RETURN);
    Label l8 = new Label();
    mv.visitLabel(l8);
    mv.visitLocalVariable("this", meta.type.toString(), null, l0, l8, 0);
    mv.visitLocalVariable("entities", "Lcom/artemis/utils/ImmutableBag;", "Lcom/artemis/utils/ImmutableBag<Lcom/artemis/Entity;>;", l0, l8, 1);
    mv.visitLocalVariable("array", "[Ljava/lang/Object;", null, l1, l8, 2);
    mv.visitLocalVariable("i", "I", null, l2, l7, 3);
    mv.visitLocalVariable("s", "I", null, l3, l7, 4);
    mv.visitEnd();
  }

  private static int invocation(OptimizationType systemOptimization) {
    switch (systemOptimization) {
    case FULL:
      return INVOKESPECIAL;
    case SAFE:
      return INVOKEVIRTUAL;
    case NOT_OPTIMIZABLE:
      assert false;
    default:
      throw new RuntimeException("Missing case: " + systemOptimization);
   
    }
  }
}
TOP

Related Classes of com.artemis.weaver.optimizer.ProcessEntitiesInjector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.