Simplified CreateFunction
This commit is contained in:
parent
2ac1f6bac8
commit
01fc848621
11
ph7.go
11
ph7.go
@ -489,6 +489,7 @@ func write_vm_output(buf unsafe.Pointer, bufLen C.uint, userData unsafe.Pointer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) SetOutputWriter(w io.Writer) error {
|
func (vm *VM) SetOutputWriter(w io.Writer) error {
|
||||||
|
// TODO Does this need to reset to the default if it receives nil?
|
||||||
vm.outputWriter = w
|
vm.outputWriter = w
|
||||||
return newError(C.vm_set_output_callback(vm.ptr, vm.pointerKey))
|
return newError(C.vm_set_output_callback(vm.ptr, vm.pointerKey))
|
||||||
}
|
}
|
||||||
@ -562,24 +563,22 @@ func (vm *VM) Close() error {
|
|||||||
return newError(C.ph7_vm_release(vm.ptr))
|
return newError(C.ph7_vm_release(vm.ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
type ForeignFunction interface {
|
type Function func(ctx *Context, args []*Value) ResultCode
|
||||||
Call(ctx *Context, args []*Value) ResultCode
|
|
||||||
}
|
|
||||||
|
|
||||||
//export call_foreign_function
|
//export call_foreign_function
|
||||||
func call_foreign_function(ctx *C.ph7_context, argc C.int, argv **C.ph7_value) C.int {
|
func call_foreign_function(ctx *C.ph7_context, argc C.int, argv **C.ph7_value) C.int {
|
||||||
fkey := C.ph7_context_user_data(ctx)
|
fkey := C.ph7_context_user_data(ctx)
|
||||||
// TODO it looks like ph7 looks for a VFS at the user data pointer. WTF? Should we use it for that?
|
// TODO it looks like ph7 looks for a VFS at the user data pointer. WTF? Should we use it for that?
|
||||||
f := pointer.Restore(fkey).(ForeignFunction)
|
f := pointer.Restore(fkey).(Function)
|
||||||
args := make([]*Value, 0, argc)
|
args := make([]*Value, 0, argc)
|
||||||
argvSlice := unsafe.Slice(argv, argc)
|
argvSlice := unsafe.Slice(argv, argc)
|
||||||
for i := range argvSlice {
|
for i := range argvSlice {
|
||||||
args = append(args, (*Value)(argvSlice[i]))
|
args = append(args, (*Value)(argvSlice[i]))
|
||||||
}
|
}
|
||||||
return C.int(f.Call((*Context)(ctx), args))
|
return C.int(f((*Context)(ctx), args))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) CreateFunction(name string, f ForeignFunction) error {
|
func (vm *VM) CreateFunction(name string, f Function) error {
|
||||||
cname := C.CString(name)
|
cname := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(cname))
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
|
||||||
|
18
ph7_test.go
18
ph7_test.go
@ -139,23 +139,23 @@ func TestOutputWriter(t *testing.T) {
|
|||||||
// TODO Test failing writer, including vm.OutputWriteError
|
// TODO Test failing writer, including vm.OutputWriteError
|
||||||
// TODO Test setting writer twice
|
// TODO Test setting writer twice
|
||||||
|
|
||||||
type CtxFunc func(*ph7.Context) error
|
func CtxFunc(f func(*ph7.Context) error) ph7.Function {
|
||||||
|
return func(ctx *ph7.Context, _ []*ph7.Value) ph7.ResultCode {
|
||||||
func (r CtxFunc) Call(ctx *ph7.Context, _ []*ph7.Value) ph7.ResultCode {
|
err := f(ctx)
|
||||||
err := r(ctx)
|
if err != nil {
|
||||||
if err != nil {
|
return f(ctx).(ph7.Error).Code
|
||||||
return r(ctx).(ph7.Error).Code
|
}
|
||||||
|
return ph7.ResultCodeOK
|
||||||
}
|
}
|
||||||
return ph7.ResultCodeOK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResultCode(t *testing.T, expectedOutput string, f CtxFunc) {
|
func testResultCode(t *testing.T, expectedOutput string, f func(*ph7.Context) error) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
const script = "echo doStuff();"
|
const script = "echo doStuff();"
|
||||||
vm, close := setupVM(t, script)
|
vm, close := setupVM(t, script)
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
mustSucceed(t, vm.CreateFunction("doStuff", f))
|
mustSucceed(t, vm.CreateFunction("doStuff", CtxFunc(f)))
|
||||||
expectOutput(t, vm, expectedOutput)
|
expectOutput(t, vm, expectedOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user