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

Implement wasm=>host feature query #37

Closed
wants to merge 2 commits 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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ include = [
travis-ci = { repository = "dtolnay/watt" }

[workspace]
members = ["demo/caller", "demo/wa", "runtime/tests", "proc-macro"]
members = ["demo/caller", "demo/wa", "runtime/tests", "proc-macro", "watt-feature-passthrough"]

[patch.crates-io]
watt = { path = "." }
4 changes: 4 additions & 0 deletions demo/caller/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ publish = false

[dependencies]
wa-demo = { path = "../wa" }

[features]
feat_a = ["wa-demo/feat_a"]
feat_b = ["wa-demo/feat_b"]
1 change: 1 addition & 0 deletions demo/impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ crate-type = ["cdylib"]
proc-macro2 = "1.0"
quote = "1.0"
syn = "1.0"
watt-feature-passthrough = { path = "../../watt-feature-passthrough" }

[workspace]

Expand Down
10 changes: 9 additions & 1 deletion demo/impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::DeriveInput;
use watt_feature_passthrough::query_feature_flag;

#[no_mangle]
pub extern "C" fn demo(input: TokenStream) -> TokenStream {
Expand All @@ -10,7 +11,14 @@ pub extern "C" fn demo(input: TokenStream) -> TokenStream {
};

let ident = input.ident;
let message = format!("Hello from WASM! My name is {}.", ident);
let mut message = format!("Hello from WASM! My name is {}.", ident);

if query_feature_flag("feat_a").unwrap() {
message.push_str(" feat_a is enabled.");
}
if query_feature_flag("feat_b").unwrap() {
message.push_str(" feat_a is enabled.");
}

quote! {
impl #ident {
Expand Down
4 changes: 4 additions & 0 deletions demo/wa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ proc-macro = true

[dependencies]
watt = "0.3"

[features]
feat_a = []
feat_b = []
2 changes: 1 addition & 1 deletion demo/wa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ extern crate proc_macro;
use proc_macro::TokenStream;
use watt::WasmMacro;

static MACRO: WasmMacro = WasmMacro::new(WASM);
static MACRO: WasmMacro = WasmMacro!(WASM, "feat_a", "feat_b");
static WASM: &[u8] = include_bytes! {
"../../impl/target/wasm32-unknown-unknown/release/watt_demo.wasm"
};
Expand Down
2 changes: 2 additions & 0 deletions src/data.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use proc_macro::{Literal, Span, TokenStream};
use std::cell::RefCell;
use std::ops::{Index, IndexMut};
use std::collections::BTreeMap;

thread_local! {
static DATA: RefCell<Data> = RefCell::new(Data::default());
Expand All @@ -13,6 +14,7 @@ pub struct Data {
pub tokenstream: Collection<TokenStream>,
pub literal: Collection<Literal>,
pub span: Collection<Span>,
pub flags: BTreeMap<&'static str, bool>,
}

impl Data {
Expand Down
2 changes: 2 additions & 0 deletions src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pub fn host_func(name: &str, store: &Store) -> HostFunc {
"token_stream_parse" => mem_func2(sym::token_stream_parse, store),
"literal_to_string" => func1(sym::literal_to_string, store),

"query_feature_flag" => mem_func2(sym::query_feature_flag, store),

"string_new" => mem_func2(sym::string_new, store),
"string_len" => func1(sym::string_len, store),
"string_read" => mem_func2(sym::string_read, store),
Expand Down
2 changes: 2 additions & 0 deletions src/interpret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ impl ThreadState {
pub fn proc_macro(fun: &str, inputs: Vec<TokenStream>, instance: &WasmMacro) -> TokenStream {
STATE.with(|state| {
let state = &mut state.borrow_mut();
let flags = instance.flags().iter().cloned().collect();
let instance = state.instance(instance);
let exports = Exports::collect(instance, fun);

let _guard = Data::guard();
let raws: Vec<Value> = Data::with(|d| {
d.flags = flags;
inputs
.into_iter()
.map(|input| Value::I32(d.tokenstream.push(input)))
Expand Down
2 changes: 2 additions & 0 deletions src/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ impl ThreadState {
pub fn proc_macro(fun: &str, inputs: Vec<TokenStream>, instance: &WasmMacro) -> TokenStream {
STATE.with(|state| {
let mut state = state.borrow_mut();
let flags = instance.flags().iter().cloned().collect();
let (module, instance) = state.instance(instance);
let instance_exports = instance.exports();
let exports = Exports::collect(module, &instance_exports, fun);

let _guard = Data::guard();
let raws = Data::with(|d| {
d.flags = flags;
inputs
.into_iter()
.map(|input| Val::i32(d.tokenstream.push(input) as i32))
Expand Down
26 changes: 26 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
/// ```
pub struct WasmMacro {
wasm: &'static [u8],
flags: &'static [(&'static str, bool)],
id: AtomicUsize,
}

Expand All @@ -232,8 +233,18 @@ impl WasmMacro {
/// # };
/// ```
pub const fn new(wasm: &'static [u8]) -> WasmMacro {
const EMPTY: &[(&str, bool)] = &[];
WasmMacro::new_with_flags(wasm, EMPTY)
}

#[doc(hidden)]
pub const fn new_with_flags(
wasm: &'static [u8],
flags: &'static [(&'static str, bool)],
) -> WasmMacro {
WasmMacro {
wasm,
flags,
id: AtomicUsize::new(0),
}
}
Expand Down Expand Up @@ -365,4 +376,19 @@ impl WasmMacro {
.compare_exchange(0, id, SeqCst, SeqCst)
.unwrap_or_else(|id| id)
}

fn flags(&self) -> &[(&'static str, bool)] {
&self.flags
}
}

#[macro_export]
#[allow(non_snake_case)]
macro_rules! WasmMacro {
($wasm:expr, $($flag:expr),* $(,)?) => {
$crate::WasmMacro::new_with_flags(
$wasm,
&[$(($flag, cfg!(feature = $flag))),*],
)
};
}
14 changes: 14 additions & 0 deletions src/sym.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
use crate::data::Data;
use std::str;

pub fn query_feature_flag(memory: &mut [u8], ptr: u32, len: u32) -> u32 {
Data::with(|d| {
let len = len as usize;
let ptr = ptr as usize;
let bytes = &memory[ptr..ptr + len];
let string = str::from_utf8(bytes).expect("non-utf8");
match d.flags.get(string) {
Some(&false) => 0,
Some(&true) => 1,
None => (-1i32) as u32,
}
})
}

pub fn literal_to_string(literal: u32) -> u32 {
Data::with(|d| {
let string = d.literal[literal].to_string();
Expand Down
9 changes: 9 additions & 0 deletions watt-feature-passthrough/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "watt-feature-passthrough"
version = "0.1.0"
edition = "2018"
publish = false

authors = ["Christopher Durham (CAD97) <cad97@cad97.com>"]

[dependencies]
14 changes: 14 additions & 0 deletions watt-feature-passthrough/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#[link(wasm_import_module = "watt-0.3")]
extern "C" {
#[link_name = "query_feature_flag"]
fn query_feature_flag_raw(ptr: *const u8, len: u32) -> u32;
}

pub fn query_feature_flag(flag: &str) -> Option<bool> {
let res = unsafe { query_feature_flag_raw(flag.as_bytes().as_ptr(), flag.len() as u32) };
match res {
0 => Some(false),
1 => Some(true),
_ => None,
}
}