-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathNativeInterop.milone
108 lines (76 loc) · 3.48 KB
/
NativeInterop.milone
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
module rec Std.NativeInterop
open Std.Ptr
let private memcpy (dest: voidptr) (src: VoidInPtr) (size: unativeint) : voidptr =
__nativeFun ("memcpy", dest, src, size)
let private npPointeeSize (p: nativeptr<'T>) : unativeint = __nativeExpr ("sizeof(*({0}))", p)
let private cpPointeeSize (p: InPtr<'T>) : unativeint = __nativeExpr ("sizeof(*({0}))", p)
// See also:
//
// - https://github.com/dotnet/fsharp/blob/main/src/fsharp/FSharp.Core/nativeptr.fs
// - https://github.com/fsharp/fslang-design/blob/main/RFCs/FS-1109-Additional-intrinsics-for-the-NativePtr-module.md
module NativePtr =
// ---------------------------------------------
// NativePtr at F# 5.0
// ---------------------------------------------
let ofNativeInt (p: nativeint) : nativeptr<'T> = __nativeCast p
let toNativeInt (p: nativeptr<_>) : nativeint = nativeint p
let toVoidPtr (p: nativeptr<_>) : voidptr = __nativeCast p
let ofVoidPtr (p: voidptr) : nativeptr<_> = __nativeCast p
let add (p: nativeptr<'T>) (i: int) : nativeptr<'T> = __nativeExpr ("(&({0})[{1}])", p, i)
let get (p: nativeptr<'T>) (i: int) : 'T =
assert (i >= 0)
__nativeExpr ("(({0})[{1}])", p, i)
let set (p: nativeptr<'T>) (i: int) (value: 'T) : unit =
assert (i >= 0)
__nativeStmt ("({0})[{1}] = {2};", p, i, value)
let read (p: nativeptr<'T>) : 'T =
assert (__nativeCast p <> 0n)
__nativeExpr ("(*({0}))", p)
let write (p: nativeptr<'T>) (value: 'T) : unit =
assert (__nativeCast p <> 0n)
__nativeStmt ("*({0}) = {1};", p, value)
// not supported: stackalloc, toByRef
// ---------------------------------------------
// NativePtr at F# RFC FS-1109
// ---------------------------------------------
let isNullPtr (p: nativeptr<_>) : bool = p = Ptr.nullPtr
/// Copies single value. (`*dest = *src`)
let copy (dest: nativeptr<'T>) (src: nativeptr<'T>) : unit =
assert (__nativeCast dest <> 0n)
assert (__nativeCast src <> 0n)
let _ =
memcpy (__nativeCast dest) (__nativeCast src) (npPointeeSize dest)
()
/// Copies a number of values.
let copyBlock (dest: nativeptr<'T>) (src: nativeptr<'T>) (len: int) : unit =
if len > 0 then
assert (__nativeCast dest <> 0n)
assert (__nativeCast src <> 0n)
let _ =
memcpy (__nativeCast dest) (__nativeCast src) (npPointeeSize dest * unativeint len)
()
// not supported: nullPtr (generic constant isn't supported)
// unimplemented: initBlock, clear
// =============================================================================
module InPtr =
// F# 5.0
// not supported: stackalloc, toByRef, set, write
let ofNativeInt (p: nativeint) : InPtr<'T> = __nativeCast p
let toNativeInt (p: InPtr<_>) : nativeint = nativeint p
let toVoid (p: InPtr<_>) : VoidInPtr = __nativeCast p
let ofVoid (p: VoidInPtr) : InPtr<_> = __nativeCast p
let add (p: InPtr<'T>) (i: int) : InPtr<'T> = __nativeExpr ("(&({0})[{1}])", p, i)
let get (p: InPtr<'T>) (i: int) : 'T =
assert (i >= 0)
__nativeExpr ("(({0})[{1}])", p, unativeint (uint i))
let read (p: InPtr<'T>) : 'T =
assert (p <> Ptr.nullPtr)
__nativeExpr ("(*({0}))", p)
// F# RFC FS-1109
// not supported: nullPtr (generic constant isn't supported)
let isNullPtr (p: InPtr<_>) : bool = p = Ptr.nullPtr
// =============================================
/// Adds const qualifier.
let ofNativePtr (p: nativeptr<'T>) : InPtr<'T> = __nativeCast p
/// Drops const qualifier.
let toNativePtr (p: InPtr<'T>) : nativeptr<'T> = __nativeCast p