-
Notifications
You must be signed in to change notification settings - Fork 245
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Inflate as helper in noir wasm and fix browser test
- Loading branch information
1 parent
9e5e880
commit 08c9b74
Showing
7 changed files
with
117 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { inflate } from 'pako'; | ||
|
||
/** Decompresses and decodes the debug symbols */ | ||
export function inflateDebugSymbols(debugSymbols: string) { | ||
return JSON.parse(inflate(Buffer.from(debugSymbols, 'base64'), { to: 'string', raw: true })); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 7 additions & 69 deletions
76
compiler/wasm/test/compiler/node/compile_with_deps.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,20 @@ | ||
import { join, resolve } from 'path'; | ||
import { getPaths } from '../../shared'; | ||
|
||
import { inflate } from 'pako'; | ||
import { expect } from 'chai'; | ||
import { readFile } from 'fs/promises'; | ||
import { compile, createFileManager } from '@noir-lang/noir_wasm'; | ||
import { CompiledContract, DebugFileMap, DebugInfo } from '../../../src/types/noir_artifact'; | ||
import { ContractCompilationArtifacts, NoirFunctionEntry } from 'dist/types/src/types/noir_artifact'; | ||
import { readFile } from 'fs/promises'; | ||
import { CompiledContract } from '../../../src/types/noir_artifact'; | ||
import { shouldCompileIdentically } from '../shared/compile_with_deps.test'; | ||
|
||
const basePath = resolve(join(__dirname, '../../')); | ||
const { contractProjectPath, contractExpectedArtifact } = getPaths(basePath); | ||
|
||
describe('noir-compiler', () => { | ||
it('both nargo and noir_wasm should compile identically', async () => { | ||
describe('noir-compiler/node', () => { | ||
shouldCompileIdentically(async () => { | ||
const fm = createFileManager(contractProjectPath); | ||
const nargoArtifact = JSON.parse((await readFile(contractExpectedArtifact)).toString()) as CompiledContract; | ||
const [nargoDebugInfos, nargoFileMap] = deleteDebugMetadata(nargoArtifact); | ||
normalizeVersion(nargoArtifact); | ||
|
||
const noirWasmArtifact = await compile(fm); | ||
const noirWasmContract = (noirWasmArtifact as ContractCompilationArtifacts).contract; | ||
expect(noirWasmContract).not.to.be.undefined; | ||
const [noirWasmDebugInfos, norWasmFileMap] = deleteDebugMetadata(noirWasmContract); | ||
normalizeVersion(noirWasmContract); | ||
|
||
// We first compare both contracts without considering debug info | ||
expect(nargoArtifact).to.deep.eq(noirWasmContract); | ||
|
||
// Compare the file maps, ignoring keys, since those depend in the order in which files are visited, | ||
// which may change depending on the file manager implementation. Also ignores paths, since the base | ||
// path is reported differently between nargo and noir-wasm. | ||
expect(getSources(nargoFileMap)).to.have.members(getSources(norWasmFileMap)); | ||
|
||
// Compare the debug symbol information, ignoring the actual ids used for file identifiers. | ||
// Debug symbol info looks like the following, what we need is to ignore the 'file' identifiers | ||
// {"locations":{"0":[{"span":{"start":141,"end":156},"file":39},{"span":{"start":38,"end":76},"file":38},{"span":{"start":824,"end":862},"file":23}]}} | ||
expect(nargoDebugInfos).to.deep.eq(noirWasmDebugInfos); | ||
}).timeout(5000); | ||
return { nargoArtifact, noirWasmArtifact }; | ||
}, expect); | ||
}); | ||
|
||
/** Remove commit identifier from version, which may not match depending on cached nargo and noir-wasm */ | ||
function normalizeVersion(contract: CompiledContract) { | ||
contract.noir_version = contract.noir_version.replace(/\+.+$/, ''); | ||
} | ||
|
||
/** Decompresses and decodes the debug symbols */ | ||
function inflateDebugSymbols(debugSymbols: string) { | ||
return JSON.parse(inflate(Buffer.from(debugSymbols, 'base64'), { to: 'string', raw: true })); | ||
} | ||
|
||
/** Extracts the debug symbols from all functions, decodes them, removes their file identifiers, and deletes them from the artifact. */ | ||
function extractDebugInfos(fns: NoirFunctionEntry[]) { | ||
return fns.map((fn) => { | ||
const debugSymbols = inflateDebugSymbols(fn.debug_symbols); | ||
delete (fn as Partial<NoirFunctionEntry>).debug_symbols; | ||
clearFileIdentifiers(debugSymbols); | ||
return debugSymbols; | ||
}); | ||
} | ||
|
||
/** Deletes all debug info from a contract and returns it. */ | ||
function deleteDebugMetadata(contract: CompiledContract) { | ||
contract.functions.sort((a, b) => a.name.localeCompare(b.name)); | ||
const fileMap = contract.file_map; | ||
delete (contract as Partial<CompiledContract>).file_map; | ||
return [extractDebugInfos(contract.functions), fileMap]; | ||
} | ||
|
||
/** Clears file identifiers from a set of debug symbols. */ | ||
function clearFileIdentifiers(debugSymbols: DebugInfo) { | ||
for (const loc of Object.values(debugSymbols.locations)) { | ||
for (const span of loc) { | ||
span.file = 0; | ||
} | ||
} | ||
} | ||
|
||
/** Returns list of sources from file map, dropping paths along the way, since they don't match depending on the file manager. */ | ||
function getSources(fileMap: DebugFileMap) { | ||
return Object.values(fileMap).map((file) => file.source); | ||
} |
80 changes: 80 additions & 0 deletions
80
compiler/wasm/test/compiler/shared/compile_with_deps.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { CompilationResult, inflateDebugSymbols } from '@noir-lang/noir_wasm'; | ||
import { type expect as Expect } from 'chai'; | ||
import { | ||
CompiledContract, | ||
ContractCompilationArtifacts, | ||
DebugFileMap, | ||
DebugInfo, | ||
NoirFunctionEntry, | ||
} from '../../../src/types/noir_artifact'; | ||
|
||
export function shouldCompileIdentically( | ||
compileFn: () => Promise<{ nargoArtifact: CompiledContract; noirWasmArtifact: CompilationResult }>, | ||
expect: typeof Expect, | ||
timeout = 5000, | ||
) { | ||
it('both nargo and noir_wasm should compile identically', async () => { | ||
// Compile! | ||
const { nargoArtifact, noirWasmArtifact } = await compileFn(); | ||
|
||
// Prepare nargo artifact | ||
const [nargoDebugInfos, nargoFileMap] = deleteDebugMetadata(nargoArtifact); | ||
normalizeVersion(nargoArtifact); | ||
|
||
// Prepare noir-wasm artifact | ||
const noirWasmContract = (noirWasmArtifact as ContractCompilationArtifacts).contract; | ||
expect(noirWasmContract).not.to.be.undefined; | ||
const [noirWasmDebugInfos, norWasmFileMap] = deleteDebugMetadata(noirWasmContract); | ||
normalizeVersion(noirWasmContract); | ||
|
||
// We first compare both contracts without considering debug info | ||
expect(nargoArtifact).to.deep.eq(noirWasmContract); | ||
|
||
// Compare the file maps, ignoring keys, since those depend in the order in which files are visited, | ||
// which may change depending on the file manager implementation. Also ignores paths, since the base | ||
// path is reported differently between nargo and noir-wasm. | ||
expect(getSources(nargoFileMap)).to.have.members(getSources(norWasmFileMap)); | ||
|
||
// Compare the debug symbol information, ignoring the actual ids used for file identifiers. | ||
// Debug symbol info looks like the following, what we need is to ignore the 'file' identifiers | ||
// {"locations":{"0":[{"span":{"start":141,"end":156},"file":39},{"span":{"start":38,"end":76},"file":38},{"span":{"start":824,"end":862},"file":23}]}} | ||
expect(nargoDebugInfos).to.deep.eq(noirWasmDebugInfos); | ||
}).timeout(timeout); | ||
} | ||
|
||
/** Remove commit identifier from version, which may not match depending on cached nargo and noir-wasm */ | ||
function normalizeVersion(contract: CompiledContract) { | ||
contract.noir_version = contract.noir_version.replace(/\+.+$/, ''); | ||
} | ||
|
||
/** Extracts the debug symbols from all functions, decodes them, removes their file identifiers, and deletes them from the artifact. */ | ||
function extractDebugInfos(fns: NoirFunctionEntry[]) { | ||
return fns.map((fn) => { | ||
const debugSymbols = inflateDebugSymbols(fn.debug_symbols); | ||
delete (fn as Partial<NoirFunctionEntry>).debug_symbols; | ||
clearFileIdentifiers(debugSymbols); | ||
return debugSymbols; | ||
}); | ||
} | ||
|
||
/** Deletes all debug info from a contract and returns it. */ | ||
function deleteDebugMetadata(contract: CompiledContract) { | ||
contract.functions.sort((a, b) => a.name.localeCompare(b.name)); | ||
const fileMap = contract.file_map; | ||
delete (contract as Partial<CompiledContract>).file_map; | ||
return [extractDebugInfos(contract.functions), fileMap]; | ||
} | ||
|
||
/** Clears file identifiers from a set of debug symbols. */ | ||
function clearFileIdentifiers(debugSymbols: DebugInfo) { | ||
for (const loc of Object.values(debugSymbols.locations)) { | ||
for (const span of loc) { | ||
span.file = 0; | ||
} | ||
} | ||
} | ||
|
||
/** Returns list of sources from file map, dropping paths along the way, since they don't match depending on the file manager. */ | ||
function getSources(fileMap: DebugFileMap) { | ||
return Object.values(fileMap).map((file) => file.source); | ||
} |