public BinaryOperationAction(CalculatedValue target, Op operation, JavaValue value1, JavaValue value2) { Target = target ?? throw new ArgumentNullException(nameof(target)); Operation = operation; Value1 = value1 ?? throw new ArgumentNullException(nameof(value1)); Value2 = value2 ?? throw new ArgumentNullException(nameof(value2)); }
public InvokeAction(CalculatedValue target, JavaValue instance, MethodReference method, JavaValue[] args, bool virt = false) { Target = target; Instance = instance; Method = method; Args = args; Virtual = virt; if (Instance == null) { Debug.Assert(!Virtual || !Method.HasThis); } }
public (List <MethodAction>, JavaState) Unconst() { var actions = new List <MethodAction>(); var newStack = new List <JavaValue>(); var newLocals = new Dictionary <int, JavaValue>(); foreach (var st in _stack.Reverse()) { if (st?.IsConst == true) { var v = new CalculatedValue(st.ActualType); actions.Add(new ConstantSetAction(v, st)); newStack.Add(v); } else { newStack.Add(st); } } foreach (var(key, value) in _locals) { if (value?.IsConst == true) { var v = new CalculatedValue(value.ActualType); actions.Add(new ConstantSetAction(v, value)); newLocals.Add(key, v); } else { newLocals.Add(key, value); } } return(actions, new JavaState(ImmutableStack.Create(newStack.ToArray()), newLocals.ToImmutableDictionary())); }
internal override (JavaState newState, IEnumerable <MethodAction> actions) ActUpon(JavaState curState, Dictionary <int, ActionBlock> blocks) { var noActions = new MethodAction[0]; var typeSystem = JavaAssemblyBuilder.Instance.TypeSystem; switch (Instr) { case JavaInstruction.nop: return(curState, noActions); case JavaInstruction.aconst_null: return(curState.Push(new ConstantValue(typeSystem.Object, null)), noActions); case JavaInstruction.iconst_m1: case JavaInstruction.iconst_0: case JavaInstruction.iconst_1: case JavaInstruction.iconst_2: case JavaInstruction.iconst_3: case JavaInstruction.iconst_4: case JavaInstruction.iconst_5: return(curState .Push(new ConstantValue(typeSystem.Int32, Instr - JavaInstruction.iconst_0)), noActions); case JavaInstruction.lconst_0: case JavaInstruction.lconst_1: return(curState .Push(new ConstantValue(typeSystem.Int64, (long)(Instr - JavaInstruction.lconst_0))) .Push(null), noActions); case JavaInstruction.fconst_0: case JavaInstruction.fconst_1: case JavaInstruction.fconst_2: return(curState .Push(new ConstantValue(typeSystem.Single, (float)(Instr - JavaInstruction.fconst_0))), noActions); case JavaInstruction.dconst_0: case JavaInstruction.dconst_1: return(curState .Push(new ConstantValue(typeSystem.Double, (double)(Instr - JavaInstruction.dconst_0))) .Push(null), noActions); case JavaInstruction.iload_0: case JavaInstruction.iload_1: case JavaInstruction.iload_2: case JavaInstruction.iload_3: { var toLoad = curState.Load(Instr - JavaInstruction.iload_0); return(curState.Push(toLoad), noActions); } case JavaInstruction.lload_0: case JavaInstruction.lload_1: case JavaInstruction.lload_2: case JavaInstruction.lload_3: { var toLoad = curState.Load(Instr - JavaInstruction.lload_0); return(curState.Push(toLoad).Push(null), noActions); } case JavaInstruction.fload_0: case JavaInstruction.fload_1: case JavaInstruction.fload_2: case JavaInstruction.fload_3: { var toLoad = curState.Load(Instr - JavaInstruction.fload_0); return(curState.Push(toLoad), noActions); } case JavaInstruction.dload_0: case JavaInstruction.dload_1: case JavaInstruction.dload_2: case JavaInstruction.dload_3: { var toLoad = curState.Load(Instr - JavaInstruction.dload_0); return(curState.Push(toLoad).Push(null), noActions); } case JavaInstruction.aload_0: case JavaInstruction.aload_1: case JavaInstruction.aload_2: case JavaInstruction.aload_3: { var toLoad = curState.Load(Instr - JavaInstruction.aload_0); return(curState.Push(toLoad), noActions); } case JavaInstruction.iaload: case JavaInstruction.faload: case JavaInstruction.baload: case JavaInstruction.caload: case JavaInstruction.saload: case JavaInstruction.aaload: case JavaInstruction.laload: case JavaInstruction.daload: { var newState = curState.Pop(out var index).Pop(out var array); var value = new CalculatedValue(array.ActualType.GetElementType()); newState = newState.Push(value); if (Instr == JavaInstruction.laload || Instr == JavaInstruction.daload) { newState = newState.Push(null); } return(newState, new[] { new ArrayIndexAction(value, array, index) }); } case JavaInstruction.istore_0: case JavaInstruction.istore_1: case JavaInstruction.istore_2: case JavaInstruction.istore_3: { return(curState.Pop(out var v).Store(Instr - JavaInstruction.istore_0, v), noActions); } case JavaInstruction.lstore_0: case JavaInstruction.lstore_1: case JavaInstruction.lstore_2: case JavaInstruction.lstore_3: { return(curState.Pop().Pop(out var v).Store(Instr - JavaInstruction.lstore_0, v), noActions); } case JavaInstruction.fstore_0: case JavaInstruction.fstore_1: case JavaInstruction.fstore_2: case JavaInstruction.fstore_3: { return(curState.Pop(out var v).Store(Instr - JavaInstruction.fstore_0, v), noActions); } case JavaInstruction.dstore_0: case JavaInstruction.dstore_1: case JavaInstruction.dstore_2: case JavaInstruction.dstore_3: { return(curState.Pop().Pop(out var v).Store(Instr - JavaInstruction.dstore_0, v), noActions); } case JavaInstruction.astore_0: case JavaInstruction.astore_1: case JavaInstruction.astore_2: case JavaInstruction.astore_3: { return(curState.Pop(out var v).Store(Instr - JavaInstruction.astore_0, v), noActions); } case JavaInstruction.iastore: case JavaInstruction.fastore: case JavaInstruction.bastore: case JavaInstruction.castore: case JavaInstruction.sastore: case JavaInstruction.aastore: case JavaInstruction.lastore: case JavaInstruction.dastore: { var newState = curState; if (Instr == JavaInstruction.lastore || Instr == JavaInstruction.dastore) { newState = newState.Pop(); } newState = newState.Pop(out var value).Pop(out var index).Pop(out var array); return(newState, new[] { new ArraySetAction(array, index, value) }); } case JavaInstruction.pop: return(curState.Pop(out _), noActions); case JavaInstruction.pop2: return(curState.Pop().Pop(out _), noActions); case JavaInstruction.dup: { return( curState .Pop(out var value) .Push(value).Push(value), noActions); } case JavaInstruction.dup_x1: { return( curState .Pop(out var value1).Pop(out var value2) .Push(value1).Push(value2).Push(value1), noActions); } case JavaInstruction.dup_x2: { return( curState .Pop(out var value1).Pop(out var value2).Pop(out var value3) .Push(value1).Push(value3).Push(value2).Push(value1), noActions); } case JavaInstruction.dup2: { return( curState .Pop(out var value1).Pop(out var value2) .Push(value2).Push(value1).Push(value2).Push(value1), noActions); } case JavaInstruction.dup2_x1: { return( curState .Pop(out var value1).Pop(out var value2).Pop(out var value3) .Push(value2).Push(value1).Push(value3).Push(value2).Push(value1), noActions); } case JavaInstruction.dup2_x2: { return( curState .Pop(out var value1).Pop(out var value2).Pop(out var value3).Pop(out var value4) .Push(value2).Push(value1).Push(value4).Push(value3).Push(value2).Push(value1), noActions); } case JavaInstruction.swap: { return( curState .Pop(out var value1).Pop(out var value2) .Push(value1).Push(value2), noActions); } case JavaInstruction.iadd: return(BinaryOp <int, int>(curState, false, (x, y) => x + y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Add))); case JavaInstruction.ladd: return(BinaryOp <long, long>(curState, true, (x, y) => x + y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Add))); case JavaInstruction.fadd: return(BinaryOp <float, float>(curState, false, (x, y) => x + y, typeSystem.Single, BinaryOperationAction.Creator(BinaryOperationAction.Op.Add))); case JavaInstruction.dadd: return(BinaryOp <double, double>(curState, true, (x, y) => x + y, typeSystem.Double, BinaryOperationAction.Creator(BinaryOperationAction.Op.Add))); case JavaInstruction.isub: return(BinaryOp <int, int>(curState, false, (x, y) => x - y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Sub))); case JavaInstruction.lsub: return(BinaryOp <long, long>(curState, true, (x, y) => x - y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Sub))); case JavaInstruction.fsub: return(BinaryOp <float, float>(curState, false, (x, y) => x - y, typeSystem.Single, BinaryOperationAction.Creator(BinaryOperationAction.Op.Sub))); case JavaInstruction.dsub: return(BinaryOp <double, double>(curState, true, (x, y) => x - y, typeSystem.Double, BinaryOperationAction.Creator(BinaryOperationAction.Op.Sub))); case JavaInstruction.imul: return(BinaryOp <int, int>(curState, false, (x, y) => x * y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Mul))); case JavaInstruction.lmul: return(BinaryOp <long, long>(curState, true, (x, y) => x * y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Mul))); case JavaInstruction.fmul: return(BinaryOp <float, float>(curState, false, (x, y) => x * y, typeSystem.Single, BinaryOperationAction.Creator(BinaryOperationAction.Op.Mul))); case JavaInstruction.dmul: return(BinaryOp <double, double>(curState, true, (x, y) => x * y, typeSystem.Double, BinaryOperationAction.Creator(BinaryOperationAction.Op.Mul))); case JavaInstruction.idiv: return(BinaryOp <int, int>(curState, false, (x, y) => x / y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Div))); case JavaInstruction.ldiv: return(BinaryOp <long, long>(curState, true, (x, y) => x / y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Div))); case JavaInstruction.fdiv: return(BinaryOp <float, float>(curState, false, (x, y) => x / y, typeSystem.Single, BinaryOperationAction.Creator(BinaryOperationAction.Op.Div))); case JavaInstruction.ddiv: return(BinaryOp <double, double>(curState, true, (x, y) => x / y, typeSystem.Double, BinaryOperationAction.Creator(BinaryOperationAction.Op.Div))); case JavaInstruction.irem: return(BinaryOp <int, int>(curState, false, (x, y) => x % y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Rem))); case JavaInstruction.lrem: return(BinaryOp <long, long>(curState, true, (x, y) => x % y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Rem))); case JavaInstruction.frem: return(BinaryOp <float, float>(curState, false, (x, y) => x % y, typeSystem.Single, BinaryOperationAction.Creator(BinaryOperationAction.Op.Rem))); case JavaInstruction.drem: return(BinaryOp <double, double>(curState, true, (x, y) => x % y, typeSystem.Double, BinaryOperationAction.Creator(BinaryOperationAction.Op.Rem))); case JavaInstruction.ishl: return(BinaryOp <int, int>(curState, false, (x, y) => x << y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Shl))); case JavaInstruction.lshl: return(BinaryOp <long, int>(curState, true, (x, y) => x << y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Shl), true)); case JavaInstruction.ishr: return(BinaryOp <int, int>(curState, false, (x, y) => x >> y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Shr))); case JavaInstruction.lshr: return(BinaryOp <long, int>(curState, true, (x, y) => x >> y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Shr), true)); case JavaInstruction.iushr: return(BinaryOp <int, int>(curState, false, (x, y) => (int)((uint)x >> y), typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Ushr))); case JavaInstruction.lushr: return(BinaryOp <long, int>(curState, true, (x, y) => (long)((ulong)x >> y), typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Ushr), true)); case JavaInstruction.iand: return(BinaryOp <int, int>(curState, false, (x, y) => x & y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.And))); case JavaInstruction.land: return(BinaryOp <long, long>(curState, true, (x, y) => x & y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.And))); case JavaInstruction.ior: return(BinaryOp <int, int>(curState, false, (x, y) => x | y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Or))); case JavaInstruction.lor: return(BinaryOp <long, long>(curState, true, (x, y) => x | y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Or))); case JavaInstruction.ixor: return(BinaryOp <int, int>(curState, false, (x, y) => x ^ y, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Xor))); case JavaInstruction.lxor: return(BinaryOp <long, long>(curState, true, (x, y) => x ^ y, typeSystem.Int64, BinaryOperationAction.Creator(BinaryOperationAction.Op.Xor))); case JavaInstruction.ineg: return(UnaryOp <int, int>(curState, false, false, x => - x, typeSystem.Int32, UnaryOperationAction.Creator(UnaryOperationAction.Op.Neg))); case JavaInstruction.lneg: return(UnaryOp <long, long>(curState, true, true, x => - x, typeSystem.Int64, UnaryOperationAction.Creator(UnaryOperationAction.Op.Neg))); case JavaInstruction.fneg: return(UnaryOp <float, float>(curState, false, false, x => - x, typeSystem.Single, UnaryOperationAction.Creator(UnaryOperationAction.Op.Neg))); case JavaInstruction.dneg: return(UnaryOp <double, double>(curState, true, true, x => - x, typeSystem.Double, UnaryOperationAction.Creator(UnaryOperationAction.Op.Neg))); case JavaInstruction.l2i: return(UnaryOp <long, int>(curState, true, false, x => (int)x, typeSystem.Int32, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToI))); case JavaInstruction.f2i: return(UnaryOp <float, int>(curState, false, false, x => (int)x, typeSystem.Int32, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToI))); case JavaInstruction.d2i: return(UnaryOp <double, int>(curState, true, false, x => (int)x, typeSystem.Int32, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToI))); case JavaInstruction.i2l: return(UnaryOp <int, long>(curState, false, true, x => (long)x, typeSystem.Int64, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToL))); case JavaInstruction.f2l: return(UnaryOp <float, long>(curState, false, true, x => (long)x, typeSystem.Int64, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToL))); case JavaInstruction.d2l: return(UnaryOp <double, long>(curState, true, true, x => (long)x, typeSystem.Int64, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToL))); case JavaInstruction.i2f: return(UnaryOp <int, float>(curState, false, false, x => (float)x, typeSystem.Single, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToF))); case JavaInstruction.l2f: return(UnaryOp <long, float>(curState, true, false, x => (float)x, typeSystem.Single, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToF))); case JavaInstruction.d2f: return(UnaryOp <double, float>(curState, true, false, x => (float)x, typeSystem.Single, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToF))); case JavaInstruction.i2d: return(UnaryOp <int, double>(curState, false, true, x => (double)x, typeSystem.Double, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToD))); case JavaInstruction.l2d: return(UnaryOp <long, double>(curState, true, true, x => (double)x, typeSystem.Double, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToD))); case JavaInstruction.f2d: return(UnaryOp <float, double>(curState, false, true, x => (double)x, typeSystem.Double, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToD))); case JavaInstruction.i2b: return(UnaryOp <int, int>(curState, false, false, x => (sbyte)x, typeSystem.Byte, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToB))); case JavaInstruction.i2c: return(UnaryOp <int, int>(curState, false, false, x => (char)x, typeSystem.Char, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToC))); case JavaInstruction.i2s: return(UnaryOp <int, int>(curState, false, false, x => (short)x, typeSystem.Int16, UnaryOperationAction.Creator(UnaryOperationAction.Op.ToS))); case JavaInstruction.lcmp: return(BinaryOp <long, long>(curState, true, null, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Lcmp), false, true)); case JavaInstruction.fcmpg: return(BinaryOp <float, float>(curState, false, null, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Fcmpg), false, true)); case JavaInstruction.fcmpl: return(BinaryOp <float, float>(curState, false, null, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Fcmpl), false, true)); case JavaInstruction.dcmpg: return(BinaryOp <double, double>(curState, true, null, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Fcmpg), false, true)); case JavaInstruction.dcmpl: return(BinaryOp <double, double>(curState, true, null, typeSystem.Int32, BinaryOperationAction.Creator(BinaryOperationAction.Op.Fcmpl), false, true)); case JavaInstruction.ireturn: case JavaInstruction.freturn: case JavaInstruction.areturn: return(Return(curState, false)); case JavaInstruction.lreturn: case JavaInstruction.dreturn: return(Return(curState, true)); case JavaInstruction.@return: return(Return(curState, false, true)); case JavaInstruction.arraylength: { var newState = curState.Pop(out var array); var length = new CalculatedValue(typeSystem.Int32); return(newState.Push(length), new[] { new ArrayLengthAction(length, array) }); } case JavaInstruction.athrow: { curState.Pop(out var exc); return(null, new[] { new ThrowAction(exc) }); } case JavaInstruction.monitorenter: case JavaInstruction.monitorexit: { return(curState.Pop(out var exc), new[] { new MonitorAction(exc, Instr == JavaInstruction.monitorenter) }); } default: throw new NotImplementedException($"{Instr} as Niladic"); } }
public ConstructorAction(CalculatedValue target, MethodReference method, JavaValue[] args) { Target = target; Method = method; Args = args; }
public GetFieldAction(CalculatedValue target, JavaValue from, FieldReference field) { Target = target; From = @from; Field = field; }
public GetStaticAction(CalculatedValue target, FieldReference field) { Target = target; Field = field; }
public ArrayIndexAction(CalculatedValue target, JavaValue array, JavaValue index) { Target = target; Array = array; Index = index; }
public MultiNewArrayAction(CalculatedValue target, TypeReference targetType, JavaValue[] dimensions) { TargetType = targetType; Dimensions = dimensions; Target = target; }
public NewArrayAction(CalculatedValue target, TypeReference type, JavaValue count) { Target = target; Type = type; Count = count; }
public ConstantSetAction(CalculatedValue target, JavaValue value) { Target = target; Value = value; }
public UnaryOperationAction(CalculatedValue target, Op operation, JavaValue value) { Target = target ?? throw new ArgumentNullException(nameof(target)); Operation = operation; Value = value ?? throw new ArgumentNullException(nameof(value)); }
public ArrayLengthAction(CalculatedValue target, JavaValue array) { Target = target; Array = array; }