Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: seperate pointer from handle #18

Merged
merged 5 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 43 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ int32_t EXTISM_EXPORTED_FUNCTION(greet) {

// Load input
static uint8_t inputData[Greet_Max_Input];
extism_load_input(inputData, inputLen);
extism_load_input(0, inputData, inputLen);

// Allocate a new offset used to store greeting and name
// Allocate memory to store greeting and name
const uint64_t greetingLen = sizeof(Greeting) - 1;
const uint64_t outputLen = greetingLen + inputLen;
ExtismPointer offs = extism_alloc(outputLen);
extism_store(offs, (const uint8_t *)Greeting, greetingLen);
extism_store(offs + greetingLen, inputData, inputLen);
ExtismHandle handle = extism_alloc(outputLen);
extism_store_to_handle(handle, 0, Greeting, greetingLen);
extism_store_to_handle(handle, greetingLen, inputData, inputLen);

// Set output
extism_output_set(offs, outputLen);
extism_output_set_from_handle(handle, 0, outputLen);
return 0;
}
```
Expand All @@ -71,7 +71,7 @@ command:

```bash
extism call plugin.wasm greet --input="Benjamin"
# => Hello, Benjamin!
# => Hello, Benjamin
```

### More Exports: Error Handling
Expand Down Expand Up @@ -101,26 +101,26 @@ int32_t EXTISM_EXPORTED_FUNCTION(greet) {

// Load input
static uint8_t inputData[Greet_Max_Input];
extism_load_input(inputData, inputLen);
extism_load_input(0, inputData, inputLen);
inputData[inputLen] = '\0';

// Check if the input matches "benjamin", if it does
// return an error
if (is_benjamin((const char *)inputData)) {
ExtismPointer err = extism_alloc_string("ERROR", 5);
ExtismHandle err = extism_alloc_buf_from_sz("ERROR");
extism_error_set(err);
return -1;
}

// Allocate a new offset used to store greeting and name
// Allocate memory to store greeting and name
const uint64_t greetingLen = sizeof(Greeting) - 1;
const uint64_t outputLen = greetingLen + inputLen;
ExtismPointer offs = extism_alloc(outputLen);
extism_store(offs, (const uint8_t *)Greeting, greetingLen);
extism_store(offs + greetingLen, inputData, inputLen);
ExtismHandle handle = extism_alloc(outputLen);
extism_store_to_handle(handle, 0, Greeting, greetingLen);
extism_store_to_handle(handle, greetingLen, inputData, inputLen);

// Set output
extism_output_set(offs, outputLen);
extism_output_set_from_handle(handle, 0, outputLen);
return 0;
}
```
Expand All @@ -135,7 +135,7 @@ extism call plugin.wasm greet --input="Benjamin" --wasi
echo $? # print last status code
# => 1
extism call plugin.wasm greet --input="Zach" --wasi
# => Hello, Zach!
# => Hello, Zach
echo $?
# => 0
```
Expand All @@ -155,12 +155,12 @@ plug-in. These can be useful to statically configure the plug-in with some data
static const char Greeting[] = "Hello, ";

int32_t EXTISM_EXPORTED_FUNCTION(greet) {
ExtismPointer key = extism_alloc_string("user", 4);
ExtismPointer value = extism_config_get(key);
ExtismHandle key = extism_alloc_buf_from_sz("user");
ExtismHandle value = extism_config_get(key);
extism_free(key);

if (value == 0) {
ExtismPointer err = extism_alloc_string("Invalid key", 11);
ExtismHandle err = extism_alloc_buf_from_sz("Invalid key");
extism_error_set(err);
return -1;
}
Expand All @@ -170,22 +170,22 @@ int32_t EXTISM_EXPORTED_FUNCTION(greet) {
// Load config value
uint8_t *valueData = malloc(valueLen);
if (valueData == NULL) {
ExtismPointer err = extism_alloc_string("OOM", 11);
ExtismHandle err = extism_alloc_buf_from_sz("OOM");
extism_error_set(err);
return -1;
}
extism_load(value, valueData, valueLen);
extism_load_from_handle(value, 0, valueData, valueLen);

// Allocate a new offset used to store greeting and name
// Allocate memory to store greeting and name
const uint64_t greetingLen = sizeof(Greeting) - 1;
const uint64_t outputLen = greetingLen + valueLen;
ExtismPointer offs = extism_alloc(outputLen);
extism_store(offs, (const uint8_t *)Greeting, greetingLen);
extism_store(offs + greetingLen, valueData, valueLen);
ExtismHandle handle = extism_alloc(outputLen);
extism_store_to_handle(handle, 0, Greeting, greetingLen);
extism_store_to_handle(handle, greetingLen, valueData, valueLen);
free(valueData);

// Set output
extism_output_set(offs, outputLen);
extism_output_set_from_handle(handle, 0, outputLen);
return 0;
}
```
Expand All @@ -195,7 +195,7 @@ To test it, the [Extism CLI](https://github.com/extism/cli) has a `--config` opt

```bash
extism call plugin.wasm greet --config user=Benjamin
# => Hello, Benjamin!
# => Hello, Benjamin
```

### Variables
Expand All @@ -211,12 +211,12 @@ You can use `extism_var_get`, and `extism_var_set` to manipulate vars:
#include <stdint.h>

int32_t EXTISM_EXPORTED_FUNCTION(count) {
ExtismPointer key = extism_alloc_string("count", 5);
ExtismPointer value = extism_var_get(key);
ExtismHandle key = extism_alloc_buf_from_sz("count");
ExtismHandle value = extism_var_get(key);

uint64_t count = 0;
if (value != 0) {
extism_load(value, (uint8_t *)&count, sizeof(uint64_t));
extism_load_from_handle(value, 0, &count, sizeof(uint64_t));
}
count += 1;

Expand All @@ -226,7 +226,7 @@ int32_t EXTISM_EXPORTED_FUNCTION(count) {
}

// Update the memory block
extism_store(value, (uint8_t *)&count, sizeof(uint64_t));
extism_store_to_handle(value, 0, &count, sizeof(uint64_t));

// Set the variable
extism_var_set(key, value);
Expand All @@ -250,12 +250,12 @@ The `extism_log*` functions can be used to emit logs:
#include <stdint.h>

int32_t EXTISM_EXPORTED_FUNCTION(log_stuff) {
ExtismPointer msg = extism_alloc_string("Hello!", 6);
ExtismHandle msg = extism_alloc_buf_from_sz("Hello!");
extism_log_info(msg);
extism_log_debug(msg);
extism_log_warn(msg);
extism_log_error(msg);
extism_log("Hello!", 6, ExtismLogInfo);
extism_log_sz("Hello!", ExtismLogInfo);
return 0;
}
```
Expand Down Expand Up @@ -288,14 +288,14 @@ int32_t EXTISM_EXPORTED_FUNCTION(call_http) {
\"url\": \"https://jsonplaceholder.typicode.com/todos/1\"\
}";

ExtismPointer req = extism_alloc_string(reqStr, strlen(reqStr));
ExtismPointer res = extism_http_request(req, 0);
ExtismHandle req = extism_alloc_buf_from_sz(reqStr);
ExtismHandle res = extism_http_request(req, 0);

if (extism_http_status_code() != 200) {
return -1;
}

extism_output_set(res, extism_length(res));
extism_output_set_from_handle(res, 0, extism_length(res));
return 0;
}
```
Expand All @@ -318,29 +318,29 @@ to do this correctly. So we recommend reading out [concept doc on Host Functions
Host functions have a similar interface as exports. You just need to declare them as `extern` on the top of your header file. You only declare the interface as it is the host's responsibility to provide the implementation:

```c
extern ExtismPointer a_python_func(ExtismPointer);
extern ExtismHandle a_python_func(ExtismHandle);
```

A namespace may be set for an import using the `IMPORT` macro in `extism-pdk.h`:

```c
IMPORT("my_module", "a_python_func") extern ExtismPointer a_python_func(ExtismPointer);
IMPORT("my_module", "a_python_func") extern ExtismHandle a_python_func(ExtismHandle);
```

> **Note**: The types we accept here are the same as the exports as the interface also uses the [convert crate](https://docs.rs/extism-convert/latest/extism_convert/).

To call this function, we pass an Extism pointer and receive one back:
To call this function, we pass an Extism handle and receive one back:

```c
#define EXTISM_IMPLEMENTATION
#include "extism-pdk.h"
#include <stdint.h>

int32_t EXTISM_EXPORTED_FUNCTION(hello_from_python) {
ExtismPointer arg = extism_alloc_string("Hello!", 6);
ExtismPointer res = a_python_func(arg);
ExtismHandle arg = extism_alloc_buf_from_sz("Hello!");
ExtismHandle res = a_python_func(arg);
extism_free(arg);
extism_output_set(res, extism_length(res));
extism_output_set_from_handle(res, 0, extism_length(res));
return 0;
}
```
Expand Down Expand Up @@ -407,6 +407,8 @@ All other source files using the pdk must include the header without `#define EX

The C PDK does not require building with `libc`, but additional functions can be enabled when `libc` is available. `#define EXTISM_USE_LIBC` in each file before including the pdk (everywhere it is included) or, when compiling, pass it as a flag to clang: `-D EXTISM_USE_LIBC`

The low-level API that operates on `ExtismPointer` is no longer included by default, `#define EXTISM_ENABLE_LOW_LEVEL_API` in each file before including the pdk (everywhere it is included) or, when compiling, pass it as a flag to clang: `-D EXTISM_ENABLE_LOW_LEVEL_API` . Updating to use the `ExtismHandle`-based API is highly recommended.

The C PDK may be used from C++, however, the implementation must be built with a C compiler. See `cplusplus` in `tests/Makefile` for an example.

## Exports (details)
Expand Down
7 changes: 4 additions & 3 deletions examples/count-vowels/count-vowels.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define EXTISM_ENABLE_LOW_LEVEL_API
#define EXTISM_IMPLEMENTATION
#include "../../extism-pdk.h"

Expand All @@ -19,9 +20,9 @@ int32_t EXTISM_EXPORTED_FUNCTION(count_vowels) {
char out[128];
int n = snprintf(out, 128, "{\"count\": %llu}", count);

uint64_t offs_ = extism_alloc(n);
extism_store(offs_, (const uint8_t *)out, n);
extism_output_set(offs_, n);
ExtismHandle buf = extism_alloc(n);
extism_store(buf, out, n);
extism_output_set(buf, n);

return 0;
}
6 changes: 3 additions & 3 deletions examples/globals/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ int32_t EXTISM_EXPORTED_FUNCTION(globals) {
char out[128];
int n = snprintf(out, 128, "{\"count\": %llu}", count);

uint64_t offs_ = extism_alloc(n);
extism_store(offs_, (const uint8_t *)out, n);
extism_output_set(offs_, n);
ExtismHandle buf = extism_alloc(n);
extism_store_to_handle(buf, 0, out, n);
extism_output_set_from_handle(buf, 0, n);

count += 1;

Expand Down
11 changes: 6 additions & 5 deletions examples/host-functions/host-functions.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#define EXTISM_ENABLE_LOW_LEVEL_API
#define EXTISM_IMPLEMENTATION
#include "../../extism-pdk.h"

#include <stdio.h>

EXTISM_IMPORT("extism:host/user", "hello_world")
extern uint64_t hello_world(uint64_t);
extern ExtismHandle hello_world(ExtismHandle);

int32_t EXTISM_EXPORTED_FUNCTION(count_vowels) {
uint64_t length = extism_input_length();
Expand All @@ -25,9 +26,9 @@ int32_t EXTISM_EXPORTED_FUNCTION(count_vowels) {

char out[128];
int n = snprintf(out, 128, "{\"count\": %lld}", count);
uint64_t offs_ = extism_alloc(n);
extism_store(offs_, (const uint8_t *)out, n);
offs_ = hello_world(offs_);
extism_output_set(offs_, extism_length(offs_));
ExtismHandle buf = extism_alloc(n);
extism_store_to_handle(buf, 0, out, n);
buf = hello_world(buf);
extism_output_set(buf, extism_length(buf));
return 0;
}
Loading
Loading