Fixed issue #632 async/await (#633)

Co-authored-by: Fabian <copy@copy.sh>
This commit is contained in:
Nitin Tejuja 2022-07-25 18:25:07 +05:30 committed by GitHub
parent b96665285b
commit 0615be5d60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 205 additions and 357 deletions

View file

@ -31,21 +31,15 @@ window.onload = function()
].join(" "),
});
document.getElementById("save_file").onclick = function()
document.getElementById("save_file").onclick = async function()
{
emulator.save_state(function(error, new_state)
{
if(error)
{
throw error;
}
const new_state = await emulator.save_state();
var a = document.createElement("a");
a.download = "v86state.bin";
a.href = window.URL.createObjectURL(new Blob([new_state]));
a.dataset.downloadurl = "application/octet-stream:" + a.download + ":" + a.href;
a.click();
});
var a = document.createElement("a");
a.download = "v86state.bin";
a.href = window.URL.createObjectURL(new Blob([new_state]));
a.dataset.downloadurl = "application/octet-stream:" + a.download + ":" + a.href;
a.click();
this.blur();
};
@ -57,9 +51,9 @@ window.onload = function()
var filereader = new FileReader();
emulator.stop();
filereader.onload = function(e)
filereader.onload = async function(e)
{
emulator.restore_state(e.target.result);
await emulator.restore_state(e.target.result);
emulator.run();
};

View file

@ -36,7 +36,7 @@ window.onload = function()
document.getElementById("status").textContent += ".";
emulator.add_listener("emulator-ready", function()
emulator.add_listener("emulator-ready", async function()
{
document.getElementById("status").textContent += ".";
@ -45,28 +45,20 @@ window.onload = function()
buffer.set(code.split("").map(function(chr) { return chr.charCodeAt(0); }));
emulator.create_file("/root/code.js", buffer, function(error)
{
if(error) throw error;
emulator.serial0_send("node /root/code.js > /root/out.txt 2> /root/out.txt\n");
});
await emulator.create_file("/root/code.js", buffer);
emulator.serial0_send("node /root/code.js > /root/out.txt 2> /root/out.txt\n");
});
var serial_out = "";
emulator.add_listener("serial0-output-char", function(chr)
emulator.add_listener("serial0-output-char", async function(chr)
{
serial_out += chr;
//document.getElementById("output").textContent += chr;
if(serial_out.endsWith("root@nyu"))
{
emulator.read_file("/root/out.txt", function(error, data)
{
if(error) throw error;
document.getElementById("output").textContent += String.fromCharCode.apply(this, data);
});
const data = await emulator.read_file("/root/out.txt");
document.getElementById("output").textContent += String.fromCharCode.apply(this, data);
}
});
}

View file

@ -36,7 +36,7 @@ emulator.add_listener("serial0-output-char", function(chr)
var state;
process.stdin.on("data", function(c)
process.stdin.on("data", async function(c)
{
if(c === "\u0003")
{
@ -47,16 +47,8 @@ process.stdin.on("data", function(c)
else if(c === "\x1b\x4f\x51")
{
// f2
emulator.save_state(function(err, s)
{
console.log("--- Saved ---");
if(err)
{
throw err;
}
state = s;
});
state = await emulator.save_state();
console.log("--- Saved ---");
}
else if(c === "\x1b\x4f\x52")
{
@ -64,7 +56,7 @@ process.stdin.on("data", function(c)
if(state)
{
console.log("--- Restored ---");
emulator.restore_state(state);
await emulator.restore_state(state);
}
}
else

View file

@ -26,50 +26,35 @@ window.onload = function()
var state;
document.getElementById("save_restore").onclick = function()
document.getElementById("save_restore").onclick = async function()
{
var button = this;
if(state)
{
button.value = "Save state";
emulator.restore_state(state);
await emulator.restore_state(state);
state = undefined;
}
else
{
emulator.save_state(function(error, new_state)
{
if(error)
{
throw error;
}
console.log("Saved state of " + new_state.byteLength + " bytes");
button.value = "Restore state";
state = new_state;
});
const new_state = await emulator.save_state();
console.log("Saved state of " + new_state.byteLength + " bytes");
button.value = "Restore state";
state = new_state;
}
button.blur();
};
document.getElementById("save_file").onclick = function()
document.getElementById("save_file").onclick = async function()
{
emulator.save_state(function(error, new_state)
{
if(error)
{
throw error;
}
var a = document.createElement("a");
a.download = "v86state.bin";
a.href = window.URL.createObjectURL(new Blob([new_state]));
a.dataset.downloadurl = "application/octet-stream:" + a.download + ":" + a.href;
a.click();
});
const new_state = await emulator.save_state();
var a = document.createElement("a");
a.download = "v86state.bin";
a.href = window.URL.createObjectURL(new Blob([new_state]));
a.dataset.downloadurl = "application/octet-stream:" + a.download + ":" + a.href;
a.click();
this.blur();
};
@ -81,9 +66,9 @@ window.onload = function()
var filereader = new FileReader();
emulator.stop();
filereader.onload = function(e)
filereader.onload = async function(e)
{
emulator.restore_state(e.target.result);
await emulator.restore_state(e.target.result);
emulator.run();
};

View file

@ -99,10 +99,11 @@ ServerFileStorageWrapper.prototype.load_from_server = function(sha256sum)
{
return new Promise((resolve, reject) =>
{
v86util.load_file(this.baseurl + sha256sum, { done: buffer =>
v86util.load_file(this.baseurl + sha256sum, { done: async buffer =>
{
const data = new Uint8Array(buffer);
this.cache(sha256sum, data).then(() => resolve(data));
await this.cache(sha256sum, data);
resolve(data);
}});
});
};

View file

@ -1575,20 +1575,10 @@
// $("memory_dump_dmp").blur();
//};
$("save_state").onclick = function()
$("save_state").onclick = async function()
{
emulator.save_state(function(error, result)
{
if(error)
{
console.log(error.stack);
console.log("Couldn't save state: ", error);
}
else
{
dump_file(result, "v86state.bin");
}
});
const result = await emulator.save_state();
dump_file(result, "v86state.bin");
$("save_state").blur();
};
@ -1599,7 +1589,7 @@
$("load_state").blur();
};
$("load_state_input").onchange = function()
$("load_state_input").onchange = async function()
{
var file = this.files[0];
@ -1612,15 +1602,15 @@
if(was_running)
{
emulator.stop();
await emulator.stop();
}
var filereader = new FileReader();
filereader.onload = function(e)
filereader.onload = async function(e)
{
try
{
emulator.restore_state(e.target.result);
await emulator.restore_state(e.target.result);
}
catch(err)
{
@ -1789,9 +1779,9 @@
var loader = new v86util.SyncFileBuffer(file);
loader.onload = function()
{
loader.get_buffer(function(buffer)
loader.get_buffer(async function(buffer)
{
emulator.create_file("/" + file.name, new Uint8Array(buffer));
await emulator.create_file("/" + file.name, new Uint8Array(buffer));
});
};
loader.load();
@ -1801,7 +1791,7 @@
this.blur();
};
$("filesystem_get_file").onkeypress = function(e)
$("filesystem_get_file").onkeypress = async function(e)
{
if(e.which !== 13)
{
@ -1810,23 +1800,30 @@
this.disabled = true;
emulator.read_file(this.value, function(err, uint8array)
let result;
try
{
this.disabled = false;
result = await emulator.read_file(this.value);
}
catch(err)
{
console.log(err);
}
if(uint8array)
{
var filename = this.value.replace(/\/$/, "").split("/");
filename = filename[filename.length - 1] || "root";
this.disabled = false;
dump_file(uint8array, filename);
this.value = "";
}
else
{
alert("Can't read file");
}
}.bind(this));
if(result)
{
var filename = this.value.replace(/\/$/, "").split("/");
filename = filename[filename.length - 1] || "root";
dump_file(result, filename);
this.value = "";
}
else
{
alert("Can't read file");
}
};
}

View file

@ -183,23 +183,22 @@ function V86Starter(options)
}
v86util.load_file(v86_bin, {
done: bytes =>
done: async bytes =>
{
WebAssembly
.instantiate(bytes, env)
.then(({ instance }) => {
resolve(instance.exports);
}, err => {
v86util.load_file(v86_bin_fallback, {
done: bytes => {
WebAssembly
.instantiate(bytes, env)
.then(({ instance }) => {
resolve(instance.exports);
});
try
{
const { instance } = await WebAssembly.instantiate(bytes, env);
resolve(instance.exports);
}
catch(err)
{
v86util.load_file(v86_bin_fallback, {
done: async bytes => {
const { instance } = await WebAssembly.instantiate(bytes, env);
resolve(instance.exports);
},
});
});
}
},
progress: e =>
{
@ -586,7 +585,7 @@ V86Starter.prototype.continue_init = async function(emulator, options)
}.bind(this);
cont(0);
function done()
async function done()
{
//if(settings.initial_state)
//{
@ -607,18 +606,17 @@ V86Starter.prototype.continue_init = async function(emulator, options)
if(options["bzimage_initrd_from_filesystem"])
{
const { bzimage, initrd } = this.get_bzimage_initrd_from_filesystem(settings.fs9p);
const { bzimage_path, initrd_path } = this.get_bzimage_initrd_from_filesystem(settings.fs9p);
dbg_log("Found bzimage: " + bzimage + " and initrd: " + initrd);
dbg_log("Found bzimage: " + bzimage_path + " and initrd: " + initrd_path);
Promise.all([
settings.fs9p.read_file(initrd),
settings.fs9p.read_file(bzimage),
]).then(([initrd, bzimage]) => {
put_on_settings.call(this, "initrd", new SyncBuffer(initrd.buffer));
put_on_settings.call(this, "bzimage", new SyncBuffer(bzimage.buffer));
finish.call(this);
});
const [initrd, bzimage] = await Promise.all([
settings.fs9p.read_file(initrd_path),
settings.fs9p.read_file(bzimage_path),
]);
put_on_settings.call(this, "initrd", new SyncBuffer(initrd.buffer));
put_on_settings.call(this, "bzimage", new SyncBuffer(bzimage.buffer));
finish.call(this);
}
else
{
@ -664,8 +662,8 @@ V86Starter.prototype.get_bzimage_initrd_from_filesystem = function(filesystem)
const root = (filesystem.read_dir("/") || []).map(x => "/" + x);
const boot = (filesystem.read_dir("/boot/") || []).map(x => "/boot/" + x);
let initrd;
let bzimage;
let initrd_path;
let bzimage_path;
for(let f of [].concat(root, boot))
{
@ -673,25 +671,25 @@ V86Starter.prototype.get_bzimage_initrd_from_filesystem = function(filesystem)
const is_bzimage = /vmlinuz/i.test(f) || /bzimage/i.test(f);
const is_initrd = /initrd/i.test(f) || /initramfs/i.test(f);
if(is_bzimage && (!bzimage || !old))
if(is_bzimage && (!bzimage_path || !old))
{
bzimage = f;
bzimage_path = f;
}
if(is_initrd && (!initrd || !old))
if(is_initrd && (!initrd_path || !old))
{
initrd = f;
initrd_path = f;
}
}
if(!initrd || !bzimage)
if(!initrd_path || !bzimage_path)
{
console.log("Failed to find bzimage or initrd in filesystem. Files:");
console.log(root.join(" "));
console.log(boot.join(" "));
}
return { initrd, bzimage };
return { initrd_path, bzimage_path };
};
/**
@ -699,7 +697,7 @@ V86Starter.prototype.get_bzimage_initrd_from_filesystem = function(filesystem)
* asynchronous.
* @export
*/
V86Starter.prototype.run = function()
V86Starter.prototype.run = async function()
{
this.bus.send("cpu-run");
};
@ -708,7 +706,7 @@ V86Starter.prototype.run = function()
* Stop emulation. Do nothing if emulator is not running. Can be asynchronous.
* @export
*/
V86Starter.prototype.stop = function()
V86Starter.prototype.stop = async function()
{
this.bus.send("cpu-stop");
};
@ -780,34 +778,22 @@ V86Starter.prototype.remove_listener = function(event, listener)
* @param {ArrayBuffer} state
* @export
*/
V86Starter.prototype.restore_state = function(state)
V86Starter.prototype.restore_state = async function(state)
{
console.assert(arguments.length === 1);
this.v86.restore_state(state);
};
/**
* Asynchronously save the current state of the emulator. The first argument to
* the callback is an Error object if something went wrong and is null
* otherwise.
* Asynchronously save the current state of the emulator.
*
* @param {function(Object, ArrayBuffer)} callback
* @return {Promise<ArrayBuffer>}
* @export
*/
V86Starter.prototype.save_state = function(callback)
V86Starter.prototype.save_state = async function()
{
// Might become asynchronous at some point
setTimeout(function()
{
try
{
callback(null, this.v86.save_state());
}
catch(e)
{
callback(e, null);
}
}.bind(this), 0);
console.assert(arguments.length === 0);
return this.v86.save_state();
};
/**
@ -1169,18 +1155,15 @@ V86Starter.prototype.mount_fs = async function(path, baseurl, basefs, callback)
/**
* Write to a file in the 9p filesystem. Nothing happens if no filesystem has
* been initialized. First argument to the callback is an error object if
* something went wrong and null otherwise.
* been initialized.
*
* @param {string} file
* @param {Uint8Array} data
* @param {function(Object)=} callback
* @export
*/
V86Starter.prototype.create_file = function(file, data, callback)
V86Starter.prototype.create_file = async function(file, data)
{
callback = callback || function() {};
console.assert(arguments.length === 2);
var fs = this.fs9p;
if(!fs)
@ -1197,15 +1180,11 @@ V86Starter.prototype.create_file = function(file, data, callback)
if(!not_found)
{
fs.CreateBinaryFile(filename, parent_id, data)
.then(() => callback(null));
await fs.CreateBinaryFile(filename, parent_id, data);
}
else
{
setTimeout(function()
{
callback(new FileNotFoundError());
}, 0);
return Promise.reject(new FileNotFoundError());
}
};
@ -1214,11 +1193,11 @@ V86Starter.prototype.create_file = function(file, data, callback)
* initialized.
*
* @param {string} file
* @param {function(Object, Uint8Array)} callback
* @export
*/
V86Starter.prototype.read_file = function(file, callback)
V86Starter.prototype.read_file = async function(file)
{
console.assert(arguments.length === 1);
var fs = this.fs9p;
if(!fs)
@ -1226,16 +1205,16 @@ V86Starter.prototype.read_file = function(file, callback)
return;
}
fs.read_file(file).then((result) => {
if(result)
{
callback(null, result);
}
else
{
callback(new FileNotFoundError(), null);
}
});
const result = await fs.read_file(file);
if(result)
{
return result;
}
else
{
return Promise.reject(new FileNotFoundError());
}
};
V86Starter.prototype.automatically = function(steps)

View file

@ -45,30 +45,23 @@ function run_test(name, config, done)
{
const emulator = new V86(config);
setTimeout(function()
setTimeout(async function()
{
console.log("Saving: %s", name);
emulator.save_state(function(error, state)
const state = await emulator.save_state();
setTimeout(async function()
{
if(error)
{
console.error(error);
assert(false);
}
console.log("Restoring: %s", name);
await emulator.restore_state(state);
setTimeout(function()
{
console.log("Restoring: %s", name);
emulator.restore_state(state);
setTimeout(function()
{
console.log("Done: %s", name);
emulator.stop();
done && done();
}, 1000);
console.log("Done: %s", name);
emulator.stop();
done && done();
}, 1000);
});
}, 1000);
}, 5000);
}

View file

@ -142,20 +142,11 @@ const tests =
},
capture_trigger: "start-capture",
end_trigger: "done-read-existing",
end: (capture, done) =>
end: async (capture, done) =>
{
emulator.read_file("read-existing", function(err, data)
{
if(err)
{
log_warn("Reading read-existing failed: %s", err);
test_fail();
done();
return;
}
assert_equal(capture, Buffer.from(data).toString());
done();
});
const data = await emulator.read_file("read-existing");
assert_equal(capture, Buffer.from(data).toString());
done();
},
},
{
@ -167,25 +158,16 @@ const tests =
emulator.serial0_send("echo done-read-new\n");
},
end_trigger: "done-read-new",
end: (capture, done) =>
end: async (capture, done) =>
{
emulator.read_file("read-new", function(err, data)
const data = await emulator.read_file("read-new");
assert_equal(data.length, 512 * 1024);
if(data.find(v => v !== 0))
{
if(err)
{
log_warn("Reading read-new failed: %s", err);
test_fail();
done();
return;
}
assert_equal(data.length, 512 * 1024);
if(data.find(v => v !== 0))
{
log_warn("Fail: Incorrect data. Expected all zeros.");
test_fail();
}
done();
});
log_warn("Fail: Incorrect data. Expected all zeros.");
test_fail();
}
done();
},
},
{
@ -203,21 +185,12 @@ const tests =
},
capture_trigger: "start-capture",
end_trigger: "done-read-async",
end: (capture, done) =>
end: async (capture, done) =>
{
assert_equal(capture, "bar\n");
emulator.read_file("foo", function(err, data)
{
if(err)
{
log_warn("Reading foo failed: %s", err);
test_fail();
done();
return;
}
assert_equal(Buffer.from(data).toString(), "bar\n");
done();
});
const data = await emulator.read_file("foo");
assert_equal(Buffer.from(data).toString(), "bar\n");
done();
},
},
{
@ -579,20 +552,11 @@ const tests =
emulator.serial0_send("echo fifomessage > /mnt/testfifo\n");
},
end_trigger: "done-fifo",
end: (capture, done) =>
end: async (capture, done) =>
{
emulator.read_file("testfifo-output", function(err, data)
{
if(err)
{
log_warn("Reading testfifo-output failed: %s", err);
test_fail();
done();
return;
}
assert_equal(Buffer.from(data).toString(), "fifomessage\n");
done();
});
const data = await emulator.read_file("testfifo-output");
assert_equal(Buffer.from(data).toString(), "fifomessage\n");
done();
},
},
{
@ -628,20 +592,11 @@ const tests =
emulator.serial0_send("echo done-mkdir\n");
},
end_trigger: "done-mkdir",
end: (capture, done) =>
end: async (capture, done) =>
{
emulator.read_file("a-dir/e-file", function(err, data)
{
if(err)
{
log_warn("Reading a-dir/e-file failed: %s", err);
test_fail();
done();
return;
}
assert_equal(Buffer.from(data).toString(), "mkdirfoobar\n");
done();
});
const data = await emulator.read_file("a-dir/e-file");
assert_equal(Buffer.from(data).toString(), "mkdirfoobar\n");
done();
},
},
{
@ -1251,21 +1206,12 @@ const tests =
},
capture_trigger: "start-capture",
end_trigger: "done-read-mounted",
end: (capture, done) =>
end: async (capture, done) =>
{
assert_equal(capture, "bar\nfoobaz\n");
emulator.read_file("/a/b/fs2/dir/bar", function(err, data)
{
if(err)
{
log_warn("Reading /a/b/fs2/dir/bar failed: %s", err);
test_fail();
done();
return;
}
assert_equal(Buffer.from(data).toString(), "foobaz\n");
done();
});
const data = await emulator.read_file("/a/b/fs2/dir/bar");
assert_equal(Buffer.from(data).toString(), "foobaz\n");
done();
},
},
{
@ -1294,7 +1240,7 @@ const tests =
},
capture_trigger: "start-capture",
end_trigger: "done-write-mounted",
end: (capture, done) =>
end: async (capture, done) =>
{
const lines = capture.split("\n");
assert_equal(lines.shift(), "foobar");
@ -1304,18 +1250,9 @@ const tests =
assert_equal(line, test_file_string.slice(pos, line.length));
pos += line.length;
}
emulator.read_file("a/b/fs2/c/write-new-guest", function(err, data)
{
if(err)
{
log_warn("Reading a/b/fs2/c/write-new-guest failed: %s", err);
test_fail();
done();
return;
}
assert_equal(Buffer.from(data).toString(), "foobar\n");
done();
});
const data = await emulator.read_file("a/b/fs2/c/write-new-guest");
assert_equal(Buffer.from(data).toString(), "foobar\n");
done();
},
},
{
@ -1717,7 +1654,7 @@ function do_mounts()
}
}
function load_files()
async function load_files()
{
console.log(" Loading additional files");
if(tests[test_num].files)
@ -1725,27 +1662,20 @@ function load_files()
let remaining = tests[test_num].files.length;
for(const f of tests[test_num].files)
{
emulator.create_file(f.file, f.data, function(err)
await emulator.create_file(f.file, f.data);
remaining--;
if(!remaining)
{
if(err)
if(test_has_failed)
{
log_warn("Failed to add file required for test %s: %s",
tests[test_num].name, err);
test_fail();
report_test();
}
remaining--;
if(!remaining)
else
{
if(test_has_failed)
{
report_test();
}
else
{
start_test();
}
start_test();
}
});
}
}
}
else

View file

@ -29,7 +29,7 @@ emulator.bus.register("emulator-started", function()
var ran_command = false;
var line = "";
emulator.add_listener("serial0-output-char", function(chr)
emulator.add_listener("serial0-output-char", async function(chr)
{
if(chr < " " && chr !== "\n" && chr !== "\t" || chr > "~")
{
@ -59,21 +59,19 @@ emulator.add_listener("serial0-output-char", function(chr)
{
console.error("Done. Reading result ...");
emulator.read_file("/result", function(err, data)
{
emulator.stop();
if(err) throw err;
let result = Buffer.from(data).toString();
if(result !== "test_shared passed\ntest_consecutive_written passed\n")
{
console.error("[!] Error. Result was:\n" + result);
process.exit(1);
}
else
{
console.log("[+] Test passed");
}
});
}
const data = await emulator.read_file("/result");
emulator.stop();
let result = Buffer.from(data).toString();
if(result !== "test_shared passed\ntest_consecutive_written passed\n")
{
console.error("[!] Error. Result was:\n" + result);
process.exit(1);
}
else
{
console.log("[+] Test passed");
}
}
});

View file

@ -29,7 +29,7 @@ emulator.bus.register("emulator-started", function()
var ran_command = false;
var line = "";
emulator.add_listener("serial0-output-char", function(chr)
emulator.add_listener("serial0-output-char", async function(chr)
{
if(chr < " " && chr !== "\n" && chr !== "\t" || chr > "~")
{
@ -59,17 +59,10 @@ emulator.add_listener("serial0-output-char", function(chr)
{
console.error("Done. Reading result ...");
emulator.read_file("/result", function(err, data)
{
if(err)
{
console.error("Reading test result failed: " + err);
process.exit(1);
}
console.error("Got result, writing to stdout");
process.stdout.write(Buffer.from(data));
emulator.stop();
});
}
const data = await emulator.read_file("/result");
console.error("Got result, writing to stdout");
process.stdout.write(Buffer.from(data));
emulator.stop();
}
});

View file

@ -58,21 +58,15 @@ emulator.add_listener("serial0-output-char", function(c)
// sync and drop caches: Makes it safer to change the filesystem as fewer files are rendered
emulator.serial0_send("sync;echo 3 >/proc/sys/vm/drop_caches\n");
setTimeout(function ()
setTimeout(async function ()
{
emulator.save_state(function(err, s)
{
if(err)
{
throw err;
}
const s = await emulator.save_state();
fs.writeFile(OUTPUT_FILE, new Uint8Array(s), function(e)
{
if(e) throw e;
console.error("Saved as " + OUTPUT_FILE);
stop();
});
fs.writeFile(OUTPUT_FILE, new Uint8Array(s), function(e)
{
if(e) throw e;
console.error("Saved as " + OUTPUT_FILE);
stop();
});
}, 10 * 1000);
}