File Coverage

blib/lib/Wasm/Wasmtime/Instance.pm
Criterion Covered Total %
statement 46 48 95.8
branch 10 14 71.4
condition 4 6 66.6
subroutine 14 14 100.0
pod 2 2 100.0
total 76 84 90.4


line stmt bran cond sub pod time code
1             package Wasm::Wasmtime::Instance;
2              
3 15     15   3087 use strict;
  15         36  
  15         477  
4 15     15   175 use warnings;
  15         33  
  15         353  
5 15     15   465 use 5.008004;
  15         55  
6 15     15   93 use Wasm::Wasmtime::FFI;
  15         36  
  15         1672  
7 15     15   4780 use Wasm::Wasmtime::Module;
  15         45  
  15         541  
8 15     15   960 use Wasm::Wasmtime::Extern;
  15         121  
  15         426  
9 15     15   88 use Wasm::Wasmtime::Func;
  15         38  
  15         422  
10 15     15   94 use Wasm::Wasmtime::Trap;
  15         34  
  15         389  
11 15     15   7246 use Wasm::Wasmtime::Instance::Exports;
  15         41  
  15         567  
12 15     15   102 use Ref::Util qw( is_ref is_blessed_ref is_plain_coderef is_plain_scalarref );
  15         28  
  15         873  
13 15     15   87 use Carp ();
  15         220  
  15         11759  
14              
15             # ABSTRACT: Wasmtime instance class
16             our $VERSION = '0.21'; # VERSION
17              
18              
19             $ffi_prefix = 'wasm_instance_';
20             $ffi->load_custom_type('::PtrObject' => 'wasm_instance_t' => __PACKAGE__);
21              
22              
23             sub _cast_import
24             {
25 5     5   13 my($ii, $mi, $store, $keep) = @_;
26 5 50 66     60 if(ref($ii) eq 'Wasm::Wasmtime::Extern')
    100 66        
    100          
    50          
27             {
28 0         0 return $ii->{ptr};
29             }
30             elsif(is_blessed_ref($ii) && $ii->isa('Wasm::Wasmtime::Extern'))
31             {
32 2         13 return $ii->{ptr};
33             }
34             elsif(is_plain_coderef($ii))
35             {
36 1 50       5 if($mi->type->kind eq 'functype')
37             {
38 1         5 my $f = Wasm::Wasmtime::Func->new(
39             $store,
40             $mi->type,
41             $ii,
42             );
43 1         4 push @$keep, $f;
44 1         6 return $f->{ptr};
45             }
46             }
47             elsif(is_plain_scalarref($ii) || !defined $ii)
48             {
49 2 50       8 if($mi->type->kind eq 'memorytype')
50             {
51 2         7 my $m = Wasm::Wasmtime::Memory->new(
52             $store,
53             $mi->type,
54             );
55 2 100       115 $$ii = $m if defined $ii;
56 2         7 push @$keep, $m;
57 2         8 return $m->{ptr};
58             }
59             }
60 0         0 Carp::croak("Non-extern object as import");
61             }
62              
63             $ffi->attach( [ wasmtime_instance_new => 'new' ] => ['wasm_store_t','wasm_module_t','opaque[]','size_t','opaque*','opaque*'] => 'wasmtime_error_t' => sub {
64             my $xsub = shift;
65             my $class = shift;
66             my $module = shift;
67             my $store = is_blessed_ref($_[0]) && $_[0]->isa('Wasm::Wasmtime::Store')
68             ? shift
69             : Carp::croak('Creating a Wasm::Wasmtime::Instance instance without a Wasm::Wasmtime::Store object is no longer allowed');
70              
71             my $ptr;
72             my @keep;
73              
74             if(defined $_[0] && !is_ref($_[0]))
75             {
76             ($ptr) = @_;
77             return bless {
78             ptr => $ptr,
79             module => $module,
80             keep => \@keep,
81             }, $class;
82             }
83             else
84             {
85             my($imports) = @_;
86              
87             $imports ||= [];
88             Carp::confess("imports is not an array reference") unless ref($imports) eq 'ARRAY';
89             my @imports = @$imports;
90             my $trap;
91              
92             {
93             my @mi = @{ $module->imports };
94             if(@mi != @imports)
95             {
96             Carp::croak("Got @{[ scalar @imports ]} imports, but expected @{[ scalar @mi ]}");
97             }
98              
99             @imports = map { _cast_import($_, shift @mi, $store, \@keep) } @imports;
100             }
101              
102             my $ptr;
103             if(my $error = $xsub->($store, $module, \@imports, scalar(@imports), \$ptr, \$trap))
104             {
105             Carp::croak("error creating module: " . $error->message);
106             }
107             else
108             {
109             if($trap)
110             {
111             $trap = Wasm::Wasmtime::Trap->new($trap);
112             die $trap;
113             }
114             else
115             {
116             return bless {
117             ptr => $ptr,
118             module => $module,
119             keep => \@keep,
120             }, $class;
121             }
122             }
123             }
124              
125             });
126              
127              
128 31     31 1 1849 sub module { shift->{module} }
129              
130              
131             sub exports
132             {
133 29     29 1 13718 Wasm::Wasmtime::Instance::Exports->new(shift);
134             }
135              
136             $ffi->attach( [ exports => '_exports' ] => ['wasm_instance_t','wasm_extern_vec_t*'] => sub {
137             my($xsub, $self) = @_;
138             my $externs = Wasm::Wasmtime::ExternVec->new;
139             $xsub->($self, $externs);
140             $externs->to_list;
141             });
142              
143             _generate_destroy();
144              
145             1;
146              
147             __END__