Skip to content

Commit

Permalink
syscall/js: add Scope function
Browse files Browse the repository at this point in the history
Fixes golang#56084

This changes allow to pass an arbitrary object from the JS world to the WASM program.

 - if no object is provided, globalThis is returned instead.
 - the scope object is derive from internal jsGo object, avoiding a possible ID clash when the scope is unset (so left as globalThis)
 - test uses a dummy object to perform a simple get/set action.

Change-Id: I71afd43f6b32d04b76c3760ac5b2cb6c0c9dbd73
GitHub-Last-Rev: 44a0f15
GitHub-Pull-Request: golang#56867
  • Loading branch information
romaindoumenc committed Jun 10, 2024
1 parent c83b1a7 commit 0e5cc46
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions misc/wasm/wasm_exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
constructor() {
this.argv = ["js"];
this.env = {};
this.scope = globalThis;
this.exit = (code) => {
if (code !== 0) {
console.warn("exit code:", code);
Expand Down
1 change: 1 addition & 0 deletions misc/wasm/wasm_exec_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require("./wasm_exec");
const go = new Go();
go.argv = process.argv.slice(2);
go.env = Object.assign({ TMPDIR: require("os").tmpdir() }, process.env);
go.scope = {};
go.exit = process.exit;
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
process.on("exit", (code) => { // Node.js exits if no event handler is pending
Expand Down
6 changes: 6 additions & 0 deletions src/syscall/js/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ func Global() Value {
return valueGlobal
}

// Scope returns the Javascript object attached to the scope field of the Go class.
// If nothing has been explicitly set, behaves like [js.Global].
func Scope() Value {
return jsGo.Get("scope")
}

// ValueOf returns x as a JavaScript value:
//
// | Go | JavaScript |
Expand Down
16 changes: 16 additions & 0 deletions src/syscall/js/js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,3 +688,19 @@ func TestGlobal(t *testing.T) {
t.Errorf("got %#v, want %#v", got, js.Global())
}
}

func TestScope(t *testing.T) {
ident := js.FuncOf(func(this js.Value, args []js.Value) any {
return args[0]
})
defer ident.Release()

js.Scope().Set("key", "value")
if js.Scope().Get("key").String() != "value" {
t.Errorf("get key %s: got %#v", "key", js.Scope().Get("key"))
}

if got := ident.Invoke(js.Scope()); got.Equal(js.Global()) {
t.Errorf("scope %#v mixed with global %#v", got, js.Global())
}
}

0 comments on commit 0e5cc46

Please sign in to comment.