Skip to content

Commit a6a73fc

Browse files
authored
feat: Add read/write for fixed-sized arrays (#191)
Fixes #181
1 parent 26f054e commit a6a73fc

File tree

5 files changed

+44
-9
lines changed

5 files changed

+44
-9
lines changed

build.sc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import mill.contrib.scoverage.{ScoverageModule, ScoverageReport}
1313
object scoverage extends BaseModule with ScoverageReport
1414

1515
trait BaseModule extends ScoverageModule with ScalafmtModule {
16-
def scalaVersion = "3.3.0-RC5"
16+
def scalaVersion = "3.3.0-RC6"
1717
def scoverageVersion = "2.0.7"
1818

1919
val munitVersion = "1.0.0-M7"

core/src/fr/hammons/slinc/DescriptorOf.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import fr.hammons.slinc.container.*
44
import scala.quoted.*
55
import scala.compiletime.{summonInline, erasedValue, constValue}
66
import scala.NonEmptyTuple
7+
import scala.reflect.ClassTag
78

89
/** Typeclass that summons TypeDescriptors
910
*/
@@ -78,8 +79,8 @@ object DescriptorOf:
7879
CUnionDescriptor(helper[A])
7980
.asInstanceOf[CUnionDescriptor { type Inner = CUnion[A] }]
8081

81-
inline given [A, B <: Int](using
82-
innerDesc: DescriptorOf[A]
82+
inline given [A, B <: Int](using innerDesc: DescriptorOf[A])(using
83+
classTag: ClassTag[innerDesc.descriptor.Inner]
8384
): DescriptorOf[SetSizeArray[A, B]] = new DescriptorOf[SetSizeArray[A, B]]:
8485
val descriptor: TypeDescriptor { type Inner = SetSizeArray[A, B] } =
8586
SetSizeArrayDescriptor(innerDesc.descriptor, constValue[B]).asInstanceOf[

core/src/fr/hammons/slinc/SetSizeArray.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import scala.compiletime.ops.int.{`*`, `-`, `<=`, `+`, `<`}
55
import scala.compiletime.constValue
66
import scala.quoted.*
77
import scala.language.experimental.erasedDefinitions
8-
import scala.annotation.experimental
98

109
class SetSizeArray[A, B <: Int] private[slinc] (private val array: Array[A])
1110
extends AnyVal:
@@ -16,6 +15,7 @@ class SetSizeArray[A, B <: Int] private[slinc] (private val array: Array[A])
1615
): SetSizeArray[C, B * D] =
1716
new SetSizeArray[C, B * D](array.flatMap(fn.andThen(_.array)))
1817
def toSeq: Seq[A] = array.toSeq
18+
def toArray: Array[A] = array
1919
inline def take[C <: Int](using
2020
C <= B =:= true,
2121
0 <= C =:= true

core/src/fr/hammons/slinc/TypeDescriptor.scala

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import fr.hammons.slinc.modules.TransitionModule
1414
import fr.hammons.slinc.modules.{ArgumentTransition, ReturnTransition}
1515
import scala.NonEmptyTuple
1616
import scala.language.implicitConversions
17-
import dotty.tools.dotc.transform.patmat.Typ
1817

1918
/** Describes types used by C interop
2019
*/
2120
sealed trait TypeDescriptor:
21+
self =>
2222
type Inner
23+
given DescriptorOf[Inner] with
24+
val descriptor = self
2325
def size(using dm: DescriptorModule): Bytes = dm.sizeOf(this)
2426
def alignment(using dm: DescriptorModule): Bytes = dm.alignmentOf(this)
2527
def toCarrierType(using dm: DescriptorModule): Class[?] =
@@ -220,13 +222,19 @@ case class CUnionDescriptor(possibleTypes: Set[TypeDescriptor])
220222
case class SetSizeArrayDescriptor(
221223
val contained: TypeDescriptor,
222224
val number: Int
223-
) extends TypeDescriptor:
225+
)(using ClassTag[contained.Inner])
226+
extends TypeDescriptor:
224227

225228
override val reader: (ReadWriteModule, DescriptorModule) ?=> Reader[Inner] =
226-
???
229+
(mem, offset) =>
230+
new SetSizeArray(
231+
summon[ReadWriteModule].readArray[contained.Inner](mem, offset, number)
232+
)
227233

228234
override val writer: (ReadWriteModule, DescriptorModule) ?=> Writer[Inner] =
229-
???
235+
(mem, offset, value) =>
236+
summon[ReadWriteModule]
237+
.writeArray[contained.Inner](mem, offset, value.toArray)
230238

231239
override val argumentTransition
232240
: (TransitionModule, ReadWriteModule, Allocator) ?=> ArgumentTransition[
@@ -236,4 +244,4 @@ case class SetSizeArrayDescriptor(
236244
override val returnTransition
237245
: (TransitionModule, ReadWriteModule) ?=> ReturnTransition[Inner] = ???
238246

239-
type Inner = SetSizeArray[?, ?]
247+
type Inner = SetSizeArray[contained.Inner, ?]

core/test/src/fr/hammons/slinc/TransferSpec.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ trait TransferSpec[ThreadException <: Throwable](val slinc: Slinc)(using
2828

2929
case class F(u: CUnion[(CInt, CFloat)]) derives Struct
3030

31+
case class G(arr: SetSizeArray[CLong, 2]) derives Struct
32+
3133
test("can read and write jvm ints") {
3234
Scope.global {
3335
val mem = Ptr.blank[Int]
@@ -353,3 +355,27 @@ trait TransferSpec[ThreadException <: Throwable](val slinc: Slinc)(using
353355
}
354356

355357
assertEquals(fReturn.u.get[CFloat], union.get[CFloat])
358+
359+
test("can copy SetSizeArray[Int, 2] to native memory"):
360+
val ssa = SetSizeArray(1, 2)
361+
362+
Scope.confined {
363+
val ptr = Ptr.copy(ssa)
364+
assertEquals((!ptr)[0], 1)
365+
}
366+
367+
test("can copy SetSizeArray[CLong, 2] to native memory"):
368+
val ssa = SetSizeArray(CLong(1), CLong(2))
369+
370+
Scope.confined {
371+
val ptr = Ptr.copy(ssa)
372+
assertEquals((!ptr)[0], CLong(1))
373+
}
374+
375+
test("can copy G to native memory and back"):
376+
val g = G(SetSizeArray(CLong(1), CLong(2)))
377+
378+
Scope.confined {
379+
val ptr = Ptr.copy(g)
380+
assertEquals((!ptr).arr[0], CLong(1))
381+
}

0 commit comments

Comments
 (0)