-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stabilization: part XXIV #284
Changes from 22 commits
298df94
b6e2c59
bc1a914
86e608f
c29c248
77d15fc
e93ada7
e64068f
ea0c545
49d5712
42b4bf7
5f8a7b8
5c3f3f7
a81df8e
fd4e3d7
e19b1c8
5f916b6
d0cddc9
3f53eea
428a729
9b17a71
bf9b21b
5398955
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,47 +10,25 @@ open VSharp.Interpreter.IL.CilStateOperations | |
|
||
module internal Buffer = | ||
|
||
let private getArrayInfo cilState ref = | ||
let private getAddress cilState ref = | ||
let state = cilState.state | ||
let zero = MakeNumber 0 | ||
match ref.term with | ||
| HeapRef(address, _) -> | ||
let t = MostConcreteTypeOfRef state ref | ||
if TypeUtils.isArrayType t then | ||
let elemType = t.GetElementType() | ||
let indices, arrayType = | ||
if t.IsSZArray then [zero], (elemType, 1, true) | ||
else | ||
let rank = t.GetArrayRank() | ||
let indices = List.init rank (fun _ -> zero) | ||
let arrayType = (elemType, rank, false) | ||
indices, arrayType | ||
(Some (address, indices, arrayType), cilState) |> List.singleton | ||
elif t = typeof<string> then | ||
let address, stringArrayType = Memory.StringArrayInfo state address None | ||
(Some (address, [zero], stringArrayType), cilState) |> List.singleton | ||
else internalfail $"Memmove: unexpected HeapRef type {t}" | ||
| Ref(ArrayIndex(address, indices, arrayType)) -> | ||
(Some (address, indices, arrayType), cilState) |> List.singleton | ||
| Ref(ClassField(address, field)) when field = Reflection.stringFirstCharField -> | ||
let address, stringArrayType = Memory.StringArrayInfo state address None | ||
(Some (address, [zero], stringArrayType), cilState) |> List.singleton | ||
| Ptr(HeapLocation _ as pointerBase, sightType, offset) -> | ||
let cases = PtrToRefFork state pointerBase sightType offset | ||
assert(List.isEmpty cases |> not) | ||
let createArrayRef (address, state) = | ||
let cilState = changeState cilState state | ||
match address with | ||
| Some(ArrayIndex(address, index, arrayType)) -> Some (address, index, arrayType), cilState | ||
| _ -> | ||
let iie = createInsufficientInformation "Memmove: unknown pointer" | ||
cilState.iie <- Some iie | ||
None, cilState | ||
List.map createArrayRef cases | ||
let cases = Memory.TryAddressFromRefFork state ref | ||
assert(List.length cases >= 1) | ||
let createArrayRef (address, state) = | ||
let cilState = changeState cilState state | ||
match address with | ||
| Some address -> Some address, cilState | ||
| _ -> | ||
let iie = createInsufficientInformation "Memmove: unknown pointer" | ||
cilState.iie <- Some iie | ||
None, cilState | ||
List.map createArrayRef cases | ||
|
||
| _ -> internalfail $"Memmove: unexpected reference {ref}" | ||
|
||
let private Copy dstAddr dstIndex dstIndices dstArrayType srcAddr srcIndex srcIndices srcArrayType state elemCount = | ||
let private Copy dstAddr dstIndex dstIndices dstArrayType srcAddr srcIndex srcIndices srcArrayType state bytesCount = | ||
if Memory.IsSafeContextCopy srcArrayType dstArrayType |> not then | ||
internalfail $"Buffer.Copy: unsafe memory copy is not implemented, src type {srcArrayType}, dst type {dstArrayType}" | ||
let size = TypeUtils.internalSizeOf (fst3 srcArrayType) | ||
let elemCount = Arithmetics.Div bytesCount (MakeNumber size) | ||
let dstType = Types.ArrayTypeToSymbolicType dstArrayType | ||
let srcType = Types.ArrayTypeToSymbolicType srcArrayType | ||
let dstHeapRef = HeapRef dstAddr dstType | ||
|
@@ -67,46 +45,81 @@ module internal Buffer = | |
| None -> srcLinearIndex | ||
Memory.CopyArray state srcHeapRef srcLinearIndex srcType dstHeapRef dstLinearIndex dstType elemCount | ||
|
||
let CommonMemmove (cilState : cilState) dst dstIndex src srcIndex elemCount = | ||
let CommonMemmove (cilState : cilState) dst dstIndex src srcIndex bytesCount = | ||
let state = cilState.state | ||
let elemCount = Types.Cast elemCount typeof<int> | ||
let bytesCount = Types.Cast bytesCount typeof<int> | ||
let checkDst (info, cilState) = | ||
match info with | ||
| Some(dstAddr, dstIndices, dstArrayType) -> | ||
| Some (dstAddress : address) -> | ||
let checkSrc (info, cilState) = | ||
match info with | ||
| Some(srcAddr, srcIndices, srcArrayType) -> | ||
Copy dstAddr dstIndex dstIndices dstArrayType srcAddr srcIndex srcIndices srcArrayType state elemCount | ||
cilState | ||
| Some (srcAddress : address) -> | ||
let dstType = lazy dstAddress.TypeOfLocation | ||
let srcType = lazy srcAddress.TypeOfLocation | ||
let dstSize = lazy(TypeUtils.internalSizeOf dstType.Value) | ||
let srcSize = lazy(TypeUtils.internalSizeOf srcType.Value) | ||
let allSafe() = | ||
let isSafe = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Такой же код как в isSafeContextWrite There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это сделано для эффективности, так как размеры используются в нескольких местах |
||
dstType.Value = srcType.Value | ||
|| TypeUtils.canCastImplicitly srcType.Value dstType.Value | ||
&& dstSize.Value = srcSize.Value | ||
isSafe && MakeNumber srcSize.Value = bytesCount | ||
let dstSafe = lazy(MakeNumber dstSize.Value = bytesCount) | ||
let srcSafe = lazy(MakeNumber srcSize.Value = bytesCount) | ||
match dstAddress, srcAddress with | ||
| _ when allSafe() -> | ||
let value = read cilState (Ref srcAddress) | ||
let cilStates = write cilState (Ref dstAddress) value | ||
assert(List.length cilStates = 1) | ||
List.head cilStates | ||
| _ when dstSafe.Value -> | ||
let ptr = Types.Cast (Ref srcAddress) (dstType.Value.MakePointerType()) | ||
let value = read cilState ptr | ||
let cilStates = write cilState (Ref dstAddress) value | ||
assert(List.length cilStates = 1) | ||
List.head cilStates | ||
| _ when srcSafe.Value -> | ||
let value = read cilState (Ref srcAddress) | ||
let ptr = Types.Cast (Ref dstAddress) (srcType.Value.MakePointerType()) | ||
let cilStates = write cilState ptr value | ||
assert(List.length cilStates = 1) | ||
List.head cilStates | ||
| ArrayIndex(dstAddress, dstIndices, dstArrayType), ArrayIndex(srcAddress, srcIndices, srcArrayType) -> | ||
Copy dstAddress dstIndex dstIndices dstArrayType srcAddress srcIndex srcIndices srcArrayType state bytesCount | ||
cilState | ||
// TODO: implement unsafe copy | ||
| _ -> internalfail $"CommonMemmove unexpected addresses {srcAddress}, {dstAddress}" | ||
| None -> cilState | ||
getArrayInfo cilState src |> List.map checkSrc | ||
getAddress cilState src |> List.map checkSrc | ||
| None -> cilState |> List.singleton | ||
getArrayInfo cilState dst |> List.collect checkDst | ||
getAddress cilState dst |> List.collect checkDst | ||
|
||
let Memmove (cilState : cilState) dst src elemCount = | ||
CommonMemmove cilState dst None src None elemCount | ||
let Memmove (cilState : cilState) dst src bytesCount = | ||
CommonMemmove cilState dst None src None bytesCount | ||
|
||
let GenericMemmove (_ : IInterpreter) (cilState : cilState) (args : term list) = | ||
assert(List.length args = 4) | ||
let dst, src, elemCount = args[1], args[2], args[3] | ||
Memmove cilState dst src elemCount | ||
let elemType, dst, src, elemCount = args[0], args[1], args[2], args[3] | ||
let elemSize = Helpers.unwrapType elemType |> TypeUtils.internalSizeOf | ||
let bytesCount = Arithmetics.Mul elemCount (MakeNumber elemSize) | ||
Memmove cilState dst src bytesCount | ||
|
||
let ByteMemmove (_ : IInterpreter) (cilState : cilState) (args : term list) = | ||
assert(List.length args = 3) | ||
let dst, src, elemCount = args[0], args[1], args[2] | ||
Memmove cilState dst src elemCount | ||
let dst, src, bytesCount = args[0], args[1], args[2] | ||
Memmove cilState dst src bytesCount | ||
|
||
let MemoryCopy (i : IInterpreter) (cilState : cilState) (args : term list) = | ||
assert(List.length args = 4) | ||
let dst, src, dstSize, count = args[0], args[1], args[2], args[3] | ||
let dst, src, dstBytesCount, bytesCount = args[0], args[1], args[2], args[3] | ||
let memMove cilState k = | ||
Memmove cilState dst src count |> k | ||
Memmove cilState dst src bytesCount |> k | ||
let checkDst cilState k = | ||
i.NpeOrInvoke cilState dst memMove k | ||
let checkSrc cilState k = | ||
i.NpeOrInvoke cilState src checkDst k | ||
StatedConditionalExecutionCIL cilState | ||
(fun state k -> k (Arithmetics.LessOrEqual count dstSize, state)) | ||
(fun state k -> k (Arithmetics.LessOrEqual bytesCount dstBytesCount, state)) | ||
checkSrc | ||
(i.Raise i.ArgumentOutOfRangeException) | ||
id |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
namespace VSharp.System | ||
|
||
open global.System | ||
open VSharp | ||
open VSharp.Core | ||
|
||
// ------------------------------- mscorlib.System.Environment ------------------------------- | ||
|
||
module Environment = | ||
module internal Environment = | ||
|
||
let internal GetResourceFromDefault (state : state) (_ : term list) = | ||
let GetResourceFromDefault (state : state) (_ : term list) = | ||
Memory.AllocateString "Getting resource strings currently not supported!" state | ||
|
||
let GetCurrentManagedThreadId (_ : state) (_ : term list) = | ||
|
@@ -16,14 +17,29 @@ module Environment = | |
let GetManagedThreadId (_ : state) (_ : term list) = | ||
MakeNumber 0 | ||
|
||
let internal WriteLine (_ : state) (args : term list) = | ||
let WriteLine (_ : state) (args : term list) = | ||
assert(List.length args = 1) | ||
Nop() | ||
|
||
let internal get_IsOutputRedirected (_ : state) (args : term list) = | ||
let get_IsOutputRedirected (_ : state) (args : term list) = | ||
assert(List.length args = 0) | ||
MakeBool false | ||
|
||
let internal consoleClear (_ : state) (args : term list) = | ||
let consoleClear (_ : state) (args : term list) = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Название этого метода лучше с большой буквы |
||
assert(List.length args = 0) | ||
Nop() | ||
|
||
let CreateDirectory (state : state) (args : term list) = | ||
assert(List.length args = 1) | ||
let name = args[0] | ||
let t = typeof<System.IO.DirectoryInfo> | ||
let dir = Memory.AllocateDefaultClass state t | ||
let fields = Reflection.fieldsOf false t | ||
let nameField = fields |> Array.find (fun (f, _) -> f.name = "_name") |> fst | ||
let states = Memory.WriteClassField state dir nameField name | ||
assert(List.length states = 1) | ||
dir | ||
|
||
let FileExists (_ : state) (args : term list) = | ||
assert(List.length args = 1) | ||
False() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Пустая и нулловая строки будут равны