Skip to content

Commit

Permalink
update wasm_exec.js
Browse files Browse the repository at this point in the history
  • Loading branch information
bketelsen committed Oct 2, 2018
1 parent 187a41c commit 0a98481
Showing 1 changed file with 72 additions and 47 deletions.
119 changes: 72 additions & 47 deletions markdownvecty/wasm_exec.js
Expand Up @@ -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");
Expand Down Expand Up @@ -91,61 +97,56 @@
}

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;
}
mem().setFloat64(addr, v, true);
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);
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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;
});
}
})();

0 comments on commit 0a98481

Please sign in to comment.