|
|
@@ -1,19 +1,15 @@
|
|
|
-package net.ranides.assira.reflection.asm.impl;
|
|
|
+package net.ranides.assira.reflection.asm;
|
|
|
|
|
|
-import net.ranides.assira.math.MathUtils;
|
|
|
import net.ranides.assira.reflection.*;
|
|
|
-import net.ranides.assira.reflection.asm.IClassBuilder;
|
|
|
-import net.ranides.assira.reflection.asm.IMethodBuilder;
|
|
|
import net.ranides.assira.reflection.util.ClassUtils;
|
|
|
-import org.objectweb.asm.*;
|
|
|
-
|
|
|
import java.util.Arrays;
|
|
|
|
|
|
-import static org.objectweb.asm.Opcodes.*;
|
|
|
+import net.ranides.asm.*;
|
|
|
+import static net.ranides.asm.Opcodes.*;
|
|
|
|
|
|
-public class CMethodBuilder implements IMethodBuilder {
|
|
|
+public class AsmMethodBuilder {
|
|
|
|
|
|
- private final IClassBuilder parent;
|
|
|
+ private final AsmClassBuilder parent;
|
|
|
|
|
|
private final MethodVisitor mv;
|
|
|
|
|
|
@@ -23,32 +19,28 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
|
|
|
private int vars;
|
|
|
|
|
|
- CMethodBuilder(IClassBuilder parent, IAttributes attrs, String name, Iterable<IClass<?>> params, IClass<?> ret, Iterable<IClass<?>> exceptions) {
|
|
|
+ AsmMethodBuilder(AsmClassBuilder parent, IAttributes attrs, String name, Iterable<IClass<?>> params, IClass<?> ret, Iterable<IClass<?>> exceptions) {
|
|
|
this.parent = parent;
|
|
|
this.mv = parent.asm().visitMethod(attrs.reflective(), name, AsmSupport.vm(params, ret), AsmSupport.sig(params, ret), AsmSupport.path(exceptions));
|
|
|
this.first = label();
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public MethodVisitor asm() {
|
|
|
return mv;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IClassBuilder end() {
|
|
|
+ public AsmClassBuilder end() {
|
|
|
mv.visitMaxs(0, 0);
|
|
|
mv.visitEnd();
|
|
|
return parent;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public Label label() {
|
|
|
Label out = new Label();
|
|
|
mv.visitLabel(out);
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
public Label label(int line) {
|
|
|
Label out = new Label();
|
|
|
mv.visitLabel(out);
|
|
|
@@ -56,8 +48,7 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder var(IClass<?> type, String name) {
|
|
|
+ public AsmMethodBuilder var(IClass<?> type, String name) {
|
|
|
if(last == null) {
|
|
|
last = label();
|
|
|
}
|
|
|
@@ -65,23 +56,20 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder var(IArgument argument) {
|
|
|
+ public AsmMethodBuilder var(IArgument argument) {
|
|
|
return var(argument.type(), argument.name());
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder var(IArguments arguments) {
|
|
|
+ public AsmMethodBuilder var(IArguments arguments) {
|
|
|
arguments.each(this::var);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder push(Object value) {
|
|
|
+ public AsmMethodBuilder push(Object value) {
|
|
|
return push(IClass.typefor(value), value);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder push(IClass<?> type, Object value) {
|
|
|
+ public AsmMethodBuilder push(IClass<?> type, Object value) {
|
|
|
if(null == value) {
|
|
|
return ins(ACONST_NULL);
|
|
|
}
|
|
|
@@ -103,7 +91,7 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return ldc(value);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder pushDouble(Number value) {
|
|
|
+ public AsmMethodBuilder pushDouble(Number value) {
|
|
|
if(value.doubleValue() == 0.0) {
|
|
|
return ins(DCONST_0);
|
|
|
}
|
|
|
@@ -113,7 +101,7 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return ldc(value.doubleValue());
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder pushFloat(Number value) {
|
|
|
+ public AsmMethodBuilder pushFloat(Number value) {
|
|
|
if(value.floatValue() == 0.0) {
|
|
|
return ins(FCONST_0);
|
|
|
}
|
|
|
@@ -126,7 +114,7 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return ldc(value.floatValue());
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder pushLong(long value) {
|
|
|
+ public AsmMethodBuilder pushLong(long value) {
|
|
|
if(value == 0) {
|
|
|
return ins(LCONST_0);
|
|
|
}
|
|
|
@@ -136,7 +124,7 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return ldc(value);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder pushInt(Number value) {
|
|
|
+ public AsmMethodBuilder pushInt(Number value) {
|
|
|
switch (value.intValue()) {
|
|
|
case -1:
|
|
|
return ins(ICONST_M1);
|
|
|
@@ -164,172 +152,145 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return ldc(value.intValue());
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder load(IClass<?> type, int index) {
|
|
|
+ public AsmMethodBuilder load(IClass<?> type, int index) {
|
|
|
mv.visitVarInsn(AsmSupport.opcode(ILOAD, type), index);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder load(IArguments arguments, int index) {
|
|
|
+ public AsmMethodBuilder load(IArguments arguments, int index) {
|
|
|
for(IArgument a : arguments) {
|
|
|
load(a.type(), index++);
|
|
|
}
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder store(IClass<?> type, int index) {
|
|
|
+ public AsmMethodBuilder store(IClass<?> type, int index) {
|
|
|
mv.visitVarInsn(AsmSupport.opcode(ISTORE, type), index);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder loadArray(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder loadArray(IClass<?> type) {
|
|
|
return ins(IALOAD, type);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder storeArray(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder storeArray(IClass<?> type) {
|
|
|
return ins(IASTORE, type);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder returns() {
|
|
|
+ public AsmMethodBuilder returns() {
|
|
|
mv.visitInsn(Opcodes.RETURN);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder returns(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder returns(IClass<?> type) {
|
|
|
return ins(IRETURN, type);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder putField(IClass<?> owner, IClass<?> type, String name) {
|
|
|
+ public AsmMethodBuilder putField(IClass<?> owner, IClass<?> type, String name) {
|
|
|
return ocField(PUTFIELD, owner, type, name);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder putField(IField field) {
|
|
|
+ public AsmMethodBuilder putField(IField field) {
|
|
|
return ocField(PUTFIELD, field);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder getField(IClass<?> owner, IClass<?> type, String name) {
|
|
|
+ public AsmMethodBuilder getField(IClass<?> owner, IClass<?> type, String name) {
|
|
|
return ocField(GETFIELD, owner, type, name);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder getField(IField field) {
|
|
|
+ public AsmMethodBuilder getField(IField field) {
|
|
|
return ocField(GETFIELD, field);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder putStatic(IClass<?> owner, IClass<?> type, String name) {
|
|
|
+ public AsmMethodBuilder putStatic(IClass<?> owner, IClass<?> type, String name) {
|
|
|
return ocField(PUTSTATIC, owner, type, name);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder putStatic(IField field) {
|
|
|
+ public AsmMethodBuilder putStatic(IField field) {
|
|
|
return ocField(PUTSTATIC, field);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder getStatic(IClass<?> owner, IClass<?> type, String name) {
|
|
|
+ public AsmMethodBuilder getStatic(IClass<?> owner, IClass<?> type, String name) {
|
|
|
return ocField(GETSTATIC, owner, type, name);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder getStatic(IField field) {
|
|
|
+ public AsmMethodBuilder getStatic(IField field) {
|
|
|
return ocField(GETSTATIC, field);
|
|
|
}
|
|
|
|
|
|
- private IMethodBuilder ocField(int oc, IField field) {
|
|
|
+ private AsmMethodBuilder 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) {
|
|
|
+ private AsmMethodBuilder ocField(int oc, IClass<?> owner, IClass<?> type, String name) {
|
|
|
mv.visitFieldInsn(oc, AsmSupport.path(owner), name, AsmSupport.vm(type));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeInit(IClass<?> owner, Iterable<IClass<?>> params) {
|
|
|
+ public AsmMethodBuilder 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(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
|
|
|
+ public AsmMethodBuilder invokeSpecial(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
|
|
|
return invoke(INVOKESPECIAL, owner, name, params, ret);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeSpecial(IClass<?> owner, IMethod method) {
|
|
|
+ public AsmMethodBuilder invokeSpecial(IClass<?> owner, IMethod method) {
|
|
|
return invoke(INVOKESPECIAL, owner, method);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeSpecial(IMethod method) {
|
|
|
+ public AsmMethodBuilder invokeSpecial(IMethod method) {
|
|
|
return invoke(INVOKESPECIAL, method);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeVirtual(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
|
|
|
+ public AsmMethodBuilder invokeVirtual(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
|
|
|
return invoke(AsmSupport.vcall(owner), owner, name, params, ret);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeVirtual(IClass<?> owner, IMethod method) {
|
|
|
+ public AsmMethodBuilder invokeVirtual(IClass<?> owner, IMethod method) {
|
|
|
return invoke(AsmSupport.vcall(owner, method), owner, method);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeVirtual(IMethod method) {
|
|
|
+ public AsmMethodBuilder invokeVirtual(IMethod method) {
|
|
|
return invoke(AsmSupport.vcall(method), method);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeStatic(IClass<?> owner, String name, Iterable<IClass<?>> params, IClass<?> ret) {
|
|
|
+ public AsmMethodBuilder 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) {
|
|
|
+ public AsmMethodBuilder invokeStatic(IClass<?> owner, IMethod method) {
|
|
|
return invoke(INVOKESTATIC, owner, method);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeStatic(IMethod method) {
|
|
|
+ public AsmMethodBuilder invokeStatic(IMethod method) {
|
|
|
return invoke(INVOKESTATIC, method);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder invokeDynamic(IMethod bootstrap, String name, Iterable<IClass<?>> params, IClass<?> ret, Object[] args) {
|
|
|
+ public AsmMethodBuilder invokeDynamic(IMethod bootstrap, String name, Iterable<IClass<?>> params, IClass<?> ret, Object[] args) {
|
|
|
Handle bootstrapHandle = new Handle(H_INVOKESTATIC, AsmSupport.path(bootstrap.parent()), bootstrap.name(), AsmSupport.vm(bootstrap), false);
|
|
|
mv.visitInvokeDynamicInsn(name, AsmSupport.vm(params, ret), bootstrapHandle, args);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- private IMethodBuilder invoke(int oc, IMethod method) {
|
|
|
+ private AsmMethodBuilder invoke(int oc, IMethod method) {
|
|
|
return invoke(oc, method.parent(), method);
|
|
|
}
|
|
|
|
|
|
- private IMethodBuilder invoke(int oc, IClass<?> owner, IMethod method) {
|
|
|
+ private AsmMethodBuilder 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) {
|
|
|
+ private AsmMethodBuilder 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) {
|
|
|
+ public AsmMethodBuilder newObject(IClass<?> type) {
|
|
|
if(type.attribute(IAttribute.ARRAY)) {
|
|
|
if(type.component().attribute(IAttribute.PRIMITIVE)) {
|
|
|
- mv.visitIntInsn(NEWARRAY, AsmSupport.ttype(type.component().raw()));
|
|
|
+ mv.visitIntInsn(NEWARRAY, AsmSupport.arrayType(type.component().raw()));
|
|
|
} else {
|
|
|
mv.visitTypeInsn(ANEWARRAY, AsmSupport.path(type.component()));
|
|
|
}
|
|
|
@@ -339,110 +300,102 @@ public class CMethodBuilder implements IMethodBuilder {
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder checkCast(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder checkCast(IClass<?> type) {
|
|
|
mv.visitTypeInsn(CHECKCAST, AsmSupport.path(type));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder isInstance(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder isInstance(IClass<?> type) {
|
|
|
mv.visitTypeInsn(INSTANCEOF, AsmSupport.path(type));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder box(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder box(IClass<?> type) {
|
|
|
IClass<?> wrapper = ClassUtils.box(type);
|
|
|
return invokeStatic(wrapper, "valueOf", Arrays.asList(type), wrapper);
|
|
|
}
|
|
|
|
|
|
- private IMethodBuilder ldc(Object v) {
|
|
|
+ private AsmMethodBuilder ldc(Object v) {
|
|
|
mv.visitLdcInsn(v);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- private IMethodBuilder ins(int oc) {
|
|
|
+ private AsmMethodBuilder ins(int oc) {
|
|
|
mv.visitInsn(oc);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- private IMethodBuilder ins(int oc, IClass<?> type) {
|
|
|
+ private AsmMethodBuilder ins(int oc, IClass<?> type) {
|
|
|
mv.visitInsn(AsmSupport.opcode(oc, type));
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder add(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder add(IClass<?> type) {
|
|
|
return ins(IADD, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder sub(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder sub(IClass<?> type) {
|
|
|
return ins(ISUB, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder div(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder div(IClass<?> type) {
|
|
|
return ins(IDIV, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder rem(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder rem(IClass<?> type) {
|
|
|
return ins(IREM, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder neg(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder neg(IClass<?> type) {
|
|
|
return ins(INEG, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder shl(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder shl(IClass<?> type) {
|
|
|
return ins(ISHR, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder shr(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder shr(IClass<?> type) {
|
|
|
return ins(ISHL, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder ushr(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder ushr(IClass<?> type) {
|
|
|
return ins(IUSHR, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder and(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder and(IClass<?> type) {
|
|
|
return ins(IAND, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder or(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder or(IClass<?> type) {
|
|
|
return ins(IOR, type);
|
|
|
}
|
|
|
|
|
|
- public IMethodBuilder xor(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder xor(IClass<?> type) {
|
|
|
return ins(IXOR, type);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder dup() {
|
|
|
+ public AsmMethodBuilder dup() {
|
|
|
return ins(DUP);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder dup(IClass<?> type) {
|
|
|
+ public AsmMethodBuilder dup(IClass<?> type) {
|
|
|
return dup(type, 0);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder dup(int x) {
|
|
|
+ public AsmMethodBuilder dup(int x) {
|
|
|
return dup(IClass.INT, x);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder dup(IClass<?> type, int x) {
|
|
|
+ public AsmMethodBuilder dup(IClass<?> type, int x) {
|
|
|
switch (x) {
|
|
|
- case 0: ins(AsmSupport.size(type) == 2 ? DUP2 : DUP);
|
|
|
- case 1: ins(AsmSupport.size(type) == 2 ? DUP2_X1 : DUP_X1);
|
|
|
- case 2: ins(AsmSupport.size(type) == 2 ? DUP2_X2 : DUP_X2);
|
|
|
+ case 0: ins(AsmSupport.sizeof(type) == 2 ? DUP2 : DUP);
|
|
|
+ case 1: ins(AsmSupport.sizeof(type) == 2 ? DUP2_X1 : DUP_X1);
|
|
|
+ case 2: ins(AsmSupport.sizeof(type) == 2 ? DUP2_X2 : DUP_X2);
|
|
|
}
|
|
|
throw new UnsupportedOperationException("DUP_X"+x + " does not exist.");
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public IMethodBuilder convert(IClass<?> source, IClass<?> target) {
|
|
|
+ public AsmMethodBuilder convert(IClass<?> source, IClass<?> target) {
|
|
|
if(source.equals(IClass.DOUBLE)) {
|
|
|
if(target.equals(IClass.FLOAT)) {
|
|
|
return ins(D2F);
|