@@ -10,7 +10,11 @@ import scala.scalanative.unsigned.*
10
10
* This implementation wraps a pointer along with the allocated size in bytes. It also provides basic support for slicing and for
11
11
* reading/writing primitive values, which are used by the Layout instances in the shared code.
12
12
*/
13
- final class MemorySegment private (private [foreign] val ptr : Ptr [Byte ], val byteSize : Long ):
13
+ final class MemorySegment private (private [foreign] val ptr : Ptr [Byte ], val byteSize : Long , private val arena : Arena ):
14
+ private def checkOpen (): Unit =
15
+ if arena.isClosed then
16
+ throw new IllegalStateException (" MemorySegment accessed after Arena was closed" )
17
+
14
18
/** Creates a new MemorySegment that is a slice of this segment.
15
19
*
16
20
* @param offset
@@ -21,70 +25,107 @@ final class MemorySegment private (private[foreign] val ptr: Ptr[Byte], val byte
21
25
* A new MemorySegment representing the slice.
22
26
*/
23
27
def asSlice (offset : Long , newSize : Long ): MemorySegment =
28
+ checkOpen()
24
29
if offset < 0 || newSize < 0 || offset + newSize > byteSize then
25
30
throw new IllegalArgumentException (s " Invalid slice parameters: byteSize= $byteSize, offset= $offset, newSize= $newSize" )
26
31
else
27
- MemorySegment (ptr + offset, newSize)
32
+ MemorySegment (ptr + offset, newSize, arena)
33
+ end if
34
+ end asSlice
28
35
29
36
/** Reads a value from memory using the provided layout.
30
37
*/
31
38
def get (layout : ValueLayout .OfBoolean , offset : Long ): Boolean =
39
+ checkOpen()
32
40
require(offset + layout.byteSize <= byteSize)
33
41
! (ptr + offset).asInstanceOf [Ptr [CBool ]]
42
+ end get
34
43
def get (layout : ValueLayout .OfByte , offset : Long ): Byte =
44
+ checkOpen()
35
45
require(offset + layout.byteSize <= byteSize)
36
46
! (ptr + offset).asInstanceOf [Ptr [Byte ]]
47
+ end get
37
48
def get (layout : ValueLayout .OfShort , offset : Long ): Short =
49
+ checkOpen()
38
50
require(offset + layout.byteSize <= byteSize)
39
51
! (ptr + offset).asInstanceOf [Ptr [Short ]]
52
+ end get
40
53
def get (layout : ValueLayout .OfInt , offset : Long ): Int =
54
+ checkOpen()
41
55
require(offset + layout.byteSize <= byteSize)
42
56
! (ptr + offset).asInstanceOf [Ptr [Int ]]
57
+ end get
43
58
def get (layout : ValueLayout .OfLong , offset : Long ): Long =
59
+ checkOpen()
44
60
require(offset + layout.byteSize <= byteSize)
45
61
! (ptr + offset).asInstanceOf [Ptr [Long ]]
62
+ end get
46
63
def get (layout : ValueLayout .OfFloat , offset : Long ): Float =
64
+ checkOpen()
47
65
require(offset + layout.byteSize <= byteSize)
48
66
! (ptr + offset).asInstanceOf [Ptr [Float ]]
67
+ end get
49
68
def get (layout : ValueLayout .OfDouble , offset : Long ): Double =
69
+ checkOpen()
50
70
require(offset + layout.byteSize <= byteSize)
51
71
! (ptr + offset).asInstanceOf [Ptr [Double ]]
72
+ end get
52
73
def get (layout : ValueLayout .OfChar , offset : Long ): Char =
74
+ checkOpen()
53
75
require(offset + layout.byteSize <= byteSize)
54
76
! (ptr + offset).asInstanceOf [Ptr [Char ]]
77
+ end get
55
78
def get (layout : AddressLayout , offset : Long ): MemorySegment =
79
+ checkOpen()
56
80
val newByteSize = byteSize - offset
57
81
require(newByteSize >= 0 )
58
- new MemorySegment ((ptr + offset).asInstanceOf [Ptr [Byte ]], newByteSize)
82
+ new MemorySegment ((ptr + offset).asInstanceOf [Ptr [Byte ]], newByteSize, arena )
59
83
end get
60
84
61
85
/** Writes a value to memory using the provided layout.
62
86
*/
63
87
def set (layout : ValueLayout .OfBoolean , offset : Long , value : Boolean ): Unit =
88
+ checkOpen()
64
89
require(offset + layout.byteSize <= byteSize)
65
90
! (ptr + offset).asInstanceOf [Ptr [CBool ]] = value
91
+ end set
66
92
def set (layout : ValueLayout .OfByte , offset : Long , value : Byte ): Unit =
93
+ checkOpen()
67
94
require(offset + layout.byteSize <= byteSize)
68
95
! (ptr + offset).asInstanceOf [Ptr [Byte ]] = value
96
+ end set
69
97
def set (layout : ValueLayout .OfShort , offset : Long , value : Short ): Unit =
98
+ checkOpen()
70
99
require(offset + layout.byteSize <= byteSize)
71
100
! (ptr + offset).asInstanceOf [Ptr [Short ]] = value
101
+ end set
72
102
def set (layout : ValueLayout .OfInt , offset : Long , value : Int ): Unit =
103
+ checkOpen()
73
104
require(offset + layout.byteSize <= byteSize)
74
105
! (ptr + offset).asInstanceOf [Ptr [Int ]] = value
106
+ end set
75
107
def set (layout : ValueLayout .OfLong , offset : Long , value : Long ): Unit =
108
+ checkOpen()
76
109
require(offset + layout.byteSize <= byteSize)
77
110
! (ptr + offset).asInstanceOf [Ptr [Long ]] = value
111
+ end set
78
112
def set (layout : ValueLayout .OfFloat , offset : Long , value : Float ): Unit =
113
+ checkOpen()
79
114
require(offset + layout.byteSize <= byteSize)
80
115
! (ptr + offset).asInstanceOf [Ptr [Float ]] = value
116
+ end set
81
117
def set (layout : ValueLayout .OfDouble , offset : Long , value : Double ): Unit =
118
+ checkOpen()
82
119
require(offset + layout.byteSize <= byteSize)
83
120
! (ptr + offset).asInstanceOf [Ptr [Double ]] = value
121
+ end set
84
122
def set (layout : ValueLayout .OfChar , offset : Long , value : Char ): Unit =
123
+ checkOpen()
85
124
require(offset + layout.byteSize <= byteSize)
86
125
! (ptr + offset).asInstanceOf [Ptr [Char ]] = value
126
+ end set
87
127
def set (layout : AddressLayout , offset : Long , value : MemorySegment ): Unit =
128
+ checkOpen()
88
129
require(offset + layout.byteSize <= byteSize)
89
130
val _ = memcpy((ptr + offset).asInstanceOf [Ptr [Byte ]], value.ptr, value.byteSize.toCSize)
90
131
end set
@@ -93,10 +134,10 @@ end MemorySegment
93
134
object MemorySegment :
94
135
95
136
/** Allocates a new MemorySegment of the given byte size. */
96
- private [foreign] def allocate (byteSize : Long ): MemorySegment =
137
+ private [foreign] def allocate (byteSize : Long , arena : Arena ): MemorySegment =
97
138
val ptr = malloc(byteSize).asInstanceOf [Ptr [Byte ]]
98
139
if ptr == null then throw new RuntimeException (" malloc returned null" )
99
- new MemorySegment (ptr, byteSize)
140
+ new MemorySegment (ptr, byteSize, arena )
100
141
end allocate
101
142
102
143
/** Copies a block of memory from the source segment to the destination segment.
0 commit comments