71 """Build the type table the `codegen_harness.cpp` test program references.
73 The aliases below give every emitted struct a stable, hand-written C++
74 name (e.g. `StdU`) so the harness can use plain identifiers rather than
75 spelling the auto-generated mangled names.
78 std_u_inner = types.StructType(
80 [(
"u8", _uint8), (
"u16", _uint16), (
"u32", _uint32), (
"u64", _uint64)],
82 std_u = types.TypeAlias(
"@StdU",
"StdU", std_u_inner)
84 std_s_inner = types.StructType(
86 [(
"s8", _sint8), (
"s16", _sint16), (
"s32", _sint32), (
"s64", _sint64)],
88 std_s = types.TypeAlias(
"@StdS",
"StdS", std_s_inner)
91 odd_u_inner = types.StructType(
"@OddU::inner", [(
"u24", _uint24)])
92 odd_u = types.TypeAlias(
"@OddU",
"OddU", odd_u_inner)
93 odd_s_inner = types.StructType(
"@OddS::inner", [(
"s24", _sint24)])
94 odd_s = types.TypeAlias(
"@OddS",
"OddS", odd_s_inner)
97 sub_u_inner = types.StructType(
"@SubU::inner", [(
"u3", _uint3),
99 sub_u = types.TypeAlias(
"@SubU",
"SubU", sub_u_inner)
100 sub_s_inner = types.StructType(
"@SubS::inner", [(
"s5", _sint5),
102 sub_s = types.TypeAlias(
"@SubS",
"SubS", sub_s_inner)
105 bool_inner = types.StructType(
"@BoolField::inner", [(
"flag", _uint1),
107 bool_field = types.TypeAlias(
"@BoolField",
"BoolField", bool_inner)
110 inner_inner = types.StructType(
"@Inner::inner", [(
"x", _uint8),
112 inner = types.TypeAlias(
"@Inner",
"Inner", inner_inner)
113 outer_inner = types.StructType(
"@Outer::inner", [(
"label", _uint8),
115 outer = types.TypeAlias(
"@Outer",
"Outer", outer_inner)
123 mis_inner_inner = types.StructType(
"@MisInner::inner", [(
"x", _uint8),
125 mis_inner = types.TypeAlias(
"@MisInner",
"MisInner", mis_inner_inner)
126 misaligned_inner = types.StructType(
"@Misaligned::inner",
127 [(
"inner", mis_inner), (
"tag", _uint3)])
128 misaligned = types.TypeAlias(
"@Misaligned",
"Misaligned", misaligned_inner)
131 arr4_type = types.ArrayType(
"!hw.array<4xui8>", _uint8, 4)
132 arr4_inner = types.StructType(
"@Arr4::inner", [(
"r", arr4_type)])
133 arr4 = types.TypeAlias(
"@Arr4",
"Arr4", arr4_inner)
141 u3_arr_inner = types.StructType(
143 [(
"vals", types.ArrayType(
"!hw.array<8xui3>", _uint3, 8))])
144 u3_arr = types.TypeAlias(
"@U3Arr",
"U3Arr", u3_arr_inner)
146 bits1_arr_inner = types.StructType(
148 [(
"flags", types.ArrayType(
"!hw.array<8xui1>", _uint1, 8))])
149 bits1_arr = types.TypeAlias(
"@Bits1Arr",
"Bits1Arr", bits1_arr_inner)
151 s5_arr_inner = types.StructType(
153 [(
"vals", types.ArrayType(
"!hw.array<4xsi5>", _sint5, 4))])
154 s5_arr = types.TypeAlias(
"@S5Arr",
"S5Arr", s5_arr_inner)
156 u24_arr_inner = types.StructType(
158 [(
"vals", types.ArrayType(
"!hw.array<2xui24>", _uint24, 2))])
159 u24_arr = types.TypeAlias(
"@U24Arr",
"U24Arr", u24_arr_inner)
166 sb_cell_inner = types.StructType(
"@SbCell::inner", [(
"hi", _uint3),
168 sb_cell = types.TypeAlias(
"@SbCell",
"SbCell", sb_cell_inner)
169 sb_cell_arr_inner = types.StructType(
171 [(
"cells", types.ArrayType(
"!hw.array<4xSbCell>", sb_cell, 4))])
172 sb_cell_arr = types.TypeAlias(
"@SbCellArr",
"SbCellArr", sb_cell_arr_inner)
181 nested3_inner = types.StructType(
184 types.ArrayType(
"!hw.array<2x!hw.array<4xui3>>",
185 types.ArrayType(
"!hw.array<4xui3>", _uint3, 4), 2))])
186 nested3 = types.TypeAlias(
"@Nested3",
"Nested3", nested3_inner)
191 nested_cell_inner = types.StructType(
"@NestedCell::inner", [
193 types.ArrayType(
"!hw.array<2x!hw.array<3xSbCell>>",
194 types.ArrayType(
"!hw.array<3xSbCell>", sb_cell, 3), 2))
196 nested_cell = types.TypeAlias(
"@NestedCell",
"NestedCell", nested_cell_inner)
199 union_inner = types.UnionType(
"@UnionTwo::inner", [(
"small", _uint8),
201 union_two = types.TypeAlias(
"@UnionTwo",
"UnionTwo", union_inner)
203 union_subbyte_inner = types.UnionType(
"@UnionSubByte::inner",
205 (
"signed_small", _sint5),
206 (
"cell", sb_cell), (
"big", _uint12)])
207 union_subbyte = types.TypeAlias(
"@UnionSubByte",
"UnionSubByte",
211 list_id =
"!esi.list<ui32>"
212 list_type = types.ListType(list_id, _uint32)
213 win_arg_inner = types.StructType(
215 [(
"tag", _uint16), (
"items", list_type)],
217 win_header_inner = types.StructType(
218 "@ListWindow::header",
219 [(
"tag", _uint16), (
"items_count", _uint16)],
221 win_data_inner = types.StructType(
223 [(
"items", types.ArrayType(
"!hw.array<1xui32>", _uint32, 1))],
225 win_lowered = types.UnionType(
226 "@ListWindow::lowered",
227 [(
"header", win_header_inner), (
"data", win_data_inner)],
229 window_id = (
'!esi.window<"ListWindow", @ListWindow::arg, '
230 '[<"header", [<"tag">, <"items" countWidth 16>]>, '
231 '<"data", [<"items", 1>]>]>')
232 list_window_inner = types.WindowType(
238 types.WindowType.Frame(
241 types.WindowType.Field(
"tag", 0, 0),
242 types.WindowType.Field(
"items", 0, 16),
245 types.WindowType.Frame(
247 [types.WindowType.Field(
"items", 1, 0)],
252 list_window = types.TypeAlias(
"@ListWindow",
"ListWindow", list_window_inner)
258 sw_arg_inner = types.StructType(
259 "@SmallListWindow::arg",
260 [(
"tag", _uint16), (
"items", list_type)],
262 sw_header_inner = types.StructType(
263 "@SmallListWindow::header",
264 [(
"tag", _uint16), (
"items_count", _uint2)],
266 sw_data_inner = types.StructType(
267 "@SmallListWindow::data",
268 [(
"items", types.ArrayType(
"!hw.array<1xui32>", _uint32, 1))],
270 sw_lowered = types.UnionType(
271 "@SmallListWindow::lowered",
272 [(
"header", sw_header_inner), (
"data", sw_data_inner)],
274 sw_window_id = (
'!esi.window<"SmallListWindow", @SmallListWindow::arg, '
275 '[<"header", [<"tag">, <"items" countWidth 2>]>, '
276 '<"data", [<"items", 1>]>]>')
277 small_list_window_inner = types.WindowType(
283 types.WindowType.Frame(
286 types.WindowType.Field(
"tag", 0, 0),
287 types.WindowType.Field(
"items", 0, 2),
290 types.WindowType.Frame(
292 [types.WindowType.Field(
"items", 1, 0)],
296 small_list_window = types.TypeAlias(
"@SmallListWindow",
"SmallListWindow",
297 small_list_window_inner)
299 narrow_data_list = types.ListType(
"!esi.list<ui7>", _uint7)
300 narrow_data_arg = types.StructType(
"@NarrowDataWindow::arg",
302 (
"items", narrow_data_list)])
303 narrow_data_frame = types.StructType(
304 "@NarrowDataWindow::data",
305 [(
"items", types.ArrayType(
"!hw.array<1xui7>", _uint7, 1))])
306 narrow_data_lowered = types.UnionType(
"@NarrowDataWindow::lowered",
307 [(
"header", sw_header_inner),
308 (
"data", narrow_data_frame)])
309 narrow_data_window_inner = types.WindowType(
310 '!esi.window<"NarrowDataWindow", @NarrowDataWindow::arg, '
311 '[<"header", [<"tag">, <"items" countWidth 2>]>, '
312 '<"data", [<"items", 1>]>]>',
316 small_list_window_inner.frames,
318 narrow_data_window = types.TypeAlias(
"@NarrowDataWindow",
"NarrowDataWindow",
319 narrow_data_window_inner)
327 wide_u_inner = types.StructType(
329 [(
"u96", _uint96), (
"u128", _uint128)],
331 wide_u = types.TypeAlias(
"@WideU",
"WideU", wide_u_inner)
332 wide_s_inner = types.StructType(
334 [(
"s96", _sint96), (
"s128", _sint128)],
336 wide_s = types.TypeAlias(
"@WideS",
"WideS", wide_s_inner)
340 bits_inner = types.StructType(
342 [(
"wide", _bits128)],
344 bits_field = types.TypeAlias(
"@BitsField",
"BitsField", bits_inner)
352 wide_mis_inner = types.StructType(
353 "@WideMisaligned::inner",
354 [(
"payload", _uint128), (
"tag", _uint3)],
356 wide_mis = types.TypeAlias(
"@WideMisaligned",
"WideMisaligned",
364 arr3_u128_type = types.ArrayType(
"!hw.array<3xui128>", _uint128, 3)
365 arr_views_inner = types.StructType(
367 [(
"items", arr3_u128_type)],
369 arr_views = types.TypeAlias(
"@ArrViews",
"ArrViews", arr_views_inner)
373 arr_views_mis_inner = types.StructType(
374 "@ArrViewsMis::inner",
375 [(
"items", arr3_u128_type), (
"tag", _uint3)],
377 arr_views_mis = types.TypeAlias(
"@ArrViewsMis",
"ArrViewsMis",
381 std_u, std_s, odd_u, odd_s, sub_u, sub_s, bool_field, outer, misaligned,
382 arr4, u3_arr, bits1_arr, s5_arr, u24_arr, sb_cell, sb_cell_arr, nested3,
383 nested_cell, union_two, union_subbyte, list_window, small_list_window,
384 narrow_data_window, wide_u, wide_s, bits_field, wide_mis, arr_views,
396 """Compile `codegen_harness.cpp` against a freshly-generated `types.h`
397 and run it. The harness asserts every wire-format and accessor invariant
398 end-to-end; this Python test just drives the cmake build and reports
402 esi_dll_path = get_dll_dir()
403 if sys.platform ==
"win32":
404 runtime_lib = esi_dll_path /
"ESICppRuntime.lib"
405 runtime_dll = esi_dll_path /
"ESICppRuntime.dll"
407 runtime_lib = esi_dll_path /
"libESICppRuntime.so"
413 generated_dir = tmp_path /
"generated"
414 (generated_dir /
"codegen_harness").mkdir(parents=
True)
417 emitter.write_header(generated_dir /
"codegen_harness",
"esi_system")
419 build_dir = tmp_path /
"build"
426 "-DCMAKE_BUILD_TYPE=Debug",
427 f
"-DCODEGEN_HARNESS_GENERATED_DIR={generated_dir}",
428 f
"-DESI_RUNTIME_LIB={runtime_lib}",
430 if sys.platform ==
"win32":
431 configure_cmd.append(f
"-DESI_RUNTIME_DLL={runtime_dll}")
432 configure_proc = subprocess.run(configure_cmd, capture_output=
True, text=
True)
433 if configure_proc.returncode != 0:
435 "cmake configure failed for the codegen harness "
436 f
"(rc={configure_proc.returncode}):\n"
437 f
"--- cmd ---\n{' '.join(configure_cmd)}\n"
438 f
"--- stdout ---\n{configure_proc.stdout}\n"
439 f
"--- stderr ---\n{configure_proc.stderr}",
445 str(build_dir),
"--target",
"codegen_harness",
"--config",
"Debug"
447 build_proc = subprocess.run(build_cmd, capture_output=
True, text=
True)
448 if build_proc.returncode != 0:
453 "codegen_harness.cpp failed to compile against the generated "
454 f
"types.h (rc={build_proc.returncode}):\n"
455 f
"--- cmd ---\n{' '.join(build_cmd)}\n"
456 f
"--- stdout ---\n{build_proc.stdout}\n"
457 f
"--- stderr ---\n{build_proc.stderr}\n"
458 "--- generated types.h ---\n" +
459 (generated_dir /
"codegen_harness" /
"types.h").read_text(),
466 binary_name =
"codegen_harness" + sysconfig.get_config_var(
"EXE")
467 candidates = list(build_dir.rglob(binary_name))
470 f
"codegen_harness binary not found under {build_dir}; "
471 "the cmake build reported success but produced no executable.",
474 binary = candidates[0]
476 run_proc = subprocess.run([str(binary)], capture_output=
True, text=
True)
477 if run_proc.returncode != 0
or run_proc.stdout.strip() !=
"OK":
479 f
"codegen_harness reported failure (rc={run_proc.returncode}):\n"
480 f
"--- stdout ---\n{run_proc.stdout}\n"
481 f
"--- stderr ---\n{run_proc.stderr}",