-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Encoding for Flexible Array Members #62
Comments
Given that the C standard does not specify any field that constitutes length (and in fact the example above uses 5 bits from the char field to indicate length). The only option I see at this point is providing a helper function such as this: opaque type FAM[T, A] = Long
def flexibleArrayMemberData[T <: CStruct, A](struct: Ptr[T])(using fam: FAM[T, A]): Ptr[A] =
(struct + fam).asInstanceOf[A] Just need to check that the inference works on that correctly, if you just pass the argument without any parameters. and we generate (for the example above) an inline instance of inline given FAM[sdshdr5, CChar] = sizeOf[sdshdr5] |
Alternatively, no need to go crazy - the companion object can host those static functions. Take this header: struct vectord {
char len;
int length;
double arr[];
}; Here's the encoding: //> using platform scala-native
package libtest
import _root_.scala.scalanative.unsafe.*
import _root_.scala.scalanative.unsigned.*
import _root_.scala.scalanative.libc.*
import _root_.scala.scalanative.*
import libtest.structs.vectord
opaque type FAM[T <: CStruct, A] = CSize
object FAM:
private[libtest] inline def apply[T <: CStruct, A](a: CSize): FAM[T,A] =
a.asInstanceOf
object structs:
import _root_.libtest.structs.*
/**
* [bindgen] header: test.h
*/
opaque type vectord = CStruct2[CChar, CInt]
object vectord:
given _tag: Tag[vectord] = Tag.materializeCStruct2Tag[CChar, CInt]
def apply()(using Zone): Ptr[vectord] = scala.scalanative.unsafe.alloc[vectord](1)
def apply(len : CChar, length : CInt)(using Zone): Ptr[vectord] =
val ____ptr = apply()
(!____ptr).len = len
(!____ptr).length = length
____ptr
extension (struct: vectord)
def len : CChar = struct._1
def len_=(value: CChar): Unit = !struct.at1 = value
def length : CInt = struct._2
def length_=(value: CInt): Unit = !struct.at2 = value
inline def fam(ptr: Ptr[vectord]): Ptr[Double] =
(ptr + sizeof[vectord]).asInstanceOf[Ptr[Double]]
inline def applyWithFam(len: CChar, length: CInt)(famLength: Long)(using Zone): Ptr[vectord] =
val ____rawptr = alloc[Byte](sizeof[vectord] + famLength.toULong * sizeof[Double])
val ____ptr = ____rawptr.asInstanceOf[Ptr[vectord]]
(!____ptr).len = len
(!____ptr).length = length
____ptr
@main def hello =
Zone {implicit z =>
val p = vectord.applyWithFam('h', 50)(50)
val fam = vectord.fam(p)
for
i <- 0 until (!p).length
do
fam(i) = i * 10.0
} Specifically the |
Which I've just found out are a thing and I don't like it: https://en.wikipedia.org/wiki/Flexible_array_member
They shouldn't have any effect on sizeof or alignment, I think. We can just pretend that they don't exist and let the user manually allocate such monstrosity
Or lift it as a usable type, and provide an allocator for such length
This is the sort of thing that will crash during generation:
The text was updated successfully, but these errors were encountered: