aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--misc/wasm/wasm_exec.js48
-rw-r--r--src/syscall/js/js_test.go11
2 files changed, 32 insertions, 27 deletions
diff --git a/misc/wasm/wasm_exec.js b/misc/wasm/wasm_exec.js
index a99aaeda07..8501ae7cd8 100644
--- a/misc/wasm/wasm_exec.js
+++ b/misc/wasm/wasm_exec.js
@@ -175,37 +175,19 @@
const storeValue = (addr, v) => {
const nanHead = 0x7FF80000;
- if (typeof v === "number") {
+ if (typeof v === "number" && v !== 0) {
if (isNaN(v)) {
this.mem.setUint32(addr + 4, nanHead, true);
this.mem.setUint32(addr, 0, true);
return;
}
- if (v === 0) {
- this.mem.setUint32(addr + 4, nanHead, true);
- this.mem.setUint32(addr, 1, true);
- return;
- }
this.mem.setFloat64(addr, v, true);
return;
}
- switch (v) {
- case undefined:
- this.mem.setFloat64(addr, 0, true);
- return;
- case null:
- this.mem.setUint32(addr + 4, nanHead, true);
- this.mem.setUint32(addr, 2, true);
- return;
- case true:
- this.mem.setUint32(addr + 4, nanHead, true);
- this.mem.setUint32(addr, 3, true);
- return;
- case false:
- this.mem.setUint32(addr + 4, nanHead, true);
- this.mem.setUint32(addr, 4, true);
- return;
+ if (v === undefined) {
+ this.mem.setFloat64(addr, 0, true);
+ return;
}
let id = this._ids.get(v);
@@ -219,8 +201,13 @@
this._ids.set(v, id);
}
this._goRefCounts[id]++;
- let typeFlag = 1;
+ let typeFlag = 0;
switch (typeof v) {
+ case "object":
+ if (v !== null) {
+ typeFlag = 1;
+ }
+ break;
case "string":
typeFlag = 2;
break;
@@ -493,10 +480,17 @@
global,
this,
];
- this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
- this._ids = new Map(); // mapping from JS values to reference ids
- this._idPool = []; // unused ids that have been garbage collected
- this.exited = false; // whether the Go program has exited
+ this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
+ this._ids = new Map([ // mapping from JS values to reference ids
+ [0, 1],
+ [null, 2],
+ [true, 3],
+ [false, 4],
+ [global, 5],
+ [this, 6],
+ ]);
+ this._idPool = []; // unused ids that have been garbage collected
+ this.exited = false; // whether the Go program has exited
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
let offset = 4096;
diff --git a/src/syscall/js/js_test.go b/src/syscall/js/js_test.go
index fea4c135af..5fc9107d40 100644
--- a/src/syscall/js/js_test.go
+++ b/src/syscall/js/js_test.go
@@ -591,3 +591,14 @@ func BenchmarkDOM(b *testing.B) {
document.Get("body").Call("removeChild", div)
}
}
+
+func TestGlobal(t *testing.T) {
+ ident := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ return args[0]
+ })
+ defer ident.Release()
+
+ if got := ident.Invoke(js.Global()); !got.Equal(js.Global()) {
+ t.Errorf("got %#v, want %#v", got, js.Global())
+ }
+}