Skip to content

Commit

Permalink
Add proxy_wasm::main macro. (#141)
Browse files Browse the repository at this point in the history
This is primarly a mechanism to deliver a workaround for a breaking
change in Rust v1.56.0 (which updated LLVM to v13.0), which changed
existing reactors into multi-entry commands, leading to performance
degradation and/or unusable Proxy-Wasm plugins.

See: WebAssembly/WASI#471

This is delivered as a macro to make it somehow compatible with the
unstable "-Z wasi-exec-model=reactor" feature.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
  • Loading branch information
PiotrSikora authored Apr 7, 2022
1 parent e56f649 commit 4a71cb1
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 15 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,43 @@ jobs:
- name: Package (publish)
run: cargo publish --dry-run --target=wasm32-unknown-unknown

reactor:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Update Rust
run: |
rustup toolchain install nightly --component clippy
rustup +nightly target add wasm32-wasi
rustup default nightly
- name: Rewrite Cargo.toml examples
run: |
grep -v '^crate-type' Cargo.toml > Cargo.tmp
mv Cargo.tmp Cargo.toml
- name: Build (wasm32-wasi)
env:
RUSTFLAGS: -D warnings -C link-args=-S -Z wasi-exec-model=reactor
run: cargo build --release --all-targets --target=wasm32-wasi

- name: Build (wasm32-wasi with wee-alloc)
env:
RUSTFLAGS: -D warnings -C link-args=-S -Z wasi-exec-model=reactor
run: cargo build --release --all-targets --target=wasm32-wasi --features=wee-alloc

- name: Clippy (wasm32-wasi)
env:
RUSTFLAGS: -D warnings -C link-args=-S -Z wasi-exec-model=reactor
run: cargo clippy --release --all-targets --target=wasm32-wasi

- name: Clippy (wasm32-wasi with wee-alloc)
env:
RUSTFLAGS: -D warnings -C link-args=-S -Z wasi-exec-model=reactor
run: cargo clippy --release --all-targets --target=wasm32-wasi --features=wee-alloc

outdated:
runs-on: ubuntu-latest

Expand Down
10 changes: 10 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
load("@rules_rust//cargo:cargo_build_script.bzl", "cargo_build_script")
load("@rules_rust//rust:defs.bzl", "rust_library")

cargo_build_script(
name = "proxy_wasm_build_script",
srcs = ["build.rs"],
edition = "2018",
tags = ["manual"],
visibility = ["//visibility:private"],
)

rust_library(
name = "proxy_wasm",
srcs = glob(["src/*.rs"]),
edition = "2018",
visibility = ["//visibility:public"],
deps = [
":proxy_wasm_build_script",
"//bazel/cargo:hashbrown",
"//bazel/cargo:log",
],
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Fixed

- Fixed performance degradation with `wasm32-wasi` target in Rust v1.56.0
or newer by adding `proxy_wasm::main` macro that should be used instead
of custom `_start`, `_initialize` and/or `main` exports.

### Changed

- Updated ABI to Proxy-Wasm ABI v0.2.1.
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ readme = "README.md"
license = "Apache-2.0"
repository = "https://github.com/proxy-wasm/proxy-wasm-rust-sdk"
edition = "2018"
build = "build.rs"

[features]
wee-alloc = ["wee_alloc"]
Expand Down
33 changes: 33 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=RUSTFLAGS");

if let Some(target_os) = std::env::var_os("CARGO_CFG_TARGET_OS") {
if target_os != "wasi" {
return;
}
}

if let Some(rustflags) = std::env::var_os("CARGO_ENCODED_RUSTFLAGS") {
for flag in rustflags.to_string_lossy().split('\x1f') {
if flag.ends_with("wasi-exec-model=reactor") {
println!("cargo:rustc-cfg=wasi_exec_model_reactor");
return;
}
}
}
}
5 changes: 2 additions & 3 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ use std::time::Duration;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use getrandom::getrandom;

#[no_mangle]
pub fn _start() {
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { Box::new(HelloWorld) });
}
}}

struct HelloWorld;

Expand Down
5 changes: 2 additions & 3 deletions examples/http_auth_random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ use proxy_wasm::traits::*;
use proxy_wasm::types::*;
use std::time::Duration;

#[no_mangle]
pub fn _start() {
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_http_context(|_, _| -> Box<dyn HttpContext> { Box::new(HttpAuthRandom) });
}
}}

struct HttpAuthRandom;

Expand Down
5 changes: 2 additions & 3 deletions examples/http_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
use proxy_wasm::traits::*;
use proxy_wasm::types::*;

#[no_mangle]
pub fn _start() {
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { Box::new(HttpBodyRoot) });
}
}}

struct HttpBodyRoot;

Expand Down
5 changes: 2 additions & 3 deletions examples/http_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@
use proxy_wasm::traits::*;
use proxy_wasm::types::*;

#[no_mangle]
pub fn _start() {
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> {
Box::new(HttpConfigHeaderRoot {
header_content: String::new(),
})
});
}
}}

struct HttpConfigHeader {
header_content: String,
Expand Down
5 changes: 2 additions & 3 deletions examples/http_headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ use log::trace;
use proxy_wasm::traits::*;
use proxy_wasm::types::*;

#[no_mangle]
pub fn _start() {
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { Box::new(HttpHeadersRoot) });
}
}}

struct HttpHeadersRoot;

Expand Down
34 changes: 34 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,40 @@ mod allocator;
mod dispatcher;
mod logger;

// For crate-type="cdylib".
#[cfg(not(wasi_exec_model_reactor))]
#[macro_export]
macro_rules! main {
($code:block) => {
#[cfg(target_os = "wasi")]
extern "C" {
fn __wasm_call_ctors();
}

#[no_mangle]
pub extern "C" fn _initialize() {
#[cfg(target_os = "wasi")]
unsafe {
__wasm_call_ctors();
}

$code;
}
};
}

// For crate-type="bin" with RUSTFLAGS="-Z wasi-exec-model=reactor".
#[cfg(wasi_exec_model_reactor)]
#[macro_export]
macro_rules! main {
($code:block) => {
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
$code;
Ok(())
}
};
}

pub fn set_log_level(level: types::LogLevel) {
logger::set_log_level(level);
}
Expand Down

0 comments on commit 4a71cb1

Please sign in to comment.