Skip to content

Commit

Permalink
feat: support host context changes
Browse files Browse the repository at this point in the history
  • Loading branch information
zshipko committed May 22, 2024
1 parent 660e0bd commit 2ce5918
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/bindings.ml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ let extism_plugin_call_s =
fn "extism_plugin_call"
(plugin @-> string @-> string @-> uint64_t @-> returning int32_t)


let extism_plugin_call_with_host_context =
fn "extism_plugin_call_with_host_context"
(plugin @-> string @-> ptr char @-> uint64_t @-> ptr void @-> returning int32_t)

let extism_plugin_call_with_host_context_s =
fn "extism_plugin_call_with_host_context"
(plugin @-> string @-> string @-> uint64_t @-> ptr void @-> returning int32_t)

let extism_error = fn "extism_plugin_error" (plugin @-> returning string_opt)

let extism_plugin_output_length =
Expand Down Expand Up @@ -159,6 +168,9 @@ let extism_function_set_namespace =
let extism_function_free =
fn "extism_function_free" (ptr void @-> returning void)

let extism_current_plugin_host_context =
fn "extism_current_plugin_host_context" (ptr void @-> returning (ptr void))

let extism_current_plugin_memory =
fn "extism_current_plugin_memory" (ptr void @-> returning (ptr uint8_t))

Expand Down
25 changes: 25 additions & 0 deletions src/extism.mli
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ module Host_function : sig
val output : (module Type.S with type t = 'a) -> ?index:int -> t -> 'a -> unit
(** Convert a value, allocate it and update the results array at [index] *)

val host_context: t -> 'a
(** Get the configured host context value *)

(** Some helpter functions for reading/writing memory *)
module Memory_handle : sig
val memory : ?offs:Unsigned.UInt64.t -> t -> Unsigned.uint8 Ctypes.ptr
Expand Down Expand Up @@ -421,6 +424,28 @@ module Plugin : sig
'b
(** Similar to {!call} but raises an exception using {!Error.unwrap} *)


val call_with_host_context :
(module Type.S with type t = 'a) ->
(module Type.S with type t = 'b) ->
t ->
name:string ->
'a ->
'c ->
('b, Error.t) result
(** [call input_type output_type t ~name input host_ctx] executes a function with a host context value,
input and output types defined in {!Type} *)

val call_with_host_context_exn :
(module Type.S with type t = 'a) ->
(module Type.S with type t = 'b) ->
t ->
name:string ->
'a ->
'c ->
'b
(** Similar to {!call_with_host_context} but raises an exception using {!Error.unwrap} *)

val free : t -> unit
(** Free a plugin immediately, this isn't normally required unless there are a
lot of plugins open at once *)
Expand Down
4 changes: 4 additions & 0 deletions src/host_function.ml
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,7 @@ let input (type a) (module C : Type.S with type t = a) ?index t =
C.decode bs

let input_exn a ?index t = input a ?index t |> Error.unwrap

let host_context t =
let ptr = Bindings.extism_current_plugin_host_context t.pointer in
if Ctypes.is_null ptr then failwith "Host_function.host_context" else Ctypes.Root.get ptr
34 changes: 34 additions & 0 deletions src/plugin.ml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,26 @@ let call_bigstring (t : t) ~name input =
let call_bigstring_exn t ~name input =
call_bigstring t ~name input |> Error.unwrap

let call_with_host_context' f { pointer; _ } ~name input len ctx =
if Ctypes.is_null pointer then Error.throw (`Msg "Plugin already freed")
else
let ctx = Ctypes.Root.create ctx in
let rc = f pointer name input len ctx in
let () = Ctypes.Root.release ctx in
if rc <> 0l then
match Bindings.extism_error pointer with
| None -> Error (`Msg "extism_plugin_call failed")
| Some msg -> Error (`Msg msg)
else
let out_len = Bindings.extism_plugin_output_length pointer in
let ptr = Bindings.extism_plugin_output_data pointer in
let buf =
Ctypes.bigarray_of_ptr Ctypes.array1
(Unsigned.UInt64.to_int out_len)
Char ptr
in
Ok buf

let%test "call_bigstring" =
let manifest = Manifest.(create [ Wasm.file "test/code.wasm" ]) in
let plugin = of_manifest manifest |> Error.unwrap in
Expand Down Expand Up @@ -134,6 +154,20 @@ let call (type a b) (module In : Type.S with type t = a)

let call_exn a b t ~name input = call a b t ~name input |> Error.unwrap

let call_with_host_context (type a b) (module In : Type.S with type t = a)
(module Out : Type.S with type t = b) t ~name (a : a) ctx : (b, Error.t) result
=
let input = In.encode a in
let len = String.length input in
match
call_with_host_context' Bindings.extism_plugin_call_with_host_context_s t ~name input
(Unsigned.UInt64.of_int len) ctx
with
| Ok x -> Out.decode x
| Error e -> Error e

let call_with_host_context_exn a b t ~name input ctx = call_with_host_context a b t ~name input ctx |> Error.unwrap

let%test "call" =
let manifest = Manifest.(create [ Wasm.file "test/code.wasm" ]) in
let plugin = of_manifest manifest |> Error.unwrap in
Expand Down

0 comments on commit 2ce5918

Please sign in to comment.