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   460073 use strict;
  22         60  
  22         662  
4 22     22   125 use warnings;
  22         42  
  22         498  
5 22     22   390 use 5.008004;
  22         92  
6 22     22   1054 use Ref::Util qw( is_blessed_ref );
  22         3155  
  22         1258  
7 22     22   1335 use Wasm::Wasmtime::FFI;
  22         55  
  22         2647  
8 22     22   3043 use Wasm::Wasmtime::Engine;
  22         60  
  22         629  
9 22     22   3081 use Wasm::Wasmtime::Store;
  22         63  
  22         728  
10 22     22   9631 use Wasm::Wasmtime::Module::Exports;
  22         59  
  22         679  
11 22     22   10068 use Wasm::Wasmtime::Module::Imports;
  22         57  
  22         673  
12 22     22   5487 use Wasm::Wasmtime::ImportType;
  22         63  
  22         647  
13 22     22   5663 use Wasm::Wasmtime::ExportType;
  22         62  
  22         647  
14 22     22   137 use Ref::Util qw( is_blessed_ref );
  22         161  
  22         893  
15 22     22   119 use Carp ();
  22         45  
  22         26354  
16              
17             # ABSTRACT: Wasmtime module class
18             our $VERSION = '0.21'; # 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   137 my $wasm;
27             my $data;
28 64 100       181 if(@_ == 1)
29             {
30 12         21 $data = shift;
31 12         29 $wasm = Wasm::Wasmtime::ByteVec->new($data);
32             }
33             else
34             {
35 52         108 my $key = shift;
36 52 100       188 if($key eq 'wat')
    100          
    50          
37             {
38 36         8549 require Wasm::Wasmtime::Wat2Wasm;
39 36         136 $data = Wasm::Wasmtime::Wat2Wasm::wat2wasm(shift);
40 36         131 $wasm = Wasm::Wasmtime::ByteVec->new($data);
41             }
42             elsif($key eq 'wasm')
43             {
44 1         2 $data = shift;
45 1         4 $wasm = Wasm::Wasmtime::ByteVec->new($data);
46             }
47             elsif($key eq 'file')
48             {
49 15         1397 require Wasm::Wasmtime::Wat2Wasm;
50 15         63 require Path::Tiny;
51 15         82 my $path = Path::Tiny->new(shift);
52 15 100       467 if($path->basename =~ /\.wat/)
53             {
54 13         506 $data = Wasm::Wasmtime::Wat2Wasm::wat2wasm($path->slurp_utf8);
55 13         52 $wasm = Wasm::Wasmtime::ByteVec->new($data);
56             }
57             else
58             {
59 2         73 $data = $path->slurp_raw;
60 2         382 $wasm = Wasm::Wasmtime::ByteVec->new($data);
61             }
62             }
63             }
64 64         1583 (\$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 (Freenode::Wantarray)
119             ? $error ? (0, $error->message) : (1, '')
120             : $error ? 0 : 1;
121             });
122              
123              
124             sub exports
125             {
126 56     56 1 12214 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 3899 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 10842 sub engine { shift->{engine} }
167              
168              
169             sub to_string
170             {
171 4     4 1 1425 my($self) = @_;
172 4         7 my @externs = (@{ $self->imports }, @{ $self->exports });
  4         10  
  4         10  
173 4 100       19 return "(module)\n" unless @externs;
174 1         2 my $string = "(module\n";
175 1         3 foreach my $extern (@externs)
176             {
177 1         5 $string .= " " . $extern->to_string . "\n";
178             }
179 1         4 $string .= ")\n";
180             }
181              
182             _generate_destroy();
183              
184             1;
185              
186             __END__