1
0
mirror of https://github.com/taigrr/wasm-experiments synced 2025-01-18 04:03:21 -08:00

Remove gRPC example, add some simpler examples

This commit is contained in:
Johan Brandhorst
2018-08-11 20:55:13 +01:00
parent 1bb4e7fb1e
commit 0d5389317f
662 changed files with 942 additions and 368637 deletions

1
html/.gitignore vendored
View File

@@ -1 +0,0 @@
test.wasm

View File

@@ -1,14 +0,0 @@
#!/bin/bash
# Copyright 2018 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
exec node "$DIR/wasm_exec.js" "$@"

View File

@@ -37,6 +37,7 @@ license that can be found in the LICENSE file.
</script>
<button onClick="run();" id="runButton" disabled>Run</button>
<div id="target"></div>
</body>
</html>

BIN
html/test.wasm Executable file

Binary file not shown.

119
html/wasm_exec.js Executable file → Normal file
View File

@@ -27,11 +27,17 @@
global.TextEncoder = util.TextEncoder;
global.TextDecoder = util.TextDecoder;
} else {
window.global = window;
if (typeof window !== "undefined") {
window.global = window;
} else if (typeof self !== "undefined") {
self.global = self;
} else {
throw new Error("cannot export Go (neither window nor self is defined)");
}
let outputBuf = "";
global.fs = {
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_NONBLOCK: -1, O_SYNC: -1 }, // unused
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused
writeSync(fd, buf) {
outputBuf += decoder.decode(buf);
const nl = outputBuf.lastIndexOf("\n");
@@ -91,9 +97,11 @@
}
const storeValue = (addr, v) => {
const nanHead = 0x7FF80000;
if (typeof v === "number") {
if (isNaN(v)) {
mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 0, true);
return;
}
@@ -101,51 +109,44 @@
return;
}
mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
switch (v) {
case undefined:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 1, true);
return;
case null:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 2, true);
return;
case true:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 3, true);
return;
case false:
mem().setUint32(addr + 4, nanHead, true);
mem().setUint32(addr, 4, true);
return;
}
if (typeof v === "string") {
let ref = this._stringRefs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
this._stringRefs.set(v, ref);
}
mem().setUint32(addr, ref, true);
return;
}
if (typeof v === "symbol") {
let ref = this._symbolRefs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
this._symbolRefs.set(v, ref);
}
mem().setUint32(addr, ref, true);
return;
}
let ref = v[this._refProp];
let ref = this._refs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
v[this._refProp] = ref;
this._refs.set(v, ref);
}
let typeFlag = 0;
switch (typeof v) {
case "string":
typeFlag = 1;
break;
case "symbol":
typeFlag = 2;
break;
case "function":
typeFlag = 3;
break;
}
mem().setUint32(addr + 4, nanHead | typeFlag, true);
mem().setUint32(addr, ref, true);
}
@@ -176,8 +177,12 @@
go: {
// func wasmExit(code int32)
"runtime.wasmExit": (sp) => {
const code = mem().getInt32(sp + 8, true);
this.exited = true;
this.exit(mem().getInt32(sp + 8, true));
delete this._inst;
delete this._values;
delete this._refs;
this.exit(code);
},
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
@@ -328,16 +333,10 @@
false,
global,
this._inst.exports.mem,
() => { // resolveCallbackPromise
if (this.exited) {
throw new Error("bad callback: Go program has already exited");
}
setTimeout(this._resolveCallbackPromise, 0); // make sure it is asynchronous
},
this,
];
this._stringRefs = new Map();
this._symbolRefs = new Map();
this._refProp = Symbol();
this._refs = new Map();
this._callbackShutdown = false;
this.exited = false;
const mem = new DataView(this._inst.exports.mem.buffer)
@@ -374,7 +373,12 @@
while (true) {
const callbackPromise = new Promise((resolve) => {
this._resolveCallbackPromise = resolve;
this._resolveCallbackPromise = () => {
if (this.exited) {
throw new Error("bad callback: Go program has already exited");
}
setTimeout(resolve, 0); // make sure it is asynchronous
};
});
this._inst.exports.run(argc, argv);
if (this.exited) {
@@ -383,6 +387,28 @@
await callbackPromise;
}
}
static _makeCallbackHelper(id, pendingCallbacks, go) {
return function() {
pendingCallbacks.push({ id: id, args: arguments });
go._resolveCallbackPromise();
};
}
static _makeEventCallbackHelper(preventDefault, stopPropagation, stopImmediatePropagation, fn) {
return function(event) {
if (preventDefault) {
event.preventDefault();
}
if (stopPropagation) {
event.stopPropagation();
}
if (stopImmediatePropagation) {
event.stopImmediatePropagation();
}
fn(event);
};
}
}
if (isNodeJS) {
@@ -396,17 +422,16 @@
go.env = process.env;
go.exit = process.exit;
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
process.on("exit", () => { // Node.js exits if no callback is pending
if (!go.exited) {
console.error("error: all goroutines asleep and no JavaScript callback pending - deadlock!");
process.exit(1);
process.on("exit", (code) => { // Node.js exits if no callback is pending
if (code === 0 && !go.exited) {
// deadlock, make Go print error and stack traces
go._callbackShutdown = true;
go._inst.exports.run();
}
});
return go.run(result.instance);
}).catch((err) => {
console.error(err);
go.exited = true;
process.exit(1);
throw err;
});
}
})();