Skip to content

Commit 6aedec4

Browse files
committed
feat: add Transform types
1 parent 8e2ad0c commit 6aedec4

25 files changed

+214
-121
lines changed

build.sc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ trait BaseModule extends ScoverageModule with ScalafmtModule {
1616
def scalaVersion = "3.3.0"
1717
def scoverageVersion = "2.0.7"
1818

19-
val munitVersion = "1.0.0-M7"
19+
val munitVersion = "1.0.0-M8"
2020
val jmhV = "1.33"
2121

2222
def ivyDeps = Agg(

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import java.lang.invoke.{MethodHandle, MethodType, MethodHandles}
44
import fr.hammons.slinc.modules.DescriptorModule
55

66
trait Allocator:
7-
def allocate(descriptor: TypeDescriptor, num: Int): Mem
7+
def allocate(descriptor: ForeignTypeDescriptor, num: Int): Mem
88
def addCloseAction(fn: () => Unit): Unit
99
def upcall[Fn](descriptor: FunctionDescriptor, target: Fn): Mem
1010
protected def methodHandleFromFn[Fn](

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ class CUnion[T <: Tuple](private[slinc] val mem: Mem):
3232
setHelper[T, A](a)
3333

3434
object CUnion:
35-
private inline def applyHelper[T <: Tuple](td: TypeDescriptor | Null)(using
36-
DescriptorModule
37-
): TypeDescriptor = inline erasedValue[T] match
35+
private inline def applyHelper[T <: Tuple](td: ForeignTypeDescriptor | Null)(
36+
using DescriptorModule
37+
): ForeignTypeDescriptor = inline erasedValue[T] match
3838
case _: (a *: t) =>
39-
val aDesc = summonInline[DescriptorOf[a]].descriptor
39+
val aDesc =
40+
summonInline[DescriptorOf[a]].descriptor.toForeignTypeDescriptor
4041
val max =
4142
if td != null then
4243
if td.size > aDesc.size then td

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ final case class FunctionDescriptor(
2323
case FunctionDescriptor(head +: tail, variadicDescriptors, None) =>
2424
VoidHelper
2525
.methodTypeV(
26-
head.toCarrierType,
27-
tail.view.concat(variadicDescriptors).map(_.toCarrierType).toSeq*
26+
head.toForeignTypeDescriptor.toCarrierType,
27+
tail.view
28+
.concat(variadicDescriptors)
29+
.map(_.toForeignTypeDescriptor.toCarrierType)
30+
.toSeq*
2831
)
2932
.nn
3033

@@ -35,15 +38,20 @@ final case class FunctionDescriptor(
3538
) =>
3639
MethodType
3740
.methodType(
38-
outputDescriptor.toCarrierType,
39-
head.toCarrierType,
40-
tail.view.concat(variadicDescriptors).map(_.toCarrierType).toSeq*
41+
outputDescriptor.toForeignTypeDescriptor.toCarrierType,
42+
head.toForeignTypeDescriptor.toCarrierType,
43+
tail.view
44+
.concat(variadicDescriptors)
45+
.map(_.toForeignTypeDescriptor.toCarrierType)
46+
.toSeq*
4147
)
4248
.nn
4349

4450
case FunctionDescriptor(_, _, None) => VoidHelper.methodTypeV().nn
4551
case FunctionDescriptor(_, _, Some(outputDescriptor)) =>
46-
MethodType.methodType(outputDescriptor.toCarrierType).nn
52+
MethodType
53+
.methodType(outputDescriptor.toForeignTypeDescriptor.toCarrierType)
54+
.nn
4755

4856
object FunctionDescriptor:
4957
def fromDefDef(using q: Quotes)(symbol: q.reflect.Symbol) =

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,18 @@ class Ptr[A](private[slinc] val mem: Mem, private[slinc] val offset: Bytes):
2929
r: ReadWriteModule
3030
)(using ClassTag[A]): IArray[A] =
3131
IArray.unsafeFromArray(
32-
r.readArray(mem.resize(DescriptorOf[A].size * size), offset, size)
32+
r.readArray(
33+
mem.resize(DescriptorOf[A].toForeignTypeDescriptor.size * size),
34+
offset,
35+
size
36+
)
3337
)
3438

3539
def `unary_!_=`(value: A)(using rwM: ReadWriteModule, desc: DescriptorOf[A]) =
3640
rwM.write(mem, offset, desc.descriptor, value)
3741
def apply(bytes: Bytes): Ptr[A] = Ptr[A](mem, offset + bytes)
3842
def apply(index: Int)(using DescriptorOf[A], DescriptorModule): Ptr[A] =
39-
Ptr[A](mem, offset + (DescriptorOf[A].size * index))
43+
Ptr[A](mem, offset + (DescriptorOf[A].toForeignTypeDescriptor.size * index))
4044

4145
def castTo[A]: Ptr[A] = this.asInstanceOf[Ptr[A]]
4246
private[slinc] def resize(toBytes: Bytes) =
@@ -59,12 +63,15 @@ object Ptr:
5963
def blankArray[A](
6064
num: Int
6165
)(using descriptor: DescriptorOf[A], alloc: Allocator): Ptr[A] =
62-
Ptr[A](alloc.allocate(DescriptorOf[A], num), Bytes(0))
66+
Ptr[A](
67+
alloc.allocate(DescriptorOf[A].toForeignTypeDescriptor, num),
68+
Bytes(0)
69+
)
6370

6471
def copy[A](
6572
a: Array[A]
6673
)(using alloc: Allocator, descriptor: DescriptorOf[A], rwm: ReadWriteModule) =
67-
val mem = alloc.allocate(DescriptorOf[A], a.size)
74+
val mem = alloc.allocate(DescriptorOf[A].toForeignTypeDescriptor, a.size)
6875
rwm.writeArray(mem, Bytes(0), a)
6976
Ptr[A](mem, Bytes(0))
7077

@@ -76,7 +83,7 @@ object Ptr:
7683
val descriptor: TypeDescriptor { type Inner = A }
7784
}
7885
) =
79-
val mem = alloc.allocate(DescriptorOf[A], 1)
86+
val mem = alloc.allocate(DescriptorOf[A].toForeignTypeDescriptor, 1)
8087
rwm.write(mem, Bytes(0), descriptor.descriptor, a)
8188
Ptr[A](mem, Bytes(0))
8289

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ trait Slinc:
2222
export types.os
2323

2424
def sizeOf[A](using l: DescriptorOf[A]) =
25-
SizeT.maybe(DescriptorOf[A].size.toLong).get
25+
SizeT.maybe(DescriptorOf[A].toForeignTypeDescriptor.size.toLong).get
2626

2727
def Null[A] = scopePlatformSpecific.nullPtr[A]
2828

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ object Struct:
3636
rwm: ReadWriteModule,
3737
dm: DescriptorModule
3838
): Writer[A] =
39-
val offsets = dm.memberOffsets(memberDescriptors[A])
39+
val offsets =
40+
dm.memberOffsets(memberDescriptors[A].map(_.toForeignTypeDescriptor))
4041
(mem, offset, value) =>
4142
writeGenHelper(
4243
offsets.map(_ + offset),
@@ -67,7 +68,8 @@ object Struct:
6768
rwm: ReadWriteModule,
6869
dm: DescriptorModule
6970
): Reader[A] =
70-
val offsets: IArray[Bytes] = dm.memberOffsets(memberDescriptors[A])
71+
val offsets: IArray[Bytes] =
72+
dm.memberOffsets(memberDescriptors[A].map(_.toForeignTypeDescriptor))
7173
(mem, offset) => {
7274
val elems: m.MirroredElemTypes =
7375
readGenHelper[m.MirroredElemTypes](offsets.map(_ + offset), 0, mem)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package fr.hammons.slinc
2+
3+
trait Transform[A, B](using val desc: DescriptorOf[B])(
4+
_transformFrom: B => A,
5+
_transformTo: A => B
6+
) extends DescriptorOf[A]:
7+
val descriptor
8+
: TransformDescriptor { type Inner = A; val cRep: desc.descriptor.type } =
9+
new TransformDescriptor:
10+
val cRep: desc.descriptor.type = desc.descriptor
11+
type Inner = A
12+
val transformFrom = _transformFrom
13+
val transformTo = _transformTo
14+
15+
object Transform:
16+
given Transform[Boolean, Byte](
17+
b => if b != (0: Byte) then true else false,
18+
b => if b then 1: Byte else 0: Byte
19+
)

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

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ sealed trait TypeDescriptor:
2222
type Inner
2323
given DescriptorOf[Inner] with
2424
val descriptor = self
25-
def size(using dm: DescriptorModule): Bytes = dm.sizeOf(this)
26-
def alignment(using dm: DescriptorModule): Bytes = dm.alignmentOf(this)
27-
def toCarrierType(using dm: DescriptorModule): Class[?] =
28-
dm.toCarrierType(this)
2925

3026
val reader: (ReadWriteModule, DescriptorModule) ?=> Reader[Inner]
3127
val writer: (ReadWriteModule, DescriptorModule) ?=> Writer[Inner]
@@ -44,7 +40,7 @@ sealed trait TypeDescriptor:
4440
Inner
4541
] =
4642
val reader = this.reader
47-
val size = this.size
43+
val size = this.toForeignTypeDescriptor.size
4844
(mem, offset, num) => {
4945
var i = 0
5046
val array = Array.ofDim[Inner](num)
@@ -57,12 +53,22 @@ sealed trait TypeDescriptor:
5753
val arrayWriter
5854
: (ReadWriteModule, DescriptorModule) ?=> Writer[Array[Inner]] =
5955
val writer = this.writer
60-
val size = this.size
56+
val size = this.toForeignTypeDescriptor.size
6157
(mem, offset, a) =>
6258
var i = 0
6359
while i < a.length do
6460
writer(mem, size * i + offset, a(i))
6561
i += 1
62+
63+
def toForeignTypeDescriptor: ForeignTypeDescriptor
64+
65+
sealed trait ForeignTypeDescriptor extends TypeDescriptor:
66+
def toForeignTypeDescriptor: ForeignTypeDescriptor = this
67+
def size(using dm: DescriptorModule): Bytes = dm.sizeOf(this)
68+
def alignment(using dm: DescriptorModule): Bytes = dm.alignmentOf(this)
69+
def toCarrierType(using dm: DescriptorModule): Class[?] =
70+
dm.toCarrierType(this)
71+
6672
object TypeDescriptor:
6773
def fromTypeRepr(using q: Quotes)(
6874
typeRepr: q.reflect.TypeRepr
@@ -83,7 +89,7 @@ object TypeDescriptor:
8389

8490
inline val unusedImplicit = "msg=unused implicit parameter"
8591

86-
sealed trait BasicDescriptor extends TypeDescriptor:
92+
sealed trait BasicDescriptor extends ForeignTypeDescriptor:
8793
override val argumentTransition = identity
8894

8995
override val returnTransition = _.asInstanceOf[Inner]
@@ -118,7 +124,7 @@ case object DoubleDescriptor extends BasicDescriptor:
118124
val reader = readWriteModule.doubleReader
119125
val writer = readWriteModule.doubleWriter
120126

121-
case object PtrDescriptor extends TypeDescriptor:
127+
case object PtrDescriptor extends ForeignTypeDescriptor:
122128
type Inner = Ptr[?]
123129
override val reader = (mem, offset) =>
124130
Ptr(readWriteModule.memReader(mem, offset), Bytes(0))
@@ -152,7 +158,7 @@ trait StructDescriptor(
152158
val members: List[StructMemberDescriptor],
153159
val clazz: Class[?],
154160
val transform: Tuple => Product
155-
) extends TypeDescriptor
161+
) extends ForeignTypeDescriptor
156162

157163
case class AliasDescriptor[A](val real: TypeDescriptor) extends TypeDescriptor:
158164
type Inner = A
@@ -174,13 +180,11 @@ case class AliasDescriptor[A](val real: TypeDescriptor) extends TypeDescriptor:
174180
summon[TransitionModule].methodArgument(real, _, summon[Allocator])
175181

176182
override val returnTransition = summon[TransitionModule].methodReturn(real, _)
177-
override def size(using dm: DescriptorModule): Bytes = dm.sizeOf(real)
178-
override def alignment(using dm: DescriptorModule): Bytes =
179-
dm.alignmentOf(real)
180-
override def toCarrierType(using dm: DescriptorModule): Class[?] =
181-
dm.toCarrierType(real)
182183

183-
case object VaListDescriptor extends TypeDescriptor:
184+
def toForeignTypeDescriptor: ForeignTypeDescriptor =
185+
real.toForeignTypeDescriptor
186+
187+
case object VaListDescriptor extends ForeignTypeDescriptor:
184188
type Inner = VarArgs
185189

186190
override val reader: (ReadWriteModule, DescriptorModule) ?=> Reader[Inner] =
@@ -200,7 +204,7 @@ case object VaListDescriptor extends TypeDescriptor:
200204
summon[TransitionModule].addressReturn(o).asVarArgs
201205

202206
case class CUnionDescriptor(possibleTypes: Set[TypeDescriptor])
203-
extends TypeDescriptor:
207+
extends ForeignTypeDescriptor:
204208
type Inner = CUnion[? <: NonEmptyTuple]
205209

206210
override val reader: (ReadWriteModule, DescriptorModule) ?=> Reader[Inner] =
@@ -223,7 +227,7 @@ case class SetSizeArrayDescriptor(
223227
val contained: TypeDescriptor,
224228
val number: Int
225229
)(using ClassTag[contained.Inner])
226-
extends TypeDescriptor:
230+
extends ForeignTypeDescriptor:
227231

228232
override val reader: (ReadWriteModule, DescriptorModule) ?=> Reader[Inner] =
229233
(mem, offset) =>
@@ -256,3 +260,32 @@ case class SetSizeArrayDescriptor(
256260
summon[ReadWriteModule].read(mem, Bytes(0), this)
257261

258262
type Inner = SetSizeArray[contained.Inner, ?]
263+
264+
trait TransformDescriptor extends TypeDescriptor:
265+
val cRep: TypeDescriptor
266+
val transformTo: Inner => cRep.Inner
267+
val transformFrom: cRep.Inner => Inner
268+
269+
protected inline def toInner[A <: Matchable](a: A) =
270+
import scala.compiletime.error
271+
inline a match
272+
case b: cRep.Inner => b
273+
case _ => error("cannot convert")
274+
275+
override val reader: (ReadWriteModule, DescriptorModule) ?=> Reader[Inner] =
276+
(mem: Mem, bytes: Bytes) => transformFrom(cRep.reader(mem, bytes))
277+
278+
override val writer: (ReadWriteModule, DescriptorModule) ?=> Writer[Inner] =
279+
(mem, bytes, value) => cRep.writer(mem, bytes, transformTo(value))
280+
281+
override val argumentTransition
282+
: (TransitionModule, ReadWriteModule, Allocator) ?=> ArgumentTransition[
283+
Inner
284+
] = cRep.argumentTransition.compose(transformTo)
285+
286+
override val returnTransition
287+
: (TransitionModule, ReadWriteModule) ?=> ReturnTransition[Inner] =
288+
cRep.returnTransition.andThen(transformFrom)
289+
290+
def toForeignTypeDescriptor: ForeignTypeDescriptor =
291+
cRep.toForeignTypeDescriptor
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package fr.hammons.slinc.modules
22

3-
import fr.hammons.slinc.{Bytes, TypeDescriptor}
3+
import fr.hammons.slinc.Bytes
4+
import fr.hammons.slinc.ForeignTypeDescriptor
45

56
/** A module used to perform Platform dependent work with a descriptor
67
*/
78
trait DescriptorModule:
8-
def memberOffsets(sd: List[TypeDescriptor]): IArray[Bytes]
9-
def sizeOf(td: TypeDescriptor): Bytes
10-
def alignmentOf(td: TypeDescriptor): Bytes
11-
def toCarrierType(td: TypeDescriptor): Class[?]
9+
def memberOffsets(sd: List[ForeignTypeDescriptor]): IArray[Bytes]
10+
def sizeOf(td: ForeignTypeDescriptor): Bytes
11+
def alignmentOf(td: ForeignTypeDescriptor): Bytes
12+
def toCarrierType(td: ForeignTypeDescriptor): Class[?]

0 commit comments

Comments
 (0)