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

Generate C preprocessor code to hide things not on Windows #952

Merged
merged 2 commits into from
Nov 11, 2019
Merged
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: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@

## **[Unreleased]**

- [#952](https://github.com/wasmerio/wasmer/pull/952) Use C preprocessor to properly hide trampoline functions on Windows 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!
22 changes: 22 additions & 0 deletions lib/runtime-c-api/build.rs
Original file line number Diff line number Diff line change
@@ -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());
4 changes: 3 additions & 1 deletion lib/runtime-c-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;

37 changes: 37 additions & 0 deletions lib/runtime-c-api/wasmer.h
Original file line number Diff line number Diff line change
@@ -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,46 +803,60 @@ 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.
*/
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(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
37 changes: 37 additions & 0 deletions lib/runtime-c-api/wasmer.hh
Original file line number Diff line number Diff line change
@@ -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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: these are clearly a group, just put a single #if around them to disable all these related trampoline functions for windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's unfortunate that it did that; if we manually edit the header file though then we have to do it after every time it's generated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it at the top level in Rust

/// 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);