Initial wasm loader

main
Ashelyn Dawn 1 year ago
commit 8a907ad6d9

@ -0,0 +1,7 @@
(module
(memory (export "memory") 10)
(func (export "run")
)
)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>Ashelyn's AOC 2022</title>
<link rel="stylesheet" href="/resources/style.css"/>
</head>
<body>
<div class="selector">
<label for="day-selector">
Select a day to run its entry:
</label>
<select value="">
<option class="loading" selected value="">Loading days...</option>
</select>
</div>
<p class="output">
</p>
<div class="ui">
<p>input:</p>
<textarea class="input"></textarea>
<p>output:</p>
<textarea disabled readonly class="output"></textarea>
<button>Run</button>
</div>
<script type="text/javascript" src="https://unpkg.com/wabt@1.0.29/index.js"></script>
<script type="text/javascript" src="/resources/loader.js"></script>
</body>
</html>

@ -0,0 +1,115 @@
let wasmInstance
const textEncoder = new TextEncoder()
const textDecoder = new TextDecoder()
const daySelector = document.querySelector('.selector select')
const output = document.querySelector('.output')
const inputTextArea = document.querySelector('.ui textarea.input')
const outputTextArea = document.querySelector('.ui textarea.output')
const runButton = document.querySelector('.ui button')
async function getDayList() {
const days = []
for (let i = 1; i <= 25; i++) {
const response = await fetch(`/days/${i}/code.wat`)
if (response.status === 200) {
days.push(i)
}
}
for (const day of days) {
const option = document.createElement('option')
option.value = day
option.innerText = day
daySelector.appendChild(option)
}
document.querySelector('.loading').innerText = "Select a day"
}
async function loadDay(dayNum) {
output.className = ''
output.innerText = `loading day ${dayNum}... `
try {
const { WabtModule } = window;
const wabt = await WabtModule()
const url = `/days/${dayNum}/code.wat`
// Download wasm code
const wasmText = await fetch(url)
.then(res => res.text())
// initialize module
const module = wabt.parseWat(url, wasmText)
const { buffer: codeBuffer } = module.toBinary({
write_debug_names: true
})
const { instance } = await WebAssembly.instantiate(codeBuffer)
wasmInstance = instance
} catch (err) {
output.className = 'error'
output.innerText = 'Error: ' + err.message
return
}
try {
const inputText = await fetch(`/days/${dayNum}/input.txt`)
.then(res => res.text())
inputTextArea.value = inputText
} catch (err) {
inputTextArea.value = ''
console.error(err)
}
output.innerText = 'Loaded day ' + dayNum
}
function runLoaded() {
const { run, memory } = wasmInstance.exports;
const wasmBuffer = memory.buffer;
const inputBuffer = textEncoder.encode(inputTextArea.value)
// Set length and file contents
const inputLength = inputBuffer.length
const inputLargeArray = new Uint32Array(wasmBuffer)
const inputSmallArray = new Uint8Array(wasmBuffer)
const fileInputNums = new Uint8Array(inputBuffer)
inputLargeArray[0] = inputLength
inputSmallArray.set(fileInputNums, 4)
// run the wasm
outputTextArea.value = ""
const outputLocation = run()
// Read the output
const outputBuffer = wasmBuffer.slice(outputLocation)
const outputLargeArray = new Uint32Array(outputBuffer)
const outputSmallArray = new Uint8Array(outputBuffer)
const outputLength = outputLargeArray[0]
const outputBytes = outputSmallArray.slice(4, 4 + outputLength)
const outputText = textDecoder.decode(outputBytes)
outputTextArea.value = outputText
}
daySelector.value = ""
inputTextArea.value = ""
outputTextArea.value = ""
getDayList().then(() => {
daySelector.addEventListener('change', ev => {
loadDay(ev.target.value)
})
})
runButton.addEventListener('click', ev => {
runLoaded()
})

@ -0,0 +1,3 @@
.error {
color: red;
}
Loading…
Cancel
Save