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>
This commit is contained in:
zach
2023-10-30 11:43:40 -07:00
committed by GitHub
parent fab44c5db8
commit f3447a538c
45 changed files with 133 additions and 267 deletions

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-node.yml
- manifest/**
- runtime/**
- libextism/**
- browser/**
workflow_dispatch:
name: Browser CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-cpp.yml
- manifest/**
- runtime/**
- libextism/**
- cpp/**
workflow_dispatch:
name: C++ CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-d.yml
- manifest/**
- runtime/**
- libextism/**
- d/**
workflow_dispatch:
name: D CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-dotnet.yml
- manifest/**
- runtime/**
- libextism/**
- dotnet/**
workflow_dispatch:
name: .NET CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-elixir.yml
- manifest/**
- runtime/**
- rust/**
- elixir/**
workflow_dispatch:
name: Elixir CI

View File

@@ -1,16 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-go.yml
- manifest/**
- runtime/**
- libextism/**
- extism.go
- extism_test.go
- go.mod
- libextism.pc
- go/**
workflow_dispatch:
name: Go CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-haskell.yml
- manifest/**
- runtime/**
- libextism/**
- haskell/**
workflow_dispatch:
name: Haskell CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-java.yml
- manifest/**
- runtime/**
- libextism/**
- java/**
workflow_dispatch:
name: Java CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-node.yml
- manifest/**
- runtime/**
- libextism/**
- node/**
workflow_dispatch:
name: Node CI

View File

@@ -1,14 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-ocaml.yml
- manifest/**
- runtime/**
- libextism/**
- ocaml/**
- dune-project
- extism.opam
workflow_dispatch:
name: OCaml CI

View File

@@ -1,14 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-php.yml
- manifest/**
- runtime/**
- libextism/**
- php/**
- composer.json
- composer.lock
workflow_dispatch:
name: PHP CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-python.yml
- manifest/**
- runtime/**
- libextism/**
- python/**
workflow_dispatch:
name: Python CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-ruby.yml
- manifest/**
- runtime/**
- libextism/**
- ruby/**
workflow_dispatch:
name: Ruby CI

View File

@@ -1,12 +1,4 @@
on:
pull_request:
paths:
- .github/actions/extism/**
- .github/workflows/ci-zig.yml
- manifest/**
- runtime/**
- libextism/**
- zig/**
workflow_dispatch:
name: Zig CI

2
.gitignore vendored
View File

@@ -44,3 +44,5 @@ java/*.log
java/.idea
java/.DS_Store
extism-maturin/src/extism.h
runtime/*.log
libextism/example

Binary file not shown.

View File

@@ -1,11 +1,2 @@
.PHONY: build
build:
$(CC) -g -o main main.c -lextism -L .
.PHONY: static
static:
$(CC) -g -o main main.c -l:libextism.a -lm -L .
.PHONY: clean
clean:
rm -f main
clang -g -o main main.c -lextism -L .

View File

@@ -111,7 +111,7 @@ impl<'a, T: prost::Message> ToBytes<'a> for Protobuf<T> {
}
#[cfg(feature = "protobuf")]
impl<'a, T: Default + prost::Message> FromBytesOwned for Protobuf<T> {
impl<T: Default + prost::Message> FromBytesOwned for Protobuf<T> {
fn from_bytes_owned(data: &[u8]) -> Result<Self, Error> {
Ok(Protobuf(T::decode(data)?))
}

View File

@@ -33,7 +33,7 @@ impl<'a, T: FromBytesOwned> FromBytes<'a> for T {
}
}
impl<'a> FromBytesOwned for Box<[u8]> {
impl FromBytesOwned for Box<[u8]> {
fn from_bytes_owned(data: &[u8]) -> Result<Self, Error> {
Ok(data.to_vec().into_boxed_slice())
}

View File

@@ -1,5 +1,3 @@
# Elixir Host SDK
This contains the `0.x` version of the SDK. Development of this library has moved to [this repo](https://github.com/extism/elixir-sdk#readme).

View File

@@ -1,6 +1,6 @@
%{
"earmark_parser": {:hex, :earmark_parser, "1.4.37", "2ad73550e27c8946648b06905a57e4d454e4d7229c2dafa72a0348c99d8be5f7", [:mix], [], "hexpm", "6b19783f2802f039806f375610faa22da130b8edc21209d0bff47918bb48360e"},
"ex_doc": {:hex, :ex_doc, "0.30.9", "d691453495c47434c0f2052b08dd91cc32bc4e1a218f86884563448ee2502dd2", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "d7aaaf21e95dc5cddabf89063327e96867d00013963eadf2c6ad135506a8bc10"},
"ex_doc": {:hex, :ex_doc, "0.30.7", "dc7247091aec738ab781f71cbebfc07979d1040c98c7ee67dbde99b7829b743d", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "868ff1c7a44c462741853840d1e7ef19a07906e7467cb8da070c158ea6a42a51"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"json": {:hex, :json, "1.4.1", "8648f04a9439765ad449bc56a3ff7d8b11dd44ff08ffcdefc4329f7c93843dfa", [:mix], [], "hexpm", "9abf218dbe4ea4fcb875e087d5f904ef263d012ee5ed21d46e9dbca63f053d16"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},

View File

@@ -1,4 +1,3 @@
# Java Host SDK
This contains the `0.x` version of the SDK. Development of this library has moved to [this repo](https://github.com/extism/java-sdk#readme).

Binary file not shown.

View File

@@ -4,7 +4,6 @@
//! - An allocator for managing that memory
//! - Input/output handling
//! - Error message handling
//! - Backward compatible `extism_*` functions
//!
//! ## Allocator
//!
@@ -17,14 +16,14 @@
//! ## Input/Output
//!
//! Input and output are just allocated blocks of memory that are marked as either input or output using
//! the `extism_input_set` or `extism_output_set` functions. The MemoryRoot field `input_offset` contains
//! the `input_set` or `output_set` functions. The MemoryRoot field `input_offset` contains
//! the offset in memory to the input data and `input_length` contains the size of the input data. `output_offset`
//! and `output_length` are used for the output data.
//!
//! ## Error handling
//!
//! The `error` field is used to track the current error message. If it is set to `0` then there is no error.
//! The length of the error message can be retreived using `extism_length`.
//! The length of the error message can be retreived using `length`.
//!
//! ## Memory offsets
//! An offset of `0` is similar to a `NULL` pointer in C - it implies an allocation failure or memory error
@@ -140,10 +139,8 @@ impl MemoryRoot {
}
// Ensure that at least one page is allocated to store the `MemoryRoot` data
if core::arch::wasm32::memory_size(0) == 0 {
if core::arch::wasm32::memory_grow(0, 1) == usize::MAX {
core::arch::wasm32::unreachable()
}
if core::arch::wasm32::memory_size(0) == 0 && core::arch::wasm32::memory_grow(0, 1) == usize::MAX {
core::arch::wasm32::unreachable()
}
root.input_offset = 0;
@@ -331,7 +328,7 @@ impl MemoryBlock {
/// Allocate a block of memory and return the offset
#[no_mangle]
pub unsafe fn extism_alloc(n: Length) -> Pointer {
pub unsafe fn alloc(n: Length) -> Pointer {
if n == 0 {
return 0;
}
@@ -345,7 +342,7 @@ pub unsafe fn extism_alloc(n: Length) -> Pointer {
/// Free allocated memory
#[no_mangle]
pub unsafe fn extism_free(p: Pointer) {
pub unsafe fn free(p: Pointer) {
if p == 0 {
return;
}
@@ -364,7 +361,7 @@ pub unsafe fn extism_free(p: Pointer) {
/// Get the length of an allocated memory block
#[no_mangle]
pub unsafe fn extism_length(p: Pointer) -> Length {
pub unsafe fn length(p: Pointer) -> Length {
if p == 0 {
return 0;
}
@@ -377,7 +374,7 @@ pub unsafe fn extism_length(p: Pointer) -> Length {
/// Load a byte from Extism-managed memory
#[no_mangle]
pub unsafe fn extism_load_u8(p: Pointer) -> u8 {
pub unsafe fn load_u8(p: Pointer) -> u8 {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p) {
return 0;
@@ -387,7 +384,7 @@ pub unsafe fn extism_load_u8(p: Pointer) -> u8 {
/// Load a u64 from Extism-managed memory
#[no_mangle]
pub unsafe fn extism_load_u64(p: Pointer) -> u64 {
pub unsafe fn load_u64(p: Pointer) -> u64 {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p + core::mem::size_of::<u64>() as u64 - 1) {
return 0;
@@ -397,7 +394,7 @@ pub unsafe fn extism_load_u64(p: Pointer) -> u64 {
/// Load a byte from the input data
#[no_mangle]
pub unsafe fn extism_input_load_u8(p: Pointer) -> u8 {
pub unsafe fn input_load_u8(p: Pointer) -> u8 {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
if p >= root.input_length {
@@ -408,7 +405,7 @@ pub unsafe fn extism_input_load_u8(p: Pointer) -> u8 {
/// Load a u64 from the input data
#[no_mangle]
pub unsafe fn extism_input_load_u64(p: Pointer) -> u64 {
pub unsafe fn input_load_u64(p: Pointer) -> u64 {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
if p + core::mem::size_of::<u64>() as Pointer > root.input_length {
@@ -419,7 +416,7 @@ pub unsafe fn extism_input_load_u64(p: Pointer) -> u64 {
/// Write a byte in Extism-managed memory
#[no_mangle]
pub unsafe fn extism_store_u8(p: Pointer, x: u8) {
pub unsafe fn store_u8(p: Pointer, x: u8) {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p) {
return;
@@ -429,7 +426,7 @@ pub unsafe fn extism_store_u8(p: Pointer, x: u8) {
/// Write a u64 in Extism-managed memory
#[no_mangle]
pub unsafe fn extism_store_u64(p: Pointer, x: u64) {
pub unsafe fn store_u64(p: Pointer, x: u64) {
#[cfg(feature = "bounds-checking")]
if !MemoryRoot::pointer_in_bounds_fast(p + core::mem::size_of::<u64>() as u64 - 1) {
return;
@@ -439,7 +436,7 @@ pub unsafe fn extism_store_u64(p: Pointer, x: u64) {
/// Set the range of the input data in memory
#[no_mangle]
pub unsafe fn extism_input_set(p: Pointer, len: Length) {
pub unsafe fn input_set(p: Pointer, len: Length) {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
{
@@ -453,7 +450,7 @@ pub unsafe fn extism_input_set(p: Pointer, len: Length) {
/// Set the range of the output data in memory
#[no_mangle]
pub unsafe fn extism_output_set(p: Pointer, len: Length) {
pub unsafe fn output_set(p: Pointer, len: Length) {
let root = MemoryRoot::new();
#[cfg(feature = "bounds-checking")]
{
@@ -467,37 +464,37 @@ pub unsafe fn extism_output_set(p: Pointer, len: Length) {
/// Get the input length
#[no_mangle]
pub fn extism_input_length() -> Length {
pub fn input_length() -> Length {
unsafe { MemoryRoot::new().input_length }
}
/// Get the input offset in Exitsm-managed memory
#[no_mangle]
pub fn extism_input_offset() -> Length {
pub fn input_offset() -> Length {
unsafe { MemoryRoot::new().input_offset }
}
/// Get the output length
#[no_mangle]
pub unsafe fn extism_output_length() -> Length {
pub fn output_length() -> Length {
unsafe { MemoryRoot::new().output_length }
}
/// Get the output offset in Extism-managed memory
#[no_mangle]
pub unsafe fn extism_output_offset() -> Length {
pub unsafe fn output_offset() -> Length {
MemoryRoot::new().output_offset
}
/// Reset the allocator
#[no_mangle]
pub unsafe fn extism_reset() {
pub unsafe fn reset() {
MemoryRoot::new().reset()
}
/// Set the error message offset
#[no_mangle]
pub unsafe fn extism_error_set(ptr: Pointer) {
pub unsafe fn error_set(ptr: Pointer) {
let root = MemoryRoot::new();
// Allow ERROR to be set to 0
@@ -515,12 +512,12 @@ pub unsafe fn extism_error_set(ptr: Pointer) {
/// Get the error message offset, if it's `0` then no error has been set
#[no_mangle]
pub unsafe fn extism_error_get() -> Pointer {
pub unsafe fn error_get() -> Pointer {
MemoryRoot::new().error.load(Ordering::SeqCst)
}
/// Get the position of the allocator, this can be used as an indication of how many bytes are currently in-use
#[no_mangle]
pub unsafe fn extism_memory_bytes() -> Length {
MemoryRoot::new().position.load(Ordering::Acquire)
pub unsafe fn memory_bytes() -> Length {
MemoryRoot::new().length.load(Ordering::Acquire)
}

11
libextism/Makefile Normal file
View File

@@ -0,0 +1,11 @@
.PHONY: build
build:
$(CC) -g -o example example.c -lextism
.PHONY: static
static:
$(CC) -g -o example example.c -l:libextism.a -lm
.PHONY: clean
clean:
rm -f main

View File

@@ -24,7 +24,7 @@ void hello_world(ExtismCurrentPlugin *plugin, const ExtismVal *inputs,
outputs[0].v.i64 = inputs[0].v.i64;
}
void free_data(void *x) { puts("FREE"); }
void free_data(void *x) { puts("Freeing userdata"); }
uint8_t *read_file(const char *filename, size_t *len) {
@@ -79,9 +79,7 @@ int main(int argc, char *argv[]) {
const uint8_t *output = extism_plugin_output_data(plugin);
write(STDOUT_FILENO, output, out_len);
write(STDOUT_FILENO, "\n", 1);
puts("Freeing plugin");
extism_plugin_free(plugin);
puts("Freeing function");
extism_function_free(f);
return 0;
}

View File

@@ -252,7 +252,7 @@ impl Manifest {
/// Set MemoryOptions::memory_max
pub fn with_memory_max(mut self, max: u32) -> Self {
self.memory.max_pages = Some(max);
return self;
self
}
/// Add a hostname to `allowed_hosts`

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,3 @@
# Python Host SDK
This contains the `0.x` version of the SDK. Development of this library has moved to [this repo](https://github.com/extism/python-sdk#readme).

View File

@@ -1,5 +1,6 @@
use criterion::{criterion_group, criterion_main, Criterion};
use extism::*;
use extism_convert::Json;
const COUNT_VOWELS: &[u8] = include_bytes!("../../wasm/code.wasm");
const REFLECT: &[u8] = include_bytes!("../../wasm/reflect.wasm");
@@ -8,7 +9,6 @@ host_fn!(hello_world (a: String) -> String { Ok(a) });
pub fn basic(c: &mut Criterion) {
let mut g = c.benchmark_group("basic");
g.sample_size(300);
g.measurement_time(std::time::Duration::from_secs(6));
g.bench_function("basic", |b| {
let data = "a".repeat(4096);
@@ -23,7 +23,6 @@ pub fn create_plugin(c: &mut Criterion) {
let mut g = c.benchmark_group("create");
g.noise_threshold(1.0);
g.significance_level(0.2);
g.sample_size(300);
g.bench_function("create_plugin", |b| {
b.iter(|| {
let _plugin = PluginBuilder::new_with_module(COUNT_VOWELS)
@@ -34,6 +33,10 @@ pub fn create_plugin(c: &mut Criterion) {
});
}
#[derive(Debug, serde::Deserialize, PartialEq)]
struct Count {
count: u32,
}
pub fn count_vowels(c: &mut Criterion) {
let mut g = c.benchmark_group("count_vowels");
g.sample_size(500);
@@ -45,8 +48,11 @@ pub fn count_vowels(c: &mut Criterion) {
g.bench_function("count_vowels(4096)", |b| {
b.iter(|| {
assert_eq!(
"{\"count\": 4096}",
plugin.call::<_, &str>("count_vowels", &data).unwrap()
Count { count: 4096 },
plugin
.call::<_, Json<Count>>("count_vowels", &data)
.unwrap()
.0
);
})
});

View File

@@ -125,7 +125,7 @@ impl CurrentPlugin {
pub fn memory_bytes(&mut self, handle: MemoryHandle) -> Result<&mut [u8], Error> {
let (linker, mut store) = self.linker_and_store();
let mem = linker
.get(&mut store, "env", "memory")
.get(&mut store, EXTISM_ENV_MODULE, "memory")
.unwrap()
.into_memory()
.unwrap();
@@ -145,7 +145,7 @@ impl CurrentPlugin {
}
let (linker, mut store) = self.linker_and_store();
let output = &mut [Val::I64(0)];
if let Some(f) = linker.get(&mut store, "env", "extism_alloc") {
if let Some(f) = linker.get(&mut store, EXTISM_ENV_MODULE, "alloc") {
f.into_func()
.unwrap()
.call(&mut store, &[Val::I64(n as i64)], output)?;
@@ -167,7 +167,7 @@ impl CurrentPlugin {
pub fn memory_free(&mut self, handle: MemoryHandle) -> Result<(), Error> {
let (linker, mut store) = self.linker_and_store();
linker
.get(&mut store, "env", "extism_free")
.get(&mut store, EXTISM_ENV_MODULE, "free")
.unwrap()
.into_func()
.unwrap()
@@ -179,7 +179,7 @@ impl CurrentPlugin {
let (linker, mut store) = self.linker_and_store();
let output = &mut [Val::I64(0)];
linker
.get(&mut store, "env", "extism_length")
.get(&mut store, EXTISM_ENV_MODULE, "length")
.unwrap()
.into_func()
.unwrap()
@@ -269,7 +269,9 @@ impl CurrentPlugin {
/// Get extism memory
pub(crate) fn memory(&mut self) -> Option<wasmtime::Memory> {
let (linker, mut store) = self.linker_and_store();
linker.get(&mut store, "env", "memory")?.into_memory()
linker
.get(&mut store, EXTISM_ENV_MODULE, "memory")?
.into_memory()
}
/// Get a `MemoryHandle` from a `Val` reference - this can be used to convert a host function's
@@ -296,7 +298,7 @@ impl CurrentPlugin {
pub fn clear_error(&mut self) {
trace!("CurrentPlugin::clear_error");
let (linker, mut store) = self.linker_and_store();
if let Some(f) = linker.get(&mut store, "env", "extism_error_set") {
if let Some(f) = linker.get(&mut store, EXTISM_ENV_MODULE, "error_set") {
f.into_func()
.unwrap()
.call(&mut store, &[Val::I64(0)], &mut [])
@@ -327,7 +329,7 @@ impl CurrentPlugin {
debug!("Set error: {:?}", s);
let handle = self.current_plugin_mut().memory_new(s)?;
let (linker, mut store) = self.linker_and_store();
if let Some(f) = linker.get(&mut store, "env", "extism_error_set") {
if let Some(f) = linker.get(&mut store, EXTISM_ENV_MODULE, "error_set") {
f.into_func().unwrap().call(
&mut store,
&[Val::I64(handle.offset() as i64)],
@@ -335,16 +337,16 @@ impl CurrentPlugin {
)?;
Ok((handle.offset(), s.len() as u64))
} else {
anyhow::bail!("extism_error_set not found");
anyhow::bail!("extism:host/env::error_set not found");
}
}
pub(crate) fn get_error_position(&mut self) -> (u64, u64) {
let (linker, mut store) = self.linker_and_store();
let output = &mut [Val::I64(0)];
if let Some(f) = linker.get(&mut store, "env", "extism_error_get") {
if let Some(f) = linker.get(&mut store, EXTISM_ENV_MODULE, "error_get") {
if let Err(e) = f.into_func().unwrap().call(&mut store, &[], output) {
error!("unable to call extism_error_get: {:?}", e);
error!("unable to call extism:host/env::error_get: {:?}", e);
return (0, 0);
}
};

Binary file not shown.

View File

@@ -22,7 +22,7 @@ pub use current_plugin::CurrentPlugin;
pub use extism_convert::{FromBytes, FromBytesOwned, ToBytes};
pub use extism_manifest::{Manifest, Wasm};
pub use function::{Function, UserData, Val, ValType};
pub use plugin::{CancelHandle, Plugin};
pub use plugin::{CancelHandle, Plugin, EXTISM_ENV_MODULE, EXTISM_USER_MODULE};
pub use plugin_builder::PluginBuilder;
pub(crate) use internal::{Internal, Wasi};

View File

@@ -16,7 +16,7 @@ fn hex(data: &[u8]) -> String {
#[allow(unused)]
fn cache_add_file(hash: &str, data: &[u8]) -> Result<(), Error> {
let cache_dir = std::env::temp_dir().join("exitsm-cache");
let cache_dir = std::env::temp_dir().join("extism-cache");
let _ = std::fs::create_dir(&cache_dir);
let file = cache_dir.join(hash);
if file.exists() {
@@ -27,7 +27,7 @@ fn cache_add_file(hash: &str, data: &[u8]) -> Result<(), Error> {
}
fn cache_get_file(hash: &str) -> Result<Option<Vec<u8>>, Error> {
let cache_dir = std::env::temp_dir().join("exitsm-cache");
let cache_dir = std::env::temp_dir().join("extism-cache");
let file = cache_dir.join(hash);
if file.exists() {
let r = std::fs::read(file)?;
@@ -172,20 +172,20 @@ pub(crate) fn load(
if let Ok(s) = std::str::from_utf8(data) {
if let Ok(t) = toml::from_str::<extism_manifest::Manifest>(s) {
let mut m = modules(&t, engine)?;
m.insert("env".to_string(), extism_module);
m.insert(EXTISM_ENV_MODULE.to_string(), extism_module);
return Ok((t, m));
}
}
let t = serde_json::from_slice::<extism_manifest::Manifest>(data)?;
let mut m = modules(&t, engine)?;
m.insert("env".to_string(), extism_module);
m.insert(EXTISM_ENV_MODULE.to_string(), extism_module);
return Ok((t, m));
}
let m = Module::new(engine, data)?;
let mut modules = BTreeMap::new();
modules.insert("env".to_string(), extism_module);
modules.insert(EXTISM_ENV_MODULE.to_string(), extism_module);
modules.insert("main".to_string(), m);
Ok((Default::default(), modules))
}

View File

@@ -2,6 +2,9 @@ use std::collections::BTreeMap;
use crate::*;
pub const EXTISM_ENV_MODULE: &str = "extism:host/env";
pub const EXTISM_USER_MODULE: &str = "extism:host/user";
#[derive(Default, Clone)]
pub(crate) struct Output {
pub(crate) offset: u64,
@@ -105,8 +108,6 @@ impl Internal for Plugin {
}
}
const EXPORT_MODULE_NAME: &str = "env";
fn profiling_strategy() -> ProfilingStrategy {
match std::env::var("EXTISM_PROFILE").as_deref() {
Ok("perf") => ProfilingStrategy::PerfMap,
@@ -198,52 +199,40 @@ impl Plugin {
(entry.0.as_str(), entry.1)
});
// Define PDK functions
macro_rules! define_funcs {
($m:expr, { $($name:ident($($args:expr),*) $(-> $($r:expr),*)?);* $(;)?}) => {
match $m {
$(
concat!("extism_", stringify!($name)) => {
let t = FuncType::new([$($args),*], [$($($r),*)?]);
linker.func_new(EXPORT_MODULE_NAME, concat!("extism_", stringify!($name)), t, pdk::$name)?;
continue
}
)*
_ => ()
}
};
}
// Add builtins
for (name, module) in modules.iter() {
if name != main_name {
linker.module(&mut store, name, module)?;
}
for import in module.imports() {
let module_name = import.module();
let name = import.name();
use wasmtime::ValType::*;
if module_name == EXPORT_MODULE_NAME {
define_funcs!(name, {
config_get(I64) -> I64;
var_get(I64) -> I64;
var_set(I64, I64);
http_request(I64, I64) -> I64;
http_status_code() -> I32;
log_warn(I64);
log_info(I64);
log_debug(I64);
log_error(I64);
});
}
}
}
let mut imports: Vec<_> = imports.into_iter().collect();
// Define PDK functions
macro_rules! add_funcs {
($($name:ident($($args:expr),*) $(-> $($r:expr),*)?);* $(;)?) => {
$(
let t = FuncType::new([$($args),*], [$($($r),*)?]);
linker.func_new(EXTISM_ENV_MODULE, stringify!($name), t, pdk::$name)?;
)*
};
}
// Add builtins
use wasmtime::ValType::*;
add_funcs!(
config_get(I64) -> I64;
var_get(I64) -> I64;
var_set(I64, I64);
http_request(I64, I64) -> I64;
http_status_code() -> I32;
log_warn(I64);
log_info(I64);
log_debug(I64);
log_error(I64);
);
for f in &mut imports {
let name = f.name().to_string();
let ns = f.namespace().unwrap_or(EXPORT_MODULE_NAME);
let ns = f.namespace().unwrap_or(EXTISM_USER_MODULE);
unsafe {
linker.func_new(ns, &name, f.ty().clone(), &*(f.f.as_ref() as *const _))?;
}
@@ -392,15 +381,18 @@ impl Plugin {
let bytes = unsafe { std::slice::from_raw_parts(input, len) };
trace!("Input size: {}", bytes.len());
if let Some(f) = self.linker.get(&mut self.store, "env", "extism_reset") {
if let Some(f) = self.linker.get(&mut self.store, EXTISM_ENV_MODULE, "reset") {
f.into_func().unwrap().call(&mut self.store, &[], &mut [])?;
} else {
error!("Call to extism_reset failed");
error!("Call to extism:host/env::reset failed");
}
let handle = self.current_plugin_mut().memory_new(bytes)?;
if let Some(f) = self.linker.get(&mut self.store, "env", "extism_input_set") {
if let Some(f) = self
.linker
.get(&mut self.store, EXTISM_ENV_MODULE, "input_set")
{
f.into_func().unwrap().call(
&mut self.store,
&[Val::I64(handle.offset() as i64), Val::I64(len as i64)],
@@ -508,14 +500,14 @@ impl Plugin {
let out_len = &mut [Val::I64(0)];
let mut store = &mut self.store;
self.linker
.get(&mut store, "env", "extism_output_offset")
.get(&mut store, EXTISM_ENV_MODULE, "output_offset")
.unwrap()
.into_func()
.unwrap()
.call(&mut store, &[], out)
.unwrap();
self.linker
.get(&mut store, "env", "extism_output_length")
.get(&mut store, EXTISM_ENV_MODULE, "output_length")
.unwrap()
.into_func()
.unwrap()
@@ -635,16 +627,7 @@ impl Plugin {
}
match res {
Ok(()) => {
// If `results` is empty and the return value wasn't a WASI exit code then
// the call succeeded
if results.is_empty() {
return Ok(0);
}
// Return result to caller
Ok(0)
}
Ok(()) => Ok(0),
Err(e) => {
if let Some(coredump) = e.downcast_ref::<wasmtime::WasmCoreDump>() {
if let Some(file) = self.debug_options.coredump.clone() {
@@ -749,13 +732,13 @@ impl Plugin {
pub(crate) fn clear_error(&mut self) {
trace!("Clearing error on plugin {}", self.id);
let (linker, mut store) = self.linker_and_store();
if let Some(f) = linker.get(&mut store, "env", "extism_error_set") {
if let Some(f) = linker.get(&mut store, EXTISM_ENV_MODULE, "error_set") {
f.into_func()
.unwrap()
.call(&mut store, &[Val::I64(0)], &mut [])
.unwrap();
} else {
error!("Plugin::clear_error failed, extism_error_set not found")
error!("Plugin::clear_error failed, extism:host/env::error_set not found")
}
}

View File

@@ -5,7 +5,7 @@ const KERNEL: &[u8] = include_bytes!("../extism-runtime.wasm");
fn extism_alloc<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, n: u64) -> u64 {
let out_alloc = &mut [Val::I64(0)];
instance
.get_func(&mut store, "extism_alloc")
.get_func(&mut store, "alloc")
.unwrap()
.call(&mut store, &[Val::I64(n as i64)], out_alloc)
.unwrap();
@@ -15,7 +15,7 @@ fn extism_alloc<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance,
fn extism_length<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, p: u64) -> u64 {
let out = &mut [Val::I64(0)];
instance
.get_func(&mut store, "extism_length")
.get_func(&mut store, "length")
.unwrap()
.call(&mut store, &[Val::I64(p as i64)], out)
.unwrap();
@@ -25,7 +25,7 @@ fn extism_length<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance,
fn extism_load_u8<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, p: u64) -> u8 {
let out = &mut [Val::I32(0)];
instance
.get_func(&mut store, "extism_load_u8")
.get_func(&mut store, "load_u8")
.unwrap()
.call(&mut store, &[Val::I64(p as i64)], out)
.unwrap();
@@ -35,7 +35,7 @@ fn extism_load_u8<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance
fn extism_load_u64<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, p: u64) -> u64 {
let out = &mut [Val::I32(0)];
instance
.get_func(&mut store, "extism_load_u64")
.get_func(&mut store, "load_u64")
.unwrap()
.call(&mut store, &[Val::I64(p as i64)], out)
.unwrap();
@@ -49,7 +49,7 @@ fn extism_input_load_u8<T>(
) -> u8 {
let out = &mut [Val::I32(0)];
instance
.get_func(&mut store, "extism_input_load_u8")
.get_func(&mut store, "input_load_u8")
.unwrap()
.call(&mut store, &[Val::I64(p as i64)], out)
.unwrap();
@@ -63,7 +63,7 @@ fn extism_input_load_u64<T>(
) -> u64 {
let out = &mut [Val::I32(0)];
instance
.get_func(&mut store, "extism_input_load_u64")
.get_func(&mut store, "input_load_u64")
.unwrap()
.call(&mut store, &[Val::I64(p as i64)], out)
.unwrap();
@@ -72,7 +72,7 @@ fn extism_input_load_u64<T>(
fn extism_store_u8<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, p: u64, x: u8) {
instance
.get_func(&mut store, "extism_store_u8")
.get_func(&mut store, "store_u8")
.unwrap()
.call(
&mut store,
@@ -89,7 +89,7 @@ fn extism_store_u64<T>(
x: u64,
) {
instance
.get_func(&mut store, "extism_store_u64")
.get_func(&mut store, "store_u64")
.unwrap()
.call(
&mut store,
@@ -101,7 +101,7 @@ fn extism_store_u64<T>(
fn extism_free<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, p: u64) {
instance
.get_func(&mut store, "extism_free")
.get_func(&mut store, "free")
.unwrap()
.call(&mut store, &[Val::I64(p as i64)], &mut [])
.unwrap();
@@ -109,7 +109,7 @@ fn extism_free<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, p
fn extism_error_set<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance, p: u64) {
instance
.get_func(&mut store, "extism_error_set")
.get_func(&mut store, "error_set")
.unwrap()
.call(&mut store, &[Val::I64(p as i64)], &mut [])
.unwrap();
@@ -118,7 +118,7 @@ fn extism_error_set<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instan
fn extism_error_get<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance) -> u64 {
let out = &mut [Val::I64(0)];
instance
.get_func(&mut store, "extism_error_get")
.get_func(&mut store, "error_get")
.unwrap()
.call(&mut store, &[], out)
.unwrap();
@@ -128,7 +128,7 @@ fn extism_error_get<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instan
fn extism_reset<T>(mut store: &mut wasmtime::Store<T>, instance: &mut Instance) {
instance
.get_func(&mut store, "extism_reset")
.get_func(&mut store, "reset")
.unwrap()
.call(&mut store, &[], &mut [])
.unwrap();
@@ -141,7 +141,7 @@ fn extism_input_set<T>(
l: u64,
) {
instance
.get_func(&mut store, "extism_input_set")
.get_func(&mut store, "input_set")
.unwrap()
.call(
&mut store,

View File

@@ -47,7 +47,7 @@ fn it_works() {
UserData::default(),
hello_world,
)
.with_namespace("env");
.with_namespace(EXTISM_USER_MODULE);
let g = Function::new(
"hello_world",
[ValType::I64],
@@ -188,7 +188,7 @@ fn test_cancel() {
std::thread::sleep(std::time::Duration::from_secs(1));
assert!(handle.cancel().is_ok());
});
let _output: Result<&[u8], Error> = plugin.call("infinite_loop", "abc123");
let _output: Result<&[u8], Error> = plugin.call("loop_forever", "abc123");
let end = std::time::Instant::now();
let time = end - start;
println!("Cancelled plugin ran for {:?}", time);
@@ -210,14 +210,15 @@ fn test_timeout() {
let mut plugin = Plugin::new_with_manifest(&manifest, [f], true).unwrap();
let start = std::time::Instant::now();
let output: Result<&[u8], Error> = plugin.call("infinite_loop", "abc123");
let output: Result<&[u8], Error> = plugin.call("loop_forever", "abc123");
let end = std::time::Instant::now();
let time = end - start;
println!("Timed out plugin ran for {:?}", time);
let s = output.unwrap_err().root_cause().to_string();
println!("{}", s);
assert!(s == "timeout");
// std::io::stdout().write_all(output).unwrap();
let err = output.unwrap_err().root_cause().to_string();
println!(
"Timed out plugin ran for {:?}, with error: {:?}",
time, &err
);
assert!(err == "timeout");
}
typed_plugin!(TestTypedPluginGenerics {
@@ -400,7 +401,7 @@ fn test_extism_coredump() {
.with_coredump("extism.core")
.build()
.unwrap();
let output: Result<&[u8], Error> = plugin.call("infinite_loop", "abc123");
let output: Result<&[u8], Error> = plugin.call("loop_forever", "abc123");
assert!(output.is_err());
assert!(std::path::PathBuf::from("extism.core").exists());
let _ = std::fs::remove_file("extism.core");

View File

@@ -51,7 +51,6 @@ if __name__ == '__main__':
# Check for missing SDK functions
sdks = [
Lang('cpp', 'hpp'),
Lang('d', 'd'),
Lang('go', 'go', path='..'),
Lang('haskell', 'hs'),
Lang('node', 'ts'),

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.