added support for long, float and double
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user