Skip to content

Commit

Permalink
feat: compiled plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
G4Vi committed Nov 27, 2024
1 parent 999eb3b commit cee682e
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 27 deletions.
1 change: 1 addition & 0 deletions Extism/lib/Extism.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use 5.016;
use strict;
use warnings;
use Extism::XS qw(version log_file);
use Extism::CompiledPlugin;
use Extism::Plugin;
use Extism::Function ':all';
use Exporter 'import';
Expand Down
58 changes: 58 additions & 0 deletions Extism/lib/Extism/CompiledPlugin.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package Extism::CompiledPlugin;

use 5.016;
use strict;
use warnings;
use Carp qw(croak);
use Extism::XS qw(
compiled_plugin_new
compiled_plugin_free
);
use Exporter 'import';
use Data::Dumper qw(Dumper);
use Devel::Peek qw(Dump);
use version 0.77;
our $VERSION = qv(v0.2.0);

our @EXPORT_OK = qw(BuildPluginNewParams);

sub BuildPluginNewParams {
my ($wasm, $opt) = @_;
my $functions = $opt->{functions} // [];
my @rawfunctions = map {$$_} @{$functions};
my %p = (
wasm => $wasm,
_functions_array => pack('Q*', @rawfunctions)
);
$p{functions} = unpack('Q', pack('P', $p{_functions_array}));
$p{n_functions} = scalar(@rawfunctions);
$p{wasi} = $opt->{wasi} // 0;
$p{fuel_limit} = $opt->{fuel_limit};
$p{errptr} = "\x00" x 8;
$p{errmsg} = unpack('Q', pack('P', $p{errptr}));
\%p
}

sub new {
my ($name, $wasm, $options) = @_;
my %opt = %{$options // {}};
if (defined $opt{fuel_limit}) {
croak "No way to set fuel for CompiledPlugins yet";
}
my $p = BuildPluginNewParams($wasm, \%opt);
my $compiled = compiled_plugin_new($p->{wasm}, length($p->{wasm}), $p->{functions}, $p->{n_functions}, $p->{wasi}, $p->{errmsg});
my %savedoptions;
if ($opt{allow_http_response_headers}) {
$savedoptions{allow_http_response_headers} = $opt{allow_http_response_headers};
}
my %obj = ( compiled => $compiled, options => \%savedoptions);
bless \%obj, $name
}

sub DESTROY {
my ($self) = @_;
$self->{compiled} or return;
compiled_plugin_free($self->{compiled});
}

1;
42 changes: 16 additions & 26 deletions Extism/lib/Extism/Plugin.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use Carp qw(croak);
use Extism::XS qw(
plugin_new
plugin_new_with_fuel_limit
plugin_new_from_compiled
plugin_allow_http_response_headers
plugin_new_error_free
plugin_call
Expand All @@ -22,6 +23,7 @@ use Extism::XS qw(
);
use Extism::Plugin::CallException;
use Extism::Plugin::CancelHandle;
use Extism::CompiledPlugin qw(BuildPluginNewParams);
use Data::Dumper qw(Dumper);
use Devel::Peek qw(Dump);
use JSON::PP qw(encode_json);
Expand All @@ -31,38 +33,26 @@ our $VERSION = qv(v0.2.0);

sub new {
my ($name, $wasm, $options) = @_;
my $functions = [];
my $with_wasi = 0;
my $fuel_limit;
my $allow_http_response_headers;
if ($options) {
if (exists $options->{functions}) {
$functions = $options->{functions};
}
if (exists $options->{wasi}) {
$with_wasi = $options->{wasi};
}
if (exists $options->{fuel_limit}) {
$fuel_limit = $options->{fuel_limit};
}
if (exists $options->{allow_http_response_headers}) {
$allow_http_response_headers = $options->{allow_http_response_headers};
}
my ($plugin, $opt, $errptr);
if (!ref($wasm) || !$wasm->isa('Extism::CompiledPlugin')) {
$opt = defined $options ? {%$options} : {};
my $p = BuildPluginNewParams($wasm, $opt);
$plugin = ! defined $p->{fuel_limit}
? plugin_new($p->{wasm}, length($p->{wasm}), $p->{functions}, $p->{n_functions}, $p->{wasi}, $p->{errmsg})
: plugin_new_with_fuel_limit($p->{wasm}, length($p->{wasm}), $p->{functions}, $p->{n_functions}, $p->{wasi}, $p->{fuel_limit}, $p->{errmsg});
$errptr = $p->{errptr};
} else {
$opt = $wasm->{options};
$errptr = "\x00" x 8;
my $errmsg = unpack('Q', pack('P', $errptr));
$plugin = plugin_new_from_compiled($wasm->{compiled}, $errmsg);
}
my $errptr = "\x00" x 8;
my $errptrptr = unpack('Q', pack('P', $errptr));
my @rawfunctions = map {$$_} @{$functions};
my $functionsarray = pack('Q*', @rawfunctions);
my $functionsptr = unpack('Q', pack('P', $functionsarray));
my $plugin = ! defined $fuel_limit
? plugin_new($wasm, length($wasm), $functionsptr, scalar(@rawfunctions), $with_wasi, $errptrptr)
: plugin_new_with_fuel_limit($wasm, length($wasm), $functionsptr, scalar(@rawfunctions), $with_wasi, $fuel_limit, $errptrptr);
if (! $plugin) {
my $errmsg = unpack('p', $errptr);
plugin_new_error_free(unpack('Q', $errptr));
croak $errmsg;
}
if ($allow_http_response_headers) {
if ($opt->{allow_http_response_headers}) {
plugin_allow_http_response_headers($plugin);
}
bless \$plugin, $name
Expand Down
3 changes: 3 additions & 0 deletions Extism/lib/Extism/XS.pm
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ our @EXPORT_OK = qw(
log_file
log_custom
log_drain
compiled_plugin_new
compiled_plugin_free
plugin_new_from_compiled
CopyToPtr
);

Expand Down
30 changes: 30 additions & 0 deletions Extism/lib/Extism/XS.xs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ ExtismMemoryHandle T_UV
const ExtismCancelHandle * T_PTR
PV T_PV
uint64_t T_UV
ExtismCompiledPlugin * T_PTR
const ExtismCompiledPlugin * T_PTR
HERE

const char *
Expand All @@ -90,6 +92,34 @@ version()
OUTPUT:
RETVAL

ExtismCompiledPlugin *
compiled_plugin_new(wasm, wasm_size, functions, n_functions, with_wasi, errmsg)
const uint8_t *wasm
ExtismSize wasm_size
const ExtismFunction **functions
ExtismSize n_functions
bool with_wasi
char **errmsg
CODE:
RETVAL = extism_compiled_plugin_new(wasm, wasm_size, functions, n_functions, with_wasi, errmsg);
OUTPUT:
RETVAL

void
compiled_plugin_free(compiled_plugin)
ExtismCompiledPlugin *compiled_plugin
CODE:
extism_compiled_plugin_free(compiled_plugin);

ExtismPlugin *
plugin_new_from_compiled(compiled_plugin, errmsg)
const ExtismCompiledPlugin *compiled_plugin
char **errmsg
CODE:
RETVAL = extism_plugin_new_from_compiled(compiled_plugin, errmsg);
OUTPUT:
RETVAL

ExtismPlugin *
plugin_new(wasm, wasm_size, functions, n_functions, with_wasi, errmsg)
const uint8_t *wasm
Expand Down
19 changes: 18 additions & 1 deletion Extism/t/02-extism.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use Extism ':all';
use JSON::PP qw(encode_json decode_json);
use File::Temp qw(tempfile);
use Devel::Peek qw(Dump);
plan tests => 51;
plan tests => 54;

# ...
ok(Extism::version());
Expand Down Expand Up @@ -261,3 +261,20 @@ ok($@->{message});
my $plugin = Extism::Plugin->new($wasm, {wasi => 1, allow_http_response_headers => 1});
ok($plugin);
}

# compiled plugin
{
my $compiled = Extism::CompiledPlugin->new($wasm, {wasi => 1});
for (1..2) {
my $plugin = Extism::Plugin->new($compiled);
my $output = $plugin->call('count_vowels', "this is a test");
my $outputhash = decode_json($output);
ok($outputhash->{count} == 4);
}
}
{
eval {
Extism::CompiledPlugin->new($wasm, {wasi => 1, fuel_limit => 20});
};
ok($@);
}

0 comments on commit cee682e

Please sign in to comment.