-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.ts
executable file
·88 lines (70 loc) · 2.47 KB
/
test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env bun
// Meant to be read top-to-bottom, but testListing is in a funky spot in order
// to handle errors nicely.
import { $ } from "bun";
import fs from "fs/promises";
import path from "path";
$.cwd("listings");
// kick off the build
const promiseBuild = $`cargo build --bin decode`;
// take in the filename of one of the hosted asm files
const listingPrefixes = [
"listing_0037_single_register_mov",
"listing_0038_many_register_mov",
"listing_0039_more_movs",
"listing_0040_challenge_movs",
"listing_0041_add_sub_cmp_jnz",
];
// Define a function to test each prefix
/**
* let `sourceBin = assemble(sourceASM)`
* Result resolves if `sourceBin == assemble(decode(sourceBin))`
*/
const testListing = async (listingPrefix: string): Promise<void> => {
if (!listingPrefix.startsWith("listing") || listingPrefix.includes(".")) {
throw "Bad listing prefix";
}
// Enumerate different artifacts for the given listing
const pathSourceBin = `${listingPrefix}`;
const pathSourceASM = `${listingPrefix}.asm`;
const pathOutputBin = `${listingPrefix}.out`;
const pathOutputASM = `${listingPrefix}.out.asm`;
// Delete artifacts that could invalidate the results
const rmArtifact = (nameArtifact: string) =>
fs.rm(path.join("listings", nameArtifact), { force: true });
await Promise.all([
rmArtifact(pathSourceBin),
rmArtifact(pathOutputBin),
rmArtifact(pathOutputASM),
]);
// source ASM -> source Binary
const promiseAssembleSource = $`nasm ${pathSourceASM}`;
// we need the decoder, so wait for the build to finish
await Promise.all([promiseAssembleSource, promiseBuild]);
// source Binary -> output ASM
await $`../target/debug/decode ${pathSourceBin} > ${pathOutputASM}`;
// output ASM -> output Binary
const { exitCode: reassemblyExitCode } = await $`nasm ${pathOutputASM}`;
if (Boolean(reassemblyExitCode)) {
throw "Failed to reassemble";
}
// diff(source Binary, output Binary) should be nada
// TODO: better diff with diff <(xxd foo) <(xxd bar)
const { exitCode } = await $`diff ${pathSourceBin} ${pathOutputBin}`;
if (exitCode === 0) {
return;
}
throw { exitCode };
};
/** Process each prefix in parallel and group the results/errors */
const resultsByListing = Object.fromEntries(
await Promise.all(
listingPrefixes.map(async (prefix) => [
prefix,
await testListing(prefix)
.then((x) => "Success!")
.catch((e) => ({ error: e })),
]),
),
);
console.log(resultsByListing);