Skip to content

Commit

Permalink
feat/fix: switch from returning undef on error to croaking exceptions…
Browse files Browse the repository at this point in the history
…, fix setting namespace when creating a function
  • Loading branch information
G4Vi committed Oct 23, 2024
1 parent a8686ce commit 8d63165
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 31 deletions.
5 changes: 2 additions & 3 deletions Extism/lib/Extism/Function.pm
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ sub new {
my $output_types_array = pack('L*', @outputs);
my $output_types_ptr = unpack('Q', pack('P', $output_types_array));
my $function = function_new($name, $input_types_ptr, scalar(@inputs), $output_types_ptr, scalar(@outputs), \%hostdata);
$function or return undef;
$function or croak("Failed to create function, is the name valid?");
my $functionref = bless \$function, $class;
defined $namespace and $functionref->($namespace);
defined $namespace and $functionref->set_namespace($namespace);
return $functionref;
}

Expand All @@ -88,7 +88,6 @@ sub set_namespace {
function_set_namespace($$self, $namespace);
}


sub load_raw_array {
my ($ptr, $elm_size, $n) = @_;
$n or return [];
Expand Down
12 changes: 5 additions & 7 deletions Extism/lib/Extism/Plugin.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package Extism::Plugin;
use 5.016;
use strict;
use warnings;
use Carp qw(croak);
use Extism::XS qw(
plugin_new
plugin_new_error_free
Expand All @@ -17,6 +18,7 @@ use Extism::XS qw(
plugin_config
plugin_cancel_handle
);
use Extism::Plugin::CallException;
use Extism::Plugin::CancelHandle;
use Data::Dumper qw(Dumper);
use Devel::Peek qw(Dump);
Expand Down Expand Up @@ -45,12 +47,9 @@ sub new {
if (! $plugin) {
my $errmsg = unpack('p', $errptr);
plugin_new_error_free(unpack('Q', $errptr));
return undef unless wantarray;
return (undef, $errmsg);
croak $errmsg;
}
my $pluginobj = \$plugin;
my $realplugin = bless $pluginobj, $name;
return $realplugin;
bless \$plugin, $name
}

# call PLUGIN,FUNCNAME,INPUT
Expand All @@ -68,8 +67,7 @@ sub call {
}
my $rc = plugin_call($$self, $func_name, $input, length($input));
if ($rc != 0) {
return undef unless wantarray;
return (undef, $rc, plugin_error($$self));
die Extism::Plugin::CallException->new($rc, plugin_error($$self));
}
my $output_size = plugin_output_length($$self);
my $output_ptr = plugin_output_data($$self);
Expand Down
19 changes: 19 additions & 0 deletions Extism/lib/Extism/Plugin/CallException.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package Extism::Plugin::CallException;

use 5.016;
use strict;
use warnings;
use version 0.77; our $VERSION = qv(v0.0.1);
use Carp qw(croak shortmess);
our @CARP_NOT = qw(Extism::Plugin);
use overload '""' => sub {
"$_[0]->{message}, code: $_[0]->{code} " . shortmess()
};

sub new {
my ($name, $rc, $message) = @_;
my %obj = (code => $rc, message => $message);
bless \%obj, $name
}

1; # End of Extism::Plugin::CallException
60 changes: 39 additions & 21 deletions 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 => 44;
plan tests => 45;

# ...
ok(Extism::version());
Expand All @@ -23,7 +23,10 @@ ok(Extism::version());
my $tempfunc = sub {
$log_text .= $_[0];
};
Extism::Plugin->new('');
eval {
Extism::Plugin->new('');
fail('Extism::Plugin->new("") should throw an exception');
};
Extism::log_drain($tempfunc);
$log_text or $rc = 1;
POSIX::_exit($rc);
Expand All @@ -33,16 +36,12 @@ ok(Extism::version());
}
}

# test failing plugin new in scalar and list context
{
# test failing plugin throws an exception
eval {
my $notplugin = Extism::Plugin->new('');
ok(!defined $notplugin);
}
{
my ($notplugin, $error) = Extism::Plugin->new('');
ok(!defined $notplugin);
ok($error);
}
fail('Extism::Plugin->new("") should throw an exception');
};
ok($@);

# test succeeding plugin new in scalar and list context
# also text various Plugin:: functions
Expand All @@ -65,7 +64,7 @@ my $wasm = do { local(@ARGV, $/) = 'count_vowels.wasm'; <> };
ok($plugin->reset());
}
{
my ($plugin, $error) = Extism::Plugin->new($wasm, {wasi => 1});
my $plugin = Extism::Plugin->new($wasm, {wasi => 1});
ok($plugin);
my ($output) = $plugin->call('count_vowels', "this is a test");
ok($output);
Expand All @@ -79,18 +78,31 @@ my $wasm = do { local(@ARGV, $/) = 'count_vowels.wasm'; <> };
Extism::log_file($filename, "error");
my $failwasm = do { local(@ARGV, $/) = 'fail.wasm'; <> };
my $failplugin = Extism::Plugin->new($failwasm, {wasi => 1});
my $failed = $failplugin->call('run_test', "");
ok(!$failed);
eval {
my $failed = $failplugin->call('run_test', "");
fail('calling run_test in failplugin should throw an exception');
};
ok($@);
my $rc = read($error_fh, my $filler, 1);
ok($rc == 1);
unlink($filename);
Extism::log_file("/dev/stdout", "error");
my ($res, $rca, $info) = $failplugin->call('run_test', "");
ok($rca == 1);
is($info, 'Some error message');
eval {
$failplugin->call('run_test', "");
fail('calling run_test in failplugin should throw an exception');
};
ok($@);
ok($@->{code} == 1);
is($@->{message}, 'Some error message');
}

# test basic host functions
eval {
my $badname = Extism::Function->new("\x{D800}", [], [], sub {});
fail('Function->new should throw an exception when an invalid name is passed');
};
ok($@);

my $voidfunction = Extism::Function->new("hello_void", [], [], sub {
print "hello_void\n";
return;
Expand All @@ -101,6 +113,9 @@ my $paramsfunction = Extism::Function->new("hello_params", [Extism_F64, Extism_I
return 18446744073709551615;
});
ok($paramsfunction);
my $withnamespace = Extism::Function->new("with_namespace", [], [], sub {
}, 'namespace');
ok($withnamespace);
my $hostwasm = do { local(@ARGV, $/) = 'host.wasm'; <> };
my $fplugin = Extism::Plugin->new($hostwasm, {functions => [$voidfunction, $paramsfunction], wasi => 1});
ok($fplugin);
Expand Down Expand Up @@ -191,7 +206,10 @@ my $unreachable = encode_json({
});
my $uplugin = Extism::Plugin->new($unreachable, {wasi => 1});
ok($uplugin);
my ($ures, $urc, $uinfo) = $uplugin->call('do_unreachable');
ok(!defined $ures);
ok($urc != 0);
ok($uinfo);
eval {
$uplugin->call('do_unreachable');
fail('calling do_unreachable should throw an exception');
};
ok($@);
ok($@->{code} != 0);
ok($@->{message});

0 comments on commit 8d63165

Please sign in to comment.