Wrapped ph7_create_function

This commit is contained in:
Brandon Dyck 2022-11-26 21:45:16 -07:00
parent b2697e184c
commit 30bb620dba
3 changed files with 44 additions and 1 deletions

4
cgo.c
View File

@ -11,3 +11,7 @@ int vm_extract_output(ph7_vm *pVm, const char **pzPtr, int *pLen) {
int vm_set_output_callback(ph7_vm *pVm, void *pUserData) {
return ph7_vm_config(pVm, PH7_VM_CONFIG_OUTPUT, &write_vm_output, pUserData);
}
int vm_create_function(ph7_vm *pVm, const char *zName, void *pUserData) {
return ph7_create_function(pVm, zName, call_foreign_function, pUserData);
}

3
cgo.h
View File

@ -6,3 +6,6 @@ int vm_extract_output(ph7_vm *pVm, const char **pzPtr, int *pLen);
extern int write_vm_output(void*, unsigned int, void*);
int vm_set_output_callback(ph7_vm *pVm, void *pUserData);
extern int call_foreign_function(ph7_context *pCtx, int argc, ph7_value **argv);
int vm_create_function(ph7_vm *pVm, const char *zName, void *pUserData);

38
ph7.go
View File

@ -53,6 +53,8 @@ type Error struct {
Code ResultCode
}
// TODO create a CompileError that contains the error log text
func newError(code C.int) error {
if code != C.PH7_OK {
return Error{
@ -112,12 +114,17 @@ func (e Engine) Close() error {
return newError(C.ph7_release(e.ptr))
}
type Value C.ph7_value
type Context C.ph7_context
type VM struct {
ptr *C.ph7_vm
pointerKey unsafe.Pointer
outputWriter io.Writer
// TODO clear outputWriteError when resetting VM
outputWriteErr error
outputWriteErr error
userFunctionKeys []unsafe.Pointer
}
func newVM(cvm *C.ph7_vm) *VM {
@ -170,5 +177,34 @@ func (vm *VM) Reset() error {
func (vm *VM) Close() error {
pointer.Unref(vm.pointerKey)
for _, key := range vm.userFunctionKeys {
pointer.Unref(key)
}
return newError(C.ph7_vm_release(vm.ptr))
}
type ForeignFunction interface {
Call(ctx *Context, args []*Value) ResultCode
}
//export call_foreign_function
func call_foreign_function(ctx *C.ph7_context, argc C.int, argv **C.ph7_value) C.int {
fkey := C.ph7_context_user_data(ctx)
f := pointer.Restore(fkey).(ForeignFunction)
args := make([]*Value, 0, argc)
argvSlice := unsafe.Slice(argv, argc)
for i := range argvSlice {
args = append(args, (*Value)(argvSlice[i]))
}
return C.int(f.Call((*Context)(ctx), args))
}
func (vm *VM) CreateFunction(name string, f ForeignFunction) error {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
fkey := pointer.Save(f)
vm.userFunctionKeys = append(vm.userFunctionKeys, fkey)
return newError(C.vm_create_function(vm.ptr, cname, fkey))
}