added support for long, float and double

This commit is contained in:
wea_ondara
2022-07-13 21:05:14 +02:00
parent a267d7034b
commit 7dafade67a
10 changed files with 257 additions and 194 deletions

View File

@@ -132,38 +132,31 @@ class FilterMethodVisitor extends MethodVisitor {
@Override
public void visitInsn(int opcode) {
System.out.println("insn: " + ops.getOrDefault(opcode, "" + opcode));
if (opcode == Opcodes.ICONST_1) {
varStack.push(ConstantExpression.I1);
} else if (opcode == Opcodes.ICONST_0) {
varStack.push(ConstantExpression.I0);
} else if (opcode == Opcodes.IRETURN) {
//collapse conditions
for (int i = condStack.size() - 1; i >= 0; i--) {
condStack.get(i).e1 = varStack.pop();
varStack = condStack.get(i).varStack;
evalCond(condStack.get(i));
}
switch (opcode) {
case Opcodes.ICONST_0, Opcodes.LCONST_0, Opcodes.FCONST_0, Opcodes.DCONST_0 -> varStack.push(ConstantExpression.V0);
case Opcodes.ICONST_1, Opcodes.LCONST_1, Opcodes.FCONST_1, Opcodes.DCONST_1 -> varStack.push(ConstantExpression.V1);
case Opcodes.ICONST_2, Opcodes.FCONST_2 -> varStack.push(ConstantExpression.V2);
case Opcodes.ICONST_3 -> varStack.push(ConstantExpression.V3);
case Opcodes.ICONST_4 -> varStack.push(ConstantExpression.V4);
case Opcodes.ICONST_5 -> varStack.push(ConstantExpression.V5);
case Opcodes.IRETURN -> {
//collapse conditions
for (int i = condStack.size() - 1; i >= 0; i--) {
condStack.get(i).e1 = varStack.pop();
varStack = condStack.get(i).varStack;
evalCond(condStack.get(i));
}
// condStack.clear();
prediacteExpr = varStack.pop();
} else {
throw new RuntimeException("insn: unsupported opcode " + ops.getOrDefault(opcode, "" + opcode));
prediacteExpr = varStack.pop();
}
case Opcodes.FCMPL, Opcodes.FCMPG, Opcodes.DCMPL, Opcodes.DCMPG, Opcodes.LCMP -> {
var var2 = varStack.pop();
var var1 = varStack.pop();
varStack.push(new BinaryExpression(var1, var2, BinaryExpression.Operator.NE));
}
default -> throw new RuntimeException("insn: unsupported opcode " + ops.getOrDefault(opcode, "" + opcode));
}
// if (!mpgotoconds.isEmpty()) {
// var e1 = varStack.pop();
// for (int i = mpgotoconds.size() - 1; i >= 0; i--) {
// var cond = mpgotoconds.get(i);
// cond.e1 = e1;
//// for (int j = 0; j < condStack.size() && condStack.get(j) != cond; j++) {
//// condStack.get(j).e1 = e1;
//// }
// condStack.remove(cond);
// varStack = cond.varStack;
// evalCond(cond);
// }
// mpgotoconds = new ArrayList<>();
// }
super.visitInsn(opcode);
debugExpr();
}
@@ -302,7 +295,7 @@ class FilterMethodVisitor extends MethodVisitor {
// System.out.println("left: " + left);
// System.out.println("cond.e1: " + cond.e1);
// System.out.println("cond.e2: " + cond.e2);
boolean wrapInTernary = cond.e1 != ConstantExpression.I1 || cond.e2 != ConstantExpression.I0;
boolean wrapInTernary = cond.e1 != ConstantExpression.V1 || cond.e2 != ConstantExpression.V0;
// boolean wrapInTernary = true;
Expression expr;
// 153, "IFEQ",
@@ -369,6 +362,7 @@ class FilterMethodVisitor extends MethodVisitor {
@Override
public void visitLdcInsn(Object value) {
System.out.println("ldc: " + value);
varStack.push(new ConstantExpression(value));
super.visitLdcInsn(value);
debugExpr();
}
@@ -398,10 +392,26 @@ class FilterMethodVisitor extends MethodVisitor {
private Map<Integer, String> ops = createOpsMap(
3, "ICONST_0",
4, "ICONST_1",
5, "ICONST_2",
6, "ICONST_3",
7, "ICONST_4",
8, "ICONST_5",
9, "LCONST_0",
10, "LCONST_1",
11, "FCONST_0",
12, "FCONST_1",
13, "FCONST_2",
14, "DCONST_0",
15, "DCONST_1",
17, "SIPUSH",
25, "ALOAD",
//jmp
148, "LCMP",
149, "FCMPL",
150, "FCMPG",
151, "DCMPL",
152, "DCMPG",
153, "IFEQ",
154, "IFNE",
155, "IFLT",

View File

@@ -22,7 +22,7 @@ public class PredicateParser {
try {
return parseExpression();
} catch (Exception e) {
throw new AsmParseException("PredicateParser: failed to parse expression", e);
throw new AsmParseException("PredicateParser: failed to parse expression: " + e.getLocalizedMessage(), e);
}
}

View File

@@ -6,8 +6,12 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public class ConstantExpression implements Expression {
public static final jef.expressions.ConstantExpression I0 = new jef.expressions.ConstantExpression(0);
public static final jef.expressions.ConstantExpression I1 = new jef.expressions.ConstantExpression(1);
public static final jef.expressions.ConstantExpression V0 = new jef.expressions.ConstantExpression(0);
public static final jef.expressions.ConstantExpression V1 = new jef.expressions.ConstantExpression(1);
public static final jef.expressions.ConstantExpression V2 = new jef.expressions.ConstantExpression(2);
public static final jef.expressions.ConstantExpression V3 = new jef.expressions.ConstantExpression(3);
public static final jef.expressions.ConstantExpression V4 = new jef.expressions.ConstantExpression(4);
public static final jef.expressions.ConstantExpression V5 = new jef.expressions.ConstantExpression(5);
protected final Object value;

View File

@@ -29,7 +29,7 @@ public class ParameterExpression extends ConstantExpression implements Expressio
} else if (this.value == null) {
return "null";
} else if (this.value instanceof Collection) {
return "(" + ((Collection<?>) this.value).stream().map(Objects::toString).collect(Collectors.joining(",")) + ")";
return "(" + ((Collection<?>) this.value).stream().map(Objects::toString).collect(Collectors.joining(", ")) + ")";
}
return value.toString();
}

View File

@@ -17,8 +17,6 @@ public class TernaryExpression implements Expression {
@Override
public String toString() {
return cond
+ " ? " + (!(whenTrue instanceof ConstantExpression) ? "(" + whenTrue + ")" : whenTrue)
+ " : " + (!(whenFalse instanceof ConstantExpression) ? "(" + whenFalse + ")" : whenFalse);
return "IF(" + cond + ", " + whenTrue + ", " + whenFalse + ")";
}
}

View File

@@ -27,11 +27,11 @@ public class ExpressionOptimizer extends ExpressionModifier {
// x && false -> false
for (Expression e : ands) {
if (e == ConstantExpression.I0) {
return ConstantExpression.I0;
if (e == ConstantExpression.V0) {
return ConstantExpression.V0;
}
}
while (ands.remove(ConstantExpression.I1)) ;
while (ands.remove(ConstantExpression.V1)) ;
return new AndExpression(ands);
}
@@ -52,27 +52,27 @@ public class ExpressionOptimizer extends ExpressionModifier {
// x || true -> true
for (Expression e : ors) {
if (e == ConstantExpression.I1) {
return ConstantExpression.I1;
if (e == ConstantExpression.V1) {
return ConstantExpression.V1;
}
}
while (ors.remove(ConstantExpression.I0)) ;
while (ors.remove(ConstantExpression.V0)) ;
return new OrExpression(ors);
}
@Override
public Expression modifyTernary(TernaryExpression expr) {
if (expr.getWhenFalse() == ConstantExpression.I1 && expr.getWhenFalse() == ConstantExpression.I0) {
if (expr.getWhenFalse() == ConstantExpression.V1 && expr.getWhenFalse() == ConstantExpression.V0) {
//x ? 1 : 0 -> x
return modify(expr.getCond());
} else if (expr.getWhenFalse() == ConstantExpression.I0 && expr.getWhenFalse() == ConstantExpression.I1) {
} else if (expr.getWhenFalse() == ConstantExpression.V0 && expr.getWhenFalse() == ConstantExpression.V1) {
//x ? 0 : 1 -> !x
return modify(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT));
} else if (expr.getWhenFalse() == ConstantExpression.I0) {
} else if (expr.getWhenFalse() == ConstantExpression.V0) {
//x ? y : 0 -> x && y
return modify(new AndExpression(expr.getCond(), expr.getWhenTrue()));
} else if (expr.getWhenFalse() == ConstantExpression.I1) {
} else if (expr.getWhenFalse() == ConstantExpression.V1) {
//x ? y : 1 -> !x or y
return modify(new OrExpression(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT), expr.getWhenTrue()));
} else if (expr.getWhenTrue() instanceof TernaryExpression t && expr.getWhenFalse() == t.getWhenFalse()) {

View File

@@ -28,11 +28,11 @@ public class ExpressionOptimizerBottomUp extends ExpressionModifier {
// x && false -> false
for (Expression e : ands) {
if (e == ConstantExpression.I0) {
return ConstantExpression.I0;
if (e == ConstantExpression.V0) {
return ConstantExpression.V0;
}
}
while (ands.remove(ConstantExpression.I1)) ;
while (ands.remove(ConstantExpression.V1)) ;
return new AndExpression(ands);
}
@@ -54,11 +54,11 @@ public class ExpressionOptimizerBottomUp extends ExpressionModifier {
// x || true -> true
for (Expression e : ors) {
if (e == ConstantExpression.I1) {
return ConstantExpression.I1;
if (e == ConstantExpression.V1) {
return ConstantExpression.V1;
}
}
while (ors.remove(ConstantExpression.I0)) ;
while (ors.remove(ConstantExpression.V0)) ;
return new OrExpression(ors);
}
@@ -68,16 +68,16 @@ public class ExpressionOptimizerBottomUp extends ExpressionModifier {
var cond = modify(expr.getCond());
var whenTrue = modify(expr.getWhenTrue());
var whenFalse = modify(expr.getWhenFalse());
if (whenTrue == ConstantExpression.I1 && whenFalse == ConstantExpression.I0) {
if (whenTrue == ConstantExpression.V1 && whenFalse == ConstantExpression.V0) {
//x ? 1 : 0 -> x
return cond;
} else if (whenTrue == ConstantExpression.I0 && whenFalse == ConstantExpression.I1) {
} else if (whenTrue == ConstantExpression.V0 && whenFalse == ConstantExpression.V1) {
//x ? 0 : 1 -> !x
return modify(new UnaryExpression(cond, UnaryExpression.Operator.NOT));
} else if (whenFalse == ConstantExpression.I0) {
} else if (whenFalse == ConstantExpression.V0) {
//x ? y : 0 -> x && y
return modify(new AndExpression(cond, whenTrue));
} else if (whenFalse == ConstantExpression.I1) {
} else if (whenFalse == ConstantExpression.V1) {
//x ? y : 1 -> !x or y
return modify(new OrExpression(new UnaryExpression(cond, UnaryExpression.Operator.NOT), whenTrue));
} else if (whenTrue instanceof TernaryExpression t && whenFalse == t.getWhenFalse()) {
@@ -92,7 +92,7 @@ public class ExpressionOptimizerBottomUp extends ExpressionModifier {
public Expression modifyUnary(UnaryExpression expr) {
var inner = modify(expr.getExpr());
if (inner instanceof UnaryExpression u
&& expr.getOperator() == u.getOperator()
&& u.getOperator() == UnaryExpression.Operator.NOT
&& expr.getOperator() == UnaryExpression.Operator.NOT) {
//!!x -> x
return modify(u.getExpr());

View File

@@ -35,8 +35,8 @@ public class FilterOp<T extends Serializable> implements Queryable<T>, Operation
System.out.println(expr);
expr = new TernaryRewriter().modify(expr);
System.out.println(expr);
expr = new ExpressionOptimizer().modify(expr);
// expr = new ExpressionOptimizerBottomUp().modify(expr);
// expr = new ExpressionOptimizer().modify(expr);
expr = new ExpressionOptimizerBottomUp().modify(expr);
expr = new TableAliasInjector(getTableAlias()).modify(expr);
this.predicateExpr = expr;
}