Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

SnapshotCreator API test v2 #43

Merged
merged 9 commits into from
Jan 19, 2022
2 changes: 1 addition & 1 deletion context.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func NewContext(opt ...ContextOption) *Context {
if createParams != nil && createParams.startupData != nil {
ctx = &Context{
ref: ref,
ptr: C.NewContextFromSnapShot(opts.iso.ptr, createParams.startupData.ptr.index, C.int(ref)),
ptr: C.NewContextFromSnapShot(opts.iso.ptr, createParams.startupData.index, C.int(ref)),
iso: opts.iso,
}
} else {
Expand Down
20 changes: 9 additions & 11 deletions isolate.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,16 @@ func NewIsolate(opts ...createOptions) *Isolate {
opt(params)
}

var iso *Isolate
var cOptions C.IsolateOptions

if params.startupData != nil {
iso = &Isolate{
ptr: C.NewIsolateWithCreateParams(params.startupData.ptr),
cbs: make(map[int]FunctionCallback),
createParams: params,
}
} else {
iso = &Isolate{
ptr: C.NewIsolate(),
cbs: make(map[int]FunctionCallback),
}
cOptions.snapshot_blob = params.startupData.ptr
}

iso := &Isolate{
ptr: C.NewIsolate(cOptions),
cbs: make(map[int]FunctionCallback),
createParams: params,
}
iso.null = newValueNull(iso)
iso.undefined = newValueUndefined(iso)
Expand Down
74 changes: 31 additions & 43 deletions snapshot_creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package v8go
import "C"
import (
"errors"
"unsafe"
)

type FunctionCodeHandling int
Expand All @@ -20,7 +19,8 @@ const (
)

type StartupData struct {
ptr *C.SnapshotBlob
ptr *C.RtnSnapshotBlob
index C.size_t
}

func (s *StartupData) Dispose() {
Expand All @@ -29,69 +29,57 @@ func (s *StartupData) Dispose() {
}
}

type snapshotCreatorOptions struct {
iso *Isolate
exitingBlob *StartupData
}

type creatorOptions func(*snapshotCreatorOptions)

func WithIsolate(iso *Isolate) creatorOptions {
return func(options *snapshotCreatorOptions) {
options.iso = iso
}
}

type SnapshotCreator struct {
ptr C.SnapshotCreatorPtr
*snapshotCreatorOptions
ptr C.SnapshotCreatorPtr
iso *Isolate
ctx *Context
index C.size_t
}

func NewSnapshotCreator(opts ...creatorOptions) *SnapshotCreator {
func NewSnapshotCreator() *SnapshotCreator {
v8once.Do(func() {
C.Init()
})

options := &snapshotCreatorOptions{}
for _, opt := range opts {
opt(options)
}

var cOptions C.SnapshotCreatorOptions
rtn := C.NewSnapshotCreator()

if options.iso != nil {
cOptions.iso = options.iso.ptr
return &SnapshotCreator{
ptr: rtn.creator,
iso: &Isolate{ptr: rtn.iso},
}
}

return &SnapshotCreator{
ptr: C.NewSnapshotCreator(cOptions),
snapshotCreatorOptions: options,
func (s *SnapshotCreator) GetIsolate() (*Isolate, error) {
if s.ptr == nil {
return nil, errors.New("v8go: Cannot get Isolate after creating the blob")
}

return s.iso, nil
}

func (s *SnapshotCreator) Create(source, origin string, functionCode FunctionCodeHandling) (*StartupData, error) {
func (s *SnapshotCreator) AddContext(ctx *Context) error {
if s.ptr == nil {
return nil, errors.New("v8go: Cannot use snapshot creator after creating the blob")
return errors.New("v8go: Cannot add context to snapshot creator after creating the blob")
}

cSource := C.CString(source)
cOrigin := C.CString(origin)
defer C.free(unsafe.Pointer(cSource))
defer C.free(unsafe.Pointer(cOrigin))
s.index = C.AddContext(s.ptr, ctx.ptr)
s.ctx = ctx

rtn := C.CreateSnapshot(s.ptr, cSource, cOrigin, C.int(functionCode))
return nil
}

if rtn.blob == nil {
return nil, newJSError(rtn.error)
func (s *SnapshotCreator) Create(functionCode FunctionCodeHandling) (*StartupData, error) {
if s.ptr == nil {
return nil, errors.New("v8go: Cannot use snapshot creator after creating the blob")
}

s.ptr = nil
rtn := C.CreateBlob(s.ptr, s.ctx.ptr, C.int(functionCode))

if s.snapshotCreatorOptions.iso != nil {
s.snapshotCreatorOptions.iso.ptr = nil
}
s.ptr = nil
s.ctx.ptr = nil
s.iso.ptr = nil

return &StartupData{ptr: rtn.blob}, nil
return &StartupData{ptr: rtn, index: s.index}, nil
}

func (s *SnapshotCreator) Dispose() {
Expand Down
107 changes: 29 additions & 78 deletions snapshot_creator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ import (

func TestCreateSnapshot(t *testing.T) {
snapshotCreator := v8.NewSnapshotCreator()
snapshotCreatorIso, err := snapshotCreator.GetIsolate()
fatalIf(t, err)

snapshotCreatorCtx := v8.NewContext(snapshotCreatorIso)
defer snapshotCreatorCtx.Close()

data, err := snapshotCreator.Create("function run() { return 1 };", "script.js", v8.FunctionCodeHandlingKlear)
snapshotCreatorCtx.RunScript(`const add = (a, b) => a + b`, "add.js")
snapshotCreatorCtx.RunScript(`function run() { return add(3, 4); }`, "main.js")
err = snapshotCreator.AddContext(snapshotCreatorCtx)
fatalIf(t, err)

data, err := snapshotCreator.Create(v8.FunctionCodeHandlingKlear)
fatalIf(t, err)
defer data.Dispose()

iso := v8.NewIsolate(v8.WithStartupData(data))
defer iso.Dispose()
defer data.Dispose()

ctx := v8.NewContext(iso)
defer ctx.Close()
Expand All @@ -36,98 +46,39 @@ func TestCreateSnapshot(t *testing.T) {
if err != nil {
panic(err)
}
if val.String() != "1" {
if val.String() != "7" {
t.Fatal("invalid val")
}
}

func TestCreateSnapshotErrorAfterSuccessfullCreate(t *testing.T) {
snapshotCreator := v8.NewSnapshotCreator()
snapshotCreatorIso, err := snapshotCreator.GetIsolate()
fatalIf(t, err)
snapshotCreatorCtx := v8.NewContext(snapshotCreatorIso)
defer snapshotCreatorCtx.Close()

data, err := snapshotCreator.Create("function run() { return 1 };", "script.js", v8.FunctionCodeHandlingKlear)
defer data.Dispose()
snapshotCreatorCtx.RunScript(`const add = (a, b) => a + b`, "add.js")
snapshotCreatorCtx.RunScript(`function run() { return add(3, 4); }`, "main.js")
err = snapshotCreator.AddContext(snapshotCreatorCtx)
fatalIf(t, err)

data, err := snapshotCreator.Create(v8.FunctionCodeHandlingKlear)
fatalIf(t, err)
defer data.Dispose()

_, err = snapshotCreator.Create("function run2() { return 2 };", "script2.js", v8.FunctionCodeHandlingKlear)
_, err = snapshotCreator.GetIsolate()
if err == nil {
t.Error("Creating snapshot should have fail")
t.Error("Getting Isolate should have fail")
}
}

func TestCreateSnapshotFail(t *testing.T) {
snapshotCreator := v8.NewSnapshotCreator()
defer snapshotCreator.Dispose()

_, err := snapshotCreator.Create("uidygwuiwgduw", "script.js", v8.FunctionCodeHandlingKlear)
err = snapshotCreator.AddContext(snapshotCreatorCtx)
if err == nil {
t.Error("Creating snapshot should have fail")
t.Error("Adding context should have fail")
}
}

func TestCreateSnapshotFailAndReuse(t *testing.T) {
snapshotCreator := v8.NewSnapshotCreator()
_, err := snapshotCreator.Create("uidygwuiwgduw", "script.js", v8.FunctionCodeHandlingKlear)
_, err = snapshotCreator.Create(v8.FunctionCodeHandlingKlear)
if err == nil {
t.Error("Creating snapshot should have fail")
}

data, err := snapshotCreator.Create("function run() { return 1 };", "script.js", v8.FunctionCodeHandlingKlear)
fatalIf(t, err)

iso := v8.NewIsolate(v8.WithStartupData(data))
defer iso.Dispose()
defer data.Dispose()

ctx := v8.NewContext(iso)
defer ctx.Close()

runVal, err := ctx.Global().Get("run")
if err != nil {
panic(err)
}

fn, err := runVal.AsFunction()
if err != nil {
panic(err)
}
val, err := fn.Call(v8.Undefined(iso))
if err != nil {
panic(err)
}
if val.String() != "1" {
t.Fatal("invalid val")
}
}

func TestCreateSnapshotWithIsolateOption(t *testing.T) {
iso1 := v8.NewIsolate()
defer iso1.Dispose()
snapshotCreator := v8.NewSnapshotCreator(v8.WithIsolate(iso1))

data, err := snapshotCreator.Create("function run() { return 1 };", "script.js", v8.FunctionCodeHandlingKlear)
fatalIf(t, err)

iso := v8.NewIsolate(v8.WithStartupData(data))
defer iso.Dispose()
defer data.Dispose()

ctx := v8.NewContext(iso)
defer ctx.Close()

runVal, err := ctx.Global().Get("run")
if err != nil {
panic(err)
}

fn, err := runVal.AsFunction()
if err != nil {
panic(err)
}
val, err := fn.Call(v8.Undefined(iso))
if err != nil {
panic(err)
}
if val.String() != "1" {
t.Fatal("invalid val")
}
}
Loading