mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-05 14:18:40 +00:00
Split binary ops into another file (#71)
This commit is contained in:
50
WoofWare.PawPrint/BinaryArithmetic.fs
Normal file
50
WoofWare.PawPrint/BinaryArithmetic.fs
Normal file
@@ -0,0 +1,50 @@
|
||||
namespace WoofWare.PawPrint
|
||||
|
||||
#nowarn "42"
|
||||
|
||||
type IArithmeticOperation =
|
||||
abstract Int32Int32 : int32 -> int32 -> int32
|
||||
abstract Int64Int64 : int64 -> int64 -> int64
|
||||
abstract FloatFloat : float -> float -> float
|
||||
abstract Name : string
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module ArithmeticOperation =
|
||||
let add =
|
||||
{ new IArithmeticOperation with
|
||||
member _.Int32Int32 a b = (# "add" a b : int32 #)
|
||||
member _.Int64Int64 a b = (# "add" a b : int64 #)
|
||||
member _.FloatFloat a b = (# "add" a b : float #)
|
||||
member _.Name = "add"
|
||||
}
|
||||
|
||||
let mul =
|
||||
{ new IArithmeticOperation with
|
||||
member _.Int32Int32 a b = (# "mul" a b : int32 #)
|
||||
member _.Int64Int64 a b = (# "mul" a b : int64 #)
|
||||
member _.FloatFloat a b = (# "mul" a b : float #)
|
||||
member _.Name = "mul"
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module BinaryArithmetic =
|
||||
let execute (op : IArithmeticOperation) (val1 : EvalStackValue) (val2 : EvalStackValue) : EvalStackValue =
|
||||
// see table at https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.add?view=net-9.0
|
||||
match val1, val2 with
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.Int32 val2 -> op.Int32Int32 val1 val2 |> EvalStackValue.Int32
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ManagedPointer val2 -> failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ObjectRef val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Int64 val1, EvalStackValue.Int64 val2 -> op.Int64Int64 val1 val2 |> EvalStackValue.Int64
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ManagedPointer val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ObjectRef val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Float val1, EvalStackValue.Float val2 -> op.FloatFloat val1 val2 |> EvalStackValue.Float
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.NativeInt val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| val1, val2 -> failwith $"invalid %s{op.Name} operation: {val1} and {val2}"
|
71
WoofWare.PawPrint/EvalStackValueComparisons.fs
Normal file
71
WoofWare.PawPrint/EvalStackValueComparisons.fs
Normal file
@@ -0,0 +1,71 @@
|
||||
namespace WoofWare.PawPrint
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module EvalStackValueComparisons =
|
||||
|
||||
let clt (var1 : EvalStackValue) (var2 : EvalStackValue) : bool =
|
||||
match var1, var2 with
|
||||
| EvalStackValue.Int64 var1, EvalStackValue.Int64 var2 -> var1 < var2
|
||||
| EvalStackValue.Float var1, EvalStackValue.Float var2 -> failwith "TODO: Clt float comparison unimplemented"
|
||||
| EvalStackValue.ObjectRef var1, EvalStackValue.ObjectRef var2 ->
|
||||
failwith $"Clt instruction invalid for comparing object refs, {var1} vs {var2}"
|
||||
| EvalStackValue.ObjectRef var1, other -> failwith $"invalid comparison, ref %O{var1} vs %O{other}"
|
||||
| other, EvalStackValue.ObjectRef var2 -> failwith $"invalid comparison, %O{other} vs ref %O{var2}"
|
||||
| EvalStackValue.Float i, other -> failwith $"invalid comparison, float %f{i} vs %O{other}"
|
||||
| other, EvalStackValue.Float i -> failwith $"invalid comparison, %O{other} vs float %f{i}"
|
||||
| EvalStackValue.Int64 i, other -> failwith $"invalid comparison, int64 %i{i} vs %O{other}"
|
||||
| other, EvalStackValue.Int64 i -> failwith $"invalid comparison, %O{other} vs int64 %i{i}"
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.Int32 var2 -> var1 < var2
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.NativeInt var2 ->
|
||||
failwith "TODO: Clt Int32 vs NativeInt comparison unimplemented"
|
||||
| EvalStackValue.Int32 i, other -> failwith $"invalid comparison, int32 %i{i} vs %O{other}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.Int32 var2 ->
|
||||
failwith "TODO: Clt NativeInt vs Int32 comparison unimplemented"
|
||||
| other, EvalStackValue.Int32 var2 -> failwith $"invalid comparison, {other} vs int32 {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.NativeInt var2 -> NativeIntSource.isLess var1 var2
|
||||
| EvalStackValue.NativeInt var1, other -> failwith $"invalid comparison, nativeint {var1} vs %O{other}"
|
||||
| EvalStackValue.ManagedPointer managedPointerSource, NativeInt int64 ->
|
||||
failwith "TODO: Clt ManagedPointer vs NativeInt comparison unimplemented"
|
||||
| EvalStackValue.ManagedPointer managedPointerSource, ManagedPointer pointerSource ->
|
||||
failwith "TODO: Clt ManagedPointer vs ManagedPointer comparison unimplemented"
|
||||
| EvalStackValue.ManagedPointer managedPointerSource, UserDefinedValueType _ ->
|
||||
failwith "TODO: Clt ManagedPointer vs UserDefinedValueType comparison unimplemented"
|
||||
| EvalStackValue.UserDefinedValueType _, NativeInt int64 ->
|
||||
failwith "TODO: Clt UserDefinedValueType vs NativeInt comparison unimplemented"
|
||||
| EvalStackValue.UserDefinedValueType _, ManagedPointer managedPointerSource ->
|
||||
failwith "TODO: Clt UserDefinedValueType vs ManagedPointer comparison unimplemented"
|
||||
| EvalStackValue.UserDefinedValueType _, UserDefinedValueType _ ->
|
||||
failwith "TODO: Clt UserDefinedValueType vs UserDefinedValueType comparison unimplemented"
|
||||
|
||||
let ceq var1 var2 : bool =
|
||||
// Table III.4
|
||||
match var1, var2 with
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.Int32 var2 -> var1 = var2
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.NativeInt var2 -> failwith "TODO: int32 CEQ nativeint"
|
||||
| EvalStackValue.Int32 _, _ -> failwith $"bad ceq: Int32 vs {var2}"
|
||||
| EvalStackValue.Int64 var1, EvalStackValue.Int64 var2 -> var1 = var2
|
||||
| EvalStackValue.Int64 _, _ -> failwith $"bad ceq: Int64 vs {var2}"
|
||||
| EvalStackValue.Float var1, EvalStackValue.Float var2 -> failwith "TODO: float CEQ float"
|
||||
| EvalStackValue.Float _, _ -> failwith $"bad ceq: Float vs {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.NativeInt var2 ->
|
||||
match var1, var2 with
|
||||
| NativeIntSource.FunctionPointer f1, NativeIntSource.FunctionPointer f2 ->
|
||||
if f1 = f2 then
|
||||
true
|
||||
else
|
||||
failwith $"TODO(CEQ): nativeint vs nativeint, {f1} vs {f2}"
|
||||
| NativeIntSource.TypeHandlePtr f1, NativeIntSource.TypeHandlePtr f2 -> f1 = f2
|
||||
| NativeIntSource.Verbatim f1, NativeIntSource.Verbatim f2 -> f1 = f2
|
||||
| NativeIntSource.ManagedPointer f1, NativeIntSource.ManagedPointer f2 -> f1 = f2
|
||||
| _, _ -> failwith $"TODO (CEQ): nativeint vs nativeint, {var1} vs {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.Int32 var2 -> failwith $"TODO (CEQ): nativeint vs int32"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.ManagedPointer var2 ->
|
||||
failwith $"TODO (CEQ): nativeint vs managed pointer"
|
||||
| EvalStackValue.NativeInt _, _ -> failwith $"bad ceq: NativeInt vs {var2}"
|
||||
| EvalStackValue.ObjectRef var1, EvalStackValue.ObjectRef var2 -> var1 = var2
|
||||
| EvalStackValue.ObjectRef _, _ -> failwith $"bad ceq: ObjectRef vs {var2}"
|
||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.ManagedPointer var2 -> var1 = var2
|
||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.NativeInt var2 ->
|
||||
failwith $"TODO (CEQ): managed pointer vs nativeint"
|
||||
| EvalStackValue.ManagedPointer _, _ -> failwith $"bad ceq: ManagedPointer vs {var2}"
|
||||
| EvalStackValue.UserDefinedValueType _, _ -> failwith $"bad ceq: UserDefinedValueType vs {var2}"
|
@@ -1,33 +1,7 @@
|
||||
namespace WoofWare.PawPrint
|
||||
|
||||
#nowarn "42"
|
||||
|
||||
open Microsoft.Extensions.Logging
|
||||
|
||||
type private IArithmeticOperation =
|
||||
abstract Int32Int32 : int32 -> int32 -> int32
|
||||
abstract Int64Int64 : int64 -> int64 -> int64
|
||||
abstract FloatFloat : float -> float -> float
|
||||
abstract Name : string
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module private ArithmeticOperation =
|
||||
let add =
|
||||
{ new IArithmeticOperation with
|
||||
member _.Int32Int32 a b = (# "add" a b : int32 #)
|
||||
member _.Int64Int64 a b = (# "add" a b : int64 #)
|
||||
member _.FloatFloat a b = (# "add" a b : float #)
|
||||
member _.Name = "add"
|
||||
}
|
||||
|
||||
let mul =
|
||||
{ new IArithmeticOperation with
|
||||
member _.Int32Int32 a b = (# "mul" a b : int32 #)
|
||||
member _.Int64Int64 a b = (# "mul" a b : int64 #)
|
||||
member _.FloatFloat a b = (# "mul" a b : float #)
|
||||
member _.Name = "mul"
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
||||
module NullaryIlOp =
|
||||
@@ -103,41 +77,6 @@ module NullaryIlOp =
|
||||
|
||||
(state, WhatWeDid.Executed) |> ExecutionResult.Stepped
|
||||
|
||||
let private binaryArithmeticOperation
|
||||
(op : IArithmeticOperation)
|
||||
(currentThread : ThreadId)
|
||||
(state : IlMachineState)
|
||||
=
|
||||
let val1, state = IlMachineState.popEvalStack currentThread state
|
||||
let val2, state = IlMachineState.popEvalStack currentThread state
|
||||
// see table at https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.add?view=net-9.0
|
||||
let result =
|
||||
match val1, val2 with
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.Int32 val2 ->
|
||||
(# "add" val1 val2 : int32 #) |> EvalStackValue.Int32
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ManagedPointer val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ObjectRef val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Int64 val1, EvalStackValue.Int64 val2 ->
|
||||
(# "add" val1 val2 : int64 #) |> EvalStackValue.Int64
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ManagedPointer val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ObjectRef val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Float val1, EvalStackValue.Float val2 ->
|
||||
(# "add" val1 val2 : float #) |> EvalStackValue.Float
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.NativeInt val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.Int32 val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| val1, val2 -> failwith $"invalid %s{op.Name} operation: {val1} and {val2}"
|
||||
|
||||
result, state
|
||||
|
||||
let private stind (varType : CliType) (currentThread : ThreadId) (state : IlMachineState) : IlMachineState =
|
||||
// TODO: throw NullReferenceException if unaligned target
|
||||
let valueToStore, state = IlMachineState.popEvalStack currentThread state
|
||||
@@ -346,38 +285,7 @@ module NullaryIlOp =
|
||||
let var2, state = state |> IlMachineState.popEvalStack currentThread
|
||||
let var1, state = state |> IlMachineState.popEvalStack currentThread
|
||||
|
||||
let comparisonResult =
|
||||
// Table III.4
|
||||
match var1, var2 with
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.Int32 var2 -> if var1 = var2 then 1 else 0
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.NativeInt var2 -> failwith "TODO: int32 CEQ nativeint"
|
||||
| EvalStackValue.Int32 _, _ -> failwith $"bad ceq: Int32 vs {var2}"
|
||||
| EvalStackValue.Int64 var1, EvalStackValue.Int64 var2 -> if var1 = var2 then 1 else 0
|
||||
| EvalStackValue.Int64 _, _ -> failwith $"bad ceq: Int64 vs {var2}"
|
||||
| EvalStackValue.Float var1, EvalStackValue.Float var2 -> failwith "TODO: float CEQ float"
|
||||
| EvalStackValue.Float _, _ -> failwith $"bad ceq: Float vs {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.NativeInt var2 ->
|
||||
match var1, var2 with
|
||||
| NativeIntSource.FunctionPointer f1, NativeIntSource.FunctionPointer f2 ->
|
||||
if f1 = f2 then
|
||||
1
|
||||
else
|
||||
failwith $"TODO(CEQ): nativeint vs nativeint, {f1} vs {f2}"
|
||||
| NativeIntSource.TypeHandlePtr f1, NativeIntSource.TypeHandlePtr f2 -> if f1 = f2 then 1 else 0
|
||||
| NativeIntSource.Verbatim f1, NativeIntSource.Verbatim f2 -> if f1 = f2 then 1 else 0
|
||||
| NativeIntSource.ManagedPointer f1, NativeIntSource.ManagedPointer f2 -> if f1 = f2 then 1 else 0
|
||||
| _, _ -> failwith $"TODO (CEQ): nativeint vs nativeint, {var1} vs {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.Int32 var2 -> failwith $"TODO (CEQ): nativeint vs int32"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.ManagedPointer var2 ->
|
||||
failwith $"TODO (CEQ): nativeint vs managed pointer"
|
||||
| EvalStackValue.NativeInt _, _ -> failwith $"bad ceq: NativeInt vs {var2}"
|
||||
| EvalStackValue.ObjectRef var1, EvalStackValue.ObjectRef var2 -> if var1 = var2 then 1 else 0
|
||||
| EvalStackValue.ObjectRef _, _ -> failwith $"bad ceq: ObjectRef vs {var2}"
|
||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.ManagedPointer var2 -> if var1 = var2 then 1 else 0
|
||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.NativeInt var2 ->
|
||||
failwith $"TODO (CEQ): managed pointer vs nativeint"
|
||||
| EvalStackValue.ManagedPointer _, _ -> failwith $"bad ceq: ManagedPointer vs {var2}"
|
||||
| EvalStackValue.UserDefinedValueType _, _ -> failwith $"bad ceq: UserDefinedValueType vs {var2}"
|
||||
let comparisonResult = if EvalStackValueComparisons.ceq var1 var2 then 1 else 0
|
||||
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack' (EvalStackValue.Int32 comparisonResult) currentThread
|
||||
@@ -390,41 +298,7 @@ module NullaryIlOp =
|
||||
let var2, state = state |> IlMachineState.popEvalStack currentThread
|
||||
let var1, state = state |> IlMachineState.popEvalStack currentThread
|
||||
|
||||
let comparisonResult =
|
||||
match var1, var2 with
|
||||
| EvalStackValue.Int64 var1, EvalStackValue.Int64 var2 -> if var1 < var2 then 1 else 0
|
||||
| EvalStackValue.Float var1, EvalStackValue.Float var2 ->
|
||||
failwith "TODO: Clt float comparison unimplemented"
|
||||
| EvalStackValue.ObjectRef var1, EvalStackValue.ObjectRef var2 ->
|
||||
failwith $"Clt instruction invalid for comparing object refs, {var1} vs {var2}"
|
||||
| EvalStackValue.ObjectRef var1, other -> failwith $"invalid comparison, ref %O{var1} vs %O{other}"
|
||||
| other, EvalStackValue.ObjectRef var2 -> failwith $"invalid comparison, %O{other} vs ref %O{var2}"
|
||||
| EvalStackValue.Float i, other -> failwith $"invalid comparison, float %f{i} vs %O{other}"
|
||||
| other, EvalStackValue.Float i -> failwith $"invalid comparison, %O{other} vs float %f{i}"
|
||||
| EvalStackValue.Int64 i, other -> failwith $"invalid comparison, int64 %i{i} vs %O{other}"
|
||||
| other, EvalStackValue.Int64 i -> failwith $"invalid comparison, %O{other} vs int64 %i{i}"
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.Int32 var2 -> if var1 < var2 then 1 else 0
|
||||
| EvalStackValue.Int32 var1, EvalStackValue.NativeInt var2 ->
|
||||
failwith "TODO: Clt Int32 vs NativeInt comparison unimplemented"
|
||||
| EvalStackValue.Int32 i, other -> failwith $"invalid comparison, int32 %i{i} vs %O{other}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.Int32 var2 ->
|
||||
failwith "TODO: Clt NativeInt vs Int32 comparison unimplemented"
|
||||
| other, EvalStackValue.Int32 var2 -> failwith $"invalid comparison, {other} vs int32 {var2}"
|
||||
| EvalStackValue.NativeInt var1, EvalStackValue.NativeInt var2 ->
|
||||
if NativeIntSource.isLess var1 var2 then 1 else 0
|
||||
| EvalStackValue.NativeInt var1, other -> failwith $"invalid comparison, nativeint {var1} vs %O{other}"
|
||||
| EvalStackValue.ManagedPointer managedPointerSource, NativeInt int64 ->
|
||||
failwith "TODO: Clt ManagedPointer vs NativeInt comparison unimplemented"
|
||||
| EvalStackValue.ManagedPointer managedPointerSource, ManagedPointer pointerSource ->
|
||||
failwith "TODO: Clt ManagedPointer vs ManagedPointer comparison unimplemented"
|
||||
| EvalStackValue.ManagedPointer managedPointerSource, UserDefinedValueType _ ->
|
||||
failwith "TODO: Clt ManagedPointer vs UserDefinedValueType comparison unimplemented"
|
||||
| EvalStackValue.UserDefinedValueType _, NativeInt int64 ->
|
||||
failwith "TODO: Clt UserDefinedValueType vs NativeInt comparison unimplemented"
|
||||
| EvalStackValue.UserDefinedValueType _, ManagedPointer managedPointerSource ->
|
||||
failwith "TODO: Clt UserDefinedValueType vs ManagedPointer comparison unimplemented"
|
||||
| EvalStackValue.UserDefinedValueType _, UserDefinedValueType _ ->
|
||||
failwith "TODO: Clt UserDefinedValueType vs UserDefinedValueType comparison unimplemented"
|
||||
let comparisonResult = if EvalStackValueComparisons.clt var1 var2 then 1 else 0
|
||||
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack' (EvalStackValue.Int32 comparisonResult) currentThread
|
||||
@@ -460,8 +334,9 @@ module NullaryIlOp =
|
||||
| Sub_ovf -> failwith "TODO: Sub_ovf unimplemented"
|
||||
| Sub_ovf_un -> failwith "TODO: Sub_ovf_un unimplemented"
|
||||
| Add ->
|
||||
let result, state =
|
||||
binaryArithmeticOperation ArithmeticOperation.add currentThread state
|
||||
let val1, state = IlMachineState.popEvalStack currentThread state
|
||||
let val2, state = IlMachineState.popEvalStack currentThread state
|
||||
let result = BinaryArithmetic.execute ArithmeticOperation.add val1 val2
|
||||
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack' result currentThread
|
||||
@@ -471,8 +346,9 @@ module NullaryIlOp =
|
||||
| Add_ovf -> failwith "TODO: Add_ovf unimplemented"
|
||||
| Add_ovf_un -> failwith "TODO: Add_ovf_un unimplemented"
|
||||
| Mul ->
|
||||
let result, state =
|
||||
binaryArithmeticOperation ArithmeticOperation.mul currentThread state
|
||||
let val1, state = IlMachineState.popEvalStack currentThread state
|
||||
let val2, state = IlMachineState.popEvalStack currentThread state
|
||||
let result = BinaryArithmetic.execute ArithmeticOperation.mul val1 val2
|
||||
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack' result currentThread
|
||||
|
@@ -16,6 +16,8 @@
|
||||
<Compile Include="TypeInitialisation.fs" />
|
||||
<Compile Include="Exceptions.fs" />
|
||||
<Compile Include="EvalStack.fs" />
|
||||
<Compile Include="EvalStackValueComparisons.fs" />
|
||||
<Compile Include="BinaryArithmetic.fs" />
|
||||
<Compile Include="MethodState.fs" />
|
||||
<Compile Include="ThreadState.fs" />
|
||||
<Compile Include="IlMachineState.fs" />
|
||||
|
Reference in New Issue
Block a user