native_source_map_fixture.py (4285B)
1 #!/usr/bin/env python3 2 """Focused Haskell-only native nested-map staging/build; no compiler source build.""" 3 import argparse 4 import json 5 import os 6 from pathlib import Path 7 import re 8 from research_session import ResearchSession, ROOT 9 10 parser = argparse.ArgumentParser(description=__doc__) 11 parser.add_argument('tricu', type=Path) 12 parser.add_argument('generation', type=Path) 13 parser.add_argument('--directory', type=Path, required=True) 14 args = parser.parse_args() 15 generation = args.generation.resolve() 16 if not json.loads((generation / 'status.json').read_text())['complete']: 17 raise ValueError('incomplete generation') 18 session = ResearchSession(args.tricu, args.directory, [], generation / 'build-stable.arboricx') 19 source_cas = generation / 'cas' 20 pin = (source_cas / 'cache/source-build/source_map').read_text().split('\t')[2] 21 manifest = (source_cas / 'objects' / pin[:3] / pin).read_bytes() 22 from native_library_migration import digest 23 if digest('arboricx.module-manifest.v1', manifest) != pin: 24 raise ValueError('corrupt map manifest') 25 exports = {line.split('\t')[1]: line.split('\t')[3] for line in manifest.decode().splitlines()[1:]} 26 tree = exports['sourceMapStage'] 27 target = session.store / 'objects' / tree[:3] / tree 28 target.parent.mkdir(parents=True, exist_ok=True) 29 if not target.exists(): os.link(source_cas / 'objects' / tree[:3] / tree, target) 30 bundle = session.root / 'stage.arboricx' 31 session.run([session.tricu, 'arboricx', 'export', '--store', session.store, 32 '--target', tree, '--name', 'stage', '--output', bundle]) 33 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store, 34 '--file', bundle]) 35 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode() 36 overlay = session.root / 'overlay' 37 map_bytes = (ROOT / 'demos/source-map/map.v1').read_text() 38 # Stored IO execution expects the io envelope, not a raw native IO action. 39 io_pin = (source_cas / 'cache/source-build/io').read_text().split('\t')[2] 40 io_payload = (source_cas / 'objects' / io_pin[:3] / io_pin).read_bytes() 41 if digest('arboricx.module-manifest.v1', io_payload) != io_pin: 42 raise ValueError('corrupt io manifest') 43 for pin in {io_pin, *[line.split('\t')[3] for line in io_payload.decode().splitlines()[1:]]}: 44 target = session.store / 'objects' / pin[:3] / pin 45 target.parent.mkdir(parents=True, exist_ok=True) 46 if not target.exists(): os.link(source_cas / 'objects' / pin[:3] / pin, target) 47 driver = session.workspace / 'stage_driver.tri' 48 driver.write_text(f'!import {module} as M\n!import {io_pin} as I\n!export main\n' 49 'main source overlay cas text = I.io (M.stage source overlay cas text)\n') 50 driver_bundle = session.root / 'stage-driver.arboricx' 51 session.compile(driver, ['main'], driver_bundle) 52 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store, 53 '--file', driver_bundle, '--indexed']) 54 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode() 55 session.run([session.tricu, 'arboricx', 'run', '--store', session.store, '--module', module, 56 '--name', 'main', '--arg', str(ROOT), '--arg', str(overlay), '--arg', str(session.store), 57 '--arg', map_bytes, '--io', '--unsafe-io', '--format', 'decode']) 58 for name, path in [('base', 'demos/source-map/base.tri'), 59 ('prelude', 'demos/source-map/nested/prelude.tri'), 60 ('app', 'demos/source-map/nested/app.tri')]: 61 staged = (overlay / (name + '.tri')).read_bytes() 62 assert staged == (ROOT / path).read_bytes(), (name, 'native staging changed bytes') 63 (session.workspace / (name + '.tri')).write_bytes(staged) 64 app = session.root / 'app.arboricx' 65 session.compile(session.workspace / 'app.tri', ['main'], app) 66 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store, 67 '--file', app, '--indexed']) 68 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode() 69 output, _ = session.run([session.tricu, 'arboricx', 'run', '--store', session.store, 70 '--module', module, '--name', 'main', '--format', 'number']) 71 assert output == b'42', output 72 print('Native nested map: exact staging bytes; portable main = 42; Haskell only')