forked from google/schism
-
Notifications
You must be signed in to change notification settings - Fork 4
/
run-utils.mjs
101 lines (88 loc) · 3.38 KB
/
run-utils.mjs
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
89
90
91
92
93
94
95
96
97
98
99
100
101
// -*- javascript -*-
//
// Copyright 2018, 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import * as Schism from './rt/rt.mjs';
import filesystem from './rt/filesystem-node.js';
import child_process from 'child_process';
import fs from 'fs';
import util from 'util';
import root from './root.cjs';
const compilerPath = root.join('schism/compiler.ss');
export const OPTIONS = {
use_snapshot: true, // load schism-stage0.wasm if true instead of
// building with host scheme
// which stages to build and run tests for
stage0: true,
stage1: true,
stage2: true,
stage3: true, // compile-only, no point running tests
}
// Returns the contents of out.wasm
export async function compileWithHostScheme(name) {
const { stdout, stderr } = await util.promisify(child_process.exec)(`./schism.ss ${name}`);
return util.promisify(fs.readFile)('out.wasm');
}
// Uses host scheme to compile schism and returns the wasm bytes
async function compileBootstrap() {
return compileWithHostScheme('./schism/compiler.ss');
}
function make_compiler(compiler_bytes) {
return async function(bytes) {
const engine = new Schism.Engine({ filesystem });
const schism = await engine.loadWasmModule(await compiler_bytes());
engine.setCurrentInputPort(bytes);
schism.exports['compile-stdin->stdout']();
return new Uint8Array(engine.output_data);
}
}
function make_cache(thunk) {
let cache = undefined;
return () => {
if (!cache) {
cache = thunk();
}
return cache;
};
}
// The stage0 bytes, either loaded from a snapshot
// (schism-stage0.wasm) or compiled by the host Scheme.
export const stage0_bytes = make_cache(() =>
OPTIONS.stage0 ? (async function() {
return OPTIONS.use_snapshot
? fs.readFileSync(root.join('schism-stage0.wasm'))
: await compileBootstrap()
})() : undefined);
// Compile bytes using the stage0 compiler.
export const stage0_compile = OPTIONS.stage0 ? make_compiler(stage0_bytes) : undefined;
export const stage1_bytes = make_cache(async () => {
if (!OPTIONS.stage1) { return undefined; }
const bytes = await stage0_compile(fs.readFileSync(compilerPath));
fs.writeFileSync(root.join('schism-stage1.wasm'), bytes);
return bytes;
});
export const stage1_compile = OPTIONS.stage1 ? make_compiler(stage1_bytes) : undefined;
export const stage2_bytes = make_cache(async () => {
if (!OPTIONS.stage2) { return undefined; }
const bytes = await stage1_compile(fs.readFileSync(compilerPath));
fs.writeFileSync(root.join('schism-stage2.wasm'), bytes);
return bytes;
});
export const stage2_compile = OPTIONS.stage2 ? make_compiler(stage2_bytes) : undefined;
export const stage3_bytes = make_cache(async () => {
if (!OPTIONS.stage3) { return undefined; }
const bytes = await stage2_compile(fs.readFileSync(compilerPath));
fs.writeFileSync(root.join('schism-stage3.wasm'), bytes);
return bytes;
});