Skip to content

Commit b67b2e8

Browse files
authored
feat: Create Java_ layouts for Java 17 (#188)
Fixes #160
1 parent 29d1fc6 commit b67b2e8

File tree

11 files changed

+169
-67
lines changed

11 files changed

+169
-67
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ object Bytes:
1515
inline def %(b: Bytes): Bytes = a % b
1616
inline def -(b: Bytes): Bytes = a - b
1717
inline def >(b: Bytes): Boolean = a > b
18+
inline def >=(b: Bytes): Boolean = a >= b
1819
inline def toLong: Long = a
1920
inline def toBits: Long = a * 8
2021
def toSizeT = SizeT

core/test/src/fr/hammons/slinc/modules/DescriptorSpec.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import fr.hammons.slinc.types.CInt
77
import fr.hammons.slinc.types.CFloat
88
import fr.hammons.slinc.CUnion
99
import fr.hammons.slinc.Struct
10+
import fr.hammons.slinc.ByteDescriptor
11+
import fr.hammons.slinc.Bytes
12+
import fr.hammons.slinc.ShortDescriptor
13+
import fr.hammons.slinc.IntDescriptor
14+
import fr.hammons.slinc.LongDescriptor
15+
import fr.hammons.slinc.FloatDescriptor
16+
import fr.hammons.slinc.DoubleDescriptor
1017

1118
trait DescriptorSpec(val slinc: Slinc) extends munit.FunSuite:
1219
import slinc.dm
@@ -23,3 +30,33 @@ trait DescriptorSpec(val slinc: Slinc) extends munit.FunSuite:
2330
DescriptorOf[CUnion[(CInt, A, CFloat)]].alignment,
2431
DescriptorOf[A].alignment
2532
)
33+
34+
test("ByteDescriptor is 1 byte in size"):
35+
assertEquals(ByteDescriptor.size, Bytes(1))
36+
37+
test("ShortDescriptor is 2 bytes in size"):
38+
assertEquals(ShortDescriptor.size, Bytes(2))
39+
40+
test("IntDescriptor is 4 bytes in size"):
41+
assertEquals(IntDescriptor.size, Bytes(4))
42+
43+
test("LongDescriptor is 8 bytes in size"):
44+
assertEquals(LongDescriptor.size, Bytes(8))
45+
46+
test("FloatDescriptor is 4 bytes in size"):
47+
assertEquals(FloatDescriptor.size, Bytes(4))
48+
49+
test("DoubleDescriptor is 8 bytes in size"):
50+
assertEquals(DoubleDescriptor.size, Bytes(8))
51+
52+
test("StructDescriptor.alignment is the max of the member elements"):
53+
assertEquals(DescriptorOf[A].alignment, Bytes(8))
54+
55+
test("StructDescriptor.size is a multiple of alignment"):
56+
57+
assertEquals(DescriptorOf[A].size % DescriptorOf[A].alignment, Bytes(0))
58+
assert(
59+
DescriptorOf[A].size >= (DescriptorOf[CInt].size * 3 + DescriptorOf[
60+
CLongLong
61+
].size * 2)
62+
)

j17/src/fr/hammons/slinc/modules/DescriptorModule17.scala

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,17 @@ package fr.hammons.slinc.modules
22

33
import fr.hammons.slinc.*
44

5-
import jdk.incubator.foreign.CLinker.{
6-
C_CHAR,
7-
C_SHORT,
8-
C_INT,
9-
C_DOUBLE,
10-
C_FLOAT,
11-
C_LONG_LONG,
12-
C_POINTER
13-
}
145
import jdk.incubator.foreign.{
156
MemoryLayout,
167
MemoryAddress,
178
MemorySegment,
189
GroupLayout,
19-
CLinker
20-
}
10+
CLinker,
11+
ValueLayout
12+
}, CLinker.C_POINTER
2113
import scala.collection.concurrent.TrieMap
14+
import fr.hammons.slinc.types.{arch, os, OS, Arch}
15+
import fr.hammons.slinc.modules.platform.*
2216

2317
given descriptorModule17: DescriptorModule with
2418
val chm: TrieMap[StructDescriptor, GroupLayout] = TrieMap.empty
@@ -69,26 +63,13 @@ given descriptorModule17: DescriptorModule with
6963
else Seq.empty
7064
)
7165

72-
override def sizeOf(td: TypeDescriptor): Bytes = td match
73-
case ByteDescriptor => Bytes(1)
74-
case ShortDescriptor => Bytes(2)
75-
case IntDescriptor => Bytes(4)
76-
case LongDescriptor => Bytes(8)
77-
case FloatDescriptor => Bytes(4)
78-
case DoubleDescriptor => Bytes(8)
79-
case PtrDescriptor => Bytes(toMemoryLayout(PtrDescriptor).byteSize())
80-
case sd: StructDescriptor =>
81-
Bytes(toGroupLayout(sd).byteSize())
82-
case VaListDescriptor => Bytes(toMemoryLayout(VaListDescriptor).byteSize())
83-
case ad: AliasDescriptor[?] => sizeOf(ad.real)
84-
case CUnionDescriptor(possibleTypes) => possibleTypes.map(sizeOf).max
66+
override def sizeOf(td: TypeDescriptor): Bytes = Bytes(
67+
toMemoryLayout(td).byteSize()
68+
)
8569

86-
override def alignmentOf(td: TypeDescriptor): Bytes = td match
87-
case s: StructDescriptor =>
88-
s.members.view.map(_.descriptor).map(alignmentOf).max
89-
case CUnionDescriptor(possibleTypes) =>
90-
possibleTypes.view.map(alignmentOf).max
91-
case _ => sizeOf(td)
70+
override def alignmentOf(td: TypeDescriptor): Bytes = Bytes(
71+
toMemoryLayout(td).byteAlignment
72+
)
9273

9374
override def memberOffsets(sd: List[TypeDescriptor]): IArray[Bytes] =
9475
offsets.getOrElseUpdate(
@@ -117,13 +98,21 @@ given descriptorModule17: DescriptorModule with
11798
}
11899
)
119100

101+
val platform = (os, arch) match
102+
case (OS.Linux, Arch.X64) => x64.Linux
103+
case (OS.Darwin, Arch.X64) => x64.Darwin
104+
case (OS.Windows, Arch.X64) => x64.Windows
105+
case (OS.Linux, Arch.AArch64) => aarch64.Linux
106+
case (OS.Darwin, Arch.AArch64) => aarch64.Darwin
107+
case _ => throw Error("Unsupported platform!")
108+
120109
def toMemoryLayout(td: TypeDescriptor): MemoryLayout = td match
121-
case ByteDescriptor => C_CHAR.nn
122-
case ShortDescriptor => C_SHORT.nn
123-
case IntDescriptor => C_INT.nn
124-
case LongDescriptor => C_LONG_LONG.nn
125-
case FloatDescriptor => C_FLOAT.nn
126-
case DoubleDescriptor => C_DOUBLE.nn
110+
case ByteDescriptor => platform.jByte
111+
case ShortDescriptor => platform.jShort
112+
case IntDescriptor => platform.jInt
113+
case LongDescriptor => platform.jLong
114+
case FloatDescriptor => platform.jFloat
115+
case DoubleDescriptor => platform.jDouble
127116
case PtrDescriptor => C_POINTER.nn
128117
case VaListDescriptor => C_POINTER.nn
129118
case sd: StructDescriptor => toGroupLayout(sd)
@@ -138,7 +127,7 @@ given descriptorModule17: DescriptorModule with
138127
chm.getOrElseUpdate(
139128
sd, {
140129
val originalMembers = sd.members.map(toMemoryLayout)
141-
val alignment = alignmentOf(sd)
130+
val alignment = Bytes(originalMembers.view.map(_.byteAlignment()).max)
142131
MemoryLayout
143132
.structLayout(genLayoutList(originalMembers, alignment)*)
144133
.nn
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package fr.hammons.slinc.modules.platform
2+
3+
import jdk.incubator.foreign.ValueLayout
4+
trait Platform {
5+
val jByte: ValueLayout
6+
val jShort: ValueLayout
7+
val jInt: ValueLayout
8+
val jLong: ValueLayout
9+
val jFloat: ValueLayout
10+
val jDouble: ValueLayout
11+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package fr.hammons.slinc.modules.platform.aarch64
2+
3+
import fr.hammons.slinc.modules.platform.Platform
4+
import jdk.incubator.foreign.CLinker.{
5+
C_CHAR,
6+
C_DOUBLE,
7+
C_FLOAT,
8+
C_INT,
9+
C_LONG,
10+
C_SHORT
11+
}
12+
import jdk.incubator.foreign.ValueLayout
13+
14+
object Darwin extends Platform:
15+
val jByte: ValueLayout = C_CHAR.nn
16+
val jShort: ValueLayout = C_SHORT.nn
17+
val jInt: ValueLayout = C_INT.nn
18+
val jLong: ValueLayout = C_LONG.nn
19+
val jFloat: ValueLayout = C_FLOAT.nn
20+
val jDouble: ValueLayout = C_DOUBLE.nn
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package fr.hammons.slinc.modules.platform.aarch64
2+
3+
import fr.hammons.slinc.modules.platform.Platform
4+
import jdk.incubator.foreign.CLinker.{
5+
C_CHAR,
6+
C_INT,
7+
C_SHORT,
8+
C_LONG,
9+
C_FLOAT,
10+
C_DOUBLE
11+
}
12+
import jdk.incubator.foreign.ValueLayout
13+
14+
object Linux extends Platform:
15+
val jByte: ValueLayout = C_CHAR.nn
16+
val jShort: ValueLayout = C_SHORT.nn
17+
val jInt: ValueLayout = C_INT.nn
18+
val jLong: ValueLayout = C_LONG.nn
19+
val jFloat: ValueLayout = C_FLOAT.nn
20+
val jDouble: ValueLayout = C_DOUBLE.nn
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package fr.hammons.slinc.modules.platform.x64
2+
3+
import fr.hammons.slinc.modules.platform.Platform
4+
import jdk.incubator.foreign.CLinker.{
5+
C_CHAR,
6+
C_DOUBLE,
7+
C_FLOAT,
8+
C_INT,
9+
C_LONG,
10+
C_SHORT
11+
}
12+
13+
object Darwin extends Platform:
14+
val jByte = C_CHAR.nn
15+
val jShort = C_SHORT.nn
16+
val jInt = C_INT.nn
17+
val jLong = C_LONG.nn
18+
val jFloat = C_FLOAT.nn
19+
val jDouble = C_DOUBLE.nn
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package fr.hammons.slinc.modules.platform.x64
2+
3+
val Linux = Darwin
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package fr.hammons.slinc.modules.platform.x64
2+
3+
import fr.hammons.slinc.modules.platform.Platform
4+
import jdk.incubator.foreign.CLinker.{
5+
C_CHAR,
6+
C_SHORT,
7+
C_INT,
8+
C_LONG_LONG,
9+
C_FLOAT,
10+
C_DOUBLE
11+
}
12+
import jdk.incubator.foreign.ValueLayout
13+
14+
object Windows extends Platform:
15+
val jByte: ValueLayout = C_CHAR.nn
16+
val jShort: ValueLayout = C_SHORT.nn
17+
val jInt: ValueLayout = C_INT.nn
18+
val jLong: ValueLayout = C_LONG_LONG.nn
19+
val jFloat: ValueLayout = C_FLOAT.nn
20+
val jDouble: ValueLayout = C_DOUBLE.nn
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package fr.hammons.slinc
2+
3+
class LayoutSpec {}

0 commit comments

Comments
 (0)