diff --git a/CHANGELOG.md b/CHANGELOG.md index d760253d..5dc0ae5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for calling constructors functions with NewInstance on Function - Build v8 with i18n support +### Changed +- Removed error return value from Context.Isolate() which never fails +- Removed error return value from NewObjectTemplate and NewFunctionTemplate. Panic if given a nil argument. + ## [v0.6.0] - 2021-05-11 ### Added diff --git a/README.md b/README.md index 60379e58..766a7e7c 100644 --- a/README.md +++ b/README.md @@ -45,11 +45,11 @@ if _, err := ctx2.RunScript("multiply(3, 4)", "main.js"); err != nil { ```go iso, _ := v8go.NewIsolate() // create a new VM // a template that represents a JS function -printfn, _ := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { +printfn := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { fmt.Printf("%v", info.Args()) // when the JS function is called this Go callback will execute return nil // you can return a value back to the JS caller if required }) -global, _ := v8go.NewObjectTemplate(iso) // a template that represents a JS Object +global := v8go.NewObjectTemplate(iso) // a template that represents a JS Object global.Set("print", printfn) // sets the "print" property of the Object to our function ctx, _ := v8go.NewContext(iso, global) // new Context with the global Object set to our object template ctx.RunScript("print('foo')", "print.js") // will execute the Go callback with a single argunent 'foo' @@ -105,7 +105,7 @@ case val := <- vals: case err := <- errs: // javascript error case <- time.After(200 * time.Milliseconds): - vm, _ := ctx.Isolate() // get the Isolate from the context + vm := ctx.Isolate() // get the Isolate from the context vm.TerminateExecution() // terminate the execution err := <- errs // will get a termination error back from the running script } diff --git a/context.go b/context.go index 4c72d977..d2563c8a 100644 --- a/context.go +++ b/context.go @@ -83,9 +83,8 @@ func NewContext(opt ...ContextOption) (*Context, error) { // Isolate gets the current context's parent isolate.An error is returned // if the isolate has been terninated. -func (c *Context) Isolate() (*Isolate, error) { - // TODO: [RC] check to see if the isolate has not been terninated - return c.iso, nil +func (c *Context) Isolate() *Isolate { + return c.iso } // RunScript executes the source JavaScript; origin or filename provides a diff --git a/context_test.go b/context_test.go index 307f4d13..c4dcf6c4 100644 --- a/context_test.go +++ b/context_test.go @@ -27,7 +27,7 @@ func TestContextExec(t *testing.T) { t.Errorf("error not expected: %v", err) } - iso, _ := ctx.Isolate() + iso := ctx.Isolate() ctx2, _ := v8go.NewContext(iso) _, err = ctx2.RunScript(`add`, "ctx2.js") if err == nil { @@ -150,7 +150,7 @@ func ExampleContext_isolate() { func ExampleContext_globalTemplate() { iso, _ := v8go.NewIsolate() - obj, _ := v8go.NewObjectTemplate(iso) + obj := v8go.NewObjectTemplate(iso) obj.Set("version", "v1.0.0") ctx, _ := v8go.NewContext(iso, obj) val, _ := ctx.RunScript("version", "main.js") diff --git a/function_template.go b/function_template.go index dd3485d3..7416d649 100644 --- a/function_template.go +++ b/function_template.go @@ -8,7 +8,6 @@ package v8go // #include "v8go.h" import "C" import ( - "errors" "runtime" "unsafe" ) @@ -40,12 +39,12 @@ type FunctionTemplate struct { } // NewFunctionTemplate creates a FunctionTemplate for a given callback. -func NewFunctionTemplate(iso *Isolate, callback FunctionCallback) (*FunctionTemplate, error) { +func NewFunctionTemplate(iso *Isolate, callback FunctionCallback) *FunctionTemplate { if iso == nil { - return nil, errors.New("v8go: failed to create new FunctionTemplate: Isolate cannot be ") + panic("nil Isolate argument not supported") } if callback == nil { - return nil, errors.New("v8go: failed to create new FunctionTemplate: FunctionCallback cannot be ") + panic("nil FunctionCallback argument not supported") } cbref := iso.registerCallback(callback) @@ -55,11 +54,12 @@ func NewFunctionTemplate(iso *Isolate, callback FunctionCallback) (*FunctionTemp iso: iso, } runtime.SetFinalizer(tmpl, (*template).finalizer) - return &FunctionTemplate{tmpl}, nil + return &FunctionTemplate{tmpl} } // GetFunction returns an instance of this function template bound to the given context. func (tmpl *FunctionTemplate) GetFunction(ctx *Context) *Function { + // TODO: Consider propagating the v8::FunctionTemplate::GetFunction error val_ptr := C.FunctionTemplateGetFunction(tmpl.ptr, ctx.ptr) return &Function{&Value{val_ptr, ctx}} } diff --git a/function_template_test.go b/function_template_test.go index 2598ddfe..2ae58651 100644 --- a/function_template_test.go +++ b/function_template_test.go @@ -17,24 +17,39 @@ import ( func TestFunctionTemplate(t *testing.T) { t.Parallel() - if _, err := v8go.NewFunctionTemplate(nil, func(*v8go.FunctionCallbackInfo) *v8go.Value { return nil }); err == nil { - t.Error("expected error but got ") - } - iso, _ := v8go.NewIsolate() - if _, err := v8go.NewFunctionTemplate(iso, nil); err == nil { - t.Error("expected error but got ") - } - - fn, err := v8go.NewFunctionTemplate(iso, func(*v8go.FunctionCallbackInfo) *v8go.Value { return nil }) - if err != nil { - t.Errorf("unexpected error: %v", err) - } + fn := v8go.NewFunctionTemplate(iso, func(*v8go.FunctionCallbackInfo) *v8go.Value { return nil }) if fn == nil { t.Error("expected FunctionTemplate, but got ") } } +func TestFunctionTemplate_panic_on_nil_isolate(t *testing.T) { + t.Parallel() + + defer func() { + if err := recover(); err == nil { + t.Error("expected panic") + } + }() + v8go.NewFunctionTemplate(nil, func(*v8go.FunctionCallbackInfo) *v8go.Value { + t.Error("unexpected call") + return nil + }) +} + +func TestFunctionTemplate_panic_on_nil_callback(t *testing.T) { + t.Parallel() + + defer func() { + if err := recover(); err == nil { + t.Error("expected panic") + } + }() + iso, _ := v8go.NewIsolate() + v8go.NewFunctionTemplate(iso, nil) +} + func TestFunctionTemplateGetFunction(t *testing.T) { t.Parallel() @@ -42,7 +57,7 @@ func TestFunctionTemplateGetFunction(t *testing.T) { ctx, _ := v8go.NewContext(iso) var args *v8go.FunctionCallbackInfo - tmpl, _ := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { + tmpl := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { args = info reply, _ := v8go.NewValue(iso, "hello") return reply @@ -66,8 +81,8 @@ func TestFunctionTemplateGetFunction(t *testing.T) { func ExampleFunctionTemplate() { iso, _ := v8go.NewIsolate() - global, _ := v8go.NewObjectTemplate(iso) - printfn, _ := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { + global := v8go.NewObjectTemplate(iso) + printfn := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { fmt.Printf("%+v\n", info.Args()) return nil }) @@ -80,9 +95,9 @@ func ExampleFunctionTemplate() { func ExampleFunctionTemplate_fetch() { iso, _ := v8go.NewIsolate() - global, _ := v8go.NewObjectTemplate(iso) + global := v8go.NewObjectTemplate(iso) - fetchfn, _ := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { + fetchfn := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { args := info.Args() url := args[0].String() diff --git a/function_test.go b/function_test.go index 196bcb15..4ef22af0 100644 --- a/function_test.go +++ b/function_test.go @@ -19,7 +19,7 @@ func TestFunctionCall(t *testing.T) { failIf(t, err) addValue, err := ctx.Global().Get("add") failIf(t, err) - iso, _ := ctx.Isolate() + iso := ctx.Isolate() arg1, err := v8go.NewValue(iso, int32(1)) failIf(t, err) @@ -66,10 +66,10 @@ func TestFunctionCallToGoFunc(t *testing.T) { t.Parallel() iso, _ := v8go.NewIsolate() - global, _ := v8go.NewObjectTemplate(iso) + global := v8go.NewObjectTemplate(iso) called := false - printfn, _ := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { + printfn := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { called = true return nil }) @@ -120,8 +120,7 @@ func TestFunctionNewInstance(t *testing.T) { ctx, err := v8go.NewContext() failIf(t, err) - iso, err := ctx.Isolate() - failIf(t, err) + iso := ctx.Isolate() value, err := ctx.Global().Get("Error") failIf(t, err) diff --git a/isolate_test.go b/isolate_test.go index c10e8cf7..922fbb99 100644 --- a/isolate_test.go +++ b/isolate_test.go @@ -103,7 +103,7 @@ func TestIsolateGarbageCollection(t *testing.T) { val, _ := v8go.NewValue(iso, "some string") fmt.Println(val.String()) - tmpl, _ := v8go.NewObjectTemplate(iso) + tmpl := v8go.NewObjectTemplate(iso) tmpl.Set("foo", "bar") v8go.NewContext(iso, tmpl) diff --git a/object_template.go b/object_template.go index a55ed7ac..2447f6f7 100644 --- a/object_template.go +++ b/object_template.go @@ -36,9 +36,9 @@ type ObjectTemplate struct { // NewObjectTemplate creates a new ObjectTemplate. // The *ObjectTemplate can be used as a v8go.ContextOption to create a global object in a Context. -func NewObjectTemplate(iso *Isolate) (*ObjectTemplate, error) { +func NewObjectTemplate(iso *Isolate) *ObjectTemplate { if iso == nil { - return nil, errors.New("v8go: failed to create new ObjectTemplate: Isolate cannot be ") + panic("nil Isolate argument not supported") } tmpl := &template{ @@ -46,7 +46,7 @@ func NewObjectTemplate(iso *Isolate) (*ObjectTemplate, error) { iso: iso, } runtime.SetFinalizer(tmpl, (*template).finalizer) - return &ObjectTemplate{tmpl}, nil + return &ObjectTemplate{tmpl} } // NewInstance creates a new Object based on the template. @@ -55,6 +55,7 @@ func (o *ObjectTemplate) NewInstance(ctx *Context) (*Object, error) { return nil, errors.New("v8go: Context cannot be ") } + // TODO: propagate v8 error valPtr := C.ObjectTemplateNewInstance(o.ptr, ctx.ptr) return &Object{&Value{valPtr, ctx}}, nil } diff --git a/object_template_test.go b/object_template_test.go index a34299bb..3e747edd 100644 --- a/object_template_test.go +++ b/object_template_test.go @@ -13,15 +13,8 @@ import ( func TestObjectTemplate(t *testing.T) { t.Parallel() - _, err := v8go.NewObjectTemplate(nil) - if err == nil { - t.Fatal("expected error but got ") - } iso, _ := v8go.NewIsolate() - obj, err := v8go.NewObjectTemplate(iso) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } + obj := v8go.NewObjectTemplate(iso) setError := func(t *testing.T, err error) { if err != nil { @@ -30,7 +23,7 @@ func TestObjectTemplate(t *testing.T) { } val, _ := v8go.NewValue(iso, "bar") - objVal, _ := v8go.NewObjectTemplate(iso) + objVal := v8go.NewObjectTemplate(iso) bigbigint, _ := new(big.Int).SetString("36893488147419099136", 10) // larger than a single word size (64bit) bigbignegint, _ := new(big.Int).SetString("-36893488147419099136", 10) @@ -62,6 +55,17 @@ func TestObjectTemplate(t *testing.T) { } } +func TestObjectTemplate_panic_on_nil_isolate(t *testing.T) { + t.Parallel() + + defer func() { + if err := recover(); err == nil { + t.Error("expected panic") + } + }() + v8go.NewObjectTemplate(nil) +} + func TestGlobalObjectTemplate(t *testing.T) { t.Parallel() iso, _ := v8go.NewIsolate() @@ -72,7 +76,7 @@ func TestGlobalObjectTemplate(t *testing.T) { }{ { func() *v8go.ObjectTemplate { - gbl, _ := v8go.NewObjectTemplate(iso) + gbl := v8go.NewObjectTemplate(iso) gbl.Set("foo", "bar") return gbl }, @@ -89,9 +93,9 @@ func TestGlobalObjectTemplate(t *testing.T) { }, { func() *v8go.ObjectTemplate { - foo, _ := v8go.NewObjectTemplate(iso) + foo := v8go.NewObjectTemplate(iso) foo.Set("bar", "baz") - gbl, _ := v8go.NewObjectTemplate(iso) + gbl := v8go.NewObjectTemplate(iso) gbl.Set("foo", foo) return gbl }, @@ -121,7 +125,7 @@ func TestGlobalObjectTemplate(t *testing.T) { func TestObjectTemplateNewInstance(t *testing.T) { t.Parallel() iso, _ := v8go.NewIsolate() - tmpl, _ := v8go.NewObjectTemplate(iso) + tmpl := v8go.NewObjectTemplate(iso) if _, err := tmpl.NewInstance(nil); err == nil { t.Error("expected error but got ") } diff --git a/object_test.go b/object_test.go index 041d6fca..21dd8bd3 100644 --- a/object_test.go +++ b/object_test.go @@ -15,7 +15,6 @@ func TestObjectMethodCall(t *testing.T) { t.Parallel() ctx, _ := v8go.NewContext() - iso, _ := ctx.Isolate() val, _ := ctx.RunScript(`class Obj { constructor(input) { this.input = input, this.prop = "" } print() { return this.input.toString() } }; new Obj("some val")`, "") obj, _ := val.AsObject() val, err := obj.MethodCall("print") @@ -27,7 +26,7 @@ func TestObjectMethodCall(t *testing.T) { val, err = ctx.RunScript(`class Obj2 { print(str) { return str.toString() } }; new Obj2()`, "") failIf(t, err) obj, _ = val.AsObject() - arg, _ := v8go.NewValue(iso, "arg") + arg, _ := v8go.NewValue(ctx.Isolate(), "arg") _, err = obj.MethodCall("print", arg) failIf(t, err) _, err = obj.MethodCall("notamethod") @@ -126,8 +125,8 @@ func ExampleObject_global() { ctx, _ := v8go.NewContext(iso) global := ctx.Global() - console, _ := v8go.NewObjectTemplate(iso) - logfn, _ := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { + console := v8go.NewObjectTemplate(iso) + logfn := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value { fmt.Println(info.Args()[0]) return nil }) diff --git a/promise.go b/promise.go index 7ab63dd3..5db55e04 100644 --- a/promise.go +++ b/promise.go @@ -41,6 +41,7 @@ func NewPromiseResolver(ctx *Context) (*PromiseResolver, error) { } ptr := C.NewPromiseResolver(ctx.ptr) val := &Value{ptr, ctx} + // TODO: Propagate Promise::Resolver::New error return &PromiseResolver{&Object{val}, nil}, nil }