Skip to content

Commit 237a9d7

Browse files
committed
add greet exmaple: passing strings back and forth
1 parent 7a558e0 commit 237a9d7

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

examples/wasm/greet.pl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use strict;
2+
use warnings;
3+
use Path::Tiny qw( path );
4+
use lib path(__FILE__)->parent->child('lib')->stringify;
5+
use Greet;
6+
7+
print greet("Perl!"), "\n";

examples/wasm/lib/Greet.pm

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package Greet;
2+
3+
use strict;
4+
use warnings;
5+
use FFI::Platypus;
6+
use FFI::Platypus::Memory qw( strcpy );
7+
use base qw( Exporter );
8+
use Wasm
9+
-api => 0,
10+
-self
11+
;
12+
13+
our @EXPORT = qw( greet );
14+
15+
sub greet
16+
{
17+
my($subject) = @_;
18+
19+
my $input_size = do { use bytes; length($subject)+1 };
20+
my $input_offset = _allocate($input_size);
21+
strcpy( $memory->address + $input_offset, $subject );
22+
23+
my $output_offset = _greet($input_offset);
24+
my $greeting = FFI::Platypus->new->cast('opaque', 'string', $memory->address + $output_offset);
25+
my $output_size = do { use bytes; length($greeting)+1 };
26+
27+
_deallocate($input_offset, $input_size);
28+
_deallocate($output_offset, $output_size);
29+
30+
return $greeting;
31+
}
32+
33+
1;

examples/wasm/lib/Greet.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* rustc --target wasm32-unknown-unknown -O --crate-type=cdylib Greet.rs -o Greet.wasm
3+
* chmod -x Greet.wasm
4+
*/
5+
6+
use std::ffi::{CStr, CString};
7+
use std::mem;
8+
use std::os::raw::{c_char, c_void};
9+
10+
#[no_mangle]
11+
pub extern fn _allocate(size: usize) -> *mut c_void {
12+
let mut buffer = Vec::with_capacity(size);
13+
let pointer = buffer.as_mut_ptr();
14+
mem::forget(buffer);
15+
16+
pointer as *mut c_void
17+
}
18+
19+
#[no_mangle]
20+
pub extern fn _deallocate(pointer: *mut c_void, capacity: usize) {
21+
unsafe {
22+
let _ = Vec::from_raw_parts(pointer, 0, capacity);
23+
}
24+
}
25+
26+
#[no_mangle]
27+
pub extern fn _greet(subject: *mut c_char) -> *mut c_char {
28+
let subject = unsafe { CStr::from_ptr(subject).to_bytes().to_vec() };
29+
let mut output = b"Hello, ".to_vec();
30+
output.extend(&subject);
31+
output.extend(&[b'!']);
32+
33+
unsafe { CString::from_vec_unchecked(output) }.into_raw()
34+
}

0 commit comments

Comments
 (0)