Ver código fonte

draft: adapter

Mariusz Sieroń 6 anos atrás
pai
commit
40e62f2e21

+ 21 - 27
assira.drafts/src/main/java/net/ranides/assira/reflection/Adapter.java

@@ -1,6 +1,5 @@
 package net.ranides.assira.reflection;
 
-import net.ranides.assira.reflection.asm.FQPName;
 import net.ranides.assira.reflection.asm.IClassBuilder;
 import net.ranides.assira.reflection.asm.IMethodBuilder;
 //import net.ranides.assira.reflection.asm.impl.VMNames;
@@ -24,16 +23,13 @@ public class Adapter {
 
         IClass<?> vmcDelegate = IClass.typefor(that);
 
-        IClass<?> vmcImplements = type;
-
-        String adapterName = "net.ranides.asm.generated." + vmcImplements.name();
-
-        FQPName vmcAdapter = FQPName.fromFQN(adapterName);
+        String adapterName = "net.ranides.asm.generated." + type.name();
 
+        IClass<?> vmiAdapter = IClass.symbolic(adapterName);
 
         Set<IClass<?>> classInners = new HashSet<>();
         scanForInners1(classInners, vmcDelegate);
-        scanForInners(classInners, vmcImplements);
+        scanForInners(classInners, type);
 
         IClassBuilder writer = IClassBuilder.declare(IAttributes.of(IAttribute.PUBLIC), adapterName, IClass.OBJECT, Arrays.asList(type));
 
@@ -43,50 +39,48 @@ public class Adapter {
 
         writer.field(IAttributes.of(IAttribute.PRIVATE), vmcDelegate, FIELD_THAT);
 
-        putConstructor(writer, vmcDelegate, vmcAdapter);
+        putConstructor(writer, vmcDelegate);
 
-        for(IMethod m : vmcImplements.methods()) {
-            putMethod(writer, vmcDelegate, vmcAdapter, m);
+        for(IMethod m : type.methods()) {
+            putMethod(writer, vmcDelegate, m);
         }
 
-        byte[] bytecode = writer.bytecode();
-
-        Class<?> clazz = LOADER.defineClass(adapterName, bytecode);
+        Class<?> clazz = LOADER.defineClass(adapterName, writer.bytecode());
 
         return type.cast(IClass.typeinfo(clazz).construct(that));
     }
 
-    private static void putConstructor(IClassBuilder writer, IClass<?> vmcDelegate, FQPName vmcAdapter) {
-        IMethodBuilder m = writer.method(IAttributes.of(IAttribute.PUBLIC), "<init>", Arrays.asList(vmcDelegate), IClass.typeinfo(void.class), Collections.emptyList());
+    private static void putConstructor(IClassBuilder writer, IClass<?> delegate) {
+        IMethodBuilder m = writer.constructor(IAttributes.of(IAttribute.PUBLIC), Arrays.asList(delegate), Collections.emptyList());
 
         m.load(IClass.OBJECT, 0);
-        m.invokeSpecial(IClass.OBJECT, "<init>", Collections.emptyList(), IClass.typeinfo(void.class));
+        m.invokeInit(IClass.OBJECT, Collections.emptyList());
         m.load(IClass.OBJECT, 0);
         m.load(IClass.OBJECT, 1);
-        m.putField(vmcAdapter, vmcDelegate, FIELD_THAT);
+        m.putField(writer.type(), delegate, FIELD_THAT);
         m.returns();
 
-        m.var(vmcAdapter, "this");
-        m.var(vmcDelegate, FIELD_THAT);
+        m.var(writer.type(), "this");
+        m.var(delegate, FIELD_THAT);
         m.end();
     }
 
-    private static void putMethod(IClassBuilder writer, IClass<?> vmcDelegate, FQPName vmcAdapter, IMethod src) {
-        IMethodBuilder m = writer.method(IAttributes.of(IAttribute.PUBLIC), src.name(), src.arguments().types().list(), src.returns(), src.exceptions());
+    private static void putMethod(IClassBuilder writer, IClass<?> delegate, IMethod method) {
+        IMethodBuilder m = writer.method(IAttributes.of(IAttribute.PUBLIC), method.name(), method.arguments().types().list(), method.returns(), method.exceptions());
 
         m.load(IClass.OBJECT, 0);
-        m.getField(vmcAdapter, vmcDelegate, FIELD_THAT);
+        m.getField(writer.type(), delegate, FIELD_THAT);
 
         int index = 1;
-        for(IClass<?> type : src.arguments().types()) {
+        for(IClass<?> type : method.arguments().types()) {
             m.load(type, index++);
         }
 
-        m.invokeVirtual(vmcDelegate, src);
-        m.returns(src.returns());
+        m.invokeVirtual(delegate, method);
+        m.returns(method.returns());
 
-        m.var(vmcAdapter, "this");
-        m.var(src.arguments());
+        m.var(writer.type(), "this");
+        m.var(method.arguments());
         m.end();
     }
 

+ 0 - 19
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/FQPName.java

@@ -1,19 +0,0 @@
-package net.ranides.assira.reflection.asm;
-
-public class FQPName {
-
-    public final String value;
-
-    private FQPName(String value) {
-        this.value = value;
-    }
-
-    public static FQPName fromFQP(String fqp) {
-        return new FQPName(fqp);
-    }
-
-    public static FQPName fromFQN(String fqn) {
-        return new FQPName(fqn.replace('.', '/'));
-    }
-
-}

+ 2 - 0
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/IClassBuilder.java

@@ -19,6 +19,8 @@ public interface IClassBuilder {
 
     IClassBuilder field(IAttributes attrs, IClass<?> type, String name);
 
+    IMethodBuilder constructor(IAttributes attrs, Iterable<IClass<?>> params, Iterable<IClass<?>> exceptions);
+
     IMethodBuilder method(IAttributes attrs, String name, Iterable<IClass<?>> params, IClass<?> ret, Iterable<IClass<?>> exceptions);
 
     byte[] bytecode();

+ 26 - 8
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/IMethodBuilder.java

@@ -12,7 +12,7 @@ public interface IMethodBuilder {
 
     Label label();
 
-    IMethodBuilder var(FQPName type, String name);
+    Label label(int line);
 
     IMethodBuilder var(IClass<?> type, String name);
 
@@ -22,29 +22,35 @@ public interface IMethodBuilder {
 
     IMethodBuilder load(IClass<?> type, int index);
 
+    IMethodBuilder store(IClass<?> type, int index);
+
     IMethodBuilder returns();
 
     IMethodBuilder returns(IClass<?> type);
 
-    IMethodBuilder putField(FQPName owner, IClass<?> type, String name);
-
     IMethodBuilder putField(IClass<?> owner, IClass<?> type, String name);
 
     IMethodBuilder putField(IField field);
 
-    IMethodBuilder getField(FQPName owner, IClass<?> type, String name);
-
     IMethodBuilder getField(IClass<?> owner, IClass<?> type, String name);
 
     IMethodBuilder getField(IField field);
 
-    IMethodBuilder invokeSpecial(FQPName owner, String name, Iterable<IClass<?>> params, IClass<?> ret);
+    IMethodBuilder putStatic(IClass<?> owner, IClass<?> type, String name);
+
+    IMethodBuilder putStatic(IField field);
+
+    IMethodBuilder getStatic(IClass<?> owner, IClass<?> type, String name);
+
+    IMethodBuilder getStatic(IField field);
+
+    IMethodBuilder invokeInit(IClass<?> owner, Iterable<IClass<?>> params);
 
     IMethodBuilder invokeSpecial(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret);
 
-    IMethodBuilder invokeSpecial(IMethod method);
+    IMethodBuilder invokeSpecial(IClass<?> owner, IMethod method);
 
-    IMethodBuilder invokeVirtual(FQPName owner, String name, Iterable<IClass<?>> params, IClass<?> ret);
+    IMethodBuilder invokeSpecial(IMethod method);
 
     IMethodBuilder invokeVirtual(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret);
 
@@ -52,4 +58,16 @@ public interface IMethodBuilder {
 
     IMethodBuilder invokeVirtual(IMethod method);
 
+    IMethodBuilder invokeStatic(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret);
+
+    IMethodBuilder invokeStatic(IClass<?> owner, IMethod method);
+
+    IMethodBuilder invokeStatic(IMethod method);
+
+    IMethodBuilder newObject(IClass<?> type);
+
+    IMethodBuilder checkCast(IClass<?> type);
+
+    IMethodBuilder isInstance(IClass<?> type);
+
 }

+ 0 - 61
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/impl/ASMOpcodes.java

@@ -1,61 +0,0 @@
-package net.ranides.assira.reflection.asm.impl;
-
-import net.ranides.assira.reflection.IClass;
-
-import static org.objectweb.asm.Opcodes.*;
-
-public class ASMOpcodes {
-
-    public enum OCType {
-        OCT_V,
-        OCT_I,
-        OCT_L,
-        OCT_F,
-        OCT_D,
-        OCT_A
-    }
-
-    private static OCType typeof(IClass<?> clazz) {
-        Class<?> type = clazz.raw();
-        if(void.class.equals(type)) {
-            return OCType.OCT_V;
-        }
-        if(boolean.class.equals(type) || byte.class.equals(type) || char.class.equals(type) || short.class.equals(type) || int.class.equals(type)) {
-            return OCType.OCT_I;
-        }
-        if(long.class.equals(type)) {
-            return OCType.OCT_L;
-        }
-        if(float.class.equals(type)) {
-            return OCType.OCT_F;
-        }
-        if(double.class.equals(type)) {
-            return OCType.OCT_D;
-        }
-        return OCType.OCT_A;
-    }
-
-    public static int OC_LOAD(IClass<?> clazz) {
-        switch (typeof(clazz)) {
-            case OCT_I: return ILOAD;
-            case OCT_L: return LLOAD;
-            case OCT_F: return FLOAD;
-            case OCT_D: return DLOAD;
-            case OCT_A: return ALOAD;
-        }
-        throw new IllegalArgumentException("Unknown LOAD for type: " + clazz);
-    }
-
-    public static int OC_RETURN(IClass<?> clazz) {
-        switch (typeof(clazz)) {
-            case OCT_V: return RETURN;
-            case OCT_I: return IRETURN;
-            case OCT_L: return LRETURN;
-            case OCT_F: return FRETURN;
-            case OCT_D: return DRETURN;
-            case OCT_A: return ARETURN;
-        }
-        throw new IllegalArgumentException("Unknown RETURN for type: " + clazz);
-    }
-
-}

+ 137 - 0
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/impl/AsmSupport.java

@@ -0,0 +1,137 @@
+package net.ranides.assira.reflection.asm.impl;
+
+import net.ranides.assira.collection.iterators.IteratorUtils;
+import net.ranides.assira.reflection.*;
+import net.ranides.assira.text.StrBuilder;
+import net.ranides.assira.text.StringUtils;
+import org.objectweb.asm.Type;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.objectweb.asm.Opcodes.*;
+
+public class AsmSupport {
+
+    private static final Type TYPE_OBJECT = Type.getType(Object.class);
+
+    public static int opcode(int oc, IClass<?> type) {
+        if(IAttribute.SYMBOLIC.match(type)) {
+            return TYPE_OBJECT.getOpcode(oc);
+        } else {
+            return Type.getType(type.raw()).getOpcode(oc);
+        }
+    }
+
+    public static int vcall(IClass<?> owner, IMethod method) {
+        if(method!=null && IAttribute.STATIC.match(method)) {
+            return INVOKESTATIC;
+        }
+        return IAttribute.INTERFACE.match(owner) ? INVOKEINTERFACE : INVOKEVIRTUAL;
+    }
+
+    public static int vcall(IMethod method) {
+        return vcall(method.parent(), method);
+    }
+
+    public static int vcall(IClass<?> owner) {
+        return vcall(owner, null);
+    }
+
+    public static String path(IClass<?> clazz) {
+        if(clazz.attributes().has(IAttribute.SYMBOLIC)) {
+            return clazz.name().replace('.', '/');
+        } else {
+            return Type.getType(clazz.raw()).getInternalName();
+        }
+    }
+
+    public static String[] path(IClass<?>[] types) {
+        return Arrays.stream(types).map(AsmSupport::path).toArray(String[]::new);
+    }
+
+    public static String[] path(Iterable<IClass<?>> types) {
+        return IteratorUtils.stream(types.iterator()).map(AsmSupport::path).toArray(String[]::new);
+    }
+
+    public static String[] path(Collection<IClass<?>> types) {
+        return types.stream().map(AsmSupport::path).toArray(String[]::new);
+    }
+
+    public static String vm(IClass<?> clazz) {
+        if(clazz.attributes().has(IAttribute.SYMBOLIC)) {
+            return "L"+ path(clazz)+";";
+        } else {
+            return Type.getType(clazz.raw()).getDescriptor();
+        }
+    }
+
+    public static String vm(Iterable<IClass<?>> types) {
+        return StringUtils.join(types, "", AsmSupport::vm);
+    }
+
+    public static String vm(Iterable<IClass<?>> params, IClass<?> ret) {
+        return new StrBuilder()
+            .open("(", ")", "").append(params, AsmSupport::vm).close()
+            .append(vm(ret)).toString();
+    }
+
+    public static String vm(IMethod method) {
+        return Type.getType(method.reflective()).getDescriptor();
+    }
+
+    public static String vm(IConstructor<?> ctor) {
+        return Type.getType(ctor.reflective()).getDescriptor();
+    }
+
+    public static String sig(IClass<?> clazz) {
+        return isGeneric(clazz) ? sig0(clazz) : null;
+    }
+
+    public static String sig(Iterable<IClass<?>> types) {
+        return isGeneric(types) ? StringUtils.join(types, "", AsmSupport::sig0) : null;
+    }
+
+    public static String sig(Iterable<IClass<?>> params, IClass<?> ret) {
+        return isGeneric(params) || isGeneric(ret) ? sig0(params, ret) : null;
+    }
+
+    public static String sig(IMethod method) {
+        return isGeneric(method) ? sig0(method.arguments().types(), method.returns()) : null;
+    }
+
+    public static String sig(IConstructor<?> ctor) {
+        return isGeneric(ctor) ? sig0(ctor.arguments().types(), IClass.VOID) : null;
+    }
+
+    private static String sig0(Iterable<IClass<?>> params, IClass<?> ret) {
+        return new StrBuilder()
+            .open("(", ")", "")
+            .append(params, AsmSupport::sig0)
+            .close()
+            .append(sig0(ret))
+            .toString();
+    }
+
+    private static String sig0(IClass<?> clazz) {
+        if(!isGeneric(clazz)) {
+            return vm(clazz);
+        }
+        return new StrBuilder()
+            .append("L")
+            .append(path(clazz))
+            .open("<", ">", "")
+            .append(clazz.params(), AsmSupport::sig0)
+            .close()
+            .toString();
+    }
+
+    private static boolean isGeneric(Iterable<? extends IElement> elements) {
+        return IteratorUtils.stream(elements.iterator()).anyMatch(AsmSupport::isGeneric);
+    }
+
+    private static boolean isGeneric(IElement element) {
+        return element.attributes().has(IAttribute.PARAMETERIZED);
+    }
+
+}

+ 13 - 8
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/impl/CClassBuilder.java

@@ -1,6 +1,5 @@
 package net.ranides.assira.reflection.asm.impl;
 
-import net.ranides.assira.reflection.asm.FQPName;
 import net.ranides.assira.reflection.IAttributes;
 import net.ranides.assira.reflection.IClass;
 import net.ranides.assira.reflection.asm.IClassBuilder;
@@ -13,14 +12,15 @@ import static org.objectweb.asm.Opcodes.V11;
 
 public class CClassBuilder implements IClassBuilder {
 
+    private final IClass<?> type;
+
     private final ClassWriter cv;
 
     public CClassBuilder(IAttributes attrs, String name, IClass<?> parent, Iterable<IClass<?>> interfaces) {
         cv = new ClassWriter(COMPUTE_FRAMES);
-
-        FQPName fqp = FQPName.fromFQN(name);
-        cv.visit(V11, attrs.reflective() | ACC_SUPER, VMNames.fqp(fqp), null, VMNames.fqp(parent), VMNames.fqp(interfaces));
-        cv.visitSource(VMNames.shortname(fqp)+".asm", null);
+        type = IClass.symbolic(name);
+        cv.visit(V11, attrs.reflective() | ACC_SUPER, AsmSupport.path(type), null, AsmSupport.path(parent), AsmSupport.path(interfaces));
+        cv.visitSource(type.shortname()+".asm", null);
     }
 
     @Override
@@ -30,21 +30,26 @@ public class CClassBuilder implements IClassBuilder {
 
     @Override
     public IClass<?> type() {
-        return null;
+        return type;
     }
 
     @Override
     public IClassBuilder inner(IClass<?> ref) {
-        cv.visitInnerClass(VMNames.fqp(ref), VMNames.fqp(ref.outer()), ref.shortname(), ref.attributes().reflective());
+        cv.visitInnerClass(AsmSupport.path(ref), AsmSupport.path(ref.outer()), ref.shortname(), ref.attributes().reflective());
         return this;
     }
 
     @Override
     public IClassBuilder field(IAttributes attrs, IClass<?> type, String name) {
-        cv.visitField(attrs.reflective(), name, VMNames.vm(type), VMNames.sig(type), null).visitEnd();
+        cv.visitField(attrs.reflective(), name, AsmSupport.vm(type), AsmSupport.sig(type), null).visitEnd();
         return this;
     }
 
+    @Override
+    public IMethodBuilder constructor(IAttributes attrs, Iterable<IClass<?>> params, Iterable<IClass<?>> exceptions) {
+        return method(attrs, "<init>", params, IClass.VOID, exceptions);
+    }
+
     @Override
     public IMethodBuilder method(IAttributes attrs, String name, Iterable<IClass<?>> params, IClass<?> ret, Iterable<IClass<?>> exceptions) {
         return new CMethodBuilder(this, attrs, name, params, ret, exceptions);

+ 102 - 40
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/impl/CMethodBuilder.java

@@ -1,7 +1,6 @@
 package net.ranides.assira.reflection.asm.impl;
 
 import net.ranides.assira.reflection.*;
-import net.ranides.assira.reflection.asm.FQPName;
 import net.ranides.assira.reflection.asm.IClassBuilder;
 import net.ranides.assira.reflection.asm.IMethodBuilder;
 import org.objectweb.asm.Label;
@@ -24,7 +23,7 @@ public class CMethodBuilder implements IMethodBuilder {
 
     CMethodBuilder(IClassBuilder parent, IAttributes attrs, String name, Iterable<IClass<?>> params, IClass<?> ret, Iterable<IClass<?>> exceptions) {
         this.parent = parent;
-        this.mv = parent.asm().visitMethod(attrs.reflective(), name, VMNames.vm(params, ret), VMNames.sig(params, ret), VMNames.fqp(exceptions));
+        this.mv = parent.asm().visitMethod(attrs.reflective(), name, AsmSupport.vm(params, ret), AsmSupport.sig(params, ret), AsmSupport.path(exceptions));
         this.first = label();
     }
 
@@ -48,12 +47,11 @@ public class CMethodBuilder implements IMethodBuilder {
     }
 
     @Override
-    public IMethodBuilder var(FQPName type, String name) {
-        if(last == null) {
-            last = label();
-        }
-        mv.visitLocalVariable(name, VMNames.vm(type), VMNames.sig(type), first, last, vars++);;
-        return this;
+    public Label label(int line) {
+        Label out = new Label();
+        mv.visitLabel(out);
+        mv.visitLineNumber(line, out);
+        return out;
     }
 
     @Override
@@ -61,7 +59,7 @@ public class CMethodBuilder implements IMethodBuilder {
         if(last == null) {
             last = label();
         }
-        mv.visitLocalVariable(name, VMNames.vm(type), VMNames.sig(type), first, last, vars++);;
+        mv.visitLocalVariable(name, AsmSupport.vm(type), AsmSupport.sig(type), first, last, vars++);;
         return this;
     }
 
@@ -78,92 +76,156 @@ public class CMethodBuilder implements IMethodBuilder {
 
     @Override
     public IMethodBuilder load(IClass<?> type, int index) {
-        mv.visitVarInsn(ASMOpcodes.OC_LOAD(type), index);
+        mv.visitVarInsn(AsmSupport.opcode(ILOAD, type), index);
         return this;
     }
 
     @Override
-    public IMethodBuilder returns() {
-        mv.visitInsn(Opcodes.RETURN);
+    public IMethodBuilder store(IClass<?> type, int index) {
+        mv.visitVarInsn(AsmSupport.opcode(ISTORE, type), index);
         return this;
     }
 
     @Override
-    public IMethodBuilder returns(IClass<?> type) {
-        mv.visitInsn(ASMOpcodes.OC_RETURN(type));
+    public IMethodBuilder returns() {
+        mv.visitInsn(Opcodes.RETURN);
         return this;
     }
 
     @Override
-    public IMethodBuilder putField(FQPName owner, IClass<?> type, String name) {
-        mv.visitFieldInsn(PUTFIELD, VMNames.fqp(owner), name, VMNames.vm(type));
+    public IMethodBuilder returns(IClass<?> type) {
+        mv.visitInsn(AsmSupport.opcode(IRETURN, type));
         return this;
     }
 
     @Override
     public IMethodBuilder putField(IClass<?> owner, IClass<?> type, String name) {
-        mv.visitFieldInsn(PUTFIELD, VMNames.fqp(owner), name, VMNames.vm(type));
-        return this;
+        return ocField(PUTFIELD, owner, type, name);
     }
 
     @Override
     public IMethodBuilder putField(IField field) {
-        return putField(field.parent(), field.type(), field.name());
+        return ocField(PUTFIELD, field);
     }
 
     @Override
-    public IMethodBuilder getField(FQPName owner, IClass<?> type, String name) {
-        mv.visitFieldInsn(GETFIELD, VMNames.fqp(owner), name, VMNames.vm(type));
-        return this;
+    public IMethodBuilder getField(IClass<?> owner, IClass<?> type, String name) {
+        return ocField(GETFIELD, owner, type, name);
     }
 
     @Override
-    public IMethodBuilder getField(IClass<?> owner, IClass<?> type, String name) {
-        mv.visitFieldInsn(GETFIELD, VMNames.fqp(owner), name, VMNames.vm(type));
-        return this;
+    public IMethodBuilder getField(IField field) {
+        return ocField(GETFIELD, field);
     }
 
     @Override
-    public IMethodBuilder getField(IField field) {
-        return getField(field.parent(), field.type(), field.name());
+    public IMethodBuilder putStatic(IClass<?> owner, IClass<?> type, String name) {
+        return ocField(PUTSTATIC, owner, type, name);
+    }
+
+    @Override
+    public IMethodBuilder putStatic(IField field) {
+        return ocField(PUTSTATIC, field);
+    }
+
+    @Override
+    public IMethodBuilder getStatic(IClass<?> owner, IClass<?> type, String name) {
+        return ocField(GETSTATIC, owner, type, name);
     }
 
     @Override
-    public IMethodBuilder invokeSpecial(FQPName owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
-        mv.visitMethodInsn(INVOKESPECIAL, VMNames.fqp(owner), name, VMNames.vm(params, ret), false);
+    public IMethodBuilder getStatic(IField field) {
+        return ocField(GETSTATIC, field);
+    }
+
+    private IMethodBuilder ocField(int oc, IField field) {
+        return ocField(oc, field.parent(), field.type(), field.name());
+    }
+
+    private IMethodBuilder ocField(int oc, IClass<?> owner, IClass<?> type, String name) {
+        mv.visitFieldInsn(oc, AsmSupport.path(owner), name, AsmSupport.vm(type));
         return this;
     }
 
     @Override
-    public IMethodBuilder invokeSpecial(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
-        mv.visitMethodInsn(INVOKESPECIAL, VMNames.fqp(owner), name, VMNames.vm(params, ret), owner.attributes().has(IAttribute.INTERFACE));
+    public IMethodBuilder invokeInit(IClass<?> owner, Iterable<IClass<?>> params) {
+        mv.visitMethodInsn(INVOKESPECIAL, AsmSupport.path(owner), "<init>", AsmSupport.vm(params, IClass.VOID), owner.attributes().has(IAttribute.INTERFACE));
         return this;
     }
 
     @Override
-    public IMethodBuilder invokeSpecial(IMethod method) {
-        return invokeSpecial(method.parent(), method.name(), method.arguments().types(), method.returns());
+    public IMethodBuilder invokeSpecial(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
+        return invoke(INVOKESPECIAL, owner, name, params, ret);
     }
 
     @Override
-    public IMethodBuilder invokeVirtual(FQPName owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
-        mv.visitMethodInsn(INVOKEVIRTUAL, VMNames.fqp(owner), name, VMNames.vm(params, ret), false);
-        return this;
+    public IMethodBuilder invokeSpecial(IClass<?> owner, IMethod method) {
+        return invoke(INVOKESPECIAL, owner, method);
+    }
+
+    @Override
+    public IMethodBuilder invokeSpecial(IMethod method) {
+        return invoke(INVOKESPECIAL, method);
     }
 
     @Override
     public IMethodBuilder invokeVirtual(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
-        mv.visitMethodInsn(INVOKEVIRTUAL, VMNames.fqp(owner), name, VMNames.vm(params, ret), owner.attributes().has(IAttribute.INTERFACE));
-        return this;
+        return invoke(AsmSupport.vcall(owner), owner, name, params, ret);
     }
 
     @Override
     public IMethodBuilder invokeVirtual(IClass<?> owner, IMethod method) {
-        return invokeVirtual(owner, method.name(), method.arguments().types(), method.returns());
+        return invoke(AsmSupport.vcall(owner, method), owner, method);
     }
 
     @Override
     public IMethodBuilder invokeVirtual(IMethod method) {
-        return invokeVirtual(method.parent(), method.name(), method.arguments().types(), method.returns());
+        return invoke(AsmSupport.vcall(method), method);
+    }
+
+    @Override
+    public IMethodBuilder invokeStatic(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
+        return invoke(INVOKESTATIC, owner, name, params, ret);
+    }
+
+    @Override
+    public IMethodBuilder invokeStatic(IClass<?> owner, IMethod method) {
+        return invoke(INVOKESTATIC, owner, method);
+    }
+
+    @Override
+    public IMethodBuilder invokeStatic(IMethod method) {
+        return invoke(INVOKESTATIC, method);
+    }
+
+    private IMethodBuilder invoke(int oc, IMethod method) {
+        return invoke(oc, method.parent(), method);
+    }
+
+    private IMethodBuilder invoke(int oc, IClass<?> owner, IMethod method) {
+        return invoke(oc, owner, method.name(), method.arguments().types(), method.returns());
+    }
+
+    private IMethodBuilder invoke(int oc, IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
+        mv.visitMethodInsn(oc, AsmSupport.path(owner), name, AsmSupport.vm(params, ret), owner.attributes().has(IAttribute.INTERFACE));
+        return this;
+    }
+
+    @Override
+    public IMethodBuilder newObject(IClass<?> type) {
+        mv.visitTypeInsn(type.attributes().has(IAttribute.ARRAY) ? NEWARRAY : NEW, AsmSupport.path(type));
+        return this;
+    }
+
+    @Override
+    public IMethodBuilder checkCast(IClass<?> type) {
+        mv.visitTypeInsn(CHECKCAST, AsmSupport.path(type));
+        return this;
+    }
+
+    @Override
+    public IMethodBuilder isInstance(IClass<?> type) {
+        mv.visitTypeInsn(INSTANCEOF, AsmSupport.path(type));
+        return this;
     }
 }

+ 0 - 180
assira.drafts/src/main/java/net/ranides/assira/reflection/asm/impl/VMNames.java

@@ -1,180 +0,0 @@
-package net.ranides.assira.reflection.asm.impl;
-
-import net.ranides.assira.collection.iterators.IteratorUtils;
-import net.ranides.assira.reflection.*;
-import net.ranides.assira.reflection.asm.FQPName;
-import net.ranides.assira.text.StrBuilder;
-import net.ranides.assira.text.StringUtils;
-
-import java.util.List;
-
-public class VMNames {
-
-    private static final IClass<?> VOID = IClass.typeinfo(void.class);
-
-    public static String shortname(IClass<?> clazz) {
-        return clazz.shortname();
-    }
-
-    public static String shortname(FQPName fqp) {
-        return fqp.value.substring(fqp.value.lastIndexOf('/')+1);
-    }
-
-    public static String fqp(FQPName fqp) {
-        return fqp.value;
-    }
-
-    public static String fqn(FQPName fqp) {
-        return fqp.value.replace('/', '.');
-    }
-
-    public static String fqp(IClass<?> clazz) {
-        return clazz.raw().getName().replace('.', '/');
-    }
-
-    public static String[] fqp(IClass<?>[] types) {
-        int n = types.length;
-        String[] target = new String[n];
-        for(int i=0; i<n; i++) {
-            target[i] = fqp(types[i]);
-        }
-        return target;
-    }
-
-    public static String[] fqp(Iterable<IClass<?>> types) {
-        return IteratorUtils.stream(types.iterator()).map(VMNames::fqp).toArray(String[]::new);
-    }
-
-    public static String[] fqp(List<IClass<?>> types) {
-        return types.stream().map(VMNames::fqp).toArray(String[]::new);
-    }
-
-    public static String vm(FQPName type) {
-        if(type.value.startsWith("[") || type.value.length() == 1) {
-            return type.value;
-        }
-        if("boolean".equals(type)) {
-            return "Z";
-        }
-        if("byte".equals(type)) {
-            return "B";
-        }
-        if("char".equals(type)) {
-            return "C";
-        }
-        if("short".equals(type)) {
-            return "S";
-        }
-        if("int".equals(type)) {
-            return "I";
-        }
-        if("long".equals(type)) {
-            return "J";
-        }
-        if("float".equals(type)) {
-            return "F";
-        }
-        if("double".equals(type)) {
-            return "D";
-        }
-        if("void".equals(type)) {
-            return "V";
-        }
-        return "L" + type.value + ";";
-    }
-
-    public static String vm(IClass<?> clazz) {
-        IAttributes attrs = clazz.attributes();
-        if(attrs.has(IAttribute.ARRAY)) {
-            return "[" + vm(clazz.component());
-        }
-        if(!attrs.has(IAttribute.PRIMITIVE)) {
-            return "L"+ fqp(clazz)+";";
-        }
-        Class<?> type = clazz.raw();
-        if(boolean.class.equals(type)) {
-            return "Z";
-        }
-        if(byte.class.equals(type)) {
-            return "B";
-        }
-        if(char.class.equals(type)) {
-            return "C";
-        }
-        if(short.class.equals(type)) {
-            return "S";
-        }
-        if(int.class.equals(type)) {
-            return "I";
-        }
-        if(long.class.equals(type)) {
-            return "J";
-        }
-        if(float.class.equals(type)) {
-            return "F";
-        }
-        if(double.class.equals(type)) {
-            return "D";
-        }
-        if(void.class.equals(type)) {
-            return "V";
-        }
-        return "L"+ fqp(clazz)+";";
-    }
-
-    public static String vm(Iterable<IClass<?>> types) {
-        return StringUtils.join(types, "", VMNames::vm);
-    }
-
-    public static String vm(Iterable<IClass<?>> params, IClass<?> ret) {
-        return new StrBuilder()
-            .open("(", ")", "").append(params, VMNames::vm).close()
-            .append(vm(ret)).toString();
-    }
-
-    public static String vm(IMethod method) {
-        return vm(method.arguments().types(), method.returns());
-    }
-
-    public static String vm(IConstructor<?> ctor) {
-        return vm(ctor.arguments().types(), VOID);
-    }
-
-    public static String sig(FQPName type) {
-        return null;
-    }
-
-    private static String sig0(IClass<?> clazz) {
-        if(!clazz.attributes().has(IAttribute.PARAMETERIZED)) {
-            return vm(clazz);
-        } else {
-            return new StrBuilder().append("L").append(fqp(clazz)).open("<", ">", "").append(clazz.params(), VMNames::sig0).close().toString();
-        }
-    }
-
-    public static String sig(IClass<?> clazz) {
-        String generic = sig0(clazz);
-        return generic.equals(vm(clazz)) ? null : generic;
-    }
-
-    public static String sig(Iterable<IClass<?>> types) {
-        String generic = StringUtils.join(types, "", VMNames::sig0);
-        return generic.equals(vm(types)) ? null : generic;
-    }
-
-    public static String sig(Iterable<IClass<?>> params, IClass<?> ret) {
-        String generic = new StrBuilder()
-                .open("(", ")", "").append(params, VMNames::sig0).close()
-                .append(sig0(ret)).toString();
-        return generic.equals(vm(params, ret)) ? null : generic;
-    }
-
-    public static String sig(IMethod method) {
-        return sig(method.arguments().types(), method.returns());
-    }
-
-    public static String sig(IConstructor<?> ctor) {
-        return sig(ctor.arguments().types(), VOID);
-    }
-
-}