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)
175 union_inner = types.UnionType(
"@UnionTwo::inner", [(
"small", _uint8),
177 union_two = types.TypeAlias(
"@UnionTwo",
"UnionTwo", union_inner)
180 list_id =
"!esi.list<ui32>"
181 list_type = types.ListType(list_id, _uint32)
182 win_arg_inner = types.StructType(
184 [(
"tag", _uint16), (
"items", list_type)],
186 win_header_inner = types.StructType(
187 "@ListWindow::header",
188 [(
"tag", _uint16), (
"items_count", _uint16)],
190 win_data_inner = types.StructType(
192 [(
"items", types.ArrayType(
"!hw.array<1xui32>", _uint32, 1))],
194 win_lowered = types.UnionType(
195 "@ListWindow::lowered",
196 [(
"header", win_header_inner), (
"data", win_data_inner)],
198 window_id = (
'!esi.window<"ListWindow", @ListWindow::arg, '
199 '[<"header", [<"tag">, <"items" countWidth 16>]>, '
200 '<"data", [<"items", 1>]>]>')
201 list_window_inner = types.WindowType(
207 types.WindowType.Frame(
210 types.WindowType.Field(
"tag", 0, 0),
211 types.WindowType.Field(
"items", 0, 16),
214 types.WindowType.Frame(
216 [types.WindowType.Field(
"items", 1, 0)],
221 list_window = types.TypeAlias(
"@ListWindow",
"ListWindow", list_window_inner)
229 wide_u_inner = types.StructType(
231 [(
"u96", _uint96), (
"u128", _uint128)],
233 wide_u = types.TypeAlias(
"@WideU",
"WideU", wide_u_inner)
234 wide_s_inner = types.StructType(
236 [(
"s96", _sint96), (
"s128", _sint128)],
238 wide_s = types.TypeAlias(
"@WideS",
"WideS", wide_s_inner)
242 bits_inner = types.StructType(
244 [(
"wide", _bits128)],
246 bits_field = types.TypeAlias(
"@BitsField",
"BitsField", bits_inner)
254 wide_mis_inner = types.StructType(
255 "@WideMisaligned::inner",
256 [(
"payload", _uint128), (
"tag", _uint3)],
258 wide_mis = types.TypeAlias(
"@WideMisaligned",
"WideMisaligned",
266 arr3_u128_type = types.ArrayType(
"!hw.array<3xui128>", _uint128, 3)
267 arr_views_inner = types.StructType(
269 [(
"items", arr3_u128_type)],
271 arr_views = types.TypeAlias(
"@ArrViews",
"ArrViews", arr_views_inner)
275 arr_views_mis_inner = types.StructType(
276 "@ArrViewsMis::inner",
277 [(
"items", arr3_u128_type), (
"tag", _uint3)],
279 arr_views_mis = types.TypeAlias(
"@ArrViewsMis",
"ArrViewsMis",
283 std_u, std_s, odd_u, odd_s, sub_u, sub_s, bool_field, outer, misaligned,
284 arr4, u3_arr, bits1_arr, s5_arr, u24_arr, sb_cell, sb_cell_arr, union_two,
285 list_window, wide_u, wide_s, bits_field, wide_mis, arr_views,
297 """Compile `codegen_harness.cpp` against a freshly-generated `types.h`
298 and run it. The harness asserts every wire-format and accessor invariant
299 end-to-end; this Python test just drives the cmake build and reports
303 esi_dll_path = get_dll_dir()
304 if sys.platform ==
"win32":
305 runtime_lib = esi_dll_path /
"ESICppRuntime.lib"
306 runtime_dll = esi_dll_path /
"ESICppRuntime.dll"
308 runtime_lib = esi_dll_path /
"libESICppRuntime.so"
314 generated_dir = tmp_path /
"generated"
315 (generated_dir /
"codegen_harness").mkdir(parents=
True)
318 emitter.write_header(generated_dir /
"codegen_harness",
"esi_system")
320 build_dir = tmp_path /
"build"
327 "-DCMAKE_BUILD_TYPE=Release",
328 f
"-DCODEGEN_HARNESS_GENERATED_DIR={generated_dir}",
329 f
"-DESI_RUNTIME_LIB={runtime_lib}",
331 if sys.platform ==
"win32":
332 configure_cmd.append(f
"-DESI_RUNTIME_DLL={runtime_dll}")
333 configure_proc = subprocess.run(configure_cmd, capture_output=
True, text=
True)
334 if configure_proc.returncode != 0:
336 "cmake configure failed for the codegen harness "
337 f
"(rc={configure_proc.returncode}):\n"
338 f
"--- cmd ---\n{' '.join(configure_cmd)}\n"
339 f
"--- stdout ---\n{configure_proc.stdout}\n"
340 f
"--- stderr ---\n{configure_proc.stderr}",
346 str(build_dir),
"--target",
"codegen_harness",
"--config",
"Release"
348 build_proc = subprocess.run(build_cmd, capture_output=
True, text=
True)
349 if build_proc.returncode != 0:
354 "codegen_harness.cpp failed to compile against the generated "
355 f
"types.h (rc={build_proc.returncode}):\n"
356 f
"--- cmd ---\n{' '.join(build_cmd)}\n"
357 f
"--- stdout ---\n{build_proc.stdout}\n"
358 f
"--- stderr ---\n{build_proc.stderr}\n"
359 "--- generated types.h ---\n" +
360 (generated_dir /
"codegen_harness" /
"types.h").read_text(),
367 binary_name =
"codegen_harness" + sysconfig.get_config_var(
"EXE")
368 candidates = list(build_dir.rglob(binary_name))
371 f
"codegen_harness binary not found under {build_dir}; "
372 "the cmake build reported success but produced no executable.",
375 binary = candidates[0]
377 run_proc = subprocess.run([str(binary)], capture_output=
True, text=
True)
378 if run_proc.returncode != 0
or run_proc.stdout.strip() !=
"OK":
380 f
"codegen_harness reported failure (rc={run_proc.returncode}):\n"
381 f
"--- stdout ---\n{run_proc.stdout}\n"
382 f
"--- stderr ---\n{run_proc.stderr}",