Skip to content

Instantly share code, notes, and snippets.

@ehfeng
Last active October 30, 2023 04:15
Show Gist options
  • Save ehfeng/e8284f17d2a621c6ba2fc2c8a8255784 to your computer and use it in GitHub Desktop.
Save ehfeng/e8284f17d2a621c6ba2fc2c8a8255784 to your computer and use it in GitHub Desktop.
Verified getters work with internal fields in v8
package main
import (
v8 "rogchap.com/v8go"
)
type v8BuiltIns struct {
Object struct {
create *v8.Function
defineProperty *v8.Function
}
}
func initBuiltins(ctx *v8.Context) v8BuiltIns {
objectGlobal, err := ctx.Global().Get("Object")
if err != nil {
panic(err)
}
defPropV, err := objectGlobal.Object().Get("defineProperty")
if err != nil {
panic(err)
}
defPropFn, err := defPropV.AsFunction()
if err != nil {
panic(err)
}
createV, err := objectGlobal.Object().Get("create")
if err != nil {
panic(err)
}
createFn, err := createV.AsFunction()
if err != nil {
panic(err)
}
return v8BuiltIns{
Object: struct {
create *v8.Function
defineProperty *v8.Function
}{
create: createFn,
defineProperty: defPropFn,
},
}
}
func main() {
iso := v8.NewIsolate()
ctx := v8.NewContext(iso)
builtins := initBuiltins(ctx)
ot := v8.NewObjectTemplate(iso)
ot.SetInternalFieldCount(1)
o, err := ot.NewInstance(ctx)
if err != nil {
panic(err)
}
v, err := v8.NewValue(iso, "secret")
if err != nil {
panic(err)
}
if err := o.SetInternalField(0, v); err != nil {
panic(err)
}
getterOptV, err := builtins.Object.create.Call(ctx.Global(), v8.Null(iso))
if err != nil {
panic(err)
}
getterObject, err := getterOptV.AsObject()
if err != nil {
panic(err)
}
if err := getterObject.Set("get", v8.NewFunctionTemplate(iso, func(info *v8.FunctionCallbackInfo) *v8.Value {
fmt.Println("running getter")
return info.This().GetInternalField(0)
}).GetFunction(ctx).Value); err != nil {
panic(err)
}
internalFieldName, err := v8.NewValue(iso, "internal")
if err != nil {
panic(err)
}
_, err = builtins.Object.defineProperty.Call(ctx.Global(), o, internalFieldName, getterObject)
if err != nil {
panic(err)
}
// test if getting internal field returns `secret`
v, err = o.Get("internal")
if err != nil {
panic(err)
}
if v.String() != "secret" {
panic("expected secret")
}
if err := ctx.Global().Set("o", o); err != nil {
panic(err)
}
_, err = ctx.RunScript("var p = o", "")
if err != nil {
panic(err)
}
i, err := ctx.Global().Get("p")
if err != nil {
panic(err)
}
v, err = i.Object().Get("internal")
if err != nil {
panic(err)
}
if v.String() != "secret" {
panic("expected secret")
}
v, err = ctx.RunScript("o.internal", "")
if err != nil {
panic(err)
}
if v.String() != "secret" {
panic("expected secret")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment