Activated bytecode-to-source mapping for all instructions

This commit is contained in:
Stiver 2014-10-15 06:26:49 +02:00
parent 46b494f26f
commit c975f11ecc
29 changed files with 287 additions and 188 deletions

View File

@ -174,7 +174,7 @@ public class AssertProcessor {
Exprent ascond = null, retcond = null;
if (exprres[0] != null) {
ascond = new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT,
Arrays.asList(new Exprent[]{(Exprent)exprres[0]}));
Arrays.asList((Exprent)exprres[0]), throwError.bytecode);
retcond = SecondaryFunctionsHelper.propagateBoolNot(ascond);
}

View File

@ -55,7 +55,7 @@ public class ClassReference14Processor {
bodyexprent = new ExitExprent(ExitExprent.EXIT_RETURN,
invfor,
VarType.VARTYPE_CLASS);
VarType.VARTYPE_CLASS, null);
InvocationExprent constr = new InvocationExprent();
constr.setName("<init>");
@ -65,7 +65,7 @@ public class ClassReference14Processor {
constr.setDescriptor(MethodDescriptor.parseDescriptor("()V"));
NewExprent newexpr =
new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList<Exprent>());
new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList<Exprent>(), null);
newexpr.setConstructor(constr);
InvocationExprent invcause = new InvocationExprent();
@ -79,7 +79,7 @@ public class ClassReference14Processor {
handlerexprent = new ExitExprent(ExitExprent.EXIT_THROW,
invcause,
null);
null, null);
}
@ -160,7 +160,7 @@ public class ClassReference14Processor {
String cl = isClass14Invocation(exprent, ent.getKey(), ent.getValue());
if (cl != null) {
initializers.set(i, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/')));
initializers.set(i, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/'), exprent.bytecode));
setFound.add(ent.getKey());
}
}
@ -225,7 +225,7 @@ public class ClassReference14Processor {
for (Exprent expr : exprent.getAllExprents()) {
String cl = isClass14Invocation(expr, wrapper, meth);
if (cl != null) {
exprent.replaceExprent(expr, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/')));
exprent.replaceExprent(expr, new ConstExprent(VarType.VARTYPE_CLASS, cl.replace('.', '/'), expr.bytecode));
found = true;
res = true;
break;

View File

@ -462,7 +462,7 @@ public class ClassWriter {
if (attr != null) {
PrimitiveConstant constant = cl.getPool().getPrimitiveConstant(attr.getIndex());
buffer.append(" = ");
buffer.append(new ConstExprent(fieldType, constant.value).toJava(indent, tracer));
buffer.append(new ConstExprent(fieldType, constant.value, null).toJava(indent, tracer));
}
}

View File

@ -287,7 +287,7 @@ public class ClassesProcessor {
mapper.addTotalOffset(total_offset_lines);
buffer.append(lineSeparator);
mapper.dumpMapping(buffer);
mapper.dumpMapping(buffer, true);
}
}
finally {

View File

@ -1,11 +1,11 @@
package org.jetbrains.java.decompiler.main.collectors;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
import java.util.HashMap;
import java.util.Map.Entry;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
public class BytecodeSourceMapper {
private int offset_total;
@ -37,7 +37,7 @@ public class BytecodeSourceMapper {
}
}
public void dumpMapping(TextBuffer buffer) {
public void dumpMapping(TextBuffer buffer, boolean offsetsToHex) {
String lineSeparator = DecompilerContext.getNewLineSeparator();
@ -56,7 +56,8 @@ public class BytecodeSourceMapper {
buffer.appendIndent(1).append("method " + method_entry.getKey() + "{" + lineSeparator);
for(Entry<Integer, Integer> line : method_mapping.entrySet()) {
buffer.appendIndent(2).append(line.getKey().toString()).appendIndent(2).append((line.getValue() + offset_total) + lineSeparator);
String strOffset = offsetsToHex ? Integer.toHexString(line.getKey()): line.getKey().toString();
buffer.appendIndent(2).append(strOffset).appendIndent(2).append((line.getValue() + offset_total) + lineSeparator);
}
buffer.appendIndent(1).append("}").appendLineSeparator();
is_first_method = false;

View File

@ -104,7 +104,7 @@ public class ConcatenationHelper {
}
if (first2str == 0) {
lstOperands.add(0, new ConstExprent(VarType.VARTYPE_STRING, ""));
lstOperands.add(0, new ConstExprent(VarType.VARTYPE_STRING, "", expr.bytecode));
}
// remove redundant String.valueOf
@ -133,7 +133,7 @@ public class ConcatenationHelper {
List<Exprent> lstTmp = new ArrayList<Exprent>();
lstTmp.add(func);
lstTmp.add(lstOperands.get(i));
func = new FunctionExprent(FunctionExprent.FUNCTION_STRCONCAT, lstTmp);
func = new FunctionExprent(FunctionExprent.FUNCTION_STRCONCAT, lstTmp, expr.bytecode);
}
return func;

View File

@ -213,6 +213,12 @@ public class DomHelper {
RootStatement root = graphToStatement(graph);
if (!processStatement(root, new HashMap<Integer, Set<Integer>>())) {
// try {
// DotExporter.toDotFile(root.getFirst().getStats().get(13), new File("c:\\Temp\\stat1.dot"));
// } catch (Exception ex) {
// ex.printStackTrace();
// }
throw new RuntimeException("parsing failure!");
}

View File

@ -319,7 +319,7 @@ public class ExitHelper {
ExitExprent retexpr = new ExitExprent(ExitExprent.EXIT_RETURN, null,
((MethodDescriptor)DecompilerContext
.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret);
.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret, null);
// a changeable list needed
bstat.setExprents(new ArrayList<Exprent>(Arrays.asList(new Exprent[]{retexpr})));

View File

@ -15,6 +15,14 @@
*/
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.Instruction;
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.TextBuffer;
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.DirectNode;
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.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.struct.StructClass;
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.util.InterpreterUtil;
import java.util.*;
public class ExprProcessor implements CodeConstants {
public static final String UNDEFINED_TYPE_STRING = "<undefinedtype>";
@ -333,33 +355,34 @@ public class ExprProcessor implements CodeConstants {
Instruction instr = seq.getInstr(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) {
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;
case opc_bipush:
case opc_sipush:
pushEx(stack, exprlist, new ConstExprent(instr.getOperand(0), true));
pushEx(stack, exprlist, new ConstExprent(instr.getOperand(0), true, bytecode_offsets));
break;
case opc_lconst_0:
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;
case opc_fconst_0:
case opc_fconst_1:
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;
case opc_dconst_0:
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;
case opc_ldc:
case opc_ldc_w:
case opc_ldc2_w:
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;
case opc_iload:
case opc_lload:
@ -387,7 +410,7 @@ public class ExprProcessor implements CodeConstants {
case opc_daload:
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;
case opc_istore:
case opc_lstore:
@ -397,7 +420,7 @@ public class ExprProcessor implements CodeConstants {
Exprent top = stack.pop();
int varindex = instr.getOperand(0);
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);
break;
case opc_iastore:
@ -412,7 +435,7 @@ public class ExprProcessor implements CodeConstants {
Exprent index_store = stack.pop();
Exprent arr_store = stack.pop();
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);
break;
case opc_iadd:
@ -435,7 +458,7 @@ public class ExprProcessor implements CodeConstants {
case opc_lrem:
case opc_frem:
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;
case opc_ishl:
case opc_lshl:
@ -449,19 +472,20 @@ public class ExprProcessor implements CodeConstants {
case opc_lor:
case opc_ixor:
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;
case opc_ineg:
case opc_lneg:
case opc_fneg:
case opc_dneg:
pushEx(stack, exprlist, new FunctionExprent(FunctionExprent.FUNCTION_NEG, stack));
pushEx(stack, exprlist, new FunctionExprent(FunctionExprent.FUNCTION_NEG, stack, bytecode_offsets));
break;
case opc_iinc:
VarExprent vevar = new VarExprent(instr.getOperand(0), VarType.VARTYPE_INT, varProcessor);
exprlist.add(new AssignmentExprent(vevar, new FunctionExprent(
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;
case opc_i2l:
case opc_i2f:
@ -478,14 +502,14 @@ public class ExprProcessor implements CodeConstants {
case opc_i2b:
case opc_i2c:
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;
case opc_lcmp:
case opc_fcmpl:
case opc_fcmpg:
case opc_dcmpl:
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;
case opc_ifeq:
case opc_ifne:
@ -493,7 +517,7 @@ public class ExprProcessor implements CodeConstants {
case opc_ifge:
case opc_ifgt:
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;
case opc_if_icmpeq:
case opc_if_icmpne:
@ -503,16 +527,16 @@ public class ExprProcessor implements CodeConstants {
case opc_if_icmple:
case opc_if_acmpeq:
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;
case opc_ifnull:
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;
case opc_tableswitch:
case opc_lookupswitch:
exprlist.add(new SwitchExprent(stack.pop()));
break;
exprlist.add(new SwitchExprent(stack.pop(), bytecode_offsets));
break;
case opc_ireturn:
case opc_lreturn:
case opc_freturn:
@ -525,29 +549,30 @@ public class ExprProcessor implements CodeConstants {
instr.opcode == opc_athrow
? null
: ((MethodDescriptor)DecompilerContext
.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret));
break;
.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret,
bytecode_offsets));
break;
case opc_monitorenter:
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;
case opc_checkcast:
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:
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;
case opc_getstatic:
case opc_getfield:
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;
case opc_putstatic:
case opc_putfield:
Exprent valfield = stack.pop();
Exprent exprfield =
new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_putstatic ? null : stack.pop());
exprlist.add(new AssignmentExprent(exprfield, valfield));
new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_putstatic ? null : stack.pop(), bytecode_offsets);
exprlist.add(new AssignmentExprent(exprfield, valfield, bytecode_offsets));
break;
case opc_invokevirtual:
case opc_invokespecial:
@ -566,7 +591,7 @@ public class ExprProcessor implements CodeConstants {
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) {
exprlist.add(exprinv);
}
@ -583,10 +608,10 @@ public class ExprProcessor implements CodeConstants {
if (instr.opcode != opc_multianewarray) {
arrtype.arraydim += arrdims;
}
pushEx(stack, exprlist, new NewExprent(arrtype, stack, arrdims));
pushEx(stack, exprlist, new NewExprent(arrtype, stack, arrdims, bytecode_offsets));
break;
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;
case opc_dup:
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);
var.setStack(true);
exprlist.add(new AssignmentExprent(var, exprent));
exprlist.add(new AssignmentExprent(var, exprent, null));
stack.push(var.copy());
}
@ -674,14 +699,14 @@ public class ExprProcessor implements CodeConstants {
Exprent varex = stack.pop();
VarExprent varnew = new VarExprent(base + i + 1, varex.getExprType(), varProcessor);
varnew.setStack(true);
exprlist.add(new AssignmentExprent(varnew, varex));
exprlist.add(new AssignmentExprent(varnew, varex, null));
lst.add(0, (VarExprent)varnew.copy());
}
Exprent exprent = lst.get(lst.size() + copyoffset).copy();
VarExprent var = new VarExprent(base + offset, exprent.getExprType(), varProcessor);
var.setStack(true);
exprlist.add(new AssignmentExprent(var, exprent));
exprlist.add(new AssignmentExprent(var, exprent, null));
lst.add(0, (VarExprent)var.copy());
for (VarExprent expr : lst) {
@ -742,7 +767,7 @@ public class ExprProcessor implements CodeConstants {
VarExprent vartmp = new VarExprent(VarExprent.STACK_BASE, var.getExprType(), var.getProcessor());
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());
return prlst;
}
@ -840,19 +865,19 @@ public class ExprProcessor implements CodeConstants {
ConstExprent defaultval;
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) {
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) {
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) {
defaultval = new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0));
defaultval = new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0), null);
}
else { // integer types
defaultval = new ConstExprent(0, true);
defaultval = new ConstExprent(0, true, null);
}
return defaultval;

View File

@ -200,7 +200,8 @@ public class IfHelper {
lstOperands.add(statexpr.getCondition());
lstOperands.add(ifchild.getHeadexprent().getCondition());
statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_CADD, lstOperands));
statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_CADD, lstOperands, null));
statexpr.addBytecodeOffsets(ifchild.getHeadexprent().bytecode);
return true;
}
@ -252,8 +253,9 @@ public class IfHelper {
List<Exprent> lstOperands = new ArrayList<Exprent>();
lstOperands.add(statexpr.getCondition());
lstOperands.add(new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT,
Arrays.asList(new Exprent[]{ifchild.getHeadexprent().getCondition()})));
statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_CADD, lstOperands));
Arrays.asList(ifchild.getHeadexprent().getCondition()), null));
statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_CADD, lstOperands, null));
statexpr.addBytecodeOffsets(ifchild.getHeadexprent().bytecode);
return true;
}
@ -309,13 +311,13 @@ public class IfHelper {
if (path == 2) {
lstOperands.set(0, new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT,
Arrays.asList(new Exprent[]{lstOperands.get(0)})));
Arrays.asList(lstOperands.get(0)), null));
}
lstOperands.add(statexpr.getCondition());
statexpr
.setCondition(new FunctionExprent(path == 1 ? FunctionExprent.FUNCTION_COR : FunctionExprent.FUNCTION_CADD, lstOperands));
.setCondition(new FunctionExprent(path == 1 ? FunctionExprent.FUNCTION_COR : FunctionExprent.FUNCTION_CADD, lstOperands, null));
if (secondif.getFirst().getExprents().isEmpty() &&
!firstif.getFirst().getExprents().isEmpty()) {
@ -359,7 +361,7 @@ public class IfHelper {
// negate the if condition
IfExprent statexpr = firstif.getHeadexprent();
statexpr
.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, Arrays.asList(new Exprent[]{statexpr.getCondition()})));
.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, Arrays.asList(statexpr.getCondition()), null));
return true;
}
@ -554,7 +556,7 @@ public class IfHelper {
// negate the if condition
IfExprent statexpr = ifstat.getHeadexprent();
statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, Arrays.asList(new Exprent[]{statexpr.getCondition()})));
statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, Arrays.asList(statexpr.getCondition()), null));
if (noelsestat) {
StatEdge ifedge = ifstat.getIfEdge();

View File

@ -138,7 +138,7 @@ public class PPandMMHelper {
if (left.equals(econd) && (midlayer == null || midlayer.equals(condtype))) {
FunctionExprent ret = new FunctionExprent(
func.getFunctype() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_PPI : FunctionExprent.FUNCTION_MMI,
Arrays.asList(new Exprent[]{econd}));
Arrays.asList(econd), func.bytecode);
ret.setImplicitType(condtype);
exprentReplaced = true;

View File

@ -189,7 +189,7 @@ public class SecondaryFunctionsHelper {
}
if (desttype >= 0) {
return new FunctionExprent(desttype, funcexpr.getLstOperands());
return new FunctionExprent(desttype, funcexpr.getLstOperands(), funcexpr.bytecode);
}
}
}
@ -236,7 +236,7 @@ public class SecondaryFunctionsHelper {
if (val == -1) {
List<Exprent> lstBitNotOperand = new ArrayList<Exprent>();
lstBitNotOperand.add(lstOperands.get(1 - i));
return new FunctionExprent(FunctionExprent.FUNCTION_BITNOT, lstBitNotOperand);
return new FunctionExprent(FunctionExprent.FUNCTION_BITNOT, lstBitNotOperand, fexpr.bytecode);
}
}
}
@ -257,7 +257,7 @@ public class SecondaryFunctionsHelper {
else {
List<Exprent> lstNotOperand = new ArrayList<Exprent>();
lstNotOperand.add(lstOperands.get(1 - i));
return new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, lstNotOperand);
return new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, lstNotOperand, fexpr.bytecode);
}
}
}
@ -267,10 +267,10 @@ public class SecondaryFunctionsHelper {
if (lstOperands.get(0).type == Exprent.EXPRENT_CONST) {
int val = ((ConstExprent)lstOperands.get(0)).getIntValue();
if (val == 0) {
return new ConstExprent(VarType.VARTYPE_BOOLEAN, new Integer(1));
return new ConstExprent(VarType.VARTYPE_BOOLEAN, new Integer(1), fexpr.bytecode);
}
else {
return new ConstExprent(VarType.VARTYPE_BOOLEAN, new Integer(0));
return new ConstExprent(VarType.VARTYPE_BOOLEAN, new Integer(0), fexpr.bytecode);
}
}
break;
@ -286,7 +286,7 @@ public class SecondaryFunctionsHelper {
cexpr2.getExprType().type == CodeConstants.TYPE_BOOLEAN) {
if (cexpr1.getIntValue() == 0 && cexpr2.getIntValue() != 0) {
return new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, Arrays.asList(new Exprent[]{lstOperands.get(0)}));
return new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT, Arrays.asList(lstOperands.get(0)), fexpr.bytecode);
}
else if (cexpr1.getIntValue() != 0 && cexpr2.getIntValue() == 0) {
return lstOperands.get(0);
@ -303,23 +303,22 @@ public class SecondaryFunctionsHelper {
VarType type = lstOperands.get(0).getExprType();
VarProcessor processor = (VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR);
FunctionExprent iff = new FunctionExprent(FunctionExprent.FUNCTION_IIF, Arrays.asList(new Exprent[]{
new FunctionExprent(FunctionExprent.FUNCTION_LT, Arrays.asList(new Exprent[]{new VarExprent(var, type, processor),
ConstExprent.getZeroConstant(type.type)})),
new ConstExprent(VarType.VARTYPE_INT, new Integer(-1)),
new ConstExprent(VarType.VARTYPE_INT, new Integer(1))}));
FunctionExprent iff = new FunctionExprent(FunctionExprent.FUNCTION_IIF, Arrays.asList(
new FunctionExprent(FunctionExprent.FUNCTION_LT, Arrays.asList(new VarExprent(var, type, processor),
ConstExprent.getZeroConstant(type.type)), null),
new ConstExprent(VarType.VARTYPE_INT, new Integer(-1), null),
new ConstExprent(VarType.VARTYPE_INT, new Integer(1), null)), null);
FunctionExprent head = new FunctionExprent(FunctionExprent.FUNCTION_EQ, Arrays.asList(new Exprent[]{
FunctionExprent head = new FunctionExprent(FunctionExprent.FUNCTION_EQ, Arrays.asList(
new AssignmentExprent(new VarExprent(var, type, processor), new FunctionExprent(FunctionExprent.FUNCTION_SUB,
Arrays.asList(
new Exprent[]{lstOperands.get(0),
lstOperands.get(1)}))),
ConstExprent.getZeroConstant(type.type)}));
Arrays.asList(lstOperands.get(0),
lstOperands.get(1)), null), null),
ConstExprent.getZeroConstant(type.type)), null);
processor.setVarType(new VarVersionPaar(var, 0), type);
return new FunctionExprent(FunctionExprent.FUNCTION_IIF, Arrays.asList(new Exprent[]{
head, new ConstExprent(VarType.VARTYPE_INT, new Integer(0)), iff}));
return new FunctionExprent(FunctionExprent.FUNCTION_IIF, Arrays.asList(
head, new ConstExprent(VarType.VARTYPE_INT, new Integer(0), null), iff), fexpr.bytecode);
}
break;
case Exprent.EXPRENT_ASSIGNMENT: // check for conditional assignment
@ -409,7 +408,7 @@ public class SecondaryFunctionsHelper {
List<Exprent> operands = fparam.getLstOperands();
for (int i = 0; i < operands.size(); i++) {
Exprent newparam = new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT,
Arrays.asList(new Exprent[]{operands.get(i)}));
Arrays.asList(operands.get(i)), operands.get(i).bytecode);
Exprent retparam = propagateBoolNot(newparam);
operands.set(i, retparam == null ? newparam : retparam);

View File

@ -387,7 +387,7 @@ public class SimplifyExprentsHelper {
if (asf.getLeft().type == Exprent.EXPRENT_VAR && ass.getRight().type == Exprent.EXPRENT_VAR &&
asf.getLeft().equals(ass.getRight()) && ((VarExprent)asf.getLeft()).isStack()) {
if (ass.getLeft().type != Exprent.EXPRENT_VAR || !((VarExprent)ass.getLeft()).isStack()) {
asf.setRight(new AssignmentExprent(ass.getLeft(), asf.getRight()));
asf.setRight(new AssignmentExprent(ass.getLeft(), asf.getRight(), ass.bytecode));
return true;
}
}
@ -450,7 +450,7 @@ public class SimplifyExprentsHelper {
if (left.type != Exprent.EXPRENT_VAR && left.equals(econd)) {
FunctionExprent ret = new FunctionExprent(
func.getFunctype() == FunctionExprent.FUNCTION_ADD ? FunctionExprent.FUNCTION_PPI : FunctionExprent.FUNCTION_MMI,
Arrays.asList(new Exprent[]{econd}));
Arrays.asList(econd), func.bytecode);
ret.setImplicitType(VarType.VARTYPE_INT);
return ret;
}
@ -707,7 +707,7 @@ public class SimplifyExprentsHelper {
if (lambda_class != null) { // real lambda class found, replace invocation with an anonymous class
NewExprent newexp = new NewExprent(new VarType(lambda_class_name, true), null, 0);
NewExprent newexp = new NewExprent(new VarType(lambda_class_name, true), null, 0, in.bytecode);
newexp.setConstructor(in);
// note: we don't set the instance to null with in.setInstance(null) like it is done for a common constructor invokation
// lambda can also be a reference to a virtual method (e.g. String x; ...(x::toString);)
@ -750,6 +750,10 @@ public class SimplifyExprentsHelper {
if (stat.type == Statement.TYPE_IF && stat.getExprents() == null) {
IfStatement stif = (IfStatement)stat;
Exprent ifheadexpr = stif.getHeadexprent();
Set<Integer> ifheadexpr_bytecode = (ifheadexpr == null ? null : ifheadexpr.bytecode);
if (stif.iftype == IfStatement.IFTYPE_IFELSE) {
Statement ifstat = stif.getIfstat();
Statement elsestat = stif.getElsestat();
@ -788,10 +792,10 @@ public class SimplifyExprentsHelper {
data.addAll(stif.getFirst().getExprents());
data.add(new AssignmentExprent(ifvar, new FunctionExprent(FunctionExprent.FUNCTION_IIF,
Arrays.asList(new Exprent[]{
Arrays.asList(
stif.getHeadexprent().getCondition(),
ifas.getRight(),
elseas.getRight()}))));
elseas.getRight()), ifheadexpr_bytecode), ifheadexpr_bytecode));
stif.setExprents(data);
if (stif.getAllSuccessorEdges().isEmpty()) {
@ -829,10 +833,10 @@ public class SimplifyExprentsHelper {
data.addAll(stif.getFirst().getExprents());
data.add(new ExitExprent(ifex.getExittype(), new FunctionExprent(FunctionExprent.FUNCTION_IIF,
Arrays.asList(new Exprent[]{
Arrays.asList(
stif.getHeadexprent().getCondition(),
ifex.getValue(),
elseex.getValue()})), ifex.getRettype()));
elseex.getValue()), ifheadexpr_bytecode), ifex.getRettype(), ifheadexpr_bytecode));
stif.setExprents(data);
StatEdge retedge = ifstat.getAllSuccessorEdges().get(0);

View File

@ -16,6 +16,8 @@
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.main.TextBuffer;
import java.util.Set;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult;
@ -38,14 +40,17 @@ public class ArrayExprent extends Exprent {
this.type = EXPRENT_ARRAY;
}
public ArrayExprent(Exprent array, Exprent index, VarType hardtype) {
public ArrayExprent(Exprent array, Exprent index, VarType hardtype, Set<Integer> bytecode_offsets) {
this.array = array;
this.index = index;
this.hardtype = hardtype;
addBytecodeOffsets(bytecode_offsets);
}
@Override
public Exprent copy() {
return new ArrayExprent(array.copy(), index.copy(), hardtype);
return new ArrayExprent(array.copy(), index.copy(), hardtype, bytecode);
}
public VarType getExprType() {

View File

@ -15,6 +15,10 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.TextBuffer;
@ -26,9 +30,6 @@ import org.jetbrains.java.decompiler.struct.StructField;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.util.ArrayList;
import java.util.List;
public class AssignmentExprent extends Exprent {
@ -60,9 +61,11 @@ public class AssignmentExprent extends Exprent {
}
public AssignmentExprent(Exprent left, Exprent right) {
public AssignmentExprent(Exprent left, Exprent right, Set<Integer> bytecode_offsets) {
this.left = left;
this.right = right;
addBytecodeOffsets(bytecode_offsets);
}
@ -97,8 +100,9 @@ public class AssignmentExprent extends Exprent {
return lst;
}
@Override
public Exprent copy() {
return new AssignmentExprent(left.copy(), right.copy());
return new AssignmentExprent(left.copy(), right.copy(), bytecode);
}
public int getPrecedence() {

View File

@ -15,6 +15,11 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
@ -25,10 +30,6 @@ import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ConstExprent extends Exprent {
private static final HashMap<Integer, String> escapes = new HashMap<Integer, String>();
@ -54,7 +55,7 @@ public class ConstExprent extends Exprent {
this.type = EXPRENT_CONST;
}
public ConstExprent(int val, boolean boolPermitted) {
public ConstExprent(int val, boolean boolPermitted, Set<Integer> bytecode_offsets) {
this.boolPermitted = boolPermitted;
if (boolPermitted) {
@ -85,15 +86,20 @@ public class ConstExprent extends Exprent {
}
}
value = new Integer(val);
addBytecodeOffsets(bytecode_offsets);
}
public ConstExprent(VarType consttype, Object value) {
public ConstExprent(VarType consttype, Object value, Set<Integer> bytecode_offsets) {
this.consttype = consttype;
this.value = value;
addBytecodeOffsets(bytecode_offsets);
}
@Override
public Exprent copy() {
return new ConstExprent(consttype, value);
return new ConstExprent(consttype, value, bytecode);
}
public VarType getExprType() {
@ -155,7 +161,7 @@ public class ConstExprent extends Exprent {
else {
return new TextBuffer(value.toString());
}
return new FieldExprent(intfield, "java/lang/Integer", true, null, FieldDescriptor.INTEGER_DESCRIPTOR).toJava(0, tracer);
return new FieldExprent(intfield, "java/lang/Integer", true, null, FieldDescriptor.INTEGER_DESCRIPTOR, bytecode).toJava(0, tracer);
case CodeConstants.TYPE_LONG:
long lval = ((Long)value).longValue();
@ -172,7 +178,7 @@ public class ConstExprent extends Exprent {
else {
return new TextBuffer(value.toString()).append("L");
}
return new FieldExprent(longfield, "java/lang/Long", true, null, FieldDescriptor.LONG_DESCRIPTOR).toJava(0, tracer);
return new FieldExprent(longfield, "java/lang/Long", true, null, FieldDescriptor.LONG_DESCRIPTOR, bytecode).toJava(0, tracer);
case CodeConstants.TYPE_DOUBLE:
double dval = ((Double)value).doubleValue();
@ -209,7 +215,7 @@ public class ConstExprent extends Exprent {
else {
return new TextBuffer(value.toString()).append("D");
}
return new FieldExprent(doublefield, "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR).toJava(0, tracer);
return new FieldExprent(doublefield, "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer);
case CodeConstants.TYPE_FLOAT:
float fval = ((Float)value).floatValue();
@ -246,7 +252,7 @@ public class ConstExprent extends Exprent {
else {
return new TextBuffer(value.toString()).append("F");
}
return new FieldExprent(floatfield, "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR).toJava(0, tracer);
return new FieldExprent(floatfield, "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer);
case CodeConstants.TYPE_NULL:
return new TextBuffer("null");
case CodeConstants.TYPE_OBJECT:
@ -369,13 +375,13 @@ public class ConstExprent extends Exprent {
switch (type) {
case CodeConstants.TYPE_INT:
return new ConstExprent(VarType.VARTYPE_INT, new Integer(0));
return new ConstExprent(VarType.VARTYPE_INT, new Integer(0), null);
case CodeConstants.TYPE_LONG:
return new ConstExprent(VarType.VARTYPE_LONG, new Long(0));
return new ConstExprent(VarType.VARTYPE_LONG, new Long(0), null);
case CodeConstants.TYPE_DOUBLE:
return new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0));
return new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0), null);
case CodeConstants.TYPE_FLOAT:
return new ConstExprent(VarType.VARTYPE_FLOAT, new Float(0));
return new ConstExprent(VarType.VARTYPE_FLOAT, new Float(0), null);
}
throw new RuntimeException("Invalid argument!");

View File

@ -15,6 +15,10 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext;
@ -27,9 +31,6 @@ import org.jetbrains.java.decompiler.struct.attr.StructExceptionsAttribute;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.util.ArrayList;
import java.util.List;
public class ExitExprent extends Exprent {
@ -47,14 +48,17 @@ public class ExitExprent extends Exprent {
this.type = EXPRENT_EXIT;
}
public ExitExprent(int exittype, Exprent value, VarType rettype) {
public ExitExprent(int exittype, Exprent value, VarType rettype, Set<Integer> bytecode_offsets) {
this.exittype = exittype;
this.value = value;
this.rettype = rettype;
addBytecodeOffsets(bytecode_offsets);
}
@Override
public Exprent copy() {
return new ExitExprent(exittype, value == null ? null : value.copy(), rettype);
return new ExitExprent(exittype, value == null ? null : value.copy(), rettype, bytecode);
}
public CheckTypesResult checkExprTypeBounds() {

View File

@ -15,6 +15,12 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
@ -23,11 +29,6 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Exprent {
@ -135,4 +136,10 @@ public class Exprent {
public void replaceExprent(Exprent oldexpr, Exprent newexpr) {
}
public void addBytecodeOffsets(Collection<Integer> bytecode_offsets) {
if(bytecode_offsets != null) {
bytecode.addAll(bytecode_offsets);
}
}
}

View File

@ -15,6 +15,10 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext;
@ -29,9 +33,6 @@ import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.util.ArrayList;
import java.util.List;
public class FieldExprent extends Exprent {
@ -49,7 +50,7 @@ public class FieldExprent extends Exprent {
this.type = EXPRENT_FIELD;
}
public FieldExprent(LinkConstant cn, Exprent instance) {
public FieldExprent(LinkConstant cn, Exprent instance, Set<Integer> bytecode_offsets) {
this.instance = instance;
@ -60,14 +61,18 @@ public class FieldExprent extends Exprent {
classname = cn.classname;
name = cn.elementname;
descriptor = FieldDescriptor.parseDescriptor(cn.descriptor);
addBytecodeOffsets(bytecode_offsets);
}
public FieldExprent(String name, String classname, boolean isStatic, Exprent instance, FieldDescriptor descriptor) {
public FieldExprent(String name, String classname, boolean isStatic, Exprent instance, FieldDescriptor descriptor, Set<Integer> bytecode_offsets) {
this.name = name;
this.classname = classname;
this.isStatic = isStatic;
this.instance = instance;
this.descriptor = descriptor;
addBytecodeOffsets(bytecode_offsets);
}
public VarType getExprType() {
@ -91,8 +96,9 @@ public class FieldExprent extends Exprent {
return lst;
}
@Override
public Exprent copy() {
return new FieldExprent(name, classname, isStatic, instance == null ? null : instance.copy(), descriptor);
return new FieldExprent(name, classname, isStatic, instance == null ? null : instance.copy(), descriptor, bytecode);
}
@Override

View File

@ -15,6 +15,12 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
@ -24,11 +30,6 @@ import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import org.jetbrains.java.decompiler.util.ListStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class FunctionExprent extends Exprent {
@ -207,7 +208,7 @@ public class FunctionExprent extends Exprent {
this.type = EXPRENT_FUNCTION;
}
public FunctionExprent(int functype, ListStack<Exprent> stack) {
public FunctionExprent(int functype, ListStack<Exprent> stack, Set<Integer> bytecode_offsets) {
this.functype = functype;
if (functype >= FUNCTION_BITNOT && functype <= FUNCTION_PPI && functype != FUNCTION_CAST
&& functype != FUNCTION_INSTANCEOF) {
@ -221,11 +222,15 @@ public class FunctionExprent extends Exprent {
lstOperands.add(stack.pop());
lstOperands.add(expr);
}
addBytecodeOffsets(bytecode_offsets);
}
public FunctionExprent(int functype, List<Exprent> operands) {
public FunctionExprent(int functype, List<Exprent> operands, Set<Integer> bytecode_offsets) {
this.functype = functype;
this.lstOperands = operands;
addBytecodeOffsets(bytecode_offsets);
}
public VarType getExprType() {
@ -420,12 +425,13 @@ public class FunctionExprent extends Exprent {
return lst;
}
@Override
public Exprent copy() {
List<Exprent> lst = new ArrayList<Exprent>();
for (Exprent expr : lstOperands) {
lst.add(expr.copy());
}
FunctionExprent func = new FunctionExprent(functype, lst);
FunctionExprent func = new FunctionExprent(functype, lst, bytecode);
func.setImplicitType(implicitType);
return func;

View File

@ -16,15 +16,16 @@
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.main.TextBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import org.jetbrains.java.decompiler.util.ListStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class IfExprent extends Exprent {
@ -82,29 +83,34 @@ public class IfExprent extends Exprent {
this.type = EXPRENT_IF;
}
public IfExprent(int iftype, ListStack<Exprent> stack) {
public IfExprent(int iftype, ListStack<Exprent> stack, Set<Integer> bytecode_offsets) {
if (iftype <= IF_LE) {
stack.push(new ConstExprent(0, true));
stack.push(new ConstExprent(0, true, null));
}
else if (iftype <= IF_NONNULL) {
stack.push(new ConstExprent(VarType.VARTYPE_NULL, null));
stack.push(new ConstExprent(VarType.VARTYPE_NULL, null, null));
}
if (iftype == IF_VALUE) {
condition = stack.pop();
}
else {
condition = new FunctionExprent(functypes[iftype], stack);
condition = new FunctionExprent(functypes[iftype], stack, null);
}
addBytecodeOffsets(bytecode_offsets);
}
private IfExprent(Exprent condition) {
private IfExprent(Exprent condition, Set<Integer> bytecode_offsets) {
this.condition = condition;
addBytecodeOffsets(bytecode_offsets);
}
@Override
public Exprent copy() {
return new IfExprent(condition.copy());
return new IfExprent(condition.copy(), bytecode);
}
public List<Exprent> getAllExprents() {
@ -135,7 +141,7 @@ public class IfExprent extends Exprent {
public IfExprent negateIf() {
condition = new FunctionExprent(FunctionExprent.FUNCTION_BOOLNOT,
Arrays.asList(new Exprent[]{condition}));
Arrays.asList(condition), condition.bytecode);
return this;
}

View File

@ -80,7 +80,7 @@ public class InvocationExprent extends Exprent {
public InvocationExprent() {
}
public InvocationExprent(int opcode, LinkConstant cn, ListStack<Exprent> stack, int dynamic_invokation_type) {
public InvocationExprent(int opcode, LinkConstant cn, ListStack<Exprent> stack, int dynamic_invokation_type, Set<Integer> bytecode_offsets) {
name = cn.elementname;
classname = cn.classname;
@ -134,6 +134,8 @@ public class InvocationExprent extends Exprent {
else {
instance = stack.pop();
}
addBytecodeOffsets(bytecode_offsets);
}
private InvocationExprent(InvocationExprent expr) {
@ -152,6 +154,7 @@ public class InvocationExprent extends Exprent {
for (int i = 0; i < lstParameters.size(); i++) {
lstParameters.set(i, lstParameters.get(i).copy());
}
bytecode.addAll(expr.bytecode);
}
@ -184,6 +187,7 @@ public class InvocationExprent extends Exprent {
}
@Override
public Exprent copy() {
return new InvocationExprent(this);
}

View File

@ -16,11 +16,12 @@
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
public class MonitorExprent extends Exprent {
@ -36,13 +37,16 @@ public class MonitorExprent extends Exprent {
this.type = EXPRENT_MONITOR;
}
public MonitorExprent(int montype, Exprent value) {
public MonitorExprent(int montype, Exprent value, Set<Integer> bytecode_offsets) {
this.montype = montype;
this.value = value;
addBytecodeOffsets(bytecode_offsets);
}
@Override
public Exprent copy() {
return new MonitorExprent(montype, value.copy());
return new MonitorExprent(montype, value.copy(), bytecode);
}
public List<Exprent> getAllExprents() {

View File

@ -15,6 +15,11 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassWriter;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
@ -30,10 +35,6 @@ import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import org.jetbrains.java.decompiler.util.ListStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class NewExprent extends Exprent {
private InvocationExprent constructor;
@ -56,19 +57,21 @@ public class NewExprent extends Exprent {
this.type = EXPRENT_NEW;
}
public NewExprent(VarType newtype, ListStack<Exprent> stack, int arraydim) {
public NewExprent(VarType newtype, ListStack<Exprent> stack, int arraydim, Set<Integer> bytecode_offsets) {
this.newtype = newtype;
for (int i = 0; i < arraydim; i++) {
lstDims.add(0, stack.pop());
}
addBytecodeOffsets(bytecode_offsets);
setAnonymous();
}
public NewExprent(VarType newtype, List<Exprent> lstDims) {
public NewExprent(VarType newtype, List<Exprent> lstDims, Set<Integer> bytecode_offsets) {
this.newtype = newtype;
this.lstDims = lstDims;
addBytecodeOffsets(bytecode_offsets);
setAnonymous();
}
@ -152,13 +155,14 @@ public class NewExprent extends Exprent {
return lst;
}
@Override
public Exprent copy() {
List<Exprent> lst = new ArrayList<Exprent>();
for (Exprent expr : lstDims) {
lst.add(expr.copy());
}
NewExprent ret = new NewExprent(newtype, lst);
NewExprent ret = new NewExprent(newtype, lst, bytecode);
ret.setConstructor(constructor == null ? null : (InvocationExprent)constructor.copy());
ret.setLstArrayElements(lstArrayElements);
ret.setDirectArrayInit(directArrayInit);

View File

@ -16,14 +16,15 @@
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.main.TextBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.util.ArrayList;
import java.util.List;
public class SwitchExprent extends Exprent {
@ -35,12 +36,15 @@ public class SwitchExprent extends Exprent {
this.type = EXPRENT_SWITCH;
}
public SwitchExprent(Exprent value) {
public SwitchExprent(Exprent value, Set<Integer> bytecode_offsets) {
this.value = value;
addBytecodeOffsets(bytecode_offsets);
}
@Override
public Exprent copy() {
SwitchExprent swexpr = new SwitchExprent(value.copy());
SwitchExprent swexpr = new SwitchExprent(value.copy(), bytecode);
List<List<ConstExprent>> lstCaseValues = new ArrayList<List<ConstExprent>>();
for (List<ConstExprent> lst : caseValues) {

View File

@ -15,12 +15,16 @@
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassWriter;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor;
@ -28,9 +32,6 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.util.ArrayList;
import java.util.List;
public class VarExprent extends Exprent {
public static final int STACK_BASE = 10000;
@ -73,6 +74,7 @@ public class VarExprent extends Exprent {
return new ArrayList<Exprent>();
}
@Override
public Exprent copy() {
VarExprent var = new VarExprent(index, getVartype(), processor);
var.setDefinition(definition);

View File

@ -311,7 +311,7 @@ public class SwitchStatement extends Statement {
int index = in == lstSuccs.size() ? 0 : in;
lste.add(lstSuccs.get(index));
lstv.add(index == 0 ? null : new ConstExprent(values[index - 1], false));
lstv.add(index == 0 ? null : new ConstExprent(values[index - 1], false, null));
}
lstEdges.add(lste);
lstValues.add(lstv);

View File

@ -116,7 +116,7 @@ public class VarTypeProcessor {
else if (expr.type == Exprent.EXPRENT_CONST) {
ConstExprent cexpr = (ConstExprent)expr;
if (cexpr.getConsttype().type_family == CodeConstants.TYPE_FAMILY_INTEGER) {
cexpr.setConsttype(new ConstExprent(cexpr.getIntValue(), cexpr.isBoolPermitted()).getConsttype());
cexpr.setConsttype(new ConstExprent(cexpr.getIntValue(), cexpr.isBoolPermitted(), null).getConsttype());
}
}
}
@ -183,7 +183,7 @@ public class VarTypeProcessor {
return true;
}
else if (newtype.type_family == CodeConstants.TYPE_FAMILY_INTEGER) {
VarType mininteger = new ConstExprent((Integer)((ConstExprent)exprent).getValue(), false).getConsttype();
VarType mininteger = new ConstExprent((Integer)((ConstExprent)exprent).getValue(), false, null).getConsttype();
if (mininteger.isStrictSuperset(newtype)) {
newtype = mininteger;
}

View File

@ -81,7 +81,7 @@ public class StructAnnotationAttribute extends StructGeneralAttribute {
String className = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
String constName = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
FieldDescriptor descr = FieldDescriptor.parseDescriptor(className);
return new FieldExprent(constName, descr.type.value, true, null, descr);
return new FieldExprent(constName, descr.type.value, true, null, descr, null);
case 'c': // class
String descriptor = pool.getPrimitiveConstant(data.readUnsignedShort()).getString();
@ -122,7 +122,7 @@ public class StructAnnotationAttribute extends StructGeneralAttribute {
default:
throw new RuntimeException("invalid class type: " + type.type);
}
return new ConstExprent(VarType.VARTYPE_CLASS, value);
return new ConstExprent(VarType.VARTYPE_CLASS, value, null);
case '[': // array
List<Exprent> elements = Collections.emptyList();
@ -143,7 +143,7 @@ public class StructAnnotationAttribute extends StructGeneralAttribute {
newType = new VarType(elementType.type, 1, elementType.value);
}
NewExprent newExpr = new NewExprent(newType, Collections.<Exprent>emptyList());
NewExprent newExpr = new NewExprent(newType, Collections.<Exprent>emptyList(), null);
newExpr.setDirectArrayInit(true);
newExpr.setLstArrayElements(elements);
return newExpr;
@ -155,23 +155,23 @@ public class StructAnnotationAttribute extends StructGeneralAttribute {
PrimitiveConstant cn = pool.getPrimitiveConstant(data.readUnsignedShort());
switch (tag) {
case 'B':
return new ConstExprent(VarType.VARTYPE_BYTE, cn.value);
return new ConstExprent(VarType.VARTYPE_BYTE, cn.value, null);
case 'C':
return new ConstExprent(VarType.VARTYPE_CHAR, cn.value);
return new ConstExprent(VarType.VARTYPE_CHAR, cn.value, null);
case 'D':
return new ConstExprent(VarType.VARTYPE_DOUBLE, cn.value);
return new ConstExprent(VarType.VARTYPE_DOUBLE, cn.value, null);
case 'F':
return new ConstExprent(VarType.VARTYPE_FLOAT, cn.value);
return new ConstExprent(VarType.VARTYPE_FLOAT, cn.value, null);
case 'I':
return new ConstExprent(VarType.VARTYPE_INT, cn.value);
return new ConstExprent(VarType.VARTYPE_INT, cn.value, null);
case 'J':
return new ConstExprent(VarType.VARTYPE_LONG, cn.value);
return new ConstExprent(VarType.VARTYPE_LONG, cn.value, null);
case 'S':
return new ConstExprent(VarType.VARTYPE_SHORT, cn.value);
return new ConstExprent(VarType.VARTYPE_SHORT, cn.value, null);
case 'Z':
return new ConstExprent(VarType.VARTYPE_BOOLEAN, cn.value);
return new ConstExprent(VarType.VARTYPE_BOOLEAN, cn.value, null);
case 's':
return new ConstExprent(VarType.VARTYPE_STRING, cn.value);
return new ConstExprent(VarType.VARTYPE_STRING, cn.value, null);
default:
throw new RuntimeException("invalid element type!");
}