Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: (cargo serde example) #61

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,13 @@ To compile the entire project, run the following commands:
```sh
$ just rust
$ just php
$ composer install
$ php -d extension=wasm examples/simple.php
```

Additionally, to compile one of the cargo examples, run the following:
```bash
$ just compile-and-run-cargo-example serde
```
(Yes, you need [`just`](https://github.com/casey/just/)).

## Testing
Expand Down
2 changes: 2 additions & 0 deletions examples/cargo/serde/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
serde.wasm
target
89 changes: 89 additions & 0 deletions examples/cargo/serde/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions examples/cargo/serde/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
publish = false
name = "php-ext-wasm-cargo-serde-example"
version = "1.0.0"
edition = "2018"

[lib]
path = "serde.rs"
crate-type = ["cdylib"]

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
49 changes: 49 additions & 0 deletions examples/cargo/serde/serde.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types = 1);

require_once __DIR__ . '/../../../vendor/autoload.php';

// Instantiate the module.
$instance = new Wasm\Instance(__DIR__ . '/serde.wasm');

// Set the subject to greet.
$subject = 'Hello, this is PHP.';
$length_of_subject = strlen($subject);

// Allocate memory for the subject, and get a pointer to it.
$input_pointer = $instance->allocate($length_of_subject);

// Write the subject into the memory.
$memory_buffer = $instance->getMemoryBuffer();
$memory = new Wasm\Uint8Array($memory_buffer, $input_pointer);

for ($nth = 0; $nth < $length_of_subject; ++$nth) {
$memory[$nth] = ord($subject[$nth]);
}

// C-string terminates by NULL.
$memory[$nth] = 0;

// Run the `greet` function. Give the pointer to the subject.
$output_pointer = $instance->to_subject($input_pointer);

// Read the result of the `greet` function.
$memory = new Wasm\Uint8Array($memory_buffer, $output_pointer);

$output = '';
$nth = 0;

while (0 !== $memory[$nth]) {
$output .= chr($memory[$nth]);
++$nth;
}

$length_of_output = $nth;

var_dump($output);
var_dump(json_decode($output));

// Deallocate the subject, and the output.
$instance->deallocate($input_pointer, $length_of_subject);
$instance->deallocate($output_pointer, $length_of_output);
35 changes: 35 additions & 0 deletions examples/cargo/serde/serde.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::ffi::{CStr, CString};
use std::mem;
use std::borrow::Cow;
use std::os::raw::{c_char, c_void};
use serde::{Serialize, Deserialize};


#[derive(Serialize, Deserialize, Debug)]
struct Subject<'a> {
subject: Cow<'a, str>,
}

#[no_mangle]
pub extern fn allocate(size: usize) -> *mut c_void {
let mut buffer = Vec::with_capacity(size);
let pointer = buffer.as_mut_ptr();
mem::forget(buffer);

pointer as *mut c_void
}

#[no_mangle]
pub extern fn deallocate(pointer: *mut c_void, capacity: usize) {
unsafe {
let _ = Vec::from_raw_parts(pointer, 0, capacity);
}
}

#[no_mangle]
pub extern fn to_subject(subject: *mut c_char) -> *mut c_char {
let subject = unsafe { CStr::from_ptr(subject).to_string_lossy() };
let point = Subject { subject };
let serialized = serde_json::to_string(&point).unwrap();
unsafe { CString::from_vec_unchecked(serialized.as_bytes().to_vec()) }.into_raw()
}
8 changes: 8 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ compile-wasm FILE='examples/simple':
mv {{FILE}}.opt.wasm {{FILE}}.wasm
rm {{FILE}}.raw.wasm

compile-and-run-cargo-example FILE='serde':
#!/usr/bin/env bash
set -euo pipefail
cd examples/cargo/{{FILE}}
cargo +nightly build --target wasm32-unknown-unknown
cp target/wasm32-unknown-unknown/debug/php_ext_wasm_cargo_{{FILE}}_example.wasm {{FILE}}.wasm
php -d extension=wasm {{FILE}}.php

# Compile the Rust part.
rust:
cargo build --release
Expand Down