diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ce32fa48..4b1c7cf25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## **[Unreleased]** +- [#952](https://github.com/wasmerio/wasmer/pull/952) Use C preprocessor to properly hide trampoline functions on Windowns and non-x86_64 targets. + ## 0.10.0 - 2019-11-11 Special thanks to [@newpavlov](https://github.com/newpavlov) and [@Maxgy](https://github.com/Maxgy) for their contributions! diff --git a/lib/runtime-c-api/build.rs b/lib/runtime-c-api/build.rs index 1db19a197..7c518398c 100644 --- a/lib/runtime-c-api/build.rs +++ b/lib/runtime-c-api/build.rs @@ -12,12 +12,31 @@ fn main() { let mut out_wasmer_header_file = PathBuf::from(&out_dir); out_wasmer_header_file.push("wasmer"); + const WASMER_PRE_HEADER: &str = r#" +#ifndef WASMER_H_MACROS +#define WASMER_H_MACROS +#if MSVC +#ifdef _M_AMD64 +#define ARCH_X86_64 +#endif +#endif + +#if GCC +#ifdef __x86_64__ +#define ARCH_X86_64 +#endif +#endif +#endif // WASMER_H_MACROS +"#; // Generate the C bindings in the `OUT_DIR`. out_wasmer_header_file.set_extension("h"); Builder::new() .with_crate(crate_dir.clone()) .with_language(Language::C) .with_include_guard("WASMER_H") + .with_header(WASMER_PRE_HEADER) + .with_define("target_family", "windows", "_WIN32") + .with_define("target_arch", "x86_64", "ARCH_X86_64") .generate() .expect("Unable to generate C bindings") .write_to_file(out_wasmer_header_file.as_path()); @@ -28,6 +47,9 @@ fn main() { .with_crate(crate_dir) .with_language(Language::Cxx) .with_include_guard("WASMER_H") + .with_header(WASMER_PRE_HEADER) + .with_define("target_family", "windows", "_WIN32") + .with_define("target_arch", "x86_64", "ARCH_X86_64") .generate() .expect("Unable to generate C++ bindings") .write_to_file(out_wasmer_header_file.as_path()); diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index 17e96a4c3..f04640754 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -101,7 +101,9 @@ pub mod instance; pub mod memory; pub mod module; pub mod table; -#[cfg(all(unix, target_arch = "x86_64"))] +// `not(target_family = "windows")` is simpler than `unix`. See build.rs +// if you want to change the meaning of these `cfg`s in the header file. +#[cfg(all(not(target_family = "windows"), target_arch = "x86_64"))] pub mod trampoline; pub mod value; diff --git a/lib/runtime-c-api/wasmer.h b/lib/runtime-c-api/wasmer.h index eb9dab50d..bc4a3ed4f 100644 --- a/lib/runtime-c-api/wasmer.h +++ b/lib/runtime-c-api/wasmer.h @@ -1,3 +1,20 @@ + +#ifndef WASMER_H_MACROS +#define WASMER_H_MACROS +#if MSVC +#ifdef _M_AMD64 +#define ARCH_X86_64 +#endif +#endif + +#if GCC +#ifdef __x86_64__ +#define ARCH_X86_64 +#endif +#endif +#endif // WASMER_H_MACROS + + #ifndef WASMER_H #define WASMER_H @@ -162,17 +179,23 @@ typedef struct { } wasmer_serialized_module_t; +#if (!defined(_WIN32) && defined(ARCH_X86_64)) typedef struct { } wasmer_trampoline_buffer_builder_t; +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) typedef struct { } wasmer_trampoline_callable_t; +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) typedef struct { } wasmer_trampoline_buffer_t; +#endif /** * Opens a directory that's visible to the WASI module as `alias` but @@ -780,6 +803,7 @@ uint32_t wasmer_table_length(wasmer_table_t *table); */ wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits); +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /** * Adds a callinfo trampoline to the builder. */ @@ -787,39 +811,52 @@ uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampo const wasmer_trampoline_callable_t *func, const void *ctx, uint32_t num_params); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /** * Adds a context trampoline to the builder. */ uintptr_t wasmer_trampoline_buffer_builder_add_context_trampoline(wasmer_trampoline_buffer_builder_t *builder, const wasmer_trampoline_callable_t *func, const void *ctx); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /** * Finalizes the trampoline builder into an executable buffer. */ wasmer_trampoline_buffer_t *wasmer_trampoline_buffer_builder_build(wasmer_trampoline_buffer_builder_t *builder); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /** * Creates a new trampoline builder. */ wasmer_trampoline_buffer_builder_t *wasmer_trampoline_buffer_builder_new(void); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /** * Destroys the trampoline buffer if not null. */ void wasmer_trampoline_buffer_destroy(wasmer_trampoline_buffer_t *buffer); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /** * Returns the callable pointer for the trampoline with index `idx`. */ const wasmer_trampoline_callable_t *wasmer_trampoline_buffer_get_trampoline(const wasmer_trampoline_buffer_t *buffer, uintptr_t idx); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /** * Returns the context added by `add_context_trampoline`, from within the callee function. */ void *wasmer_trampoline_get_context(void); +#endif /** * Returns true for valid wasm bytes and false for invalid bytes diff --git a/lib/runtime-c-api/wasmer.hh b/lib/runtime-c-api/wasmer.hh index 04a095c48..acf4b20e7 100644 --- a/lib/runtime-c-api/wasmer.hh +++ b/lib/runtime-c-api/wasmer.hh @@ -1,3 +1,20 @@ + +#ifndef WASMER_H_MACROS +#define WASMER_H_MACROS +#if MSVC +#ifdef _M_AMD64 +#define ARCH_X86_64 +#endif +#endif + +#if GCC +#ifdef __x86_64__ +#define ARCH_X86_64 +#endif +#endif +#endif // WASMER_H_MACROS + + #ifndef WASMER_H #define WASMER_H @@ -146,17 +163,23 @@ struct wasmer_serialized_module_t { }; +#if (!defined(_WIN32) && defined(ARCH_X86_64)) struct wasmer_trampoline_buffer_builder_t { }; +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) struct wasmer_trampoline_callable_t { }; +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) struct wasmer_trampoline_buffer_t { }; +#endif /// Opens a directory that's visible to the WASI module as `alias` but /// is backed by the host file at `host_file_path` @@ -612,32 +635,46 @@ uint32_t wasmer_table_length(wasmer_table_t *table); /// and `wasmer_last_error_message` to get an error message. wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits); +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /// Adds a callinfo trampoline to the builder. uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder, const wasmer_trampoline_callable_t *func, const void *ctx, uint32_t num_params); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /// Adds a context trampoline to the builder. uintptr_t wasmer_trampoline_buffer_builder_add_context_trampoline(wasmer_trampoline_buffer_builder_t *builder, const wasmer_trampoline_callable_t *func, const void *ctx); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /// Finalizes the trampoline builder into an executable buffer. wasmer_trampoline_buffer_t *wasmer_trampoline_buffer_builder_build(wasmer_trampoline_buffer_builder_t *builder); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /// Creates a new trampoline builder. wasmer_trampoline_buffer_builder_t *wasmer_trampoline_buffer_builder_new(); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /// Destroys the trampoline buffer if not null. void wasmer_trampoline_buffer_destroy(wasmer_trampoline_buffer_t *buffer); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /// Returns the callable pointer for the trampoline with index `idx`. const wasmer_trampoline_callable_t *wasmer_trampoline_buffer_get_trampoline(const wasmer_trampoline_buffer_t *buffer, uintptr_t idx); +#endif +#if (!defined(_WIN32) && defined(ARCH_X86_64)) /// Returns the context added by `add_context_trampoline`, from within the callee function. void *wasmer_trampoline_get_context(); +#endif /// Returns true for valid wasm bytes and false for invalid bytes bool wasmer_validate(const uint8_t *wasm_bytes, uint32_t wasm_bytes_len);