From 436e551de735997b761284d6e4b9f5b472601ed3 Mon Sep 17 00:00:00 2001 From: Hakkin Lain <hakkin@github> Date: Sat, 25 Jan 2025 09:22:39 -0800 Subject: [PATCH] Add Runtime.SetGlobalObject() method. --- runtime.go | 6 +++++ runtime_test.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/runtime.go b/runtime.go index fe889944..047855c7 100644 --- a/runtime.go +++ b/runtime.go @@ -2377,6 +2377,12 @@ func (r *Runtime) GlobalObject() *Object { return r.globalObject } +// SetGlobalObject sets the global object to the given object. +// Note, any existing references to the previous global object will continue to reference that object. +func (r *Runtime) SetGlobalObject(object *Object) { + r.globalObject = object +} + // Set the specified variable in the global context. // Equivalent to running "name = value" in non-strict mode. // The value is first converted using ToValue(). diff --git a/runtime_test.go b/runtime_test.go index 00b5523f..31e64ac2 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -1087,6 +1087,72 @@ func TestRuntime_ExportToObject(t *testing.T) { } } +func TestRuntime_SetGlobalObject(t *testing.T) { + vm := New() + + _, err := vm.RunString(`var myVar = 123;`) + if err != nil { + t.Fatal(err) + } + + oldGlobalObject := vm.GlobalObject() + + newGlobalObject, err := vm.RunString(`({oldGlobalReference:globalThis});`) + if err != nil { + t.Fatal(err) + } + + vm.SetGlobalObject(newGlobalObject.(*Object)) + + if vm.GlobalObject() != newGlobalObject { + t.Fatal("Expected global object to be new object") + } + + if vm.GlobalObject().Get("myVar") != nil { + t.Fatal("Expected myVar to be undefined") + } + + oldGlobalReference := vm.GlobalObject().Get("oldGlobalReference") + if oldGlobalReference == nil { + t.Fatal("Expected oldGlobalReference to be defined") + } + + if oldGlobalReference != oldGlobalObject { + t.Fatal("Expected reference to be to old global object") + } +} + +func TestRuntime_SetGlobalObject_Proxy(t *testing.T) { + vm := New() + + globalObject := vm.GlobalObject() + + globalObjectProxy := vm.NewProxy(globalObject, &ProxyTrapConfig{ + Get: func(target *Object, property string, receiver Value) (value Value) { + if target != globalObject { + t.Fatal("Expected target to be global object") + } + + if property != "testing" { + t.Fatal("Expected property to be 'testing'") + } + + return valueTrue + }, + }) + + vm.SetGlobalObject(vm.ToValue(globalObjectProxy).(*Object)) + + ret, err := vm.RunString("testing") + if err != nil { + t.Fatal(err) + } + + if ret != valueTrue { + t.Fatal("Expected return value to equal true") + } +} + func ExampleAssertFunction() { vm := New() _, err := vm.RunString(`