1+ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+ namespace FSharp.Compiler.UnitTests
4+
5+ open NUnit.Framework
6+ open FSharp.Test .Utilities
7+ open FSharp.Compiler .SourceCodeServices
8+
9+ #nowarn " 9"
10+
11+ [<TestFixture>]
12+ module ` `Stackalloc Tests`` =
13+
14+ type E = | A = 1
15+ | B = 2
16+
17+ [<Test>]
18+ let ``Stackalloc of DateTime`` () =
19+ let data = NativeInterop.NativePtr.stackalloc< System.DateTime> 100
20+ let now = System.DateTime.Now
21+ for i = 0 to 99 do
22+ NativeInterop.NativePtr.set data i now
23+ for i = 0 to 99 do
24+ Assert.areEqual ( NativeInterop.NativePtr.get data i) now
25+
26+ let later = now.AddDays 1.
27+ for i = 0 to 99 do
28+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
29+ datai <- later
30+ for i = 0 to 99 do
31+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
32+ Assert.areEqual datai later
33+
34+ [<Test>]
35+ let ``Stackalloc of enum`` () =
36+ let data = NativeInterop.NativePtr.stackalloc< E> 10
37+
38+ for i = 0 to 9 do
39+ NativeInterop.NativePtr.set data i ( if ( i % 2 )= 0 then E.A else E.B)
40+
41+ for i = 0 to 9 do
42+ let expected = if ( i % 2 ) = 0 then E.A else E.B
43+ Assert.areEqual ( NativeInterop.NativePtr.get data i) expected
44+
45+ for i = 0 to 9 do
46+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
47+ datai <- ( if ( i % 2 )= 1 then E.A else E.B)
48+
49+ for i = 0 to 9 do
50+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
51+ let expected = if ( i % 2 )= 1 then E.A else E.B
52+ Assert.areEqual datai expected
53+
54+ [<Test>]
55+ let ``Stackalloc of imported enum`` () =
56+ Assert.DoesNotThrow ( TestDelegate ( fun () ->
57+ NativeInterop.NativePtr.stackalloc< System.DayOfWeek> 1 |> ignore))
58+
59+ [<Test>]
60+ let ``Stackalloc of imported struct`` () =
61+ Assert.DoesNotThrow ( TestDelegate ( fun () ->
62+ NativeInterop.NativePtr.stackalloc< System.TimeSpan> 1 |> ignore))
63+
64+ [<Test>]
65+ let ``Stackalloc of imported class`` () =
66+ CompilerAssert.TypeCheckSingleError
67+ """
68+ #nowarn "9"
69+
70+ let _ = NativeInterop.NativePtr.stackalloc<System.Object> 1
71+ """
72+ FSharpErrorSeverity.Error
73+ 1
74+ ( 4 , 9 , 4 , 43 )
75+ " A generic construct requires that the type 'System.Object' is an unmanaged type"
76+
77+ [<Test>]
78+ let ``Stackalloc of imported interface`` () =
79+ CompilerAssert.TypeCheckSingleError
80+ """
81+ #nowarn "9"
82+
83+ let _ = NativeInterop.NativePtr.stackalloc<System.Collections.IEnumerable> 1
84+ """
85+ FSharpErrorSeverity.Error
86+ 1
87+ ( 4 , 9 , 4 , 43 )
88+ " A generic construct requires that the type 'System.Collections.IEnumerable' is an unmanaged type"
89+
90+ [<Test>]
91+ let ``Stackalloc of imported delegate`` () =
92+ CompilerAssert.TypeCheckSingleError
93+ """
94+ #nowarn "9"
95+
96+ let _ = NativeInterop.NativePtr.stackalloc<System.EventHandler> 1
97+ """
98+ FSharpErrorSeverity.Error
99+ 1
100+ ( 4 , 9 , 4 , 43 )
101+ " A generic construct requires that the type 'System.EventHandler' is an unmanaged type"
102+
103+ [<Test>]
104+ let ``Stackalloc of int`` () =
105+ let data = NativeInterop.NativePtr.stackalloc< int> 100
106+
107+ for i = 0 to 99 do
108+ NativeInterop.NativePtr.set data i ( i* i)
109+
110+ for i = 0 to 99 do
111+ Assert.areEqual ( NativeInterop.NativePtr.get data i) ( i* i)
112+
113+ for i = 0 to 99 do
114+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
115+ datai <- 1 - i
116+
117+ for i = 0 to 99 do
118+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
119+ Assert.areEqual datai ( 1 - i)
120+
121+ [<Test>]
122+ let ``Stackalloc of int64`` () =
123+ let data = NativeInterop.NativePtr.stackalloc< int64> 100
124+
125+ for i = 0 to 99 do
126+ NativeInterop.NativePtr.set data i ( int64 ( i* i))
127+ for i = 0 to 99 do
128+ Assert.areEqual ( NativeInterop.NativePtr.get data i) ( int64 ( i* i))
129+
130+ for i = 0 to 99 do
131+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
132+ datai <- int64 ( 1 - i)
133+
134+ for i = 0 to 99 do
135+ let datai = NativeInterop.NativePtr.toByRef ( NativeInterop.NativePtr.add data i)
136+ Assert.areEqual datai ( int64 ( 1 - i))
137+
138+ [<Test>]
139+ let ``Stackalloc of managed class`` () =
140+ CompilerAssert.TypeCheckSingleError
141+ """
142+ #nowarn "9"
143+
144+ type C() =
145+ class
146+ member __.M = 10
147+ member __.N(x) = x + 1
148+ end
149+
150+ let _ = NativeInterop.NativePtr.stackalloc<C> 1
151+ """
152+ FSharpErrorSeverity.Error
153+ 1
154+ ( 10 , 9 , 10 , 43 )
155+ " A generic construct requires that the type 'C' is an unmanaged type"
156+
157+ [<Test>]
158+ let ``Stackalloc of managed record`` () =
159+ CompilerAssert.TypeCheckSingleError
160+ """
161+ #nowarn "9"
162+
163+ type R = { A : int }
164+
165+ let _ = NativeInterop.NativePtr.stackalloc<R> 1
166+ """
167+ FSharpErrorSeverity.Error
168+ 1
169+ ( 6 , 9 , 6 , 43 )
170+ " A generic construct requires that the type 'R' is an unmanaged type"
171+
172+ [<Test>]
173+ let ``Stackalloc zero - size`` () =
174+ // Regression test for FSHARP1.0:
175+ // stackalloc<System.DateTime> 0
176+
177+ let testDelegate = TestDelegate ( fun () ->
178+ // check stackalloc 0 -- ok
179+ let data = NativeInterop.NativePtr.stackalloc< System.DateTime> 0
180+
181+ // The returned pointer is undefined
182+ // No allocation should happen
183+ let _ = NativeInterop.NativePtr.toNativeInt data
184+
185+ ())
186+
187+ Assert.DoesNotThrow testDelegate
0 commit comments