Search in sources :

Example 31 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class GenerationPass method _dup2_x2.

protected void _dup2_x2() {
    Type topType = peek().getType();
    int baseHeight = currentStack.height();
    save_stack(false);
    if (topType.getSize() == 2) {
        Type bottomType = currentStack.peek(1).getType();
        if (bottomType.getSize() == 2) {
            // 64x64
            // prestack: var2, var0 (height = 4)
            // poststack: var4, var2, var0
            // assignments: var0 = var2(initial)
            // assignments: var2 = var0(initial)
            // assignments: var4 = var2(initial)
            currentStack.assertHeights(DUP2_X2_64x64_HEIGHTS);
            Expr var2 = pop();
            Expr var0 = pop();
            // var6 = var0(initial)
            Type var6Type = assign_stack(baseHeight + 2, var0);
            // var0 = var2(initial)
            Type var0Type = assign_stack(baseHeight - 4, var2);
            // var4 = var2(initial)
            Type var4Type = assign_stack(baseHeight - 0, var2);
            // var2 = var6 = var0(initial)
            Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
            // push var0;
            push(load_stack(baseHeight - 4, var0Type));
            // push var2;
            push(load_stack(baseHeight - 2, var2Type));
            // push var4;
            push(load_stack(baseHeight - 0, var4Type));
        } else {
            // 64x32
            // prestack: var2, var1, var0 (height = 4)
            // poststack: var4, var3, var2, var0
            // assignments: var0 = var2(initial)
            // assignments: var2 = var0(initial)
            // assignments: var3 = var1(initial)
            // assignments: var4 = var2(initial)
            currentStack.assertHeights(DUP2_X2_64x32_HEIGHTS);
            Expr var2 = pop();
            Expr var1 = pop();
            Expr var0 = pop();
            // var6 = var0(initial)
            Type var6Type = assign_stack(baseHeight + 2, var0);
            // var0 = var2
            Type var0Type = assign_stack(baseHeight - 4, var2);
            // var3 = var1
            Type var3Type = assign_stack(baseHeight - 1, var1);
            // var4 = var2
            Type var4Type = assign_stack(baseHeight + 0, var2);
            // var2 = var0
            Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
            // push var0
            push(load_stack(baseHeight - 4, var0Type));
            // push var2
            push(load_stack(baseHeight - 2, var2Type));
            // push var3
            push(load_stack(baseHeight - 1, var3Type));
            // push var4
            push(load_stack(baseHeight + 0, var4Type));
        }
    } else {
        Type bottomType = currentStack.peek(2).getType();
        if (bottomType.getSize() == 2) {
            // 32x64
            // prestack: var3, var2, var0 (height = 4)
            // poststack: var5, var4, var2, var1, var0
            // assignments: var0 = var2(initial)
            // assignments: var1 = var3(initial)
            // assignments: var2 = var0(initial)
            // assignments: var4 = var2(initial)
            // assignments: var5 = var3(initial)
            currentStack.assertHeights(DUP2_X2_32x64_HEIGHTS);
            Expr var3 = pop();
            Expr var2 = pop();
            Expr var0 = pop();
            // var6 = var0(initial)
            Type var6Type = assign_stack(baseHeight + 2, var0);
            // var0 = var2(initial)
            Type var0Type = assign_stack(baseHeight - 4, var2);
            // var1 = var3(initial)
            Type var1Type = assign_stack(baseHeight - 3, var3);
            // var4 = var2(initial)
            Type var4Type = assign_stack(baseHeight + 0, var2);
            // var5 = var3(initial)
            Type var5Type = assign_stack(baseHeight + 1, var3);
            // var2 = var6 = var0(initial)
            Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
            // push var0
            push(load_stack(baseHeight - 4, var0Type));
            // push var1
            push(load_stack(baseHeight - 3, var1Type));
            // push var2
            push(load_stack(baseHeight - 2, var2Type));
            // push var4
            push(load_stack(baseHeight + 0, var4Type));
            // push var5
            push(load_stack(baseHeight + 1, var5Type));
        } else {
            // 32x32
            // prestack: var3, var2, var1, var0 (height = 4)
            // poststack: var5, var4, var3, var2, var1, var0
            // var0 = var2
            // var1 = var3
            // var2 = var0
            // var3 = var1
            // var4 = var2
            // var5 = var3
            currentStack.assertHeights(DUP2_X2_32x32_HEIGHTS);
            Expr var3 = pop();
            Expr var2 = pop();
            Expr var1 = pop();
            Expr var0 = pop();
            // var6 = var0(initial)
            Type var6Type = assign_stack(baseHeight + 2, var0);
            // var7 = var1(initial)
            Type var7Type = assign_stack(baseHeight + 3, var1);
            // var0 = var2(initial)
            Type var0Type = assign_stack(baseHeight - 4, var2);
            // var1 = var3(initial)
            Type var1Type = assign_stack(baseHeight - 3, var3);
            // var4 = var2(initial)
            Type var4Type = assign_stack(baseHeight + 0, var2);
            // var5 = var3(initial)
            Type var5Type = assign_stack(baseHeight + 1, var3);
            // var2 = var6 = var0(initial)
            Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
            // var3 = var7 = var1(initial)
            Type var3Type = assign_stack(baseHeight - 1, load_stack(baseHeight + 3, var7Type));
            // push var0
            push(load_stack(baseHeight - 4, var0Type));
            // push var1
            push(load_stack(baseHeight - 3, var1Type));
            // push var2
            push(load_stack(baseHeight - 2, var2Type));
            // push var3
            push(load_stack(baseHeight - 1, var3Type));
            // push var4
            push(load_stack(baseHeight + 0, var4Type));
            // push var5
            push(load_stack(baseHeight + 1, var5Type));
        }
    }
}
Also used : Type(org.objectweb.asm.Type) ComparisonType(org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType) ValueComparisonType(org.mapleir.ir.code.expr.ComparisonExpr.ValueComparisonType) ArrayType(org.mapleir.ir.TypeUtils.ArrayType) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Expr(org.mapleir.ir.code.Expr)

Example 32 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class SSAGenPass method isSameValue.

private boolean isSameValue(Expr e1, Expr e2) {
    Expr val1 = getValue(e1);
    Expr val2 = getValue(e2);
    if (!shouldCoalesce(val1.getOpcode()) || !shouldCoalesce(val2.getOpcode())) {
        return false;
    }
    return val1.equivalent(val2);
}
Also used : ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr)

Example 33 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class LocalsPool method realloc.

/* public Local newLocal(boolean isStack) {
		int index = cache.size();
		while(true) {
			String key = key(index, isStack);
			if(!cache.containsKey(key)) {
				return get(index, isStack);
			}
		}
	} */
public int realloc(ControlFlowGraph cfg) {
    NullPermeableHashMap<Local, Set<Type>> types = new NullPermeableHashMap<>(SetCreator.getInstance());
    int min = 0;
    Set<Local> safe = new HashSet<>();
    for (BasicBlock b : cfg.vertices()) {
        for (Stmt stmt : b) {
            if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
                CopyVarStmt cp = (CopyVarStmt) stmt;
                VarExpr var = cp.getVariable();
                Local local = var.getLocal();
                if (!cp.isSynthetic()) {
                    types.getNonNull(local).add(var.getType());
                } else {
                    safe.add(local);
                }
                types.getNonNull(local).add(var.getType());
            }
            for (Expr s : stmt.enumerateOnlyChildren()) {
                if (s.getOpcode() == Opcode.LOCAL_LOAD) {
                    VarExpr var = (VarExpr) s;
                    Local local = var.getLocal();
                    types.getNonNull(local).add(var.getType());
                }
            }
        }
    }
    Map<Local, Type> stypes = new HashMap<>();
    for (Entry<Local, Set<Type>> e : types.entrySet()) {
        Set<Type> set = e.getValue();
        Set<Type> refined = new HashSet<>();
        if (set.size() > 1) {
            for (Type t : set) {
                refined.add(TypeUtils.asSimpleType(t));
            }
            if (refined.size() != 1) {
                boolean valid = false;
                if (refined.size() == 2) {
                    // TODO: proper check
                    Iterator<Type> it = refined.iterator();
                    if (it.next().getSize() == it.next().getSize()) {
                        Type t = refined.iterator().next();
                        refined.clear();
                        refined.add(t);
                        valid = true;
                    }
                }
                if (!valid) {
                    for (Entry<Local, Set<Type>> e1 : types.entrySet()) {
                        System.err.println(e1.getKey() + "  ==  " + e1.getValue());
                    }
                    // String.format("illegal typesets for %s, set=%s, refined=%s", args)
                    throw new RuntimeException("illegal typesets for " + e.getKey());
                }
            }
            Local l = e.getKey();
            stypes.put(l, refined.iterator().next());
        // if(!safe.contains(l)) {
        // stypes.put(l, refined.iterator().next());
        // }
        } else {
            Local l = e.getKey();
            stypes.put(l, set.iterator().next());
        // if(!safe.contains(l)) {
        // }
        }
    }
    // for(Entry<Local, Type> e : stypes.entrySet()) {
    // System.out.println(e.getKey() + "  ==  " + e.getValue());
    // }
    // lvars then svars, ordered of course,
    List<Local> wl = new ArrayList<>(stypes.keySet());
    // System.out.println("safe: " + safe);
    wl.sort(new Comparator<Local>() {

        @Override
        public int compare(Local o1, Local o2) {
            boolean s1 = safe.contains(o1);
            boolean s2 = safe.contains(o2);
            if (s1 && !s2) {
                return -1;
            } else if (!s1 && s2) {
                return 1;
            } else {
                return o1.compareTo(o2);
            }
        }
    });
    // System.out.println("wl: " + wl);
    Map<Local, Local> remap = new HashMap<>();
    int idx = min;
    for (Local l : wl) {
        Type type = stypes.get(l);
        Local newL = get(idx, false);
        if (l != newL) {
            remap.put(l, newL);
        }
        idx += type.getSize();
    }
    remap(cfg, remap);
    return idx;
}
Also used : GenericBitSet(org.mapleir.stdlib.collections.bitset.GenericBitSet) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) VarExpr(org.mapleir.ir.code.expr.VarExpr) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Type(org.objectweb.asm.Type) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr)

Example 34 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class LocalsPool method remap.

public static void remap(ControlFlowGraph cfg, Map<? extends Local, ? extends Local> remap) {
    for (BasicBlock b : cfg.vertices()) {
        for (Stmt stmt : b) {
            if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
                VarExpr v = ((CopyVarStmt) stmt).getVariable();
                Local l = v.getLocal();
                if (remap.containsKey(l)) {
                    Local l2 = remap.get(l);
                    v.setLocal(l2);
                }
            }
            for (Expr s : stmt.enumerateOnlyChildren()) {
                if (s.getOpcode() == Opcode.LOCAL_LOAD) {
                    VarExpr v = (VarExpr) s;
                    Local l = v.getLocal();
                    if (remap.containsKey(l)) {
                        v.setLocal(remap.get(l));
                    }
                }
            }
        }
    }
}
Also used : VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) VarExpr(org.mapleir.ir.code.expr.VarExpr) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Example 35 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class PoolLocalValueResolver method getValues.

@Override
public TaintableSet<Expr> getValues(ControlFlowGraph cfg, Local l) {
    if (cfg.getLocals() != pool) {
        throw new UnsupportedOperationException();
    }
    AbstractCopyStmt copy = pool.defs.get(l);
    TaintableSet<Expr> set = new TaintableSet<>();
    if (copy.getOpcode() == Opcode.PHI_STORE) {
    // checkRecursive(l);
    // PhiExpr phi = ((CopyPhiStmt) copy).getExpression();
    /*for(Expr e : phi.getArguments().values()) {
				if(e.getOpcode() == Opcode.LOCAL_LOAD) {
					Local l2 = ((VarExpr) e).getLocal();
					
					if(l2 == l) {
						throw new RuntimeException(copy.toString());
					}
				}
			}*/
    // set.addAll(phi.getArguments().values());
    } else {
    // set.add(copy.getExpression());
    }
    set.add(copy.getExpression());
    return set;
}
Also used : VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) TaintableSet(org.mapleir.stdlib.collections.taint.TaintableSet)

Aggregations

Expr (org.mapleir.ir.code.Expr)87 VarExpr (org.mapleir.ir.code.expr.VarExpr)46 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)45 BasicBlock (org.mapleir.ir.cfg.BasicBlock)32 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)31 Stmt (org.mapleir.ir.code.Stmt)29 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)26 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)26 Local (org.mapleir.ir.locals.Local)22 Type (org.objectweb.asm.Type)21 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)20 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)19 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)17 ComparisonType (org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType)14 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)14 ValueComparisonType (org.mapleir.ir.code.expr.ComparisonExpr.ValueComparisonType)13 ArrayType (org.mapleir.ir.TypeUtils.ArrayType)12 HashSet (java.util.HashSet)11 ArithmeticExpr (org.mapleir.ir.code.expr.ArithmeticExpr)11 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)9