compiler-conformance.mjs (2383B)
1 import {COMPILER_BUDGET} from './budgets.mjs'; 2 // Opt-in expensive compiler execution, deliberately not a *.test.mjs/default gate. 3 import assert from 'node:assert/strict'; 4 import {readFile} from 'node:fs/promises'; 5 import {createHash} from 'node:crypto'; 6 import {contractEnvironment} from '../dist/contracts.js'; 7 import {Graph} from '../dist/graph.js'; 8 import {COMPILER_BUNDLE_LIMIT,decodeBundle,loadBundle} from '../dist/bundle.js'; 9 import {COMPILER_EXPORT,COMPILER_COLLECTION,sourceLiteral,compiledDefinitions} from '../dist/compiler.js'; 10 import {runIO} from '../dist/io.js'; 11 const vectors=JSON.parse(await readFile(new URL('./compiler-conformance.json',import.meta.url))); 12 const descriptor=JSON.parse(await readFile(new URL('../compiler.json',import.meta.url))); 13 const bytes=await readFile(new URL('../bundles/'+descriptor.hash+'.arboricx',import.meta.url)); 14 assert.equal(createHash('sha256').update(bytes).digest('hex'),vectors.compilerBundleSha256); 15 assert.equal(descriptor.hash,vectors.compilerBundleSha256); 16 const bundle=decodeBundle(bytes,COMPILER_BUNDLE_LIMIT); 17 for(const c of vectors.cases){ 18 const g=new Graph({...COMPILER_BUDGET,...(c.extended?{fuel:500_000_000}:{})},COMPILER_COLLECTION),exports=loadBundle(g,bundle),start=performance.now(); 19 const result=g.apply(exports.get(COMPILER_EXPORT),[contractEnvironment(g,exports),sourceLiteral(g,c.source)]); 20 if(c.diagnostic)assert.throws(()=>compiledDefinitions(g,result),error=>error.message===c.diagnostic); 21 else { 22 const definitions=compiledDefinitions(g,result); 23 g.collect(definitions.values()); 24 assert.deepEqual([...definitions.keys()],Object.keys(c.definitions)); 25 for(const [name,tree] of Object.entries(c.definitions))assert.equal(g.toTernary(definitions.get(name),50000),tree); 26 let applied=g.apply(definitions.get(c.export),c.arguments.map(arg=>g.fromTernary(arg))); 27 if(c.mode==='io')applied=await runIO(g,applied,{before:async()=>{},after(){},running(){},read:async()=>c.input,write(){throw Error('unexpected output');}},true); 28 assert.equal(g.toTernary(applied,50000),c.result); 29 } 30 assert.ok(g.stats.collections>0);assert.ok(g.stats.peakNodes<(c.extended?2_000_000:600_000)); 31 if(c.source.includes('other ='))assert.ok(g.stats.allocations>6_000_000); 32 console.log('PASS Haskell compiler comparison',JSON.stringify(c.source),Math.round(performance.now()-start)+'ms',g.stats); 33 }