Skip to content

WASI support #64

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -ex
# curl https://lfortran.github.io/wasm_builds/data.json -o data.json
#latest_commit=`curl https://lfortran.github.io/wasm_builds/dev/latest_commit`
# Set a specific commit to use:
latest_commit="df33df422"
latest_commit="c969e0bc3"
curl "https://lfortran.github.io/wasm_builds/dev/$latest_commit/lfortran.js" -o public/lfortran.js
curl "https://lfortran.github.io/wasm_builds/dev/$latest_commit/lfortran.wasm" -o public/lfortran.wasm
curl "https://lfortran.github.io/wasm_builds/dev/$latest_commit/lfortran.data" -o public/lfortran.data
Expand Down
67 changes: 33 additions & 34 deletions components/LoadLFortran.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,21 @@ function getLfortranExportedFuncs() {
});
}

function define_imports(memory, outputBuffer, exit_code, stdout_print) {
const printNum = (num) => outputBuffer.push(num.toString());
const printStr = (startIdx, strSize) => outputBuffer.push(
new TextDecoder("utf8").decode(new Uint8Array(memory.buffer, startIdx, strSize)));
var memory;
function define_imports(outputBuffer, exit_code, stdout_print) {
const flushBuffer = () => {
stdout_print(outputBuffer.join(" ") + "\n");
stdout_print(outputBuffer.join(""));
outputBuffer.length = 0;
}
const set_exit_code = (exit_code_val) => exit_code.val = exit_code_val;
const fd_write = (file_type, iov_location, no_of_iovs, return_val_mem_loc) => {
const mem_data = new DataView(memory.buffer, iov_location, Int32Array.BYTES_PER_ELEMENT * 2);
const strLoc = mem_data.getInt32(0, true);
const strLen = mem_data.getInt32(4, true);
const s = new TextDecoder("utf8").decode(new Uint8Array(memory.buffer, strLoc, strLen));
outputBuffer.push(s);
return 0;
}
const proc_exit = (exit_code_val) => exit_code.val = exit_code_val;
const cpu_time = (time) => (Date.now() / 1000); // Date.now() returns milliseconds, so divide by 1000
const show_image = (cols, rows, arr) => {
var arr2D_data = new DataView(memory.buffer, arr, Int32Array.BYTES_PER_ELEMENT * rows * cols);
Expand All @@ -65,7 +71,7 @@ function define_imports(memory, outputBuffer, exit_code, stdout_print) {
imgData.data[i + 3] = 255; // alpha channel (from 0-255), 0 is transparent and 255 is fully visible
}
ctx.putImageData(imgData, 0, 0);
outputBuffer.push(`<img alt="constructed image" src="${canvas.toDataURL('image/jpeg')}" height="${rows}" width="${cols}" style="aspect-ratio: 1 / 1;"/>`)
outputBuffer.push(`<img alt="constructed image" src="${canvas.toDataURL('image/jpeg')}" height="${rows}" width="${cols}" style="aspect-ratio: 1 / 1;"/>\n`)
flushBuffer();
}
const show_image_color = (cols, rows, arr) => {
Expand All @@ -83,20 +89,17 @@ function define_imports(memory, outputBuffer, exit_code, stdout_print) {
imgData.data[i] = arr2D_data.getInt32(4*i, true);
}
ctx.putImageData(imgData, 0, 0);
outputBuffer.push(`<img alt="constructed image" src="${canvas.toDataURL('image/jpeg')}" height="${rows}" width="${cols}" style="aspect-ratio: 1 / 1;"/>`)
outputBuffer.push(`<img alt="constructed image" src="${canvas.toDataURL('image/jpeg')}" height="${rows}" width="${cols}" style="aspect-ratio: 1 / 1;"/>\n`)
flushBuffer();
}
var imports = {
wasi_snapshot_preview1: {
/* wasi functions */
fd_write: fd_write,
proc_exit: proc_exit,
},
js: {
memory: memory,
/* functions */
print_i32: printNum,
print_i64: printNum,
print_f32: printNum,
print_f64: printNum,
print_str: printStr,
flush_buf: flushBuffer,
set_exit_code: set_exit_code,
/* custom functions */
cpu_time: cpu_time,
show_img: show_image,
show_img_color: show_image_color
Expand All @@ -105,15 +108,6 @@ function define_imports(memory, outputBuffer, exit_code, stdout_print) {
return imports;
}

async function run_wasm(bytes, imports) {
try {
var res = await WebAssembly.instantiate(bytes, imports);
const { _lcompilers_main } = res.instance.exports;
_lcompilers_main();
} catch(e) { return e; }
return "Success"
}

async function setup_lfortran_funcs(lfortran_funcs, myPrint) {
const compiler_funcs = await getLfortranExportedFuncs();

Expand Down Expand Up @@ -157,15 +151,20 @@ async function setup_lfortran_funcs(lfortran_funcs, myPrint) {
lfortran_funcs.execute_code = async function (bytes, stdout_print) {
var exit_code = {val: 1}; /* non-zero exit code */
var outputBuffer = [];
var memory = new WebAssembly.Memory({ initial: 100, maximum: 100 }); // fixed 6.4 Mb memory currently
var imports = define_imports(memory, outputBuffer, exit_code, stdout_print);
var err_msg = await run_wasm(bytes, imports);
if (exit_code.val == 0) {
return 1;
var imports = define_imports(outputBuffer, exit_code, stdout_print);
try {
var res = await WebAssembly.instantiate(bytes, imports);
memory = res.instance.exports.memory;
res.instance.exports._start();
stdout_print(outputBuffer.join(""));
} catch(err_msg) {
stdout_print(outputBuffer.join(""));
if (exit_code.val == 0) {
return;
}
console.log(err_msg);
stdout_print(`\n${err_msg}\nERROR: The code could not be executed. Either there is a runtime error or there is an issue at our end.`);
}
console.log(err_msg);
myPrint(err_msg + "\nERROR: The code could not be executed. Either there is a runtime error or there is an issue at our end.");
return 0;
};
}

Expand Down
4 changes: 1 addition & 3 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ export default function Home() {
new Uint8Array(compile_result),
(text) => stdout.push(text)
);
if (exec_res) {
setOutput(stdout.join(""));
}
setOutput(stdout.join(""));
}
}
} else if (key == "AST") {
Expand Down