You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to create a "re-entrant" native method, that is, I'm looking to be able to have a script call a native function, which then Eval()'s another script.
This is possible, however, if that native method is called using Object.Call or Value.Call, the This pointer is not updated, resulting in Eval() using the caller's this, not the callee's.
Here's a minimal example that demonstrates the issue
package main
import (
"fmt""github.com/robertkrimen/otto"
)
funcmain() {
varerrerrorv:=otto.New()
// Create an object "x", with a field "y" and a method "foo" which returns this and this.y using Eval()x, err:=v.Call("new Object", nil)
iferr!=nil {
panic(err)
}
err=x.Object().Set("y", 1)
iferr!=nil {
panic(err)
}
err=x.Object().Set("foo", func(call otto.FunctionCall) otto.Value {
fmt.Print("[debug] this=")
fmt.Println(call.This.Export())
fmt.Print("[debug] this.y=")
fmt.Println(call.This.Object().Get("y"))
out, err:=v.Eval("[this, this.y]")
iferr!=nil {
panic(err)
}
returnout
})
iferr!=nil {
panic(err)
}
// Now call x.foo() in each possible wayfmt.Println("--- Object.Call ---")
out, err:=x.Object().Call("foo")
out2, err2:=out.Export()
fmt.Print("[output] foo()=")
fmt.Println(out2, err, err2)
// --- Object.Call ---// [debug] this=map[foo:map[] y:1] <nil>// [debug] this.y=1 <nil>// [output] foo()=[map[console:map[]] <nil>] <nil> <nil> // this is not set correctlyfmt.Println("--- Value.Call ---")
foo2, err:=x.Object().Get("foo")
iferr!=nil {
panic(err)
}
out, err=foo2.Call(x)
out2, err2=out.Export()
fmt.Print("[output] foo()=")
fmt.Println(out2, err, err2)
// --- Value.Call ---// [debug] this=map[foo:map[] y:1] <nil>// [debug] this.y=1 <nil>// [output] foo()=[map[console:map[]] <nil>] <nil> <nil> // this is not set correctlyfmt.Println("--- Otto.Call ---")
err=v.Set("x", x)
iferr!=nil {
panic(err)
}
out, err=v.Call("x.foo", nil)
out2, err2=out.Export()
fmt.Print("[output] foo()=")
fmt.Println(out2, err, err2)
// --- Otto.Call ---// [debug] this=map[foo:map[] y:1] <nil>// [debug] this.y=1 <nil>// [output] foo()=[map[foo:map[] y:1] 1] <nil> <nil> // this is correctly!
}
The text was updated successfully, but these errors were encountered:
I would like to create a "re-entrant" native method, that is, I'm looking to be able to have a script call a native function, which then
Eval()
's another script.This is possible, however, if that native method is called using
Object.Call
orValue.Call
, theThis
pointer is not updated, resulting inEval()
using the caller'sthis
, not the callee's.Here's a minimal example that demonstrates the issue
The text was updated successfully, but these errors were encountered: