@@ -27,6 +27,7 @@ montgomery_factor = pow(2, 32, modulus)
2727_RE_DEFINED = re .compile (r"defined\(([^)]+)\)" )
2828_RE_MARKDOWN_CITE = re .compile (r"\[\^(?P<id>\w+)\]" )
2929_RE_C_CITE = re .compile (r"@\[(?P<id>\w+)" )
30+ _RE_BYTECODE_START = re .compile (r"=== bytecode start: mldsa/([^/\s]+?)\.o" )
3031_RE_DEFINE = re .compile (r"^\s*#define\s+(\w+)" )
3132
3233
@@ -2363,11 +2364,86 @@ def gen_test_configs():
23632364 gen_test_config (config_spec ["path" ], config_spec , default_config )
23642365
23652366
2367+ def extract_bytecode_from_output (output_text ):
2368+ """Convert output of proofs/hol_light/x86_64/proofs/dump_bytecode.native
2369+ into a dictionary mapping function names to byte code strings."""
2370+ bytecode_dict = {}
2371+
2372+ lines = output_text .split ("\n " )
2373+ i = 0
2374+
2375+ while i < len (lines ):
2376+ line = lines [i ]
2377+ match = _RE_BYTECODE_START .search (line )
2378+ if match :
2379+ filename = match .group (1 )
2380+
2381+ # Collect bytecode until end marker
2382+ bytecode_lines = []
2383+ i += 1
2384+ while i < len (lines ) and "==== bytecode end" not in lines [i ]:
2385+ bytecode_lines .append (lines [i ])
2386+ i += 1
2387+
2388+ bytecode = "\n " .join (bytecode_lines ).strip ()
2389+ bytecode_dict [filename ] = bytecode
2390+ i += 1
2391+
2392+ return bytecode_dict
2393+
2394+
2395+ def update_bytecode_in_proof_script (filepath , bytecode ):
2396+ content = read_file (filepath )
2397+
2398+ # Check if markers exist
2399+ start_marker = "(*** BYTECODE START ***)"
2400+ end_marker = "(*** BYTECODE END ***)"
2401+
2402+ if start_marker not in content or end_marker not in content :
2403+ raise Exception (f"Could not find BYTECODE START/END markers in { filepath } " )
2404+
2405+ # Replace content between markers
2406+ pattern = rf"{ re .escape (start_marker )} .*?{ re .escape (end_marker )} "
2407+ replacement = f"{ start_marker } \n { bytecode } \n { end_marker } "
2408+
2409+ updated_content = re .sub (pattern , replacement , content , flags = re .DOTALL )
2410+
2411+ update_file (filepath , updated_content )
2412+
2413+
2414+ def update_hol_light_bytecode (dry_run ):
2415+ """Update HOL Light proof files with bytecode from make dump_bytecode."""
2416+ status_update (
2417+ "HOL Light bytecode" ,
2418+ "Running make dump_bytecode ... (this may take a few minutes)" ,
2419+ )
2420+
2421+ # Run make to get bytecode output
2422+ result = subprocess .run (
2423+ ["make" , "-C" , "proofs/hol_light/x86_64" , "dump_bytecode" ],
2424+ capture_output = True ,
2425+ text = True ,
2426+ check = True ,
2427+ )
2428+ output_text = result .stdout
2429+
2430+ # Extract bytecode
2431+ bytecode_dict = extract_bytecode_from_output (output_text )
2432+
2433+ # Update each .ml file
2434+ for obj_name , bytecode in bytecode_dict .items ():
2435+ ml_file = "proofs/hol_light/x86_64/proofs/" + obj_name + ".ml"
2436+ update_bytecode_in_proof_script (ml_file , bytecode )
2437+
2438+
23662439def _main ():
23672440 parser = argparse .ArgumentParser (
23682441 formatter_class = argparse .ArgumentDefaultsHelpFormatter
23692442 )
23702443 parser .add_argument ("--dry-run" , default = False , action = "store_true" )
2444+ parser .add_argument (
2445+ "--update-hol-light-bytecode" , default = False , action = "store_true"
2446+ )
23712447 parser .add_argument ("--aarch64-clean" , default = True , action = "store_true" )
23722448 parser .add_argument ("--no-simplify" , default = False , action = "store_true" )
23732449 parser .add_argument ("--force-cross" , default = False , action = "store_true" )
@@ -2423,6 +2499,10 @@ def _main():
24232499 gen_test_configs ()
24242500 high_level_status ("Generated test configs" )
24252501
2502+ if args .update_hol_light_bytecode :
2503+ update_hol_light_bytecode (args .dry_run )
2504+ high_level_status ("Updated HOL Light bytecode" )
2505+
24262506 gen_preprocessor_comments ()
24272507 high_level_status ("Generated preprocessor comments" )
24282508
0 commit comments