Skip to content
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

32-bit platform support (SN 0.5+) #262

Closed
kubukoz opened this issue Jan 15, 2024 Discussed in #261 · 6 comments
Closed

32-bit platform support (SN 0.5+) #262

kubukoz opened this issue Jan 15, 2024 Discussed in #261 · 6 comments

Comments

@kubukoz
Copy link
Contributor

kubukoz commented Jan 15, 2024

It appears that certain parts of the program, like staticSize calculation, assume 64-bit pointers. For cases like WASM and embedded, this would be a great improvement for the future.

@kubukoz kubukoz changed the title 32-bit platforms and large structs 32-bit platform support Jan 15, 2024
@kubukoz kubukoz changed the title 32-bit platform support 32-bit platform support (SN 0.5+) Jan 15, 2024
@keynmol
Copy link
Contributor

keynmol commented Jan 15, 2024

Ah yes, I was waiting for any meaningful version of 0.5.0 to be published to start testing that, but I think it's actually more involved - size calculation might have to be adjusted in bindgen itself - i.e. you might wanna build bindings on your macbook to then run on playdate

Alternatively, and that's something I wanted to do for a while, is to use modern libclang's interface to get the size calculations directly. Then my hope is that by changing the triplet, you'd get different sizes during calculation

@keynmol
Copy link
Contributor

keynmol commented Jan 15, 2024

FTR, there are a bunch of functions to get offset and size of type/field directly from clang: https://github.com/indoorvivants/sn-bindgen/blob/main/modules/libclang/src/main/scala/generated/libclang/functions.scala#L3815-L3842

It will take some considerable rejigging of internals (which are currently laid out like shit), but I think the end result will be much more robust with regards to changing triplets.

But frist - one needs to verify that by varying the libclang triplet you get different sizes and alignments

@kubukoz
Copy link
Contributor Author

kubukoz commented Jan 26, 2024

hmmmmmmmmmmmmmmmmmm

what if we got the size from a SN type? (sizeOf[Word]) If the generated code differs so much per platform, we can say goodbye to publishing any SN jars in these cases (I mean cases like large structs, where you actually have to do this kind of math).

@kubukoz
Copy link
Contributor Author

kubukoz commented Jan 26, 2024

I understand the generated code is already platform-specific to some extent (see numeric types), but maybe we can turn things around a little bit to make it a more portable.

@keynmol
Copy link
Contributor

keynmol commented Jun 22, 2024

@kubukoz good news, I'm changing the opaque structs encoding to calculate offsets using the runtime information, e.g.

    val offsets: Array[Int] =
      val res = Array.ofDim[Int](7)
      def align(offset: Int, alignment: Int) =
        val alignmentMask = alignment - 1
        val padding =
          if (offset & alignmentMask) == 0 then 0
          else alignment - (offset & alignmentMask)
        offset + padding

      res(0) = align(0, alignmentof[StructSimple].toInt)
      res(1) = align(
        res(0) + sizeof[StructSimple].toInt,
        alignmentof[StructSimple].toInt
      )
      res(2) =
        align(res(1) + sizeof[StructSimple].toInt, alignmentof[CInt].toInt)
      res(3) = align(res(2) + sizeof[CInt].toInt, alignmentof[my_bool].toInt)
      res(4) =
        align(res(3) + sizeof[my_bool].toInt, alignmentof[CStruct1[CInt]].toInt)
      res(5) =
        align(res(4) + sizeof[CStruct1[CInt]].toInt, alignmentof[CString].toInt)
      res(6) = align(
        res(5) + sizeof[CString].toInt,
        alignmentof[
          CArray[StructComplex.Struct0, Nat.Digit2[Nat._2, Nat._5]]
        ].toInt
      )
      res
    end offsets

For this code:

typedef enum my_bool { m_false, m_true } my_bool;

typedef struct StructSimple {
  int x, y;
  char *s1, *s2;
} StructSimple;

typedef struct StructComplex {
  StructSimple p1, p2;
  int x;
  my_bool flag;
  struct {
    int HELLO;
  };
  char* bla;

  int test[25];

} StructComplex;

additionally I'm making sure the anonymous struct is included in calculation, even if it's not rendered as a field.

I've created two issues which are more focused: #285 #286

@keynmol keynmol closed this as completed Jun 22, 2024
@keynmol
Copy link
Contributor

keynmol commented Jun 22, 2024

To clarify - the goal is to remove the alignment and size calculations entirely out of bindgen, and instead get that info from clang (for compiletime), and from SN runtime (for runtime)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants