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)
204 list_id =
"!esi.list<ui32>"
205 list_type = types.ListType(list_id, _uint32)
206 win_arg_inner = types.StructType(
208 [(
"tag", _uint16), (
"items", list_type)],
210 win_header_inner = types.StructType(
211 "@ListWindow::header",
212 [(
"tag", _uint16), (
"items_count", _uint16)],
214 win_data_inner = types.StructType(
216 [(
"items", types.ArrayType(
"!hw.array<1xui32>", _uint32, 1))],
218 win_lowered = types.UnionType(
219 "@ListWindow::lowered",
220 [(
"header", win_header_inner), (
"data", win_data_inner)],
222 window_id = (
'!esi.window<"ListWindow", @ListWindow::arg, '
223 '[<"header", [<"tag">, <"items" countWidth 16>]>, '
224 '<"data", [<"items", 1>]>]>')
225 list_window_inner = types.WindowType(
231 types.WindowType.Frame(
234 types.WindowType.Field(
"tag", 0, 0),
235 types.WindowType.Field(
"items", 0, 16),
238 types.WindowType.Frame(
240 [types.WindowType.Field(
"items", 1, 0)],
245 list_window = types.TypeAlias(
"@ListWindow",
"ListWindow", list_window_inner)
251 sw_arg_inner = types.StructType(
252 "@SmallListWindow::arg",
253 [(
"tag", _uint16), (
"items", list_type)],
255 sw_header_inner = types.StructType(
256 "@SmallListWindow::header",
257 [(
"tag", _uint16), (
"items_count", _uint2)],
259 sw_data_inner = types.StructType(
260 "@SmallListWindow::data",
261 [(
"items", types.ArrayType(
"!hw.array<1xui32>", _uint32, 1))],
263 sw_lowered = types.UnionType(
264 "@SmallListWindow::lowered",
265 [(
"header", sw_header_inner), (
"data", sw_data_inner)],
267 sw_window_id = (
'!esi.window<"SmallListWindow", @SmallListWindow::arg, '
268 '[<"header", [<"tag">, <"items" countWidth 2>]>, '
269 '<"data", [<"items", 1>]>]>')
270 small_list_window_inner = types.WindowType(
276 types.WindowType.Frame(
279 types.WindowType.Field(
"tag", 0, 0),
280 types.WindowType.Field(
"items", 0, 2),
283 types.WindowType.Frame(
285 [types.WindowType.Field(
"items", 1, 0)],
289 small_list_window = types.TypeAlias(
"@SmallListWindow",
"SmallListWindow",
290 small_list_window_inner)
298 wide_u_inner = types.StructType(
300 [(
"u96", _uint96), (
"u128", _uint128)],
302 wide_u = types.TypeAlias(
"@WideU",
"WideU", wide_u_inner)
303 wide_s_inner = types.StructType(
305 [(
"s96", _sint96), (
"s128", _sint128)],
307 wide_s = types.TypeAlias(
"@WideS",
"WideS", wide_s_inner)
311 bits_inner = types.StructType(
313 [(
"wide", _bits128)],
315 bits_field = types.TypeAlias(
"@BitsField",
"BitsField", bits_inner)
323 wide_mis_inner = types.StructType(
324 "@WideMisaligned::inner",
325 [(
"payload", _uint128), (
"tag", _uint3)],
327 wide_mis = types.TypeAlias(
"@WideMisaligned",
"WideMisaligned",
335 arr3_u128_type = types.ArrayType(
"!hw.array<3xui128>", _uint128, 3)
336 arr_views_inner = types.StructType(
338 [(
"items", arr3_u128_type)],
340 arr_views = types.TypeAlias(
"@ArrViews",
"ArrViews", arr_views_inner)
344 arr_views_mis_inner = types.StructType(
345 "@ArrViewsMis::inner",
346 [(
"items", arr3_u128_type), (
"tag", _uint3)],
348 arr_views_mis = types.TypeAlias(
"@ArrViewsMis",
"ArrViewsMis",
352 std_u, std_s, odd_u, odd_s, sub_u, sub_s, bool_field, outer, misaligned,
353 arr4, u3_arr, bits1_arr, s5_arr, u24_arr, sb_cell, sb_cell_arr, nested3,
354 nested_cell, union_two, list_window, small_list_window, wide_u, wide_s,
355 bits_field, wide_mis, arr_views, arr_views_mis
366 """Compile `codegen_harness.cpp` against a freshly-generated `types.h`
367 and run it. The harness asserts every wire-format and accessor invariant
368 end-to-end; this Python test just drives the cmake build and reports
372 esi_dll_path = get_dll_dir()
373 if sys.platform ==
"win32":
374 runtime_lib = esi_dll_path /
"ESICppRuntime.lib"
375 runtime_dll = esi_dll_path /
"ESICppRuntime.dll"
377 runtime_lib = esi_dll_path /
"libESICppRuntime.so"
383 generated_dir = tmp_path /
"generated"
384 (generated_dir /
"codegen_harness").mkdir(parents=
True)
387 emitter.write_header(generated_dir /
"codegen_harness",
"esi_system")
389 build_dir = tmp_path /
"build"
396 "-DCMAKE_BUILD_TYPE=Release",
397 f
"-DCODEGEN_HARNESS_GENERATED_DIR={generated_dir}",
398 f
"-DESI_RUNTIME_LIB={runtime_lib}",
400 if sys.platform ==
"win32":
401 configure_cmd.append(f
"-DESI_RUNTIME_DLL={runtime_dll}")
402 configure_proc = subprocess.run(configure_cmd, capture_output=
True, text=
True)
403 if configure_proc.returncode != 0:
405 "cmake configure failed for the codegen harness "
406 f
"(rc={configure_proc.returncode}):\n"
407 f
"--- cmd ---\n{' '.join(configure_cmd)}\n"
408 f
"--- stdout ---\n{configure_proc.stdout}\n"
409 f
"--- stderr ---\n{configure_proc.stderr}",
415 str(build_dir),
"--target",
"codegen_harness",
"--config",
"Release"
417 build_proc = subprocess.run(build_cmd, capture_output=
True, text=
True)
418 if build_proc.returncode != 0:
423 "codegen_harness.cpp failed to compile against the generated "
424 f
"types.h (rc={build_proc.returncode}):\n"
425 f
"--- cmd ---\n{' '.join(build_cmd)}\n"
426 f
"--- stdout ---\n{build_proc.stdout}\n"
427 f
"--- stderr ---\n{build_proc.stderr}\n"
428 "--- generated types.h ---\n" +
429 (generated_dir /
"codegen_harness" /
"types.h").read_text(),
436 binary_name =
"codegen_harness" + sysconfig.get_config_var(
"EXE")
437 candidates = list(build_dir.rglob(binary_name))
440 f
"codegen_harness binary not found under {build_dir}; "
441 "the cmake build reported success but produced no executable.",
444 binary = candidates[0]
446 run_proc = subprocess.run([str(binary)], capture_output=
True, text=
True)
447 if run_proc.returncode != 0
or run_proc.stdout.strip() !=
"OK":
449 f
"codegen_harness reported failure (rc={run_proc.returncode}):\n"
450 f
"--- stdout ---\n{run_proc.stdout}\n"
451 f
"--- stderr ---\n{run_proc.stderr}",