Commit Graph

73 Commits

Author SHA1 Message Date
zach
e979987dc7 feat: add ability to limit the number of instructions executed by a plugin (#754)
*Note*: this will be limited for the time being as not all runtimes
support this yet
2024-08-23 10:24:28 -07:00
zach
f0c9640e1e cleanup: allow shadowing host functions (#751) 2024-08-08 13:20:40 -07:00
innuendo
d48dc4021c feat(runtime): support log_trace in rust-sdk (#747)
Add support for logtrace in Rust SDK runtime.

Fix `clippy::needless_borrows_for_generic_args` lints.

Ref: https://github.com/extism/extism/issues/744

Co-authored-by: corda.ilaria@gmail.com <ilariac691@gmail.com>
Co-authored-by: Steve Manuel <steve@dylibso.com>
Co-authored-by: Chris Dickinson <chris@dylibso.com>
2024-07-30 11:53:23 -07:00
zach
6d2735cec7 fix: require error messages to be null terminated in C SDK (#745)
Related to https://github.com/extism/python-sdk/issues/23 - there is
currently no way to get the length of the error message, so we need to
make sure it is a valid C string.
2024-07-23 09:35:59 -07:00
zach
9dbc22830e fix: use wasi-common to avoid issues with tokio (#728)
See https://github.com/bytecodealliance/wasmtime/issues/8799

I will make a 1.4.1 release after this is merged
2024-06-14 09:22:55 -07:00
zach
2a7345a480 fix: return error when non-zero exit code in returned (#727)
Returns an error when a plugin call returns a non-zero exit code

See https://github.com/extism/go-pdk/issues/33
2024-06-11 12:34:10 -07:00
zach
3f54892a39 refactor!: update to wasmtime 20 or greater (#723)
- Breaking: No longer copies Extism config values into WASI environment
variables because the new interface doesn't allow for the environment to
be updated - these should be accessed using the Extism config functions
instead
- Requires wasmtime 20 or greater
- Enables wasm-gc
- Similar to https://github.com/extism/extism/pull/697 without sockets
or additional support for command modules
2024-06-05 12:57:25 -07:00
zach
ecf18a2d81 fix: re-use linking code from Plugin::new in Plugin::reset_store (#722) 2024-05-31 08:25:06 -07:00
zach
0882f35300 fix: respect overall timeout when using http requests (#717)
Currently HTTP requests can extend beyond the configured timeout for a
plugin - this PR sets the timeout of the HTTP request to the remaining
time left if a timeout is set in the manifest.
2024-05-21 20:11:00 -07:00
Chris Dickinson
5d9c8c5d05 feat: per call context (#711)
Add `plugin.call_with_host_context` and `current_plugin.host_context`
methods, enabling per-call context to be looped from the guest invocation
to any host functions it calls. In an HTTP server environment, this enables
re-using a plugin across multiple requests while switching out backing
connections and user information in host functions. (Imagine a host
function, `update_user` -- previously the plugin would have to have been
aware of the user to pass to the host function. Now that information is
ambient.)

This is a backwards-compatible change and requires no changes to
existing plugins.

Implement by adding a global, mutable externref to the extism kernel.
Since most programming languages, including Rust, don't let you define
these natively, we accomplish this by using `wasm-merge` to combine the
kernel Wasm with Wasm generated by a WAT file containing only the
global.

(This pattern might be useful for other Wasm constructs we can't use
directly from Rust, like `v128` in argument parameters.)

Wasmtime requires extern refs to be `Any + Send + Sync + 'static`; we
additionally add `Clone`. I haven't tried this with an `Arc` directly,
but it should work at least for container structs that hold `Arc`'s
themselves.
2024-05-21 11:53:43 -07:00
zach
ed1439ec2d fix: linker issue that depends on the ordering of the linked functions (#685)
It looks like when a module is added to the linker, all of its imports
must already be present. This PR updates the linking process to take
that into consideration and adds a test with a reproduction of the issue
@chrisdickinson shared with me.
2024-02-22 10:56:21 -08:00
Onigbinde Oluwamuyiwa Elijah
fbae853505 fix: make function Plugin::function_extists check the type of the functions. (#664)
This PR addresses #654
It checks the parameters and results of the function as described in the
mentioned issue.
2024-01-22 08:40:09 -08:00
zach
03e761908c feat: add Plugin::call_get_error_code to get Extism error code along with the error (#649)
- Adds `Plugin::call_get_error_code` to get the Extism error code when a
call fails
2024-01-05 12:52:31 -08:00
zach
a5edf58747 fix(kernel): improve performance after large allocations, add extism_plugin_reset to give users more control when dealing with large allocations (#627)
See https://github.com/extism/cpp-sdk/issues/15

- Limits a call to memset in the kernel to the size of the current
memory offset instead of the total size of memory.
- Adds `extism_plugin_reset` to the C API and `extism::Plugin::reset` to
Rust

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: zshipko <zshipko@users.noreply.github.com>
2023-12-12 13:56:34 -08:00
zach
9bff8be915 refactor!: better scoping of arguments in host_fn macro, allow visibility in macros to be specified (#621)
Fixes #619  

- Also updates `host_fn`, `encoding`, and `typed_plugin` macros to allow
for visibility specifiers to manage the visibility of the defined types.
This means that `pub` will need to be added to existing invocations that
should remain public
2023-12-05 09:58:35 -08:00
zach
af4fd184e6 cleanup: simplify main module resolution (#612)
This PR simplifies the resolution of the `main` module when multiple
modules are provided. Before we would try to look at the path/URL when
the wasm was coming from disk or via HTTP, now any module missing a name
will be used as `main`. This is much nicer and more consistent since
this is what was being done when no filename was available (i.e. raw
data modules). It also make sense because non-main modules will need to
be named for the functions to be linked correctly.
2023-11-28 16:15:44 -08:00
zach
a517cd23be feat: enable wasmtime caching (#605)
Alternate to: #596 without support for manually compiling/loading native
code

- Enables wasmtime caching: https://docs.wasmtime.dev/cli-cache.html
- Adds `EXTISM_CACHE_CONFIG` and `PluginBuilder::with_cache_config` to
determine where to load a custom cache configuration from
- Adds `PluginBuilder::with_cache_disabled` to disable the cache when
initializing a plugin
  - Setting `EXTISM_CACHE_CONFIG=""` will also disable caching 

## Performance

With caching:
```
create/create_plugin    time:   [2.9079 ms 2.9139 ms 2.9200 ms]                                  
                        change: [+3.2677% +3.6399% +3.9766%] (p = 0.00 < 0.20)
                        Change within noise threshold.
```

Compared to `main`:
```
create/create_plugin    time:   [26.089 ms 26.498 ms 26.923 ms]                                 
                        change: [+0.1729% +2.0868% +4.1337%] (p = 0.04 < 0.20)
                        Change within noise threshold.
```
2023-11-28 11:50:21 -08:00
zach
2a24d13c9b refactor!: use tracing crate for logging, add extism_log_callback function (#578)
- Uses `tracing` instead of `log` crate
- Uses `tracing-subscriber` instead of `fern`
- This allows us to automatically capture `log` events using
`tracing-subscriber`
- Breaking: Makes `extism::set_log_file` private and only used through
the C API, Rust users should use `tracing-subscriber` to determine which
filters/levels to log.
- Adds `extism::set_log_callback` function to set a callback that can be
used for custom logging from Rust.
- Adds `bool extism_log_custom(const char *level)` and
`extism_log_drain(void (*fn)(const char *s, size_t length)` to the C API
to enable custom sinks in other SDKs
2023-11-16 10:35:22 -08:00
zach
91257f0a54 cleanup: simplify logging, include plugin ID in log messages (#573)
My initial goal was to make logging configurable for each plugin instead
of global but wasn't able to accomplish that in this PR (still looking
into it)

- Switches from `log4rs` to `fern` - this significantly simplifies the
logging code
  - Also considered `simplelog`
- Adds `plugin.id` to the logs whenever available
- Uses `extism::plugin::$id` target for functions logged from the PDK
2023-11-08 15:36:47 -08:00
zach
3226060dd1 refactor!: allow Plugin::new to take raw wasm or Manifest (#569)
- Removes `Plugin::new_with_manifest` and updates `Plugin::new` to take
wasm bytes or `Manifest` using the new `WasmInput` trait
- Removes `PluginBuilder::new_with_module` in favor of a
`PluginBuilder::new` with a `WasmInput` argument
2023-11-06 13:31:24 -08:00
zach
b86ce1fec7 fix: improve handling of custom error messages (#568)
Fixes #567
2023-11-06 10:18:52 -08:00
zach
f36d0f60cc cleanup: update error message (#561) 2023-11-03 11:25:57 -07:00
zach
c5b3af2963 fix: set epoch deadline before each plugin call (#557)
We were updating the epoch deadline callback after the call has ended to
ignore any timeouts that might happen when reading output, which would
allow for the plugin to be cancelled successfully the first time a
plugin is called but would fail after the first call. This PR fixes
cancellation by resetting the epoch deadline and callback before each
plugin call.

I tested this against the dotnet sdk tests, where this was discovered,
and added a similar test to the runtime test suite,

Fixes #556
2023-11-01 13:05:08 -07:00
zach
f3447a538c refactor!: Use extism:host/env namespace for extism functions and extism:host/user for user-defined host functions (#511)
See #504 

Removes CI for the in-repo SDKs, we can remove the actual code closer to
the 1.0 release.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: zshipko <zshipko@users.noreply.github.com>
2023-10-30 11:43:40 -07:00
zach
0e65c3afae refactor!: Cleanup UserData implementation, update example in README (#550)
Fixes #545 

- Adds a type parameter to `UserData` type to avoid dynamic typing
issues
- Adds KV example from README to `examples/readme.rs` to make sure it
stays in-sync
- Implement `Default` for `UserData<T>` when `T` implements `Default`
- Make `UserData` argument non-optional in `Function::new`,
`UserData::default()` can be used instead.
2023-10-26 11:19:48 -07:00
Benjamin Eckel
fea4e6c293 docs: Add some documentation for plugin.call (#546)
We should go through some of the main ones people will be interacting
with and make sure there is a little more description of how to use it.
2023-10-26 12:42:55 -05:00
zach
4bd0ed6d03 feat: add ability to dump extism kernel memory and generate coredumps, cleanup kernel memory layout (#539)
Fixes https://github.com/extism/extism/issues/537

- Requires wasmtime 14.0.0 or greater for coredump serialization
- Adds `EXTISM_COREDUMP` environment variable to write wasmtime coredump
to a file when an error occurs
- This will create a coredump from the main wasm module, which means it
doesn't give us too much insight into the kernel
- Adds `EXTISM_MEMDUMP` environment variable to write extism linear
memory to a file when an error occurs
  - This gives us access to the kernel memory  
- Adds some missing profiling options
- Converts timeouts to a Trap instead of a plain error, this helps us
get better information about where the timeout occured
- Some small improvements to error handling after a plugin call
- Adds a test for coredump and memdump generation
- Adds the ability to configure debug options using `PluginBuilder`
- Fixes memory layout and a wasted page of memory in the kernel, found
while debugging a memory dump

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: zshipko <zshipko@users.noreply.github.com>
2023-10-24 17:31:26 -07:00
zach
a9835da614 fix(rust): return extism_error message from Plugin::call if it is set (#508) 2023-10-12 13:24:10 -07:00
zach
08db39c153 chore: bump wasmtime lower bound to 13.0.0, remove wasi-nn support (#483)
- Updates to wasmtime 13.0.0 as the lowest supported version
- Removes `wasmtime-wasi-nn` support because it now takes parameters to
specify particular backends and registries during initialization. Since
I don't think anyone is using the `nn` feature I chose to remove it for
now, but we could also expand the manifest to add these options.
2023-09-23 09:12:54 -07:00
zach
75a8495772 cleanup(runtime): remove restrictions around memory.max_pages option, fix crash (#482)
- Removes restrictions around when `memory.max_pages` setting can be
used. Before we used `wasmtime::MemoryLimiter` it was hard to determine
how much was being allocated at runtime, so we used to calculate the
totals statically, which required every module to have a maximum memory
set at compile time. This PR allows `memory.max` to be used on any
module!
- Fixes a crash when the `memory.max_pages` field is set
- Adds a test that checks for failure when allocating more than
configured
2023-09-23 09:12:15 -07:00
zach
cb55e52506 feat: Add extism-convert crate and use it for input/output to plugin calls (#443)
- Adds `extism-convert` crate with `ToBytes`, `FromBytes` and
`FromBytesOwned` traits
- This serves as a single interface for reading/writing rich types from
WebAssembly linear memory.
- Supports `Json` and `Msgpack` and `Protobuf` encodings out-of-the-box
- Updates `Plugin::call` to take `ToBytes` as the input argument and
return a `FromBytes` value
- Adds `host_fn!` macro to simplify host function creation
- Cleans up generated documentation a little
- PR for the Rust PDK: https://github.com/extism/rust-pdk/pull/31
- Adds a `typed_plugin!` macro to implement type-safe wrappers around
`Plugin`
- After this we should focus on adding similar type-conversion helpers
to the SDKs and other PDKs to make it easier to use across languages.
For example, a Python host running a Rust plugin using Msgpack encoded
types.

## Examples

### Calling a function

Instead of the untyped, bytes-only `call` function:

```rust
let output = plugin.call("func_name", "my data").unwrap();
let output: MyType = serde_json::from_slice(&output).unwrap();
```
We can now use richer types to encode/decode our values directly when
using `call`:

```rust
let Json(output) = plugin.call::<_, Json<MyType>>("func_name", "my data").unwrap();
```

### Allocating inside of a host function

The same interface works for host functions, so instead of:

```rust
fn hello_world(
    plugin: &mut CurrentPlugin,
    inputs: &[Val],
    outputs: &mut [Val],
    _user_data: UserData,
) -> Result<(), Error> {
    let handle = plugin.memory_handle_val(&inputs[0])?;
    let input = plugin.memory_read_str(handle)?;
    let output = plugin.memory_alloc_bytes(&input).unwrap();
    outputs[0] = output.into();
    Ok(())
}
```

Becomes:

```rust
fn hello_world(
    plugin: &mut CurrentPlugin,
    inputs: &[Val],
    outputs: &mut [Val],
    _user_data: UserData,
) -> Result<(), Error> {
    let my_value: String = plugin.memory_get_val(&inputs[0])?;
    let output = plugin.memory_new(&my_value)?;
    outputs[0] = plugin.memory_to_val(output);
    Ok(())
}
```

Although this isn't much of an improvement, using the `host_fn` macro,
we can really begin to see how the above function is really just an
identity function:
```rust
host_fn!(hello_world(a: String) -> String {
    a
});
```

### typed_plugin!

`typed_plugin!` is used to make a typed wrapper around a Plugin:

```rust
/// Create the typed plugin
typed_plugin!(Testing {
    count_vowels(&str) -> Json<Count>
});

/// Create the `Plugin` and convert it to `Testing` wrapper
let mut plugin: Testing = Plugin::new(WASM, [f], true).unwrap().into();

/// Call the `count_vowels` function:
let Json(output0): Json<Count> = plugin.count_vowels("abc123")?;
```

It could make sense to convert `host_fn` and/or `typed_plugin` to
proc-macros at some point, but for now they work and provide some
flexibility in experimenting with the interfaces. Another future update
could be to figure out a nice way to make it so input can be written in
multiple chunks, so the entire input doesn't have to get copied into
memory at once.
2023-09-14 12:32:38 -07:00
Chris Dickinson
3ca661546d fix: toml manifests load the extism runtime (#447)
Just getting my feet wet with the codebase a little bit! I noticed that
TOML manifests weren't loading the extism runtime by default while doing
a walkthrough. This commit ensures the runtime is loaded and adds a
test.

Also, fix a tiny typo in a comment.
2023-09-05 16:36:16 -07:00
zach
ddcbeec3de refactor!: Remove context, unify extism-runtime and extism crates (#421)
- Removes the `ExtismContext` type from runtime and all SDKs
- Removed SDK functions: `extism_context_new`, `extism_context_reset`,
`extism_context_free`
  - All SDKs have been updated, but there are still some TODOs below 
- Removes `extism_plugin_update`
- Plugins can no longer be updated - a new plugin should be created
instead
- Adds `extism_plugin_id` to uniquely identify plugins
- Merges the `extism-runtime` and `extism` crates (there is no longer an
`extism-runtime` crate)
- Makes `extism::Manifest` an alias for `extism_manifest::Manifest`
instead of a distinct type
- Adds `MemoryHandle` type to SDKs to refer to blocks of Extism memory
that can be accessed in host functions
- Improves thread-safety of Plugins, adds C++ test to call a single
plugin from multiple threads.
- Expands wasmtime bounds to include 12.0
2023-08-29 13:57:17 -07:00
zach
b6f2e845d9 fix(runtime): register all host function imports (#419)
Fixes #417
2023-08-15 10:02:30 -07:00
zach
d80584600b refactor: Simplify runtime handling (#411)
It seems like our runtime initialization process is a little too
aggressive, this PR scales it back to initialize the runtime once if it
exists and only reinitializes when `_start` is called. This prevents
globals from being wiped out between plugin calls.

- Removes Runtime::cleanup
- Only initializes runtime once, or if `_start` is called
- Improves Haskell reactor support

See https://github.com/extism/go-sdk/pull/11 for the go-sdk PR.
2023-08-08 14:12:09 -07:00
zach
07623ef2da fix: avoid timeout errors outside of extism_plugin_call (#407)
- Delays instantiation to right before a call by using `instantiate_pre`
instead. This fixes an issue with the assemblyscript PDK.
- Makes timeouts only apply to calls
- Also bumps the wasmtime lower-bounds to 10.0, because the return type
of the epoch callback has changed
2023-08-04 13:44:24 -07:00
zach
3da526286e feat: Implement parts of the extism runtime in WebAssembly (#384)
This PR adds the `kernel` directory which contains a port of the Extism
memory allocator compiled to WebAssembly and removes
`runtime/src/memory.rs` completely.

Being able to re-use memory functions as a WASM module allows us to
begin to experiment with porting Extism to new runtimes!

This is in a draft state while I'm verifying some of these changes.
2023-07-27 11:31:23 -07:00
zach
360df45e1a fix: require modules to have exported, bounded memory when manifest memory.max_pages field is set (#356)
- Requires modules compiled to run with manifests that set `max_memory`
to have an exported memory with lower and upper bounds
- Includes the size of memory exported from modules when calculating
available memory for plugins

## How to compile a module with bounded memory 

You will need to pass `--max-memory=$NUM_BYTES` to wasm-ld. `$NUM_BYTES`
must be a multiple of the page size. Here are some examples for
supported PDK languages:

**C** 
Pass `-Wl,--max-memory=65536` to your C compiler

**Rust**: 
In a `.cargo/config` file:
```toml
[target.wasm32-unknown-unknown]
rustflags = ["-Clink-args=--max-memory=65536"]
 ```
**Haskell**
Add the following to the cabal file entry for your `cabal.project` file:

```
package myproject
  ghc-options:
    -optl -Wl,--max-memory=65536
```
**AssemblyScript**
Pass `--maximumMemory 65536` to the assemblyscropt compiler

**TinyGo**:
Create a `target.json` file:
```json
{
    "inherits": [ "wasm" ],
    "ldflags": [
        "--max-memory=65536",
    ]
}
```
and build using `tinygo -target ./target.json`
2023-06-01 09:37:42 -07:00
zach
0c70be285d feat: add EXTISM_PROFILE environment variable to configure profiling (#326)
This could also be extended to support other wasmtime-based profiling
methods, for now just `perf` is supported.

Co-authored-by: zach <zach@dylib.so>
2023-05-18 10:39:23 -05:00
zach
0f8954c203 feat!: add ability to create plugins without an existing Context (#335)
EIP: https://github.com/extism/proposals/pull/8

This PR makes minor breaking changes to several SDKs, but not to runtime
C API. The threadsafety updates in the Rust SDK are kind of specific to
Rust, I'm not sure if it makes sense to add the locks to all the other
SDKs at this point. For the most part the `Context` and `Plugin` types
in the SDKs should be safe to use protected by a mutex but they aren't
inherently threadsafe. That kind of locking should probably be done by
the user.

- Runtime 
  - improve thread safety
  - reinstantiates less
- fixes a potential resource exhaustion bug from re-instantiating using
the same store too many times
- Rust SDK
  - adds `Send` and `Sync` implementations for `Context`
  - adds test sharing a context between threads
- adds `Plugin::call_map` to call a plugin and handle the output with
the lock held
  - adds testing sharing an `Arc<Mutex<Plugin>>` between threads
- adds `Plugin::create` and `Plugin::create_from_manifest` to create a
plugin without a `Context`
- Python
  - BREAKING
- changes `Plugin` constructor to take `context` as an optional named
argument, to update use `Plugin(data, context=context)` instead
 - Ruby
   - BREAKING
- changes `Plugin` constructor to take `context` as an optional named
argument, to update use `Plugin.new(data, context=context)` instead
 - Go
   - adds `NewPlugin` and `NewPluginFromManifest` functions
 - Node
   - BREAKING
- changes `Plugin` constructor to take `context` as an optional named
argument, to update use `new Plugin(data, wasi, config, host, context)`
instead of `new Plugin(context, data, wasi, functions, config)` (most
people are probably using `context.plugin` instead of the Plugin
constructor anyway)
 - OCaml
   - BREAKING
- changes `Plugin.create` and `Plugin.of_manifest` to take `context` as
an optional named argument, to update `Plugin.create ~context data` and
`Plugin.of_manifest ~context data` instead
- Haskell
  - adds `createPlugin` and `createPluginFromManifest` functions
 - Elixir
- adds `Plugin.new` to make a plugin without going through
`Context.new_plugin`
 - Java
   - adds new `Plugin` constructors without a `Context` argument
- C++
  - BREAKING
- Updates `Plugin` constructor to take an optional context as the last
argument, instead of requiring it to be the first argument
- Use `Plugin(wasm, wasi, functions, ctx)` instead of `Plugin(ctx, wasm,
wasi, functions)`
 - Zig
- Adds `Plugin.create` and `Plugin.createWithManifest` to create plugins
in their own context.

---------

Co-authored-by: zach <zach@dylib.so>
Co-authored-by: Benjamin Eckel <bhelx@simst.im>
2023-05-17 11:35:16 -07:00
zach
b2e0884442 feat: automatically call __wasm_call_ctors when available and not calling _start (#311) 2023-04-24 14:27:28 -07:00
zach
94d5bd98c8 feat: Add plugin cancellation (#270)
This PR adds the ability to cancel running plugins from another thread
in the host.

- All SDKs have been updated except  .NET
- Adds a new SDK type: `ExtismCancelHandle`
- Adds 2 new SDK functions: `extism_plugin_cancel_handle` and
`extism_plugin_cancel`
- `extism_plugin_cancel_handle` returns a pointer to
`ExtismCancelHandle`, which can be passed to `extism_plugin_cancel` to
stop plugin execution.
- One thing that's worth noting is when plugin is executing a host
function it cannot be cancelled until after the host function returns.

---------

Co-authored-by: Etienne ANNE <etienne.anne@icloud.com>
2023-03-08 17:44:40 -08:00
Steve Manuel
581e9cea99 chore: update wasmtime to 6.0, bump extism versions (#247)
Unsure if now is the best time to do the `extism` crate version bumps,
but I figured they'd need to happen at some point in the near future
anyways. Happy to revert if there is any opposition. Also, I added back
the local `path` property to the Elixir NIF crate manifest. I want to
see if this breaks again in CI, or if we can leave it.

---------

Co-authored-by: zach <zach@dylib.so>
2023-03-01 15:24:37 -08:00
zach
a44124bdb0 feat: add ability to set host function namespace (#246)
- Adds `extism_function_set_namespace` to SDK
- Updates SDKs with host function support to allow setting the namespace
for a function
2023-02-01 11:04:15 -08:00
zach
a1f36c58d2 cleanup: use debug logging instead of info in runtime, fix C example (#214) 2023-01-15 17:16:29 -08:00
zach
dc3d54e260 feat: Add C API for host functions + support for C++, Python, Go, Node, OCaml (#195)
- New types:
  - `ExtismValType` - Enum of WebAssembly types
  - `ExtismValUnion` - A union of the possible WebAssembly types
  - `ExtismVal` - A struct with `ExtismValType` and `ExtismValUnion`
  - `ExtismFunction` - The host function wrapper type
  - `ExtismFunctionType` - The type of the host function callback
- `ExtismCurrentPlugin` - Provides access to the currently running
plugin from inside a host function

- New functions:
  - `extism_function_new` - Create a new `ExtismFunction`
  - `extism_function_free` - Free an `ExtismFunction`
- `extism_current_plugin_memory`, `extism_current_plugin_memory_alloc`,
`extism_current_plugin_memory_free`,
`extism_current_plugin_memory_length` - Manage plugin memory from inside
a host functions

- Updated functions
- `extism_plugin_new` and `extsim_plugin_update` - now accept two extra
parameters for `ExtismFunction*` array and length of that array

## Notes

- Host functions take a user-data argument, which is owned by the
resulting `ExtismFunction` and will be cleaned up when
`extism_function_free` is called (if a cleanup function was passed in
with the user data)
- Host functions in every SDK require working with `ExtismVal` arguments
directly, this is pretty low-level for what is kind of a high-level
feature. We could work on adding some types to the SDKs that make
working with pointers to plugin data more accessible, maybe something
similar to how the Rust PDK handes input/output data.
- In each language the host functions more-or-less share a signature:
`(CurrentPlugin plugin, Val inputs[], Val outputs[], userData)`
- C, C++, OCaml and Go take a single userData argument but Python and
Node take a "rest" argument which allows passing any number of user-data
values
- Go requires the host function to be exported:
f9eb5ed839/go/main.go (L13-L26)
- Zig and Ruby should be relatively simple to add host functions to next
but I haven't really looked into Elixir, .NET or Java yet.
- Also closes #20
2023-01-10 12:04:40 -08:00
zach
9a6b4997dc feat: add EXTISM_DEBUG env variable to enable debug info (#201) 2023-01-06 14:06:11 -08:00
zach
8c2255eafa chore: update to wasmtime 4.0.0 (#181) 2022-12-22 10:43:49 -08:00
zach
34b5942dd5 fix: use timeouts for language-specific runtime initialization/finalization calls (#169)
After adding the timer code plugins written in Haskell fail with a
timeout when trying to call `hs_init` - this PR fixes the runtime
initialization and updates those functions to respect the configured
timeout.
2022-12-15 16:43:19 -08:00
zach
0c4b985ed7 feat: Add option to set timeout for plugin (#163)
- Adds `Manifest::timeout_ms` field to specify the plugin timeout in
milliseconds
- Sets a 30 second default timeout

Co-authored-by: Steve Manuel <steve@dylib.so>
2022-12-13 15:58:52 -08:00