Skip to content

Commit

Permalink
feat: Add type descriptor for set-sized array (#190)
Browse files Browse the repository at this point in the history
Fixes #179
  • Loading branch information
markehammons authored May 20, 2023
1 parent 2248343 commit 26f054e
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 28 deletions.
10 changes: 9 additions & 1 deletion core/src/fr/hammons/slinc/DescriptorOf.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package fr.hammons.slinc

import fr.hammons.slinc.container.*
import scala.quoted.*
import scala.compiletime.{summonInline, erasedValue}
import scala.compiletime.{summonInline, erasedValue, constValue}
import scala.NonEmptyTuple

/** Typeclass that summons TypeDescriptors
Expand Down Expand Up @@ -77,3 +77,11 @@ object DescriptorOf:
val descriptor: CUnionDescriptor { type Inner = CUnion[A] } =
CUnionDescriptor(helper[A])
.asInstanceOf[CUnionDescriptor { type Inner = CUnion[A] }]

inline given [A, B <: Int](using
innerDesc: DescriptorOf[A]
): DescriptorOf[SetSizeArray[A, B]] = new DescriptorOf[SetSizeArray[A, B]]:
val descriptor: TypeDescriptor { type Inner = SetSizeArray[A, B] } =
SetSizeArrayDescriptor(innerDesc.descriptor, constValue[B]).asInstanceOf[
SetSizeArrayDescriptor { type Inner = SetSizeArray[A, B] }
]
22 changes: 22 additions & 0 deletions core/src/fr/hammons/slinc/TypeDescriptor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import fr.hammons.slinc.modules.TransitionModule
import fr.hammons.slinc.modules.{ArgumentTransition, ReturnTransition}
import scala.NonEmptyTuple
import scala.language.implicitConversions
import dotty.tools.dotc.transform.patmat.Typ

/** Describes types used by C interop
*/
Expand Down Expand Up @@ -215,3 +216,24 @@ case class CUnionDescriptor(possibleTypes: Set[TypeDescriptor])

override val writer: (ReadWriteModule, DescriptorModule) ?=> Writer[Inner] =
summon[ReadWriteModule].unionWriter(this)

case class SetSizeArrayDescriptor(
val contained: TypeDescriptor,
val number: Int
) extends TypeDescriptor:

override val reader: (ReadWriteModule, DescriptorModule) ?=> Reader[Inner] =
???

override val writer: (ReadWriteModule, DescriptorModule) ?=> Writer[Inner] =
???

override val argumentTransition
: (TransitionModule, ReadWriteModule, Allocator) ?=> ArgumentTransition[
Inner
] = ???

override val returnTransition
: (TransitionModule, ReadWriteModule) ?=> ReturnTransition[Inner] = ???

type Inner = SetSizeArray[?, ?]
13 changes: 13 additions & 0 deletions core/test/src/fr/hammons/slinc/modules/DescriptorSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import fr.hammons.slinc.IntDescriptor
import fr.hammons.slinc.LongDescriptor
import fr.hammons.slinc.FloatDescriptor
import fr.hammons.slinc.DoubleDescriptor
import fr.hammons.slinc.SetSizeArray

trait DescriptorSpec(val slinc: Slinc) extends munit.FunSuite:
import slinc.dm
Expand Down Expand Up @@ -60,3 +61,15 @@ trait DescriptorSpec(val slinc: Slinc) extends munit.FunSuite:
CLongLong
].size * 2)
)

test("SetSizeArrayDescriptor is size of inner type * num"):
assertEquals(
DescriptorOf[SetSizeArray[CInt, 15]].size,
DescriptorOf[CInt].size * 15
)

test("SetSizeArrayDescriptor is alignment of inner type"):
assertEquals(
DescriptorOf[SetSizeArray[CInt, 15]].alignment,
DescriptorOf[CInt].alignment
)
21 changes: 12 additions & 9 deletions j17/src/fr/hammons/slinc/modules/DescriptorModule17.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ given descriptorModule17: DescriptorModule with
val offsets: TrieMap[List[TypeDescriptor], IArray[Bytes]] = TrieMap.empty

def toCarrierType(td: TypeDescriptor): Class[?] = td match
case ByteDescriptor => classOf[Byte]
case ShortDescriptor => classOf[Short]
case IntDescriptor => classOf[Int]
case LongDescriptor => classOf[Long]
case FloatDescriptor => classOf[Float]
case DoubleDescriptor => classOf[Double]
case PtrDescriptor => classOf[MemoryAddress]
case _: StructDescriptor => classOf[MemorySegment]
case ByteDescriptor => classOf[Byte]
case ShortDescriptor => classOf[Short]
case IntDescriptor => classOf[Int]
case LongDescriptor => classOf[Long]
case FloatDescriptor => classOf[Float]
case DoubleDescriptor => classOf[Double]
case PtrDescriptor => classOf[MemoryAddress]
case _: StructDescriptor | _: CUnionDescriptor |
_: SetSizeArrayDescriptor =>
classOf[MemorySegment]
case VaListDescriptor => classOf[MemoryAddress]
case ad: AliasDescriptor[?] => toCarrierType(ad.real)
case ud: CUnionDescriptor => classOf[MemorySegment]

def genLayoutList(
layouts: Seq[MemoryLayout],
Expand Down Expand Up @@ -117,6 +118,8 @@ given descriptorModule17: DescriptorModule with
case VaListDescriptor => C_POINTER.nn
case sd: StructDescriptor => toGroupLayout(sd)
case ad: AliasDescriptor[?] => toMemoryLayout(ad.real)
case SetSizeArrayDescriptor(inner, num) =>
MemoryLayout.sequenceLayout(num, toMemoryLayout(inner)).nn
case CUnionDescriptor(possibleTypes) =>
MemoryLayout.unionLayout(possibleTypes.map(toMemoryLayout).toSeq*).nn

Expand Down
39 changes: 21 additions & 18 deletions j19/src/fr/hammons/slinc/modules/DescriptorModule19.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ given descriptorModule19: DescriptorModule with
private val offsets = TrieMap.empty[List[TypeDescriptor], IArray[Bytes]]

def toMemoryLayout(td: TypeDescriptor): MemoryLayout = td match
case ByteDescriptor => ValueLayout.JAVA_BYTE.nn
case ShortDescriptor => ValueLayout.JAVA_SHORT.nn
case IntDescriptor => ValueLayout.JAVA_INT.nn
case LongDescriptor => ValueLayout.JAVA_LONG.nn
case FloatDescriptor => ValueLayout.JAVA_FLOAT.nn
case DoubleDescriptor => ValueLayout.JAVA_DOUBLE.nn
case PtrDescriptor => ValueLayout.ADDRESS.nn
case VaListDescriptor => ValueLayout.ADDRESS.nn
case ByteDescriptor => ValueLayout.JAVA_BYTE.nn
case ShortDescriptor => ValueLayout.JAVA_SHORT.nn
case IntDescriptor => ValueLayout.JAVA_INT.nn
case LongDescriptor => ValueLayout.JAVA_LONG.nn
case FloatDescriptor => ValueLayout.JAVA_FLOAT.nn
case DoubleDescriptor => ValueLayout.JAVA_DOUBLE.nn
case PtrDescriptor => ValueLayout.ADDRESS.nn
case VaListDescriptor => ValueLayout.ADDRESS.nn
case SetSizeArrayDescriptor(inner, num) =>
MemoryLayout.sequenceLayout(num, toMemoryLayout(inner)).nn
case sd: StructDescriptor => toGroupLayout(sd)
case ad: AliasDescriptor[?] => toMemoryLayout(ad.real)
case CUnionDescriptor(possibleTypes) =>
Expand Down Expand Up @@ -78,17 +80,18 @@ given descriptorModule19: DescriptorModule with
)

def toCarrierType(td: TypeDescriptor): Class[?] = td match
case ByteDescriptor => classOf[Byte]
case ShortDescriptor => classOf[Short]
case IntDescriptor => classOf[Int]
case LongDescriptor => classOf[Long]
case FloatDescriptor => classOf[Float]
case DoubleDescriptor => classOf[Double]
case VaListDescriptor => classOf[MemoryAddress]
case PtrDescriptor => classOf[MemoryAddress]
case _: StructDescriptor => classOf[MemorySegment]
case ByteDescriptor => classOf[Byte]
case ShortDescriptor => classOf[Short]
case IntDescriptor => classOf[Int]
case LongDescriptor => classOf[Long]
case FloatDescriptor => classOf[Float]
case DoubleDescriptor => classOf[Double]
case VaListDescriptor => classOf[MemoryAddress]
case PtrDescriptor => classOf[MemoryAddress]
case _: StructDescriptor | _: CUnionDescriptor |
_: SetSizeArrayDescriptor =>
classOf[MemorySegment]
case ad: AliasDescriptor[?] => toCarrierType(ad.real)
case CUnionDescriptor(_) => classOf[MemorySegment]

override def memberOffsets(sd: List[TypeDescriptor]): IArray[Bytes] =
offsets.getOrElseUpdate(
Expand Down

0 comments on commit 26f054e

Please sign in to comment.