File Coverage

blib/lib/Wasm/Wasm3/Module.pm
Criterion Covered Total %
statement 23 25 92.0
branch 3 6 50.0
condition 2 3 66.6
subroutine 7 7 100.0
pod 2 2 100.0
total 37 43 86.0


line stmt bran cond sub pod time code
1             package Wasm::Wasm3::Module;
2              
3 4     4   24 use strict;
  4         7  
  4         101  
4 4     4   16 use warnings;
  4         13  
  4         92  
5              
6             =encoding utf-8
7              
8             =head1 NAME
9              
10             Wasm::Wasm3::Module
11              
12             =head1 SYNOPSIS
13              
14             See L.
15              
16             =head1 DESCRIPTION
17              
18             This module exposes L’s
19             module object to Perl.
20              
21             =cut
22              
23             #----------------------------------------------------------------------
24              
25 4     4   17 use Wasm::Wasm3;
  4         6  
  4         1054  
26              
27             #----------------------------------------------------------------------
28              
29             =head1 METHODS
30              
31             This class is not directly instantiated; see L for
32             details.
33              
34             =head2 $value = I->get_global( $NAME )
35              
36             Returns the value of the $NAMEd export global.
37              
38             =head2 $type = I->get_global_type( $NAME )
39              
40             Returns the type (e.g., Wasm::Wasm3::TYPE_I32) of the $NAMEd export global.
41              
42             =head2 $obj = I->link_function( $MODULE_NAME, $FUNCTION_NAME, $SIGNATURE, $CODEREF )
43              
44             Sets $CODEREF as $MODULE_NAME.$FUNCTION_NAME’s implementation inside the
45             WebAssembly module. See below for L.
46              
47             $CODEREF will I be called in list context. $CODEREF B return
48             the number of arguments that $SIGNATURE indicates, or you’ll get an error
49             (possibly an unhelpful one).
50              
51             If $CODEREF throws, the exception is Ced, and a generic
52             callback-failed error is thrown to the C caller.
53              
54             =head3 WASM Context in Callbacks
55              
56             Your callback may need to reference either the wasm3 runtime or module.
57             When doing this, be sure to use a Ced copy (cf. L)
58             of that object, or you’ll leak memory (and eventually get a Cing
59             about it).
60              
61             For example:
62              
63             my $weak_runtime = $runtime;
64             Scalar::Util::weaken($weak_runtime);
65              
66             $module->link_function(
67             mymodule => myfuncname => 'v(ii)',
68             sub {
69             my ($buf_p, $buflen) = @_;
70              
71             my $buf = $weak_runtime->get_memory($buf_p, $buflen);
72              
73             # Now do something cool with $buf.
74              
75             return;
76             },
77             );
78              
79             The distribution’s F shows this technique in action.
80              
81             (An alternative design would be to pass a special context object
82             to every callback, but the weak-reference approach is more efficient.)
83              
84             =head3 $SIGNATURE
85              
86             $SIGNATURE is wasm3’s own convention to describe a function’s inputs &
87             outputs. As of this writing wasm3’s documentation doesn’t describe it very
88             well, so we’ll describe it here.
89              
90             The format is C<$RETURNS($ARGS)>, where $RETURNS and $ARGS are both either:
91              
92             =over
93              
94             =item * C, to indicate empty (C meaning “void”)
95              
96             =item * … a sequence of one or more of: C (i32), C (i64), C (f32),
97             C, (f64)
98              
99             =back
100              
101             Space characters are ignored.
102              
103             For example: C indicates a function that takes i32 and f32 as
104             arguments and returns nothing.
105              
106             =head2 $obj = I->link_wasi_default()
107              
108             A quick helper to link L includes via
109             wasm3’s L integration.
110              
111             This uses wasm3’s built-in WASI defaults, e.g., STDIN becomes WASI file
112             descriptor 0.
113              
114             =head2 $obj = I->link_wasi( %OPTS )
115              
116             (NB: Only available if uvwasi is your WASI backend; see L
117             for details.)
118              
119             Like C but takes a list of key/value pairs that
120             offer the following controls:
121              
122             %OPTS are:
123              
124             =over
125              
126             =item * C, C, C - File handles to the WASI input, output,
127             and error streams. Defaults are file descriptors 0, 1, and 2 respectively.
128              
129             =item * C - A reference to an array of key/value byte-string pairs
130             to pass as the WASI environment.
131              
132             =item * C - A reference to a hash of WASI paths to system/real
133             paths.
134              
135             B WASI paths are character strings, while system paths are
136             B strings. The discrepancy arises because WASI paths are always
137             character strings, while Perl treats all system paths as byte strings
138             (even on OSes like Windows where paths are character strings).
139              
140             So if, for example, you have directory F that you’ll access
141             in WASI as F, your code might look thus:
142              
143             preopen => {
144             do { use utf8; '/épée' } => do { no utf8; '/tmp/føø' },
145             },
146              
147             =back
148              
149             =cut
150              
151             our $WASI_MODULE_STR;
152              
153             sub link_wasi_default {
154 1     1 1 6092 my ($self) = @_;
155              
156 1         3 return $self->_perl_link_wasi('_link_wasi_default');
157             }
158              
159             sub link_wasi {
160 1     1 1 9783 my ($self, @args) = @_;
161              
162 1         25 return $self->_perl_link_wasi('_link_wasi', @args);
163             }
164              
165             sub _perl_link_wasi {
166 2     2   11 my ($self, $fn, @args) = @_;
167              
168 2 50       5 if ($WASI_MODULE_STR) {
169 0 0       0 if ($WASI_MODULE_STR ne "$self") {
170 0         0 die "$self: WASI is already linked! ($WASI_MODULE_STR)";
171             }
172             }
173             else {
174 2         289 $self->$fn(@args);
175 2         27 $WASI_MODULE_STR = "$self";
176             }
177              
178 2         9 return $self;
179             }
180              
181             sub DESTROY {
182 6     6   47952 my ($self) = @_;
183              
184 6         144 $self->_destroy_xs();
185              
186 6 100 66     54 if ($WASI_MODULE_STR && ($WASI_MODULE_STR eq "$self")) {
187 2         4 undef $WASI_MODULE_STR;
188             }
189              
190 6         262 return;
191             }
192              
193             1;