Skip to content

Commit 705d07c

Browse files
Bind a MEOS scalar at the width its ABI defines
A C type the mapping table does not name falls through to IntPtr, the pointer-width opaque handle. The `_t` spellings libclang leaves unreduced — int8_t through uint64_t — and `unsigned char` are absent from that table, so 530 of the 4825 bound functions declared a scalar at pointer width: 246 int64_t, 140 uint64_t, 38 uint32_t and 24 unsigned char arguments, and 72 int64_t, 58 uint64_t, 56 uint32_t and one unsigned char returns. A uint32_t returned as IntPtr reads eight bytes of a register the ABI defines four of, so the value carries whatever the upper half held. The enum types come from the catalog's own `enums` rather than from names listed one at a time. The five listed names covered MeosType, interpType and tempSubtype, missed IndexSearchOp, SPTreeKind, MeosPixType, MeosOper, SkipListType and nullHandleType across 43 further parameters and returns, and one of them — spanType — names no catalog enum at all. Reading the set from the catalog is what keeps the next enum from arriving as a pointer.
1 parent 8ad54ee commit 705d07c

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

tools/codegen.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,32 @@
5353
"uint32": "uint",
5454
"int64": "long",
5555
"uint64": "ulong",
56+
"int8_t": "sbyte",
57+
"int16_t": "short",
58+
"int32_t": "int",
59+
"int64_t": "long",
60+
"uint16_t": "ushort",
61+
"uint32_t": "uint",
62+
"uint64_t": "ulong",
63+
"signed char": "sbyte",
64+
"unsigned char": "byte",
65+
"unsigned short": "ushort",
5666
"size_t": "ulong",
5767
"ssize_t": "long",
58-
"meosType": "int",
59-
"MeosType": "int",
60-
"interpType": "int",
61-
"tempSubtype": "int",
62-
"spanType": "int",
6368
}
6469

70+
# The names of the catalog's own enums, filled in by ``configure``. A C enum is
71+
# an int at the ABI, and taking the set from the catalog is what keeps a newly
72+
# added enum from arriving as an opaque pointer the way a hand-list leaves it.
73+
ENUM_TYPES: set[str] = set()
74+
75+
76+
def configure(idl: dict) -> None:
77+
"""Take from the catalog the type facts the mapping below reads."""
78+
ENUM_TYPES.clear()
79+
ENUM_TYPES.update(e["name"] for e in idl.get("enums", []) if e.get("name"))
80+
81+
6582
# C pointer-to-char marshalled as managed string when StringMarshalling.Utf8 is on.
6683
def is_string_pointer(c_type: str) -> bool:
6784
t = c_type.replace("const ", "").strip()
@@ -77,6 +94,8 @@ def csharp_type_for(canonical: str) -> str:
7794
# Pointer of any depth -> IntPtr (we don't propagate pointer types into C# semantics).
7895
if "*" in t or t.endswith("[]"):
7996
return "IntPtr"
97+
if t in ENUM_TYPES:
98+
return "int"
8099
return SCALAR_MAP.get(t, "IntPtr") # unknown scalar -> opaque pointer is safer than guessing
81100

82101

@@ -453,6 +472,7 @@ def main(idl_path: str, dll_path: str = DLL_PATH) -> None:
453472
DLL_PATH = dll_path
454473
with open(idl_path) as fh:
455474
idl = json.load(fh)
475+
configure(idl)
456476
funcs = idl["functions"]
457477
repo_root = Path(__file__).resolve().parent.parent
458478
out_dir = repo_root / "MEOS.NET" / "Internal"

0 commit comments

Comments
 (0)