forked from rogchap/v8go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunction_template.go
81 lines (67 loc) · 2.25 KB
/
function_template.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright 2021 Roger Chapman and the v8go contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package v8go
// #include <stdlib.h>
// #include "v8go.h"
import "C"
import (
"errors"
"runtime"
"unsafe"
)
// FunctionCallback is a callback that is executed in Go when a function is executed in JS.
type FunctionCallback func(info *FunctionCallbackInfo) *Value
// FunctionCallbackInfo is the argument that is passed to a FunctionCallback.
type FunctionCallbackInfo struct {
ctx *Context
args []*Value
}
// Context is the current context that the callback is being executed in.
func (i *FunctionCallbackInfo) Context() *Context {
return i.ctx
}
// Args returns a slice of the value arguments that are passed to the JS function.
func (i *FunctionCallbackInfo) Args() []*Value {
return i.args
}
// FunctionTemplate is used to create functions at runtime.
// There can only be one function created from a FunctionTemplate in a context.
// The lifetime of the created function is equal to the lifetime of the context.
type FunctionTemplate struct {
*template
}
// NewFunctionTemplate creates a FunctionTemplate for a given callback.
func NewFunctionTemplate(iso *Isolate, callback FunctionCallback) (*FunctionTemplate, error) {
if iso == nil {
return nil, errors.New("v8go: failed to create new FunctionTemplate: Isolate cannot be <nil>")
}
if callback == nil {
return nil, errors.New("v8go: failed to create new FunctionTemplate: FunctionCallback cannot be <nil>")
}
cbref := iso.registerCallback(callback)
tmpl := &template{
ptr: C.NewFunctionTemplate(iso.ptr, C.int(cbref)),
iso: iso,
}
runtime.SetFinalizer(tmpl, (*template).finalizer)
return &FunctionTemplate{tmpl}, nil
}
//export goFunctionCallback
func goFunctionCallback(ctxref int, cbref int, args *C.ValuePtr, argsCount int) C.ValuePtr {
ctx := getContext(ctxref)
info := &FunctionCallbackInfo{
ctx: ctx,
args: make([]*Value, argsCount),
}
argv := (*[1 << 30]C.ValuePtr)(unsafe.Pointer(args))[:argsCount:argsCount]
for i, v := range argv {
val := &Value{ptr: v}
info.args[i] = val
}
callbackFunc := ctx.iso.getCallback(cbref)
if val := callbackFunc(info); val != nil {
return val.ptr
}
return nil
}