Skip to content

Commit

Permalink
feat: OperandUtil#load supports array related operands.
Browse files Browse the repository at this point in the history
  • Loading branch information
teletha committed Feb 24, 2023
1 parent 8a7a3fe commit c9cf309
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 15 deletions.
8 changes: 4 additions & 4 deletions src/main/java/reincarnation/JavaClassDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
package reincarnation;

import static org.objectweb.asm.Opcodes.*;
import static reincarnation.Util.*;
import static reincarnation.OperandUtil.*;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -48,9 +48,9 @@ class JavaClassDecompiler extends ClassVisitor {
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
Debugger.current().start(source.clazz);

source.require(Util.load(superName));
source.require(OperandUtil.load(superName));
for (String i : interfaces) {
source.require(Util.load(i));
source.require(OperandUtil.load(i));
}
}

Expand All @@ -59,7 +59,7 @@ public void visit(int version, int access, String name, String signature, String
*/
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
source.require(Util.load(Type.getType(desc)));
source.require(OperandUtil.load(Type.getType(desc)));
return null;
}

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/reincarnation/JavaMethodDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import static org.objectweb.asm.Opcodes.*;
import static reincarnation.Node.Termination;
import static reincarnation.OperandCondition.*;
import static reincarnation.Util.load;
import static reincarnation.OperandUtil.load;

import java.lang.reflect.Executable;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -261,7 +261,7 @@ class JavaMethodDecompiler extends MethodVisitor implements Code {
super(ASM9);

this.source = source;
this.returnType = Util.load(returns);
this.returnType = OperandUtil.load(returns);
this.locals = locals;

debugger.startMethod(descriptor);
Expand Down Expand Up @@ -1426,7 +1426,7 @@ public void visitLdcInsn(Object constant) {
if (constant instanceof String) {
current.stack.add(new OperandString((String) constant));
} else if (constant instanceof Type) {
current.addOperand(new OperandClass(Util.load((Type) constant)));
current.addOperand(new OperandClass(OperandUtil.load((Type) constant)));
} else {
current.addOperand(constant);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/reincarnation/LocalVariables.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
package reincarnation;

import static reincarnation.Util.load;
import static reincarnation.OperandUtil.load;

import java.lang.reflect.Parameter;
import java.util.ArrayDeque;
Expand Down Expand Up @@ -53,7 +53,7 @@ final class LocalVariables {
}

for (int i = 0; i < types.length; i++) {
Class<?> type = Util.load(types[i]);
Class<?> type = OperandUtil.load(types[i]);
OperandLocalVariable variable = new OperandLocalVariable(type, offset, parameters[i].getName());
variable.fix();
params.put(offset, variable);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/reincarnation/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ final void condition(Operand left, int operator, Operand right, Node transition)
final Node join(BinaryOperator operator, int opecode) {
Operand right = remove(0);
Operand left = remove(0);
addOperand(new OperandBinary(left, operator, right).fix(Util.load(opecode)));
addOperand(new OperandBinary(left, operator, right).fix(OperandUtil.load(opecode)));

// API definition
return this;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/reincarnation/OperandArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ protected void writeCode(Coder coder) {

// fill by default value
for (int i = 0; i < requiredSize; i++) {
initializer.add(i, Util.defaultValueFor(type));
initializer.add(i, OperandUtil.defaultValueFor(type));
}

// assign by specified value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

/**
* @version 2018/10/22 19:06:27
*/
public class Util {
public class OperandUtil {

/**
* Load {@link Class} by internal name.
Expand Down Expand Up @@ -64,6 +61,8 @@ static Class load(int opecode) {
case L2I:
case F2I:
case D2I:
case IALOAD:
case IASTORE:
return int.class;

case LADD:
Expand All @@ -86,6 +85,8 @@ static Class load(int opecode) {
case I2L:
case F2L:
case D2L:
case LALOAD:
case LASTORE:
return long.class;

case FADD:
Expand All @@ -103,6 +104,8 @@ static Class load(int opecode) {
case I2F:
case L2F:
case D2F:
case FALOAD:
case FASTORE:
return float.class;

case DADD:
Expand All @@ -119,6 +122,8 @@ static Class load(int opecode) {
case I2D:
case L2D:
case F2D:
case DALOAD:
case DASTORE:
return double.class;

case ALOAD:
Expand Down
231 changes: 231 additions & 0 deletions src/test/java/reincarnation/decompiler/array/IntArrayTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/*
* Copyright (C) 2023 The REINCARNATION Development Team
*
* Licensed under the MIT License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/MIT
*/
package reincarnation.decompiler.array;

import org.junit.jupiter.api.Test;

import reincarnation.CodeVerifier;
import reincarnation.Debuggable;
import reincarnation.TestCode;

public class IntArrayTest extends CodeVerifier {

@Test
@Debuggable
public void base() {
verify(new TestCode.IntArray() {

@Override
public int[] run() {
int[] array = new int[2];
array[0] = 0;
array[1] = 1;

return array;
}
});
}

@Test
public void multipleAssign() throws Exception {
verify(new TestCode.IntArray() {

@Override
public int[] run() {
int[] array = new int[3];
array[0] = array[1] = array[2] = 1;

return array;
}
});
}

@Test
public void ArrayWithExpression() {
verify(new TestCode.IntArray() {

private int field = 1;

@Override
public int[] run() {
int[] array = new int[2];
array[0] = field;
array[1] = field + 1;

return array;
}
});
}

@Test
public void ArrayByShorthand() {
verify(new TestCode.IntArray() {

@Override

public int[] run() {
return new int[] {1, 0};
}
});
}

@Test
public void ArrayByShorthandWithAllFalse() {
verify(new TestCode.IntArray() {

@Override
public int[] run() {
return new int[] {0, 0};
}
});
}

@Test
public void ArrayWithExpressionByShorthand() {
verify(new TestCode.IntArray() {

private int field = 1;

@Override
public int[] run() {
return new int[] {field, field + 1};
}
});
}

@Test
public void ArraySoMany() {
verify(new TestCode.IntArray() {

@Override
public int[] run() {
return new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -1, -2};
}
});
}

@Test
public void MultiDimensionArray() {
verify(new TestCode.Object<int[][]>() {

@Override
public int[][] run() {
int[][] array = new int[3][2];
array[0] = new int[] {1, 2};
array[1] = new int[] {3, 4};
array[2] = new int[] {5, 6};

return array;
}
});
}

@Test
public void MultiDimensionArrayByShorthand() {
verify(new TestCode.Object<int[][]>() {

@Override
public int[][] run() {
return new int[][] {{1, 2}, {3, 4}, {5, 6}};
}
});
}

@Test
public void ThreeDimensionArray() {
verify(new TestCode.Object<int[][][]>() {

@Override
public int[][][] run() {
int[][][] array = new int[2][3][1];
array[0] = new int[][] {{1}, {2}, {3}};
array[1] = new int[][] {{5}, {6}, {7, 8, 9}};

return array;
}
});
}

@Test
public void ThreeDimensionArrayWithoutNeedlessDeclaration() {
verify(new TestCode.Object<int[][][]>() {

@Override
public int[][][] run() {
int[][][] array = new int[2][][];
array[0] = new int[][] {{1}, {2}, {3}};
array[1] = new int[][] {{4}, {5}, {6, 7, 8}};

return array;
}
});
}

@Test
public void ArrayAccess() {
verify(new TestCode.IntParam() {

@Override
public int run(int value) {
int[] array = {1, value};

return array[1];
}
});
}

@Test
public void ArrayLength() {
verify(new TestCode.IntParam() {

@Override
public int run(@Param(ints = {0, 1, 10}) int value) {
return new int[value].length;
}
});
}

@Test
public void ArrayFor() {
verify(new TestCode.IntParam() {

@Override
public int run(int value) {
int sum = 0;
int[] array = {1, 2, 3};

for (int i = 0; i < array.length; i++) {
if (array[i] == 1) {
sum++;
}
}
return sum;
}
});
}

@Test
public void ArrayForEach() {
verify(new TestCode.IntParam() {
@Override
public int run(int value) {
int sum = 0;
int[] array = {1, 2, 3};

for (int i : array) {
if (i == 1) {
sum++;
}
}
return sum;
}
});
}
}

0 comments on commit c9cf309

Please sign in to comment.