Skip to content

Commit 2d7f862

Browse files
authored
feat:Add transitions for CUnion (#184)
Fixes #176
1 parent a33580c commit 2d7f862

File tree

20 files changed

+291
-70
lines changed

20 files changed

+291
-70
lines changed

build.sc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ trait BaseModule extends ScoverageModule with ScalafmtModule {
2626
def scalacOptions = Seq(
2727
"-deprecation",
2828
"-Wunused:all",
29+
"-feature",
2930
"-unchecked",
3031
"-Xcheck-macros",
3132
"-Xprint-suspension",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import fr.hammons.slinc.modules.DescriptorModule
55

66
trait Allocator:
77
def allocate(descriptor: TypeDescriptor, num: Int): Mem
8+
def addCloseAction(fn: () => Unit): Unit
89
def upcall[Fn](descriptor: FunctionDescriptor, target: Fn): Mem
910
protected def methodHandleFromFn[Fn](
1011
descriptor: FunctionDescriptor,

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package fr.hammons.slinc
33
import scala.compiletime.erasedValue
44
import scala.compiletime.error
55
import scala.compiletime.summonInline
6+
import scala.compiletime.summonFrom
67
import fr.hammons.slinc.modules.ReadWriteModule
78
import fr.hammons.slinc.modules.DescriptorModule
89
import scala.NonEmptyTuple
@@ -47,10 +48,14 @@ object CUnion:
4748
case EmptyTuple => td.nn
4849

4950
inline def apply[T <: NonEmptyTuple](using
50-
is: InferredScope,
5151
descriptorModule: DescriptorModule
52-
) =
52+
): CUnion[T] =
5353
val maxDescriptor = applyHelper[T](null).nn
54-
is { allocator ?=>
55-
new CUnion[T](allocator.allocate(maxDescriptor, 1))
54+
summonFrom {
55+
case allocator: Allocator =>
56+
new CUnion[T](allocator.allocate(maxDescriptor, 1))
57+
case inferredScope: InferredScope =>
58+
inferredScope { allocator ?=>
59+
new CUnion[T](allocator.allocate(maxDescriptor, 1))
60+
}
5661
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ object FunctionContext:
2525
case a => a
2626
.exists:
2727
case _: StructDescriptor => true
28+
case _: CUnionDescriptor => true
2829
case _ => false
2930

3031
val allocationTransition: Seq[InputTransition] =

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,23 @@ object MethodHandleTools:
107107
_ => retType
108108
),
109109
(meth, params) =>
110-
retType.asType match
110+
val invokeExpr = retType.asType match
111111
case '[r] =>
112-
val invokeExpr = invokeArguments[r](
112+
invokeArguments[r](
113113
methodHandleExpr,
114114
'{ $mem.asBase } +:
115115
params.map(_.asExpr)
116116
)
117-
val invokeResultExpr = '{
118-
val invokeResult = $invokeExpr
119-
if invokeResult == null then ().asInstanceOf[r]
120-
else invokeResult.asInstanceOf[r]
117+
118+
val invokeResultExpr = retType.asType match
119+
case '[Unit] =>
120+
'{
121+
$invokeExpr
122+
()
121123
}
122-
invokeResultExpr.asTerm
123-
.changeOwner(meth)
124+
case '[r] => '{ $invokeExpr.asInstanceOf[r] }
125+
invokeResultExpr.asTerm
126+
.changeOwner(meth)
124127
).asExprOf[A]
125128

126129
expr

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ object Scope:
2323
def confined(using c: ConfinedScope): ConfinedScope = c
2424
def global(using g: GlobalScope): GlobalScope = g
2525
def shared(using s: SharedScope): SharedScope = s
26+
def inferred(using i: InferredScope): InferredScope = i
2627

2728
class ScopeI(platformSpecific: ScopeI.PlatformSpecific):
2829
given TempScope = platformSpecific.createTempScope

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import scala.quoted.*
1313
import fr.hammons.slinc.modules.TransitionModule
1414
import fr.hammons.slinc.modules.{ArgumentTransition, ReturnTransition}
1515
import scala.NonEmptyTuple
16+
import scala.language.implicitConversions
1617

1718
/** Describes types used by C interop
1819
*/
@@ -203,12 +204,13 @@ case class CUnionDescriptor(possibleTypes: Set[TypeDescriptor])
203204
???
204205

205206
override val returnTransition
206-
: (TransitionModule, ReadWriteModule) ?=> ReturnTransition[Inner] = ???
207+
: (TransitionModule, ReadWriteModule) ?=> ReturnTransition[Inner] = obj =>
208+
summon[TransitionModule].cUnionReturn(this, obj).asInstanceOf[Inner]
207209

208210
override val argumentTransition
209211
: (TransitionModule, ReadWriteModule, Allocator) ?=> ArgumentTransition[
210212
Inner
211-
] = ???
213+
] = (i: Inner) => i.mem.asBase
212214

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

core/src/fr/hammons/slinc/container/Container.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import scala.reflect.ClassTag
44
import scala.compiletime.erasedValue
55
import scala.compiletime.error
66
import scala.quoted.*
7+
import scala.language.implicitConversions
78

89
class Data[A](a: A):
910
type B = A

core/src/fr/hammons/slinc/modules/TransitionModule.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ trait TransitionModule:
4444

4545
def memReturn(value: Object): Mem
4646

47+
def cUnionReturn(td: TypeDescriptor, value: Object): CUnion[?]
48+
4749
def functionArgument[A](td: TypeDescriptor, value: Object): A =
4850
methodReturn[A](td, value)
4951

core/test/resources/native/test.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,25 @@ EXPORTED int i30_function_ptr_va_list(int count, Adder adder, ...) {
102102

103103
EXPORTED void* i157_null_eq() {
104104
return NULL;
105+
}
106+
107+
typedef union {
108+
float x;
109+
int y;
110+
} union_a_issue_176;
111+
112+
typedef union {
113+
long x;
114+
double y;
115+
} union_b_issue_176;
116+
117+
static union_b_issue_176 b;
118+
EXPORTED union_b_issue_176 i176_test(union_a_issue_176 a, char is_left) {
119+
if(is_left) {
120+
b.y = (double) a.x;
121+
} else {
122+
b.x = (long) a.y;
123+
}
124+
125+
return b;
105126
}

0 commit comments

Comments
 (0)