Merge remote-tracking branch 'origin/master' into feature/unified-exceptions

This commit is contained in:
losfair
2020-01-16 02:59:56 +08:00
39 changed files with 481 additions and 115 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@
.idea
**/.vscode
install/
api-docs/
api-docs-repo/

View File

@ -2,6 +2,8 @@
## **[Unreleased]**
- [#1133](https://github.com/wasmerio/wasmer/pull/1133) New `wasmer_trap` function in the C API, to properly error from within a host function
- [#1147](https://github.com/wasmerio/wasmer/pull/1147) Remove `log` and `trace` macros from `wasmer-runtime-core`, remove `debug` and `trace` features from `wasmer-*` crates, use the `log` crate for logging and use `fern` in the Wasmer CLI binary to output log messages. Colorized output will be enabled automatically if printing to a terminal, to force colorization on or off, set the `WASMER_COLOR` environment variable to `true` or `false`.
- [#1128](https://github.com/wasmerio/wasmer/pull/1128) Fix a crash when a host function is missing and the `allow_missing_functions` flag is enabled
- [#1099](https://github.com/wasmerio/wasmer/pull/1099) Remove `backend::Backend` from `wasmer_runtime_core`
- [#1097](https://github.com/wasmerio/wasmer/pull/1097) Move inline breakpoint outside of runtime backend

70
Cargo.lock generated
View File

@ -138,6 +138,17 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "chrono"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
dependencies = [
"num-integer",
"num-traits",
"time",
]
[[package]]
name = "clap"
version = "2.33.0"
@ -171,6 +182,17 @@ dependencies = [
"cc",
]
[[package]]
name = "colored"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8815e2ab78f3a59928fc32e141fbeece88320a240e43f47b2fd64ea3a88a5b3d"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "constant_time_eq"
version = "0.1.4"
@ -438,6 +460,17 @@ dependencies = [
"libc",
]
[[package]]
name = "fern"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e69ab0d5aca163e388c3a49d284fed6c3d0810700e77c5ae2756a50ec1a4daaa"
dependencies = [
"chrono",
"colored",
"log",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
@ -558,7 +591,7 @@ dependencies = [
"libc",
"llvm-sys",
"once_cell",
"parking_lot",
"parking_lot 0.10.0",
"regex",
]
@ -827,6 +860,17 @@ dependencies = [
"md5",
]
[[package]]
name = "parking_lot"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
dependencies = [
"lock_api",
"parking_lot_core 0.6.2",
"rustc_version",
]
[[package]]
name = "parking_lot"
version = "0.10.0"
@ -834,7 +878,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
dependencies = [
"lock_api",
"parking_lot_core",
"parking_lot_core 0.7.0",
]
[[package]]
name = "parking_lot_core"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
dependencies = [
"cfg-if",
"cloudabi",
"libc",
"redox_syscall",
"rustc_version",
"smallvec 0.6.13",
"winapi",
]
[[package]]
@ -1616,9 +1675,12 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
name = "wasmer"
version = "0.12.0"
dependencies = [
"atty",
"byteorder",
"errno",
"fern",
"glob 0.3.0",
"log",
"rustc_version",
"serde",
"structopt",
@ -1679,6 +1741,7 @@ dependencies = [
"getrandom",
"lazy_static",
"libc",
"log",
"time",
"wasmer-runtime-core",
]
@ -1800,7 +1863,7 @@ dependencies = [
"libc",
"nix",
"page_size",
"parking_lot",
"parking_lot 0.9.0",
"rustc_version",
"serde",
"serde-bench",
@ -1872,6 +1935,7 @@ dependencies = [
name = "wasmer-wasi-experimental-io-devices"
version = "0.12.0"
dependencies = [
"log",
"minifb",
"ref_thread_local",
"serde",

View File

@ -20,8 +20,11 @@ include = [
]
[dependencies]
atty = "0.2"
byteorder = "1.3"
errno = "0.2"
fern = { version = "0.5", features = ["colored"], optional = true }
log = "0.4"
structopt = "0.3"
wabt = "0.9.1"
wasmer-clif-backend = { path = "lib/clif-backend", optional = true }
@ -78,10 +81,9 @@ typetag = "0.1" # used by the plugin example
[features]
default = ["fast-tests", "wasi", "backend-cranelift"]
"loader-kernel" = ["wasmer-kernel-loader"]
debug = ["wasmer-runtime-core/debug"]
trace = ["wasmer-runtime-core/trace"]
debug = ["fern", "log/max_level_debug", "log/release_max_level_debug"]
trace = ["fern", "log/max_level_trace", "log/release_max_level_trace"]
docs = ["wasmer-runtime/docs"]
extra-debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]
# This feature will allow cargo test to run much faster
fast-tests = []
backend-cranelift = [

View File

@ -157,10 +157,8 @@ test-rest:
--exclude wasmer-emscripten-tests \
--exclude wasmer-runtime-core-tests
circleci-clean:
@if [ ! -z "${CIRCLE_JOB}" ]; then rm -f /home/circleci/project/target/debug/deps/libcranelift_wasm* && rm -f /Users/distiller/project/target/debug/deps/libcranelift_wasm*; fi;
test: spectests emtests middleware wasitests circleci-clean test-rest examples
test: spectests emtests middleware wasitests test-rest examples
# Integration tests
@ -231,34 +229,34 @@ check: check-bench
cargo check --release --manifest-path lib/runtime/Cargo.toml
$(RUNTIME_CHECK) \
--features=cranelift,cache,debug,llvm,singlepass,default-backend-singlepass
--features=cranelift,cache,llvm,singlepass,default-backend-singlepass
$(RUNTIME_CHECK) --release \
--features=cranelift,cache,llvm,singlepass,default-backend-singlepass
$(RUNTIME_CHECK) \
--features=cranelift,cache,debug,llvm,singlepass,default-backend-cranelift
--features=cranelift,cache,llvm,singlepass,default-backend-cranelift
$(RUNTIME_CHECK) --release \
--features=cranelift,cache,llvm,singlepass,default-backend-cranelift
$(RUNTIME_CHECK) \
--features=cranelift,cache,debug,llvm,singlepass,default-backend-llvm
--features=cranelift,cache,llvm,singlepass,default-backend-llvm
$(RUNTIME_CHECK) --release \
--features=cranelift,cache,llvm,singlepass,default-backend-llvm
$(RUNTIME_CHECK) \
--features=singlepass,default-backend-singlepass,debug
--features=singlepass,default-backend-singlepass
$(RUNTIME_CHECK) --release \
--features=singlepass,default-backend-singlepass
$(RUNTIME_CHECK) \
--features=cranelift,default-backend-cranelift,debug
--features=cranelift,default-backend-cranelift
$(RUNTIME_CHECK) --release \
--features=cranelift,default-backend-cranelift
$(RUNTIME_CHECK) \
--features=llvm,default-backend-llvm,debug
--features=llvm,default-backend-llvm
$(RUNTIME_CHECK) --release \
--features=llvm,default-backend-llvm
--features=default-backend-singlepass,singlepass,cranelift,llvm,cache,debug,deterministic-execution
--features=default-backend-singlepass,singlepass,cranelift,llvm,cache,deterministic-execution
# Release
release:
cargo build --release --features backend-singlepass,backend-cranelift,backend-llvm,loader-kernel,experimental-io-devices
cargo build --release --features backend-singlepass,backend-cranelift,backend-llvm,loader-kernel,experimental-io-devices,log/release_max_level_off
# Only one backend (cranelift)
release-clif:
@ -303,7 +301,21 @@ dep-graph:
cargo deps --optional-deps --filter wasmer-wasi wasmer-wasi-tests wasmer-kernel-loader wasmer-dev-utils wasmer-llvm-backend wasmer-emscripten wasmer-emscripten-tests wasmer-runtime-core wasmer-runtime wasmer-middleware-common wasmer-middleware-common-tests wasmer-singlepass-backend wasmer-clif-backend wasmer --manifest-path Cargo.toml | dot -Tpng > wasmer_depgraph.png
docs:
cargo doc --features=backend-singlepass,backend-cranelift,backend-llvm,docs,wasi,managed
cargo doc --features=backend-singlepass,backend-cranelift,backend-llvm,docs,wasi,managed --all --no-deps
cd lib/runtime-c-api/ && doxygen doxyfile && cd ..
mkdir -p api-docs
mkdir -p api-docs/c
cp -R target/doc api-docs/crates
cp -R lib/runtime-c-api/doc/html api-docs/c/runtime-c-api
echo '<!-- Build $(SOURCE_VERSION) --><meta http-equiv="refresh" content="0; url=rust/wasmer_runtime/index.html">' > api-docs/index.html
echo '<!-- Build $(SOURCE_VERSION) --><meta http-equiv="refresh" content="0; url=wasmer_runtime/index.html">' > api-docs/crates/index.html
docs-publish:
git clone -b "gh-pages" --depth=1 https://wasmerbot:$(GITHUB_DOCS_TOKEN)@github.com/wasmerio/wasmer.git api-docs-repo
cp -R api-docs/* api-docs-repo/
cd api-docs-repo && git add index.html crates/* c/*
cd api-docs-repo && (git diff-index --quiet HEAD || git commit -m "Publishing GitHub Pages")
cd api-docs-repo && git push origin gh-pages
wapm:
cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"

View File

@ -210,6 +210,29 @@ jobs:
- publish: $(System.DefaultWorkingDirectory)/artifacts
artifact: library-$(Agent.OS)
- job: Build_Docs
pool:
vmImage: "ubuntu-16.04"
variables:
rust_toolchain: nightly-2019-08-15
condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
steps:
- checkout: self
submodules: true
- template: .azure/install-rust.yml
- template: .azure/install-llvm.yml
- template: .azure/install-sccache.yml
- template: .azure/install-cmake.yml
- bash: |
sudo apt-get install doxygen graphviz
displayName: Install doxygen
- bash: |
make docs
displayName: Build docs
- publish: $(System.DefaultWorkingDirectory)/api-docs
artifact: api-docs
displayName: Save Docs artifact
- job: Publish
dependsOn:
- Build_CLI
@ -259,27 +282,33 @@ jobs:
isPreRelease: false
assets: '$(Build.ArtifactStagingDirectory)/**'
- job: Docs
- job: Publish_Docs
dependsOn:
- Build_Docs
displayName: Deploy API Documentation to GitHub
pool:
vmImage: "ubuntu-16.04"
variables:
rust_toolchain: nightly-2019-12-19
condition: in(variables['Build.SourceBranch'], 'refs/heads/master')
steps:
- checkout: self
submodules: true
- template: .azure/install-rust.yml
- template: .azure/install-llvm.yml
- template: .azure/install-sccache.yml
- template: .azure/install-cmake.yml
- task: DownloadPipelineArtifact@2
inputs:
artifactName: api-docs
targetPath: $(System.DefaultWorkingDirectory)/api-docs
- bash: |
make docs
displayName: Build documentation
git config --global user.email "bot@wasmer.io"
git config --global user.name "wasmerbot"
make docs-publish
env:
RUST_DOCS_DIR: $(Pipeline.Workspace)/api-docs
GITHUB_DOCS_TOKEN: $(GITHUB_DOCS_TOKEN)
SOURCE_VERSION: $(Build.SourceVersion)
# We only run the pipelines on PRs to Master
pr:
- master
# Otherwise, we test in any of this branches (master or bors related)
# Otherwise, we test in any of these branches (master or bors related)
trigger:
- master
- staging

1
index.html Normal file
View File

@ -0,0 +1 @@
<meta http-equiv="refresh" content="0; url=rust/wasmer_runtime/index.html">

View File

@ -38,6 +38,3 @@ version = "0.0.7"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.12.0" }
[features]
debug = ["wasmer-runtime-core/debug"]

View File

@ -13,11 +13,9 @@ edition = "2018"
byteorder = "1.3"
lazy_static = "1.4"
libc = "0.2.60"
log = "0.4"
time = "0.1"
wasmer-runtime-core = { path = "../runtime-core", version = "0.12.0" }
[target.'cfg(windows)'.dependencies]
getrandom = "0.1"
[features]
debug = ["wasmer-runtime-core/debug"]

View File

@ -12,6 +12,8 @@
#[macro_use]
extern crate wasmer_runtime_core;
#[macro_use]
extern crate log;
use lazy_static::lazy_static;
use std::cell::UnsafeCell;

View File

@ -46,5 +46,4 @@ rustc_version = "0.2"
wabt = "0.9.1"
[features]
debug = ["wasmer-runtime-core/debug"]
test = []

View File

@ -39,7 +39,6 @@ optional = true
[features]
default = ["cranelift-backend", "wasi"]
debug = ["wasmer-runtime/debug"]
singlepass-backend = ["wasmer-runtime/singlepass", "wasmer-runtime/default-backend-singlepass"]
cranelift-backend = ["wasmer-runtime/cranelift", "wasmer-runtime/default-backend-cranelift"]
llvm-backend = ["wasmer-runtime/llvm", "wasmer-runtime/default-backend-llvm"]

View File

@ -17,8 +17,8 @@
<a href="https://crates.io/crates/wasmer-runtime-c-api">
<img src="https://img.shields.io/crates/d/wasmer-runtime-c-api.svg?style=flat-square" alt="Number of downloads from crates.io">
</a>
<a href="https://docs.rs/wasmer-runtime-c-api">
<img src="https://docs.rs/wasmer-runtime-c-api/badge.svg" alt="Read our API documentation">
<a href="https://wasmerio.github.io/wasmer/c/runtime-c-api/">
<img src="https://img.shields.io/badge/Docs-Wasmer%20C%20API-blue?style=flat-square" alt="Wasmer C API Documentation">
</a>
</p>
@ -38,6 +38,9 @@ crate, respectively [`wasmer.h`][wasmer_h] and
up-to-date in this repository.
The runtime shared library (so, dll, dylib) can also be downloaded in Wasmer [release page](https://github.com/wasmerio/wasmer/releases).
You can find the full C API documentation here:
https://wasmerio.github.io/wasmer/c/runtime-c-api/
Here is a simple example to use the C API:
```c

View File

@ -305,7 +305,7 @@ EXTERNAL_PAGES = YES
CLASS_DIAGRAMS = YES
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
@ -324,7 +324,7 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = svg
INTERACTIVE_SVG = YES
DOT_PATH =
DOT_PATH = ${DOXYGEN_DOT_PATH}
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =

View File

@ -456,6 +456,7 @@ pub unsafe extern "C" fn wasmer_export_func_call(
let instance = &*named_export.instance;
let result = instance.call(&named_export.name, &params[..]);
match result {
Ok(results_vec) => {
if !results_vec.is_empty() {

View File

@ -4,13 +4,20 @@
use crate::{
error::{update_last_error, CApiError},
export::{wasmer_import_export_kind, wasmer_import_export_value},
instance::wasmer_instance_context_t,
module::wasmer_module_t,
value::wasmer_value_tag,
wasmer_byte_array, wasmer_result_t,
};
use libc::c_uint;
use std::{convert::TryFrom, ffi::c_void, ptr, slice, sync::Arc};
use wasmer_runtime::{Global, Memory, Module, Table};
use std::{
convert::TryFrom,
ffi::{c_void, CStr},
os::raw::c_char,
ptr, slice,
sync::Arc,
};
use wasmer_runtime::{Ctx, Global, Memory, Module, Table};
use wasmer_runtime_core::{
export::{Context, Export, FuncPointer},
import::{ImportObject, ImportObjectIterator},
@ -636,9 +643,23 @@ pub unsafe extern "C" fn wasmer_import_func_params_arity(
}
}
/// Creates new func
/// Creates new host function, aka imported function. `func` is a
/// function pointer, where the first argument is the famous `vm::Ctx`
/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
/// must be typed with compatible WebAssembly native types:
///
/// The caller owns the object and should call `wasmer_import_func_destroy` to free it.
/// | WebAssembly type | C/C++ type |
/// | ---------------- | ---------- |
/// | `i32` | `int32_t` |
/// | `i64` | `int64_t` |
/// | `f32` | `float` |
/// | `f64` | `double` |
///
/// The function pointer must have a lifetime greater than the
/// WebAssembly instance lifetime.
///
/// The caller owns the object and should call
/// `wasmer_import_func_destroy` to free it.
#[no_mangle]
#[allow(clippy::cast_ptr_alignment)]
pub unsafe extern "C" fn wasmer_import_func_new(
@ -661,6 +682,59 @@ pub unsafe extern "C" fn wasmer_import_func_new(
Box::into_raw(export) as *mut wasmer_import_func_t
}
/// Stop the execution of a host function, aka imported function. The
/// function must be used _only_ inside a host function.
///
/// The pointer to `wasmer_instance_context_t` is received by the host
/// function as its first argument. Just passing it to `ctx` is fine.
///
/// The error message must have a greater lifetime than the host
/// function itself since the error is read outside the host function
/// with `wasmer_last_error_message`.
///
/// This function returns `wasmer_result_t::WASMER_ERROR` if `ctx` or
/// `error_message` are null.
///
/// This function never returns otherwise.
#[no_mangle]
#[allow(clippy::cast_ptr_alignment)]
pub unsafe extern "C" fn wasmer_trap(
ctx: *const wasmer_instance_context_t,
error_message: *const c_char,
) -> wasmer_result_t {
if ctx.is_null() {
update_last_error(CApiError {
msg: "ctx ptr is null in wasmer_trap".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
}
if error_message.is_null() {
update_last_error(CApiError {
msg: "error_message is null in wasmer_trap".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
}
let ctx = &*(ctx as *const Ctx);
let error_message = CStr::from_ptr(error_message).to_str().unwrap();
(&*ctx.module)
.runnable_module
.do_early_trap(Box::new(error_message)); // never returns
// cbindgen does not generate a binding for a function that
// returns `!`. Since we also need to error in some cases, the
// output type of `wasmer_trap` is `wasmer_result_t`. But the OK
// case is not reachable because `do_early_trap` never
// returns. That's a compromise to satisfy the Rust type system,
// cbindgen, and get an acceptable clean code.
#[allow(unreachable_code)]
wasmer_result_t::WASMER_OK
}
/// Sets the params buffer to the parameter types of the given wasmer_import_func_t
///
/// Returns `wasmer_result_t::WASMER_OK` upon success.

View File

@ -15,6 +15,7 @@ test-exported-memory
test-exports
test-globals
test-import-function
test-import-trap
test-import-object
test-imports
test-instantiate

View File

@ -5,6 +5,7 @@ add_executable(test-exported-memory test-exported-memory.c)
add_executable(test-exports test-exports.c)
add_executable(test-globals test-globals.c)
add_executable(test-import-function test-import-function.c)
add_executable(test-import-trap test-import-trap.c)
add_executable(test-imports test-imports.c)
add_executable(test-import-object test-import-object.c)
add_executable(test-instantiate test-instantiate.c)
@ -64,6 +65,10 @@ target_link_libraries(test-import-function general ${WASMER_LIB})
target_compile_options(test-import-function PRIVATE ${COMPILER_OPTIONS})
add_test(test-import-function test-import-function)
target_link_libraries(test-import-trap general ${WASMER_LIB})
target_compile_options(test-import-trap PRIVATE ${COMPILER_OPTIONS})
add_test(test-import-trap test-import-trap)
target_link_libraries(test-imports general ${WASMER_LIB})
target_compile_options(test-imports PRIVATE ${COMPILER_OPTIONS})
add_test(test-imports test-imports)

View File

@ -31,7 +31,7 @@ void print_str(wasmer_instance_context_t *ctx, int32_t ptr, int32_t len)
actual_str[idx] = mem_bytes[ptr + idx];
}
actual_str[13] = '\0';
printf("In print_str, memory len: %d, ptr_len: %d\n, str %s", mem_len, len, actual_str);
printf("In print_str, memory len: %d, ptr_len: %d, str %s\n", mem_len, len, actual_str);
print_str_called = true;
memory_len = mem_len;
ptr_len = len;

View File

@ -0,0 +1,80 @@
#include <stdio.h>
#include "../wasmer.h"
#include <assert.h>
#include <stdint.h>
#include <string.h>
static const char *trap_error_message = "Hello";
void print_str(wasmer_instance_context_t *ctx, int32_t _ptr, int32_t _len)
{
wasmer_trap(ctx, trap_error_message);
}
int main()
{
wasmer_value_tag params_sig[] = {WASM_I32, WASM_I32};
wasmer_value_tag returns_sig[] = {};
printf("Creating new func\n");
wasmer_import_func_t *func = wasmer_import_func_new((void (*)(void *)) print_str, params_sig, 2, returns_sig, 0);
char *module_name = "env";
wasmer_byte_array module_name_bytes = {
.bytes = (const uint8_t *) module_name,
.bytes_len = strlen(module_name),
};
char *import_name = "print_str";
wasmer_byte_array import_name_bytes = {
.bytes = (const uint8_t *) import_name,
.bytes_len = strlen(import_name),
};
wasmer_import_t import = {
.module_name = module_name_bytes,
.import_name = import_name_bytes,
.tag = WASM_FUNCTION,
.value.func = func,
};
wasmer_import_t imports[] = {import};
// Read the wasm file bytes
FILE *file = fopen("assets/wasm_sample_app.wasm", "r");
fseek(file, 0, SEEK_END);
long len = ftell(file);
uint8_t *bytes = malloc(len);
fseek(file, 0, SEEK_SET);
fread(bytes, 1, len, file);
fclose(file);
printf("Instantiating\n");
wasmer_instance_t *instance = NULL;
wasmer_result_t compile_result = wasmer_instantiate(&instance, bytes, len, imports, 1);
printf("Compile result: %d\n", compile_result);
assert(compile_result == WASMER_OK);
wasmer_value_t params[] = {};
wasmer_value_t results[] = {};
wasmer_result_t call_result = wasmer_instance_call(instance, "hello_wasm", params, 0, results, 0);
printf("Call result: %d\n", call_result);
assert(call_result == WASMER_ERROR);
int error_len = wasmer_last_error_length();
printf("Error len: `%d`\n", error_len);
char *error_str = malloc(error_len);
wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str);
assert(0 == strcmp(error_str, "Call error: \"Hello\""));
printf("Destroying func\n");
wasmer_import_func_destroy(func);
printf("Destroy instance\n");
wasmer_instance_destroy(instance);
return 0;
}

View File

@ -47,7 +47,7 @@ enum Version {
Unknown = 0,
/**
* Latest version. See `wasmer_wasi::WasiVersion::Latest` to
* leran more.
* learn more.
*/
Latest = 1,
/**
@ -537,9 +537,23 @@ unsigned int wasmer_import_descriptors_len(wasmer_import_descriptors_t *exports)
void wasmer_import_func_destroy(wasmer_import_func_t *func);
/**
* Creates new func
* Creates new host function, aka imported function. `func` is a
* function pointer, where the first argument is the famous `vm::Ctx`
* (in Rust), or `wasmer_instance_context_t` (in C). All arguments
* must be typed with compatible WebAssembly native types:
*
* The caller owns the object and should call `wasmer_import_func_destroy` to free it.
* | WebAssembly type | C/C++ type |
* | ---------------- | ---------- |
* | `i32` | `int32_t` |
* | `i64` | `int64_t` |
* | `f32` | `float` |
* | `f64` | `double` |
*
* The function pointer must have a lifetime greater than the
* WebAssembly instance lifetime.
*
* The caller owns the object and should call
* `wasmer_import_func_destroy` to free it.
*/
wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data),
const wasmer_value_tag *params,
@ -966,6 +980,24 @@ const wasmer_trampoline_callable_t *wasmer_trampoline_buffer_get_trampoline(cons
void *wasmer_trampoline_get_context(void);
#endif
/**
* Stop the execution of a host function, aka imported function. The
* function must be used _only_ inside a host function.
*
* The pointer to `wasmer_instance_context_t` is received by the host
* function as its first argument. Just passing it to `ctx` is fine.
*
* The error message must have a greater lifetime than the host
* function itself since the error is read outside the host function
* with `wasmer_last_error_message`.
*
* This function returns `wasmer_result_t::WASMER_ERROR` if `ctx` or
* `error_message` are null.
*
* This function never returns otherwise.
*/
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message);
/**
* Returns true for valid wasm bytes and false for invalid bytes
*/

View File

@ -44,7 +44,7 @@ enum class Version : uint8_t {
/// Version cannot be detected or is unknown.
Unknown = 0,
/// Latest version. See `wasmer_wasi::WasiVersion::Latest` to
/// leran more.
/// learn more.
Latest = 1,
/// `wasi_unstable`.
Snapshot0 = 2,
@ -431,9 +431,23 @@ unsigned int wasmer_import_descriptors_len(wasmer_import_descriptors_t *exports)
/// Frees memory for the given Func
void wasmer_import_func_destroy(wasmer_import_func_t *func);
/// Creates new func
/// Creates new host function, aka imported function. `func` is a
/// function pointer, where the first argument is the famous `vm::Ctx`
/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
/// must be typed with compatible WebAssembly native types:
///
/// The caller owns the object and should call `wasmer_import_func_destroy` to free it.
/// | WebAssembly type | C/C++ type |
/// | ---------------- | ---------- |
/// | `i32` | `int32_t` |
/// | `i64` | `int64_t` |
/// | `f32` | `float` |
/// | `f64` | `double` |
///
/// The function pointer must have a lifetime greater than the
/// WebAssembly instance lifetime.
///
/// The caller owns the object and should call
/// `wasmer_import_func_destroy` to free it.
wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data),
const wasmer_value_tag *params,
unsigned int params_len,
@ -763,6 +777,22 @@ const wasmer_trampoline_callable_t *wasmer_trampoline_buffer_get_trampoline(cons
void *wasmer_trampoline_get_context();
#endif
/// Stop the execution of a host function, aka imported function. The
/// function must be used _only_ inside a host function.
///
/// The pointer to `wasmer_instance_context_t` is received by the host
/// function as its first argument. Just passing it to `ctx` is fine.
///
/// The error message must have a greater lifetime than the host
/// function itself since the error is read outside the host function
/// with `wasmer_last_error_message`.
///
/// This function returns `wasmer_result_t::WASMER_ERROR` if `ctx` or
/// `error_message` are null.
///
/// This function never returns otherwise.
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message);
/// Returns true for valid wasm bytes and false for invalid bytes
bool wasmer_validate(const uint8_t *wasm_bytes, uint32_t wasm_bytes_len);

View File

@ -50,7 +50,5 @@ rustc_version = "0.2"
cc = "1.0"
[features]
debug = []
trace = ["debug"]
managed = []
deterministic-execution = ["wasmparser/deterministic"]

View File

@ -179,10 +179,11 @@ pub trait RunnableModule: Send + Sync {
}
/// A wasm trampoline contains the necessary data to dynamically call an exported wasm function.
/// Given a particular signature index, we are returned a trampoline that is matched with that
/// Given a particular signature index, we return a trampoline that is matched with that
/// signature and an invoke function that can call the trampoline.
fn get_trampoline(&self, info: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm>;
/// Trap an error.
unsafe fn do_early_trap(&self, data: Box<dyn Any + Send>) -> !;
/// Returns the machine code associated with this module.

View File

@ -1,49 +1,3 @@
/// Prints a log message with args, similar to println, when the debug feature is enabled.
/// If the debug feature is disabled, arguments are not evaluated or printed.
#[macro_export]
#[cfg(feature = "debug")]
macro_rules! debug {
($fmt:expr) => (println!(concat!("[{}] wasmer-runtime(:{}) ", $fmt), {
let time = ::std::time::SystemTime::now().duration_since(::std::time::UNIX_EPOCH).expect("Can't get time");
format!("{}.{:03}", time.as_secs(), time.subsec_millis())
}, line!()));
($fmt:expr, $($arg:tt)*) => (println!(concat!("[{}] wasmer-runtime(:{}) ", $fmt, "\n"), {
let time = ::std::time::SystemTime::now().duration_since(::std::time::UNIX_EPOCH).expect("Can't get time");
format!("{}.{:03}", time.as_secs(), time.subsec_millis())
}, line!(), $($arg)*));
}
/// Prints a log message with args, similar to println, when the debug feature is enabled.
/// If the debug feature is disabled, arguments are not evaluated or printed.
#[macro_export]
#[cfg(not(feature = "debug"))]
macro_rules! debug {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => {};
}
/// Prints a log message with args, similar to println, when the trace feature is enabled.
/// If the trace feature is disabled, arguments are not evaluated or printed.
#[macro_export]
#[cfg(feature = "trace")]
macro_rules! trace {
($fmt:expr) => {
debug!($fmt)
};
($fmt:expr, $($arg:tt)*) => {
debug!($fmt, $($arg)*);
}
}
/// Prints a log message with args, similar to println, when the trace feature is enabled.
/// If the trace feature is disabled, arguments are not evaluated or printed.
#[macro_export]
#[cfg(not(feature = "trace"))]
macro_rules! trace {
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => {};
}
/// Helper macro to create a new `Func` object using the provided function pointer.
///
/// # Usage

View File

@ -2,6 +2,7 @@
name = "wasmer-runtime"
version = "0.12.0"
description = "Wasmer runtime library"
documentation = "https://wasmerio.github.io/wasmer/c/runtime-c-api/"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
repository = "https://github.com/wasmerio/wasmer"
@ -46,7 +47,6 @@ default = ["cranelift", "default-backend-cranelift"]
docs = []
cranelift = ["wasmer-clif-backend"]
cache = ["cranelift"]
debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]
llvm = ["wasmer-llvm-backend"]
singlepass = ["wasmer-singlepass-backend"]
default-backend-singlepass = ["singlepass"]

View File

@ -12,6 +12,7 @@ license = "MIT"
maintenance = { status = "experimental" }
[dependencies]
log = "0.4"
minifb = "0.13"
wasmer-wasi = { version = "0.12.0", path = "../wasi" }
wasmer-runtime-core = { version = "0.12.0", path = "../runtime-core" }

View File

@ -1,8 +1,10 @@
#[macro_use]
extern crate log;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeSet, VecDeque};
use std::convert::TryInto;
use std::io::{Read, Seek, SeekFrom, Write};
use wasmer_runtime_core::debug;
use wasmer_wasi::{
state::{Fd, WasiFile, WasiFs, WasiFsError, ALL_RIGHTS, VIRTUAL_ROOT_FD},
types::*,

View File

@ -22,6 +22,8 @@
#[cfg(target = "windows")]
extern crate winapi;
#[macro_use]
extern crate log;
#[macro_use]
mod macros;

View File

@ -3,11 +3,11 @@ macro_rules! wasi_try {
let res: Result<_, crate::syscalls::types::__wasi_errno_t> = $expr;
match res {
Ok(val) => {
wasmer_runtime_core::trace!("wasi::wasi_try::val: {:?}", val);
trace!("wasi::wasi_try::val: {:?}", val);
val
}
Err(err) => {
wasmer_runtime_core::trace!("wasi::wasi_try::err: {:?}", err);
trace!("wasi::wasi_try::err: {:?}", err);
return err;
}
}

View File

@ -31,7 +31,7 @@ use std::{
path::{Path, PathBuf},
time::SystemTime,
};
use wasmer_runtime_core::{debug, vm::Ctx};
use wasmer_runtime_core::vm::Ctx;
/// the fd value of the virtual root
pub const VIRTUAL_ROOT_FD: __wasi_fd_t = 3;

View File

@ -9,7 +9,6 @@ use std::{
path::PathBuf,
time::SystemTime,
};
use wasmer_runtime_core::debug;
/// Error type for external users
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

View File

@ -1,7 +1,7 @@
use crate::ptr::{Array, WasmPtr};
use crate::syscalls;
use crate::syscalls::types::{self, snapshot0};
use wasmer_runtime_core::{debug, vm::Ctx};
use wasmer_runtime_core::vm::Ctx;
/// Wrapper around `syscalls::fd_filestat_get` with extra logic to handle the size
/// difference of `wasi_filestat_t`

View File

@ -21,7 +21,7 @@ use std::borrow::Borrow;
use std::cell::Cell;
use std::convert::{Infallible, TryInto};
use std::io::{self, Read, Seek, Write};
use wasmer_runtime_core::{debug, memory::Memory, vm::Ctx};
use wasmer_runtime_core::{memory::Memory, vm::Ctx};
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub use unix::*;

View File

@ -1,6 +1,5 @@
use crate::syscalls::types::*;
use std::cell::Cell;
use wasmer_runtime_core::debug;
pub fn platform_clock_res_get(
clock_id: __wasi_clockid_t,

View File

@ -8,6 +8,8 @@
unreachable_patterns
)]
extern crate structopt;
#[macro_use]
extern crate log;
use std::collections::HashMap;
use std::env;
@ -37,7 +39,6 @@ use wasmer_runtime_core::tiering::{run_tiering, InteractiveShellContext, ShellEx
use wasmer_runtime_core::{
self,
backend::{Compiler, CompilerConfig, Features, MemoryBoundCheckMode},
debug,
loader::{Instance as LoadedInstance, LocalLoader},
Module,
};
@ -252,6 +253,11 @@ struct Run {
#[structopt(long = "enable-experimental-io-devices", hidden = true)]
enable_experimental_io_devices: bool,
/// Enable debug output
#[cfg(feature = "debug")]
#[structopt(long = "debug", short = "d")]
debug: bool,
/// Application arguments
#[structopt(name = "--", multiple = true)]
args: Vec<String>,
@ -962,7 +968,7 @@ fn interactive_shell(mut ctx: InteractiveShellContext) -> ShellExitOperation {
}
}
#[allow(unused_variables)]
#[allow(unused_variables, unreachable_code)]
fn get_backend(backend: Backend, path: &PathBuf) -> Backend {
// Update backend when a backend flag is `auto`.
// Use the Singlepass backend if it's enabled and the file provided is larger
@ -999,6 +1005,12 @@ fn get_backend(backend: Backend, path: &PathBuf) -> Backend {
fn run(options: &mut Run) {
options.backend = get_backend(options.backend, &options.path);
#[cfg(any(feature = "debug", feature = "trace"))]
{
if options.debug {
logging::set_up_logging().expect("failed to set up logging");
}
}
match execute_wasm(options) {
Ok(()) => {}
Err(message) => {

View File

@ -10,11 +10,13 @@
#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
#[macro_use]
extern crate wasmer_runtime_core;
// extern crate wasmer_emscripten;
#[macro_use]
extern crate log;
#[macro_use]
pub mod update;
#[cfg(feature = "debug")]
pub mod logging;
pub mod utils;
pub mod webassembly;

55
src/logging.rs Normal file
View File

@ -0,0 +1,55 @@
use crate::utils::wasmer_should_print_color;
use fern::colors::{Color, ColoredLevelConfig};
use std::time;
/// Subroutine to instantiate the loggers
pub fn set_up_logging() -> Result<(), String> {
let colors_line = ColoredLevelConfig::new()
.error(Color::Red)
.warn(Color::Yellow)
.trace(Color::BrightBlack);
let should_color = wasmer_should_print_color();
let colors_level = colors_line.info(Color::Green);
let dispatch = fern::Dispatch::new()
.level(log::LevelFilter::Debug)
.chain({
let base = if should_color {
fern::Dispatch::new().format(move |out, message, record| {
let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).expect("Can't get time");
out.finish(format_args!(
"{color_line}[{seconds}.{millis} {level} {target}{color_line}]{ansi_close} {message}",
color_line = format_args!(
"\x1B[{}m",
colors_line.get_color(&record.level()).to_fg_str()
),
seconds = time.as_secs(),
millis = time.subsec_millis(),
level = colors_level.color(record.level()),
target = record.target(),
ansi_close = "\x1B[0m",
message = message,
));
})
} else {
// default formatter without color
fern::Dispatch::new().format(move |out, message, record| {
let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).expect("Can't get time");
out.finish(format_args!(
"[{seconds}.{millis} {level} {target}] {message}",
seconds = time.as_secs(),
millis = time.subsec_millis(),
level = record.level(),
target = record.target(),
message = message,
));
})
};
base.chain(std::io::stdout())
});
dispatch.apply().map_err(|e| format!("{}", e))?;
Ok(())
}

View File

@ -119,3 +119,11 @@ pub fn parse_args(
)
}
}
/// Whether or not Wasmer should print with color
pub fn wasmer_should_print_color() -> bool {
std::env::var("WASMER_COLOR")
.ok()
.and_then(|inner| inner.parse::<bool>().ok())
.unwrap_or(atty::is(atty::Stream::Stdout))
}