mirror of
https://github.com/EsotericSoftware/reflectasm.git
synced 2025-03-29 13:30:46 +08:00
parent
ade0542b62
commit
54f453484e
src/com/esotericsoftware/reflectasm
@ -108,7 +108,11 @@ public abstract class FieldAccess {
|
||||
|
||||
abstract public float getFloat (Object instance, int fieldIndex);
|
||||
|
||||
/** @param type Must not be the Object class, an interface, a primitive type, or void. */
|
||||
static public FieldAccess get (Class type) {
|
||||
if (type.getSuperclass() == null)
|
||||
throw new IllegalArgumentException("The type must not be the Object class, an interface, a primitive type, or void.");
|
||||
|
||||
ArrayList<Field> fields = new ArrayList<Field>();
|
||||
Class nextClass = type;
|
||||
while (nextClass != Object.class) {
|
||||
@ -424,8 +428,8 @@ public abstract class FieldAccess {
|
||||
break;
|
||||
case Type.DOUBLE:
|
||||
setterMethodName = "setDouble";
|
||||
loadValueInstruction = DLOAD; // (LLOAD and DLOAD actually load two slots)
|
||||
maxLocals++;
|
||||
loadValueInstruction = DLOAD;
|
||||
maxLocals++; // (LLOAD and DLOAD actually load two slots)
|
||||
break;
|
||||
default:
|
||||
setterMethodName = "set";
|
||||
|
@ -62,7 +62,8 @@ public abstract class MethodAccess {
|
||||
public int getIndex (String methodName, int paramsCount) {
|
||||
for (int i = 0, n = methodNames.length; i < n; i++)
|
||||
if (methodNames[i].equals(methodName) && parameterTypes[i].length == paramsCount) return i;
|
||||
throw new IllegalArgumentException("Unable to find non-private method: " + methodName + " with " + paramsCount + " params.");
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to find non-private method: " + methodName + " with " + paramsCount + " params.");
|
||||
}
|
||||
|
||||
public String[] getMethodNames () {
|
||||
@ -77,7 +78,11 @@ public abstract class MethodAccess {
|
||||
return returnTypes;
|
||||
}
|
||||
|
||||
/** @param type Must not be the Object class, an interface, a primitive type, or void. */
|
||||
static public MethodAccess get (Class type) {
|
||||
if (type.getSuperclass() == null)
|
||||
throw new IllegalArgumentException("The type must not be the Object class, an interface, a primitive type, or void.");
|
||||
|
||||
ArrayList<Method> methods = new ArrayList<Method>();
|
||||
boolean isInterface = type.isInterface();
|
||||
if (!isInterface) {
|
||||
@ -116,11 +121,11 @@ public abstract class MethodAccess {
|
||||
} catch (ClassNotFoundException ignored2) {
|
||||
String accessClassNameInternal = accessClassName.replace('.', '/');
|
||||
String classNameInternal = className.replace('.', '/');
|
||||
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
MethodVisitor mv;
|
||||
cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, "com/esotericsoftware/reflectasm/MethodAccess",
|
||||
null);
|
||||
cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null,
|
||||
"com/esotericsoftware/reflectasm/MethodAccess", null);
|
||||
{
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
@ -134,19 +139,19 @@ public abstract class MethodAccess {
|
||||
mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke",
|
||||
"(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null);
|
||||
mv.visitCode();
|
||||
|
||||
|
||||
if (!methods.isEmpty()) {
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitTypeInsn(CHECKCAST, classNameInternal);
|
||||
mv.visitVarInsn(ASTORE, 4);
|
||||
|
||||
|
||||
mv.visitVarInsn(ILOAD, 2);
|
||||
Label[] labels = new Label[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
labels[i] = new Label();
|
||||
Label defaultLabel = new Label();
|
||||
mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);
|
||||
|
||||
|
||||
StringBuilder buffer = new StringBuilder(128);
|
||||
for (int i = 0; i < n; i++) {
|
||||
mv.visitLabel(labels[i]);
|
||||
@ -155,10 +160,10 @@ public abstract class MethodAccess {
|
||||
else
|
||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
||||
mv.visitVarInsn(ALOAD, 4);
|
||||
|
||||
|
||||
buffer.setLength(0);
|
||||
buffer.append('(');
|
||||
|
||||
|
||||
Class[] paramTypes = parameterTypes[i];
|
||||
Class returnType = returnTypes[i];
|
||||
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
|
||||
@ -208,7 +213,7 @@ public abstract class MethodAccess {
|
||||
}
|
||||
buffer.append(paramType.getDescriptor());
|
||||
}
|
||||
|
||||
|
||||
buffer.append(')');
|
||||
buffer.append(Type.getDescriptor(returnType));
|
||||
int invoke;
|
||||
@ -219,7 +224,7 @@ public abstract class MethodAccess {
|
||||
else
|
||||
invoke = INVOKEVIRTUAL;
|
||||
mv.visitMethodInsn(invoke, classNameInternal, methodNames[i], buffer.toString());
|
||||
|
||||
|
||||
switch (Type.getType(returnType).getSort()) {
|
||||
case Type.VOID:
|
||||
mv.visitInsn(ACONST_NULL);
|
||||
@ -249,10 +254,10 @@ public abstract class MethodAccess {
|
||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
mv.visitInsn(ARETURN);
|
||||
}
|
||||
|
||||
|
||||
mv.visitLabel(defaultLabel);
|
||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user