]> Cypherpunks repositories - gostls13.git/commitdiff
misc/wasm: use single map for string, symbol and object id mapping.
authorPaul Jolly <paul@myitcv.io>
Mon, 2 Jul 2018 07:08:14 +0000 (08:08 +0100)
committerPaul Jolly <paul@myitcv.org.uk>
Tue, 3 Jul 2018 20:45:17 +0000 (20:45 +0000)
Currently we use a globally unique symbol property on objects that get
passed from JavaScript to Go to store a unique ID that Go then uses when
referring back to the JavaScript object (via js.Value.ref). This
approach fails however when a JavaScript object cannot be modified, i.e.
cannot have new properties added or is frozen. The test that is added as
part of this commit currently fails with:

  Cannot add property Symbol(), object is not extensible

Instead we consolidate the string, symbol and object unique ID mapping
into a single map. Map key equality is determined via strict equality,
which is the semantic we want in this situation.

Change-Id: Ieb2b50fc36d3c30e148aa7a41557f3c59cd33766
Reviewed-on: https://go-review.googlesource.com/121799
Run-TryBot: Paul Jolly <paul@myitcv.org.uk>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Richard Musiol <neelance@gmail.com>
misc/wasm/wasm_exec.js
src/syscall/js/js_test.go

index 3617c498664522955f76754845e4fcc6d43e2232..7246d7bc71c7a0b05ae30c7b77c4d48f43463eb2 100644 (file)
                                                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];
-                               if (ref === undefined || this._values[ref] !== v) {
+                               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);
                                }
                                mem().setUint32(addr, ref, true);
                        }
                                        setTimeout(this._resolveCallbackPromise, 0); // make sure it is asynchronous
                                },
                        ];
-                       this._stringRefs = new Map();
-                       this._symbolRefs = new Map();
-                       this._refProp = Symbol();
+                       this._refs = new Map();
                        this.exited = false;
 
                        const mem = new DataView(this._inst.exports.mem.buffer)
index c4141c2196ede9bbe0c0e89d8b706015002da9ce..69b5209821b86d166cf8ad447f61812c112844b3 100644 (file)
@@ -116,6 +116,14 @@ func TestObject(t *testing.T) {
        }
 }
 
+func TestFrozenObject(t *testing.T) {
+       o := js.Global().Call("eval", "(function () { let o = new Object(); o.field = 5; Object.freeze(o); return o; })()")
+       want := 5
+       if got := o.Get("field").Int(); want != got {
+               t.Errorf("got %#v, want %#v", got, want)
+       }
+}
+
 func TestTypedArrayOf(t *testing.T) {
        testTypedArrayOf(t, "[]int8", []int8{0, -42, 0}, -42)
        testTypedArrayOf(t, "[]int16", []int16{0, -42, 0}, -42)