|
|
@ -15,6 +15,14 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package org.jetbrains.java.decompiler.modules.decompiler; |
|
|
|
package org.jetbrains.java.decompiler.modules.decompiler; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
import java.util.HashMap; |
|
|
|
|
|
|
|
import java.util.HashSet; |
|
|
|
|
|
|
|
import java.util.LinkedList; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.code.CodeConstants; |
|
|
|
import org.jetbrains.java.decompiler.code.CodeConstants; |
|
|
|
import org.jetbrains.java.decompiler.code.Instruction; |
|
|
|
import org.jetbrains.java.decompiler.code.Instruction; |
|
|
|
import org.jetbrains.java.decompiler.code.InstructionSequence; |
|
|
|
import org.jetbrains.java.decompiler.code.InstructionSequence; |
|
|
@ -22,12 +30,28 @@ import org.jetbrains.java.decompiler.code.cfg.BasicBlock; |
|
|
|
import org.jetbrains.java.decompiler.main.DecompilerContext; |
|
|
|
import org.jetbrains.java.decompiler.main.DecompilerContext; |
|
|
|
import org.jetbrains.java.decompiler.main.TextBuffer; |
|
|
|
import org.jetbrains.java.decompiler.main.TextBuffer; |
|
|
|
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; |
|
|
|
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.*; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.ArrayExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.FieldExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.IfExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.MonitorExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.SwitchExprent; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.FlattenStatementsHelper; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.FlattenStatementsHelper; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.FlattenStatementsHelper.FinallyPathWrapper; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.sforms.FlattenStatementsHelper.FinallyPathWrapper; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.stats.*; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchAllStatement; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.stats.CatchStatement; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; |
|
|
|
|
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; |
|
|
|
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; |
|
|
|
import org.jetbrains.java.decompiler.struct.StructClass; |
|
|
|
import org.jetbrains.java.decompiler.struct.StructClass; |
|
|
|
import org.jetbrains.java.decompiler.struct.attr.StructBootstrapMethodsAttribute; |
|
|
|
import org.jetbrains.java.decompiler.struct.attr.StructBootstrapMethodsAttribute; |
|
|
@ -40,8 +64,6 @@ import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; |
|
|
|
import org.jetbrains.java.decompiler.struct.gen.VarType; |
|
|
|
import org.jetbrains.java.decompiler.struct.gen.VarType; |
|
|
|
import org.jetbrains.java.decompiler.util.InterpreterUtil; |
|
|
|
import org.jetbrains.java.decompiler.util.InterpreterUtil; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class ExprProcessor implements CodeConstants { |
|
|
|
public class ExprProcessor implements CodeConstants { |
|
|
|
|
|
|
|
|
|
|
|
public static final String UNDEFINED_TYPE_STRING = "<undefinedtype>"; |
|
|
|
public static final String UNDEFINED_TYPE_STRING = "<undefinedtype>"; |
|
|
@ -333,33 +355,34 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
|
|
|
|
|
|
|
|
Instruction instr = seq.getInstr(i); |
|
|
|
Instruction instr = seq.getInstr(i); |
|
|
|
Integer bytecode_offset = block.getOldOffset(i); |
|
|
|
Integer bytecode_offset = block.getOldOffset(i); |
|
|
|
|
|
|
|
Set<Integer> bytecode_offsets = bytecode_offset >= 0 ? new HashSet<Integer>(Arrays.asList(bytecode_offset)) : null; |
|
|
|
|
|
|
|
|
|
|
|
switch (instr.opcode) { |
|
|
|
switch (instr.opcode) { |
|
|
|
case opc_aconst_null: |
|
|
|
case opc_aconst_null: |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_NULL, null)); |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_NULL, null, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_bipush: |
|
|
|
case opc_bipush: |
|
|
|
case opc_sipush: |
|
|
|
case opc_sipush: |
|
|
|
pushEx(stack, exprlist, new ConstExprent(instr.getOperand(0), true)); |
|
|
|
pushEx(stack, exprlist, new ConstExprent(instr.getOperand(0), true, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_lconst_0: |
|
|
|
case opc_lconst_0: |
|
|
|
case opc_lconst_1: |
|
|
|
case opc_lconst_1: |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_LONG, new Long(instr.opcode - opc_lconst_0))); |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_LONG, new Long(instr.opcode - opc_lconst_0), bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_fconst_0: |
|
|
|
case opc_fconst_0: |
|
|
|
case opc_fconst_1: |
|
|
|
case opc_fconst_1: |
|
|
|
case opc_fconst_2: |
|
|
|
case opc_fconst_2: |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_FLOAT, new Float(instr.opcode - opc_fconst_0))); |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_FLOAT, new Float(instr.opcode - opc_fconst_0), bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_dconst_0: |
|
|
|
case opc_dconst_0: |
|
|
|
case opc_dconst_1: |
|
|
|
case opc_dconst_1: |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(instr.opcode - opc_dconst_0))); |
|
|
|
pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(instr.opcode - opc_dconst_0), bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_ldc: |
|
|
|
case opc_ldc: |
|
|
|
case opc_ldc_w: |
|
|
|
case opc_ldc_w: |
|
|
|
case opc_ldc2_w: |
|
|
|
case opc_ldc2_w: |
|
|
|
PrimitiveConstant cn = pool.getPrimitiveConstant(instr.getOperand(0)); |
|
|
|
PrimitiveConstant cn = pool.getPrimitiveConstant(instr.getOperand(0)); |
|
|
|
pushEx(stack, exprlist, new ConstExprent(consts[cn.type - CONSTANT_Integer], cn.value)); |
|
|
|
pushEx(stack, exprlist, new ConstExprent(consts[cn.type - CONSTANT_Integer], cn.value, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_iload: |
|
|
|
case opc_iload: |
|
|
|
case opc_lload: |
|
|
|
case opc_lload: |
|
|
@ -387,7 +410,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
case opc_daload: |
|
|
|
case opc_daload: |
|
|
|
vartype = VarType.VARTYPE_DOUBLE; |
|
|
|
vartype = VarType.VARTYPE_DOUBLE; |
|
|
|
} |
|
|
|
} |
|
|
|
pushEx(stack, exprlist, new ArrayExprent(arr, index, arrtypes[instr.opcode - opc_iaload]), vartype); |
|
|
|
pushEx(stack, exprlist, new ArrayExprent(arr, index, arrtypes[instr.opcode - opc_iaload], bytecode_offsets), vartype); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_istore: |
|
|
|
case opc_istore: |
|
|
|
case opc_lstore: |
|
|
|
case opc_lstore: |
|
|
@ -397,7 +420,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
Exprent top = stack.pop(); |
|
|
|
Exprent top = stack.pop(); |
|
|
|
int varindex = instr.getOperand(0); |
|
|
|
int varindex = instr.getOperand(0); |
|
|
|
AssignmentExprent assign = |
|
|
|
AssignmentExprent assign = |
|
|
|
new AssignmentExprent(new VarExprent(varindex, vartypes[instr.opcode - opc_istore], varProcessor), top); |
|
|
|
new AssignmentExprent(new VarExprent(varindex, vartypes[instr.opcode - opc_istore], varProcessor), top, bytecode_offsets); |
|
|
|
exprlist.add(assign); |
|
|
|
exprlist.add(assign); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_iastore: |
|
|
|
case opc_iastore: |
|
|
@ -412,7 +435,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
Exprent index_store = stack.pop(); |
|
|
|
Exprent index_store = stack.pop(); |
|
|
|
Exprent arr_store = stack.pop(); |
|
|
|
Exprent arr_store = stack.pop(); |
|
|
|
AssignmentExprent arrassign = |
|
|
|
AssignmentExprent arrassign = |
|
|
|
new AssignmentExprent(new ArrayExprent(arr_store, index_store, arrtypes[instr.opcode - opc_iastore]), value); |
|
|
|
new AssignmentExprent(new ArrayExprent(arr_store, index_store, arrtypes[instr.opcode - opc_iastore], bytecode_offsets), value, bytecode_offsets); |
|
|
|
exprlist.add(arrassign); |
|
|
|
exprlist.add(arrassign); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_iadd: |
|
|
|
case opc_iadd: |
|
|
@ -435,7 +458,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
case opc_lrem: |
|
|
|
case opc_lrem: |
|
|
|
case opc_frem: |
|
|
|
case opc_frem: |
|
|
|
case opc_drem: |
|
|
|
case opc_drem: |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func1[(instr.opcode - opc_iadd) / 4], stack)); |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func1[(instr.opcode - opc_iadd) / 4], stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_ishl: |
|
|
|
case opc_ishl: |
|
|
|
case opc_lshl: |
|
|
|
case opc_lshl: |
|
|
@ -449,19 +472,20 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
case opc_lor: |
|
|
|
case opc_lor: |
|
|
|
case opc_ixor: |
|
|
|
case opc_ixor: |
|
|
|
case opc_lxor: |
|
|
|
case opc_lxor: |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func2[(instr.opcode - opc_ishl) / 2], stack)); |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func2[(instr.opcode - opc_ishl) / 2], stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_ineg: |
|
|
|
case opc_ineg: |
|
|
|
case opc_lneg: |
|
|
|
case opc_lneg: |
|
|
|
case opc_fneg: |
|
|
|
case opc_fneg: |
|
|
|
case opc_dneg: |
|
|
|
case opc_dneg: |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(FunctionExprent.FUNCTION_NEG, stack)); |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(FunctionExprent.FUNCTION_NEG, stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_iinc: |
|
|
|
case opc_iinc: |
|
|
|
VarExprent vevar = new VarExprent(instr.getOperand(0), VarType.VARTYPE_INT, varProcessor); |
|
|
|
VarExprent vevar = new VarExprent(instr.getOperand(0), VarType.VARTYPE_INT, varProcessor); |
|
|
|
exprlist.add(new AssignmentExprent(vevar, new FunctionExprent( |
|
|
|
exprlist.add(new AssignmentExprent(vevar, new FunctionExprent( |
|
|
|
instr.getOperand(1) < 0 ? FunctionExprent.FUNCTION_SUB : FunctionExprent.FUNCTION_ADD, Arrays |
|
|
|
instr.getOperand(1) < 0 ? FunctionExprent.FUNCTION_SUB : FunctionExprent.FUNCTION_ADD, Arrays |
|
|
|
.asList(new Exprent[]{vevar.copy(), new ConstExprent(VarType.VARTYPE_INT, new Integer(Math.abs(instr.getOperand(1))))})))); |
|
|
|
.asList(vevar.copy(), new ConstExprent(VarType.VARTYPE_INT, Math.abs(instr.getOperand(1)), null)), |
|
|
|
|
|
|
|
bytecode_offsets), bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_i2l: |
|
|
|
case opc_i2l: |
|
|
|
case opc_i2f: |
|
|
|
case opc_i2f: |
|
|
@ -478,14 +502,14 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
case opc_i2b: |
|
|
|
case opc_i2b: |
|
|
|
case opc_i2c: |
|
|
|
case opc_i2c: |
|
|
|
case opc_i2s: |
|
|
|
case opc_i2s: |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func3[instr.opcode - opc_i2l], stack)); |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func3[instr.opcode - opc_i2l], stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_lcmp: |
|
|
|
case opc_lcmp: |
|
|
|
case opc_fcmpl: |
|
|
|
case opc_fcmpl: |
|
|
|
case opc_fcmpg: |
|
|
|
case opc_fcmpg: |
|
|
|
case opc_dcmpl: |
|
|
|
case opc_dcmpl: |
|
|
|
case opc_dcmpg: |
|
|
|
case opc_dcmpg: |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func4[instr.opcode - opc_lcmp], stack)); |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(func4[instr.opcode - opc_lcmp], stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_ifeq: |
|
|
|
case opc_ifeq: |
|
|
|
case opc_ifne: |
|
|
|
case opc_ifne: |
|
|
@ -493,7 +517,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
case opc_ifge: |
|
|
|
case opc_ifge: |
|
|
|
case opc_ifgt: |
|
|
|
case opc_ifgt: |
|
|
|
case opc_ifle: |
|
|
|
case opc_ifle: |
|
|
|
exprlist.add(new IfExprent(negifs[func5[instr.opcode - opc_ifeq]], stack)); |
|
|
|
exprlist.add(new IfExprent(negifs[func5[instr.opcode - opc_ifeq]], stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_if_icmpeq: |
|
|
|
case opc_if_icmpeq: |
|
|
|
case opc_if_icmpne: |
|
|
|
case opc_if_icmpne: |
|
|
@ -503,16 +527,16 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
case opc_if_icmple: |
|
|
|
case opc_if_icmple: |
|
|
|
case opc_if_acmpeq: |
|
|
|
case opc_if_acmpeq: |
|
|
|
case opc_if_acmpne: |
|
|
|
case opc_if_acmpne: |
|
|
|
exprlist.add(new IfExprent(negifs[func6[instr.opcode - opc_if_icmpeq]], stack)); |
|
|
|
exprlist.add(new IfExprent(negifs[func6[instr.opcode - opc_if_icmpeq]], stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_ifnull: |
|
|
|
case opc_ifnull: |
|
|
|
case opc_ifnonnull: |
|
|
|
case opc_ifnonnull: |
|
|
|
exprlist.add(new IfExprent(negifs[func7[instr.opcode - opc_ifnull]], stack)); |
|
|
|
exprlist.add(new IfExprent(negifs[func7[instr.opcode - opc_ifnull]], stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_tableswitch: |
|
|
|
case opc_tableswitch: |
|
|
|
case opc_lookupswitch: |
|
|
|
case opc_lookupswitch: |
|
|
|
exprlist.add(new SwitchExprent(stack.pop())); |
|
|
|
exprlist.add(new SwitchExprent(stack.pop(), bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_ireturn: |
|
|
|
case opc_ireturn: |
|
|
|
case opc_lreturn: |
|
|
|
case opc_lreturn: |
|
|
|
case opc_freturn: |
|
|
|
case opc_freturn: |
|
|
@ -525,29 +549,30 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
instr.opcode == opc_athrow |
|
|
|
instr.opcode == opc_athrow |
|
|
|
? null |
|
|
|
? null |
|
|
|
: ((MethodDescriptor)DecompilerContext |
|
|
|
: ((MethodDescriptor)DecompilerContext |
|
|
|
.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret)); |
|
|
|
.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret, |
|
|
|
break; |
|
|
|
bytecode_offsets)); |
|
|
|
|
|
|
|
break; |
|
|
|
case opc_monitorenter: |
|
|
|
case opc_monitorenter: |
|
|
|
case opc_monitorexit: |
|
|
|
case opc_monitorexit: |
|
|
|
exprlist.add(new MonitorExprent(func8[instr.opcode - opc_monitorenter], stack.pop())); |
|
|
|
exprlist.add(new MonitorExprent(func8[instr.opcode - opc_monitorenter], stack.pop(), bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_checkcast: |
|
|
|
case opc_checkcast: |
|
|
|
case opc_instanceof: |
|
|
|
case opc_instanceof: |
|
|
|
stack.push(new ConstExprent(new VarType(pool.getPrimitiveConstant(instr.getOperand(0)).getString(), true), null)); |
|
|
|
stack.push(new ConstExprent(new VarType(pool.getPrimitiveConstant(instr.getOperand(0)).getString(), true), null, null)); |
|
|
|
case opc_arraylength: |
|
|
|
case opc_arraylength: |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(mapConsts.get(instr.opcode).intValue(), stack)); |
|
|
|
pushEx(stack, exprlist, new FunctionExprent(mapConsts.get(instr.opcode).intValue(), stack, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_getstatic: |
|
|
|
case opc_getstatic: |
|
|
|
case opc_getfield: |
|
|
|
case opc_getfield: |
|
|
|
pushEx(stack, exprlist, |
|
|
|
pushEx(stack, exprlist, |
|
|
|
new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_getstatic ? null : stack.pop())); |
|
|
|
new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_getstatic ? null : stack.pop(), bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_putstatic: |
|
|
|
case opc_putstatic: |
|
|
|
case opc_putfield: |
|
|
|
case opc_putfield: |
|
|
|
Exprent valfield = stack.pop(); |
|
|
|
Exprent valfield = stack.pop(); |
|
|
|
Exprent exprfield = |
|
|
|
Exprent exprfield = |
|
|
|
new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_putstatic ? null : stack.pop()); |
|
|
|
new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_putstatic ? null : stack.pop(), bytecode_offsets); |
|
|
|
exprlist.add(new AssignmentExprent(exprfield, valfield)); |
|
|
|
exprlist.add(new AssignmentExprent(exprfield, valfield, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_invokevirtual: |
|
|
|
case opc_invokevirtual: |
|
|
|
case opc_invokespecial: |
|
|
|
case opc_invokespecial: |
|
|
@ -566,7 +591,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
dynamic_invokation_type = content_method_handle.index1; |
|
|
|
dynamic_invokation_type = content_method_handle.index1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
InvocationExprent exprinv = new InvocationExprent(instr.opcode, invoke_constant, stack, dynamic_invokation_type); |
|
|
|
InvocationExprent exprinv = new InvocationExprent(instr.opcode, invoke_constant, stack, dynamic_invokation_type, bytecode_offsets); |
|
|
|
if (exprinv.getDescriptor().ret.type == CodeConstants.TYPE_VOID) { |
|
|
|
if (exprinv.getDescriptor().ret.type == CodeConstants.TYPE_VOID) { |
|
|
|
exprlist.add(exprinv); |
|
|
|
exprlist.add(exprinv); |
|
|
|
} |
|
|
|
} |
|
|
@ -583,10 +608,10 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
if (instr.opcode != opc_multianewarray) { |
|
|
|
if (instr.opcode != opc_multianewarray) { |
|
|
|
arrtype.arraydim += arrdims; |
|
|
|
arrtype.arraydim += arrdims; |
|
|
|
} |
|
|
|
} |
|
|
|
pushEx(stack, exprlist, new NewExprent(arrtype, stack, arrdims)); |
|
|
|
pushEx(stack, exprlist, new NewExprent(arrtype, stack, arrdims, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_newarray: |
|
|
|
case opc_newarray: |
|
|
|
pushEx(stack, exprlist, new NewExprent(new VarType(arr_type[instr.getOperand(0) - 4], 1), stack, 1)); |
|
|
|
pushEx(stack, exprlist, new NewExprent(new VarType(arr_type[instr.getOperand(0) - 4], 1), stack, 1, bytecode_offsets)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case opc_dup: |
|
|
|
case opc_dup: |
|
|
|
pushEx(stack, exprlist, stack.getByOffset(-1).copy()); |
|
|
|
pushEx(stack, exprlist, stack.getByOffset(-1).copy()); |
|
|
@ -660,7 +685,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
VarExprent var = new VarExprent(varindex, vartype == null ? exprent.getExprType() : vartype, varProcessor); |
|
|
|
VarExprent var = new VarExprent(varindex, vartype == null ? exprent.getExprType() : vartype, varProcessor); |
|
|
|
var.setStack(true); |
|
|
|
var.setStack(true); |
|
|
|
|
|
|
|
|
|
|
|
exprlist.add(new AssignmentExprent(var, exprent)); |
|
|
|
exprlist.add(new AssignmentExprent(var, exprent, null)); |
|
|
|
stack.push(var.copy()); |
|
|
|
stack.push(var.copy()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -674,14 +699,14 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
Exprent varex = stack.pop(); |
|
|
|
Exprent varex = stack.pop(); |
|
|
|
VarExprent varnew = new VarExprent(base + i + 1, varex.getExprType(), varProcessor); |
|
|
|
VarExprent varnew = new VarExprent(base + i + 1, varex.getExprType(), varProcessor); |
|
|
|
varnew.setStack(true); |
|
|
|
varnew.setStack(true); |
|
|
|
exprlist.add(new AssignmentExprent(varnew, varex)); |
|
|
|
exprlist.add(new AssignmentExprent(varnew, varex, null)); |
|
|
|
lst.add(0, (VarExprent)varnew.copy()); |
|
|
|
lst.add(0, (VarExprent)varnew.copy()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Exprent exprent = lst.get(lst.size() + copyoffset).copy(); |
|
|
|
Exprent exprent = lst.get(lst.size() + copyoffset).copy(); |
|
|
|
VarExprent var = new VarExprent(base + offset, exprent.getExprType(), varProcessor); |
|
|
|
VarExprent var = new VarExprent(base + offset, exprent.getExprType(), varProcessor); |
|
|
|
var.setStack(true); |
|
|
|
var.setStack(true); |
|
|
|
exprlist.add(new AssignmentExprent(var, exprent)); |
|
|
|
exprlist.add(new AssignmentExprent(var, exprent, null)); |
|
|
|
lst.add(0, (VarExprent)var.copy()); |
|
|
|
lst.add(0, (VarExprent)var.copy()); |
|
|
|
|
|
|
|
|
|
|
|
for (VarExprent expr : lst) { |
|
|
|
for (VarExprent expr : lst) { |
|
|
@ -742,7 +767,7 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
VarExprent vartmp = new VarExprent(VarExprent.STACK_BASE, var.getExprType(), var.getProcessor()); |
|
|
|
VarExprent vartmp = new VarExprent(VarExprent.STACK_BASE, var.getExprType(), var.getProcessor()); |
|
|
|
vartmp.setStack(true); |
|
|
|
vartmp.setStack(true); |
|
|
|
|
|
|
|
|
|
|
|
prlst.getLstExprents().add(new AssignmentExprent(vartmp, var.copy())); |
|
|
|
prlst.getLstExprents().add(new AssignmentExprent(vartmp, var.copy(), null)); |
|
|
|
prlst.getStack().push(vartmp.copy()); |
|
|
|
prlst.getStack().push(vartmp.copy()); |
|
|
|
return prlst; |
|
|
|
return prlst; |
|
|
|
} |
|
|
|
} |
|
|
@ -840,19 +865,19 @@ public class ExprProcessor implements CodeConstants { |
|
|
|
|
|
|
|
|
|
|
|
ConstExprent defaultval; |
|
|
|
ConstExprent defaultval; |
|
|
|
if (arrtype.type == CodeConstants.TYPE_OBJECT || arrtype.arraydim > 0) { |
|
|
|
if (arrtype.type == CodeConstants.TYPE_OBJECT || arrtype.arraydim > 0) { |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_NULL, null); |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_NULL, null, null); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (arrtype.type == CodeConstants.TYPE_FLOAT) { |
|
|
|
else if (arrtype.type == CodeConstants.TYPE_FLOAT) { |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_FLOAT, new Float(0)); |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_FLOAT, new Float(0), null); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (arrtype.type == CodeConstants.TYPE_LONG) { |
|
|
|
else if (arrtype.type == CodeConstants.TYPE_LONG) { |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_LONG, new Long(0)); |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_LONG, new Long(0), null); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (arrtype.type == CodeConstants.TYPE_DOUBLE) { |
|
|
|
else if (arrtype.type == CodeConstants.TYPE_DOUBLE) { |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0)); |
|
|
|
defaultval = new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0), null); |
|
|
|
} |
|
|
|
} |
|
|
|
else { // integer types
|
|
|
|
else { // integer types
|
|
|
|
defaultval = new ConstExprent(0, true); |
|
|
|
defaultval = new ConstExprent(0, true, null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return defaultval; |
|
|
|
return defaultval; |
|
|
|