File Coverage

blib/lib/Wasm/Wasmtime/Module.pm
Criterion Covered Total %
statement 70 70 100.0
branch 11 12 91.6
condition n/a
subroutine 18 18 100.0
pod 4 4 100.0
total 103 104 99.0


line stmt bran cond sub pod time code
1             package Wasm::Wasmtime::Module;
2              
3 22     22   524499 use strict;
  22         80  
  22         759  
4 22     22   118 use warnings;
  22         63  
  22         545  
5 22     22   438 use 5.008004;
  22         88  
6 22     22   1256 use Ref::Util qw( is_blessed_ref );
  22         3598  
  22         1185  
7 22     22   1456 use Wasm::Wasmtime::FFI;
  22         74  
  22         2851  
8 22     22   3360 use Wasm::Wasmtime::Engine;
  22         64  
  22         701  
9 22     22   3287 use Wasm::Wasmtime::Store;
  22         74  
  22         730  
10 22     22   10476 use Wasm::Wasmtime::Module::Exports;
  22         81  
  22         795  
11 22     22   10137 use Wasm::Wasmtime::Module::Imports;
  22         66  
  22         667  
12 22     22   6060 use Wasm::Wasmtime::ImportType;
  22         79  
  22         779  
13 22     22   6548 use Wasm::Wasmtime::ExportType;
  22         64  
  22         831  
14 22     22   140 use Ref::Util qw( is_blessed_ref );
  22         54  
  22         1000  
15 22     22   127 use Carp ();
  22         55  
  22         28698  
16              
17             # ABSTRACT: Wasmtime module class
18             our $VERSION = '0.22'; # VERSION
19              
20              
21             $ffi_prefix = 'wasm_module_';
22             $ffi->load_custom_type('::PtrObject' => 'wasm_module_t' => __PACKAGE__);
23              
24             sub _args
25             {
26 64     64   142 my $wasm;
27             my $data;
28 64 100       194 if(@_ == 1)
29             {
30 12         34 $data = shift;
31 12         37 $wasm = Wasm::Wasmtime::ByteVec->new($data);
32             }
33             else
34             {
35 52         119 my $key = shift;
36 52 100       225 if($key eq 'wat')
    100          
    50          
37             {
38 36         8748 require Wasm::Wasmtime::Wat2Wasm;
39 36         148 $data = Wasm::Wasmtime::Wat2Wasm::wat2wasm(shift);
40 36         124 $wasm = Wasm::Wasmtime::ByteVec->new($data);
41             }
42             elsif($key eq 'wasm')
43             {
44 1         3 $data = shift;
45 1         5 $wasm = Wasm::Wasmtime::ByteVec->new($data);
46             }
47             elsif($key eq 'file')
48             {
49 15         1043 require Wasm::Wasmtime::Wat2Wasm;
50 15         62 require Path::Tiny;
51 15         92 my $path = Path::Tiny->new(shift);
52 15 100       473 if($path->basename =~ /\.wat/)
53             {
54 13         514 $data = Wasm::Wasmtime::Wat2Wasm::wat2wasm($path->slurp_utf8);
55 13         59 $wasm = Wasm::Wasmtime::ByteVec->new($data);
56             }
57             else
58             {
59 2         87 $data = $path->slurp_raw;
60 2         407 $wasm = Wasm::Wasmtime::ByteVec->new($data);
61             }
62             }
63             }
64 64         1678 (\$wasm, \$data);
65             }
66              
67              
68             $ffi->attach( [ wasmtime_module_new => 'new' ] => ['wasm_engine_t', 'wasm_byte_vec_t*', 'opaque*'] => 'wasmtime_error_t' => sub {
69             my $xsub = shift;
70             my $class = shift;
71             my $store;
72             my $engine;
73             if(defined $_[0] && is_blessed_ref $_[0])
74             {
75             if($_[0]->isa('Wasm::Wasmtime::Engine'))
76             {
77             $engine = shift;
78             }
79             elsif($_[0]->isa('Wasm::Wasmtime::Store'))
80             {
81             Carp::carp("Passing a Wasm::Wasmtime::Store into the module constructor is deprecated, please pass a Wasm::Wasmtime::Engine object instead");
82             $store = shift;
83             $engine = $store->engine;
84             }
85             }
86             $engine ||= Wasm::Wasmtime::Engine->new;
87             my($wasm, $data) = _args(@_);
88             my $ptr;
89             if(my $error = $xsub->($engine, $$wasm, \$ptr))
90             {
91             Carp::croak("error creating module: " . $error->message);
92             }
93             bless { ptr => $ptr, engine => $engine, store => $store }, $class;
94             });
95              
96              
97             $ffi->attach( [ wasmtime_module_deserialize => 'deserialize' ] => ['wasm_engine_t', 'wasm_byte_vec_t*', 'opaque*'] => 'wasmtime_error_t' => sub {
98             my $xsub = shift;
99             my $class = shift;
100             my $engine;
101             $engine = defined $_[0] && is_blessed_ref $_[0] && $_[0]->isa('Wasm::Wasmtime::Engine') ? shift : Wasm::Wasmtime::Engine->new;
102             my $serialized = Wasm::Wasmtime::ByteVec->new($_[0]);
103             my $ptr;
104             if(my $error = $xsub->($engine, $serialized, \$ptr))
105             {
106             Carp::croak("error creating module: " . $error->message);
107             }
108             bless { ptr => $ptr, store => undef, engine => $engine }, $class;
109             });
110              
111              
112             $ffi->attach( [ wasmtime_module_validate => 'validate' ] => ['wasm_store_t', 'wasm_byte_vec_t*'] => 'wasmtime_error_t' => sub {
113             my $xsub = shift;
114             my $class = shift;
115             my $store = defined $_[0] && ref($_[0]) eq 'Wasm::Wasmtime::Store' ? shift : Wasm::Wasmtime::Store->new;
116             my($wasm, $data) = _args(@_);
117             my $error = $xsub->($store, $$wasm);
118             wantarray ## no critic (Community::Wantarray)
119             ? $error ? (0, $error->message) : (1, '')
120             : $error ? 0 : 1;
121             });
122              
123              
124             sub exports
125             {
126 56     56 1 14523 Wasm::Wasmtime::Module::Exports->new(shift);
127             }
128              
129             $ffi->attach( [ exports => '_exports' ]=> [ 'wasm_module_t', 'wasm_exporttype_vec_t*' ] => sub {
130             my($xsub, $self) = @_;
131             my $exports = Wasm::Wasmtime::ExportTypeVec->new;
132             $xsub->($self, $exports);
133             $exports->to_list;
134             });
135              
136              
137             sub imports
138             {
139 43     43 1 4722 Wasm::Wasmtime::Module::Imports->new(shift);
140             }
141              
142             $ffi->attach( [ imports => '_imports' ] => [ 'wasm_module_t', 'wasm_importtype_vec_t*' ] => sub {
143             my($xsub, $self) = @_;
144             my $imports = Wasm::Wasmtime::ImportTypeVec->new;
145             $xsub->($self, $imports);
146             $imports->to_list;
147             });
148              
149              
150             $ffi->attach( [ 'wasmtime_module_serialize' => 'serialize' ] => [ 'wasm_module_t', 'wasm_byte_vec_t*' ] => 'wasmtime_error_t' => sub {
151             my($xsub, $self) = @_;
152             my $s = Wasm::Wasmtime::ByteVec->new;
153             if(my $error = $xsub->($self, $s))
154             {
155             Carp::croak("error serializing module: " . $error->message);
156             }
157             else
158             {
159             my $s2 = $s->get;
160             $s->delete;
161             return $s2;
162             }
163             });
164              
165              
166 8     8 1 13833 sub engine { shift->{engine} }
167              
168              
169             sub to_string
170             {
171 4     4 1 1757 my($self) = @_;
172 4         7 my @externs = (@{ $self->imports }, @{ $self->exports });
  4         15  
  4         12  
173 4 100       40 return "(module)\n" unless @externs;
174 1         3 my $string = "(module\n";
175 1         3 foreach my $extern (@externs)
176             {
177 1         4 $string .= " " . $extern->to_string . "\n";
178             }
179 1         8 $string .= ")\n";
180             }
181              
182             _generate_destroy();
183              
184             1;
185              
186             __END__