mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 16:20:49 +00:00
Merge branch 'master' into feature/tar-install-with-wapm
This commit is contained in:
commit
a3c5fca30f
@ -12,6 +12,14 @@ run_install_dependencies: &run_install_dependencies
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
changelog:
|
||||
docker:
|
||||
- image: docker:stable-git
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: ! git diff --exit-code CHANGELOG.md
|
||||
|
||||
# Job used for testing
|
||||
lint:
|
||||
docker:
|
||||
@ -367,6 +375,7 @@ workflows:
|
||||
version: 2
|
||||
main:
|
||||
jobs:
|
||||
- changelog
|
||||
- lint
|
||||
- test:
|
||||
filters:
|
||||
|
13
CHANGELOG.md
Normal file
13
CHANGELOG.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
All PRs to the Wasmer repository must add to this file.
|
||||
|
||||
Blocks of changes will separated by version increments.
|
||||
|
||||
## **[Unreleased]**
|
||||
- [#348](https://github.com/wasmerio/wasmer/pull/348) Refactor internal runtime ↔️ backend abstraction.
|
||||
- [#355](https://github.com/wasmerio/wasmer/pull/355) Misc changes to `Cargo.toml`s for publishing
|
||||
- [#352](https://github.com/wasmerio/wasmer/pull/352) Bump version numbers to 0.3.0
|
||||
- [#351](https://github.com/wasmerio/wasmer/pull/351) Add hidden option to specify wasm program name (can be used to improve error messages)
|
||||
- [#350](https://github.com/wasmerio/wasmer/pull/350) Enforce that CHANGELOG.md is updated through CI.
|
||||
- [#349](https://github.com/wasmerio/wasmer/pull/349) Add [CHANGELOG.md](https://github.com/wasmerio/wasmer/blob/master/CHANGELOG.md).
|
81
Cargo.lock
generated
81
Cargo.lock
generated
@ -2230,19 +2230,19 @@ dependencies = [
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-clif-backend 0.2.0",
|
||||
"wasmer-emscripten 0.2.1",
|
||||
"wasmer-llvm-backend 0.1.0",
|
||||
"wasmer-runtime 0.2.1",
|
||||
"wasmer-runtime-abi 0.2.1",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-singlepass-backend 0.1.0",
|
||||
"wasmer-wasi 0.2.1",
|
||||
"wasmer-clif-backend 0.3.0",
|
||||
"wasmer-emscripten 0.3.0",
|
||||
"wasmer-llvm-backend 0.3.0",
|
||||
"wasmer-runtime 0.3.0",
|
||||
"wasmer-runtime-abi 0.3.0",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmer-singlepass-backend 0.3.0",
|
||||
"wasmer-wasi 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-clif-backend"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cranelift-codegen 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2258,15 +2258,15 @@ dependencies = [
|
||||
"serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target-lexicon 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-win-exception-handler 0.2.0",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmer-win-exception-handler 0.3.0",
|
||||
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-emscripten"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2275,15 +2275,15 @@ dependencies = [
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-clif-backend 0.2.0",
|
||||
"wasmer-llvm-backend 0.1.0",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-singlepass-backend 0.1.0",
|
||||
"wasmer-clif-backend 0.3.0",
|
||||
"wasmer-llvm-backend 0.3.0",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmer-singlepass-backend 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-llvm-backend"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"capstone 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2298,35 +2298,35 @@ dependencies = [
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-runtime"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"criterion 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-clif-backend 0.2.0",
|
||||
"wasmer-llvm-backend 0.1.0",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-singlepass-backend 0.1.0",
|
||||
"wasmer-clif-backend 0.3.0",
|
||||
"wasmer-llvm-backend 0.3.0",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmer-singlepass-backend 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-runtime-abi"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)",
|
||||
"zstd 0.4.22+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2334,17 +2334,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-runtime-c-api"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"cbindgen 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime 0.2.1",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-runtime 0.3.0",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-runtime-core"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"blake2b_simd 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2363,13 +2363,14 @@ dependencies = [
|
||||
"serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-singlepass-backend"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dynasm 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2379,24 +2380,24 @@ dependencies = [
|
||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-spectests"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-clif-backend 0.2.0",
|
||||
"wasmer-llvm-backend 0.1.0",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-singlepass-backend 0.1.0",
|
||||
"wasmer-clif-backend 0.3.0",
|
||||
"wasmer-llvm-backend 0.3.0",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"wasmer-singlepass-backend 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-wasi"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2404,19 +2405,19 @@ dependencies = [
|
||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmer-win-exception-handler"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-runtime-core 0.2.1",
|
||||
"wasmer-runtime-core 0.3.0",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
4
LICENSE
4
LICENSE
@ -1,4 +1,6 @@
|
||||
Copyright (c) 2019 Syrus Akbary
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Wasmer, Inc. and its affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -2,8 +2,9 @@ status = [
|
||||
"ci/circleci: lint",
|
||||
"ci/circleci: test",
|
||||
"ci/circleci: test-macos",
|
||||
"ci/circleci: test-rust-nightly",
|
||||
"continuous-integration/appveyor/branch"
|
||||
]
|
||||
required_approvals = 1
|
||||
timeout_sec = 900
|
||||
delete_merged_branches = true
|
||||
delete_merged_branches = true
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-clif-backend"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer runtime Cranelift compiler backend"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||
cranelift-native = "0.30.0"
|
||||
cranelift-codegen = "0.30.0"
|
||||
cranelift-entity = "0.30.0"
|
||||
@ -33,7 +33,7 @@ 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.2.0" }
|
||||
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.3.0" }
|
||||
|
||||
[features]
|
||||
debug = ["wasmer-runtime-core/debug"]
|
||||
|
@ -73,16 +73,15 @@ impl Module {
|
||||
handler_data.clone(),
|
||||
)?;
|
||||
|
||||
let protected_caller = Caller::new(&self.info, handler_data, trampolines);
|
||||
|
||||
let cache_gen = Box::new(CacheGenerator::new(
|
||||
backend_cache,
|
||||
Arc::clone(&func_resolver.memory),
|
||||
));
|
||||
|
||||
let runnable_module = Caller::new(handler_data, trampolines, func_resolver);
|
||||
|
||||
Ok(ModuleInner {
|
||||
func_resolver: Box::new(func_resolver),
|
||||
protected_caller: Box::new(protected_caller),
|
||||
runnable_module: Box::new(runnable_module),
|
||||
cache_gen,
|
||||
|
||||
info: self.info,
|
||||
@ -103,16 +102,15 @@ impl Module {
|
||||
)
|
||||
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?;
|
||||
|
||||
let protected_caller = Caller::new(&info, handler_data, trampolines);
|
||||
|
||||
let cache_gen = Box::new(CacheGenerator::new(
|
||||
backend_cache,
|
||||
Arc::clone(&func_resolver.memory),
|
||||
));
|
||||
|
||||
let runnable_module = Caller::new(handler_data, trampolines, func_resolver);
|
||||
|
||||
Ok(ModuleInner {
|
||||
func_resolver: Box::new(func_resolver),
|
||||
protected_caller: Box::new(protected_caller),
|
||||
runnable_module: Box::new(runnable_module),
|
||||
cache_gen,
|
||||
|
||||
info,
|
||||
|
@ -21,7 +21,6 @@ use wasmer_runtime_core::cache::Error as CacheError;
|
||||
use wasmer_runtime_core::{
|
||||
self,
|
||||
backend::{
|
||||
self,
|
||||
sys::{Memory, Protect},
|
||||
SigRegistry,
|
||||
},
|
||||
@ -357,13 +356,8 @@ pub struct FuncResolver {
|
||||
pub(crate) memory: Arc<Memory>,
|
||||
}
|
||||
|
||||
// Implements FuncResolver trait.
|
||||
impl backend::FuncResolver for FuncResolver {
|
||||
fn get(
|
||||
&self,
|
||||
_module: &wasmer_runtime_core::module::ModuleInner,
|
||||
index: LocalFuncIndex,
|
||||
) -> Option<NonNull<vm::Func>> {
|
||||
impl FuncResolver {
|
||||
pub fn lookup(&self, index: LocalFuncIndex) -> Option<NonNull<vm::Func>> {
|
||||
lookup_func(&self.map, &self.memory, index)
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,14 @@
|
||||
use crate::relocation::{TrapData, TrapSink};
|
||||
use crate::resolver::FuncResolver;
|
||||
use crate::trampoline::Trampolines;
|
||||
use hashbrown::HashSet;
|
||||
use libc::c_void;
|
||||
use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc};
|
||||
use wasmer_runtime_core::{
|
||||
backend::{ProtectedCaller, Token, UserTrapper},
|
||||
error::RuntimeResult,
|
||||
export::Context,
|
||||
module::{ExportIndex, ModuleInfo, ModuleInner},
|
||||
backend::{RunnableModule, UserTrapper},
|
||||
module::ModuleInfo,
|
||||
typed_func::{Wasm, WasmTrapInfo},
|
||||
types::{FuncIndex, FuncSig, LocalOrImport, SigIndex, Type, Value},
|
||||
vm::{self, ImportBacking},
|
||||
types::{LocalFuncIndex, SigIndex},
|
||||
vm,
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
@ -39,130 +37,44 @@ impl UserTrapper for Trapper {
|
||||
}
|
||||
|
||||
pub struct Caller {
|
||||
func_export_set: HashSet<FuncIndex>,
|
||||
handler_data: HandlerData,
|
||||
trampolines: Arc<Trampolines>,
|
||||
resolver: FuncResolver,
|
||||
}
|
||||
|
||||
impl Caller {
|
||||
pub fn new(
|
||||
module: &ModuleInfo,
|
||||
handler_data: HandlerData,
|
||||
trampolines: Arc<Trampolines>,
|
||||
resolver: FuncResolver,
|
||||
) -> Self {
|
||||
let mut func_export_set = HashSet::new();
|
||||
for export_index in module.exports.values() {
|
||||
if let ExportIndex::Func(func_index) = export_index {
|
||||
func_export_set.insert(*func_index);
|
||||
}
|
||||
}
|
||||
if let Some(start_func_index) = module.start_func {
|
||||
func_export_set.insert(start_func_index);
|
||||
}
|
||||
|
||||
Self {
|
||||
func_export_set,
|
||||
handler_data,
|
||||
trampolines,
|
||||
resolver,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProtectedCaller for Caller {
|
||||
fn call(
|
||||
&self,
|
||||
module: &ModuleInner,
|
||||
func_index: FuncIndex,
|
||||
params: &[Value],
|
||||
import_backing: &ImportBacking,
|
||||
vmctx: *mut vm::Ctx,
|
||||
_: Token,
|
||||
) -> RuntimeResult<Vec<Value>> {
|
||||
let (func_ptr, ctx, signature, sig_index) =
|
||||
get_func_from_index(&module, import_backing, func_index);
|
||||
|
||||
let vmctx_ptr = match ctx {
|
||||
Context::External(external_vmctx) => external_vmctx,
|
||||
Context::Internal => vmctx,
|
||||
};
|
||||
|
||||
assert!(self.func_export_set.contains(&func_index));
|
||||
|
||||
assert!(
|
||||
signature.returns().len() <= 1,
|
||||
"multi-value returns not yet supported"
|
||||
);
|
||||
|
||||
assert!(
|
||||
signature.check_param_value_types(params),
|
||||
"incorrect signature"
|
||||
);
|
||||
|
||||
let param_vec: Vec<u64> = params
|
||||
.iter()
|
||||
.map(|val| match val {
|
||||
Value::I32(x) => *x as u64,
|
||||
Value::I64(x) => *x as u64,
|
||||
Value::F32(x) => x.to_bits() as u64,
|
||||
Value::F64(x) => x.to_bits(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut return_vec = vec![0; signature.returns().len()];
|
||||
|
||||
let trampoline = self
|
||||
.trampolines
|
||||
.lookup(sig_index)
|
||||
.expect("that trampoline doesn't exist");
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
call_protected(&self.handler_data, || unsafe {
|
||||
// Leap of faith.
|
||||
trampoline(
|
||||
vmctx_ptr,
|
||||
func_ptr,
|
||||
param_vec.as_ptr(),
|
||||
return_vec.as_mut_ptr(),
|
||||
);
|
||||
})?;
|
||||
|
||||
// the trampoline is called from C on windows
|
||||
#[cfg(target_os = "windows")]
|
||||
call_protected(
|
||||
&self.handler_data,
|
||||
trampoline,
|
||||
vmctx_ptr,
|
||||
func_ptr,
|
||||
param_vec.as_ptr(),
|
||||
return_vec.as_mut_ptr(),
|
||||
)?;
|
||||
|
||||
Ok(return_vec
|
||||
.iter()
|
||||
.zip(signature.returns().iter())
|
||||
.map(|(&x, ty)| match ty {
|
||||
Type::I32 => Value::I32(x as i32),
|
||||
Type::I64 => Value::I64(x as i64),
|
||||
Type::F32 => Value::F32(f32::from_bits(x as u32)),
|
||||
Type::F64 => Value::F64(f64::from_bits(x as u64)),
|
||||
})
|
||||
.collect())
|
||||
impl RunnableModule for Caller {
|
||||
fn get_func(&self, _: &ModuleInfo, func_index: LocalFuncIndex) -> Option<NonNull<vm::Func>> {
|
||||
self.resolver.lookup(func_index)
|
||||
}
|
||||
|
||||
fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
||||
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||
unsafe extern "C" fn invoke(
|
||||
trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64),
|
||||
ctx: *mut vm::Ctx,
|
||||
func: NonNull<vm::Func>,
|
||||
args: *const u64,
|
||||
rets: *mut u64,
|
||||
trap_info: *mut WasmTrapInfo,
|
||||
_trap_info: *mut WasmTrapInfo,
|
||||
invoke_env: Option<NonNull<c_void>>,
|
||||
) -> bool {
|
||||
let handler_data = &*invoke_env.unwrap().cast().as_ptr();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let res = call_protected(handler_data, || unsafe {
|
||||
let res = call_protected(handler_data, || {
|
||||
// Leap of faith.
|
||||
trampoline(ctx, func, args, rets);
|
||||
})
|
||||
@ -194,40 +106,6 @@ impl ProtectedCaller for Caller {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_func_from_index<'a>(
|
||||
module: &'a ModuleInner,
|
||||
import_backing: &ImportBacking,
|
||||
func_index: FuncIndex,
|
||||
) -> (NonNull<vm::Func>, Context, &'a FuncSig, SigIndex) {
|
||||
let sig_index = *module
|
||||
.info
|
||||
.func_assoc
|
||||
.get(func_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
|
||||
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
||||
LocalOrImport::Local(local_func_index) => (
|
||||
module
|
||||
.func_resolver
|
||||
.get(&module, local_func_index)
|
||||
.expect("broken invariant, func resolver not synced with module.exports")
|
||||
.cast(),
|
||||
Context::Internal,
|
||||
),
|
||||
LocalOrImport::Import(imported_func_index) => {
|
||||
let imported_func = import_backing.imported_func(imported_func_index);
|
||||
(
|
||||
NonNull::new(imported_func.func as *mut _).unwrap(),
|
||||
Context::External(imported_func.vmctx),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let signature = &module.info.signatures[sig_index];
|
||||
|
||||
(func_ptr, ctx, signature, sig_index)
|
||||
}
|
||||
|
||||
unsafe impl Send for HandlerData {}
|
||||
unsafe impl Sync for HandlerData {}
|
||||
|
||||
|
@ -6,7 +6,6 @@ use cranelift_codegen::{
|
||||
isa, Context,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use std::ffi::c_void;
|
||||
use std::{iter, mem, ptr::NonNull};
|
||||
use wasmer_runtime_core::{
|
||||
backend::sys::{Memory, Protect},
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-emscripten"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer runtime emscripten implementation library"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -9,14 +9,14 @@ edition = "2018"
|
||||
build = "build/mod.rs"
|
||||
|
||||
[dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||
lazy_static = "1.2.0"
|
||||
libc = "0.2.49"
|
||||
byteorder = "1"
|
||||
time = "0.1.41"
|
||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.2.0" }
|
||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.1.0", optional = true }
|
||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.1.0", optional = true }
|
||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.3.0" }
|
||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.3.0", optional = true }
|
||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.3.0", optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
rand = "0.6"
|
||||
|
@ -226,6 +226,10 @@ pub fn invoke_iiii(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32) -> i32
|
||||
debug!("emscripten::invoke_iiii");
|
||||
invoke!(ctx, dyn_call_iiii, index, a1, a2, a3)
|
||||
}
|
||||
pub fn invoke_iifi(ctx: &mut Ctx, index: i32, a1: i32, a2: f64, a3: i32) -> i32 {
|
||||
debug!("emscripten::invoke_iifi");
|
||||
invoke!(ctx, dyn_call_iifi, index, a1, a2, a3)
|
||||
}
|
||||
pub fn invoke_v(ctx: &mut Ctx, index: i32) {
|
||||
debug!("emscripten::invoke_v");
|
||||
invoke_no_return!(ctx, dyn_call_v, index);
|
||||
@ -298,6 +302,33 @@ pub fn invoke_iiiiiiii(
|
||||
debug!("emscripten::invoke_iiiiiiii");
|
||||
invoke!(ctx, dyn_call_iiiiiiii, index, a1, a2, a3, a4, a5, a6, a7)
|
||||
}
|
||||
pub fn invoke_iiiiiiiii(
|
||||
ctx: &mut Ctx,
|
||||
index: i32,
|
||||
a1: i32,
|
||||
a2: i32,
|
||||
a3: i32,
|
||||
a4: i32,
|
||||
a5: i32,
|
||||
a6: i32,
|
||||
a7: i32,
|
||||
a8: i32,
|
||||
) -> i32 {
|
||||
debug!("emscripten::invoke_iiiiiiiii");
|
||||
invoke!(
|
||||
ctx,
|
||||
dyn_call_iiiiiiiii,
|
||||
index,
|
||||
a1,
|
||||
a2,
|
||||
a3,
|
||||
a4,
|
||||
a5,
|
||||
a6,
|
||||
a7,
|
||||
a8
|
||||
)
|
||||
}
|
||||
pub fn invoke_iiiiiiiiii(
|
||||
ctx: &mut Ctx,
|
||||
index: i32,
|
||||
@ -327,6 +358,37 @@ pub fn invoke_iiiiiiiiii(
|
||||
a9
|
||||
)
|
||||
}
|
||||
pub fn invoke_iiiiiiiiiii(
|
||||
ctx: &mut Ctx,
|
||||
index: i32,
|
||||
a1: i32,
|
||||
a2: i32,
|
||||
a3: i32,
|
||||
a4: i32,
|
||||
a5: i32,
|
||||
a6: i32,
|
||||
a7: i32,
|
||||
a8: i32,
|
||||
a9: i32,
|
||||
a10: i32,
|
||||
) -> i32 {
|
||||
debug!("emscripten::invoke_iiiiiiiiiii");
|
||||
invoke!(
|
||||
ctx,
|
||||
dyn_call_iiiiiiiiiii,
|
||||
index,
|
||||
a1,
|
||||
a2,
|
||||
a3,
|
||||
a4,
|
||||
a5,
|
||||
a6,
|
||||
a7,
|
||||
a8,
|
||||
a9,
|
||||
a10
|
||||
)
|
||||
}
|
||||
pub fn invoke_vd(ctx: &mut Ctx, index: i32, a1: f64) {
|
||||
debug!("emscripten::invoke_vd");
|
||||
invoke_no_return!(ctx, dyn_call_vd, index, a1)
|
||||
@ -450,13 +512,28 @@ pub fn invoke_viiiiiiiiii(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn invoke_iij(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32) -> i32 {
|
||||
debug!("emscripten::invoke_iij");
|
||||
invoke!(ctx, dyn_call_iij, index, a1, a2, a3)
|
||||
}
|
||||
|
||||
pub fn invoke_iiji(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) -> i32 {
|
||||
debug!("emscripten::invoke_iiji");
|
||||
if let Some(dyn_call_iiji) = &get_emscripten_data(ctx).dyn_call_iiji {
|
||||
dyn_call_iiji.call(index, a1, a2, a3, a4).unwrap()
|
||||
} else {
|
||||
panic!("dyn_call_iiji is set to None");
|
||||
}
|
||||
invoke!(ctx, dyn_call_iiji, index, a1, a2, a3, a4)
|
||||
}
|
||||
|
||||
pub fn invoke_iiijj(
|
||||
ctx: &mut Ctx,
|
||||
index: i32,
|
||||
a1: i32,
|
||||
a2: i32,
|
||||
a3: i32,
|
||||
a4: i32,
|
||||
a5: i32,
|
||||
a6: i32,
|
||||
) -> i32 {
|
||||
debug!("emscripten::invoke_iiijj");
|
||||
invoke!(ctx, dyn_call_iiijj, index, a1, a2, a3, a4, a5, a6)
|
||||
}
|
||||
pub fn invoke_j(ctx: &mut Ctx, index: i32) -> i32 {
|
||||
debug!("emscripten::invoke_j");
|
||||
@ -655,11 +732,42 @@ pub fn invoke_vijj(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32, a4: i32
|
||||
panic!("dyn_call_vijj is set to None");
|
||||
}
|
||||
}
|
||||
pub fn invoke_viid(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: f64) {
|
||||
debug!("emscripten::invoke_viid");
|
||||
invoke_no_return!(ctx, dyn_call_viid, index, a1, a2, a3);
|
||||
}
|
||||
pub fn invoke_viidii(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: f64, a4: i32, a5: i32) {
|
||||
debug!("emscripten::invoke_viidii");
|
||||
if let Some(dyn_call_viidii) = &get_emscripten_data(ctx).dyn_call_viidii {
|
||||
dyn_call_viidii.call(index, a1, a2, a3, a4, a5).unwrap();
|
||||
} else {
|
||||
panic!("dyn_call_viidii is set to None");
|
||||
}
|
||||
invoke_no_return!(ctx, dyn_call_viidii, index, a1, a2, a3, a4, a5);
|
||||
}
|
||||
pub fn invoke_viidddddddd(
|
||||
ctx: &mut Ctx,
|
||||
index: i32,
|
||||
a1: i32,
|
||||
a2: i32,
|
||||
a3: f64,
|
||||
a4: f64,
|
||||
a5: f64,
|
||||
a6: f64,
|
||||
a7: f64,
|
||||
a8: f64,
|
||||
a9: f64,
|
||||
a10: f64,
|
||||
) {
|
||||
debug!("emscripten::invoke_viidddddddd");
|
||||
invoke_no_return!(
|
||||
ctx,
|
||||
dyn_call_viidddddddd,
|
||||
index,
|
||||
a1,
|
||||
a2,
|
||||
a3,
|
||||
a4,
|
||||
a5,
|
||||
a6,
|
||||
a7,
|
||||
a8,
|
||||
a9,
|
||||
a10
|
||||
);
|
||||
}
|
||||
|
7
lib/emscripten/src/env/mod.rs
vendored
7
lib/emscripten/src/env/mod.rs
vendored
@ -47,6 +47,13 @@ pub fn _getpagesize(_ctx: &mut Ctx) -> u32 {
|
||||
16384
|
||||
}
|
||||
|
||||
pub fn _times(ctx: &mut Ctx, buffer: u32) -> u32 {
|
||||
if buffer != 0 {
|
||||
call_memset(ctx, buffer, 0, 16);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub fn ___build_environment(ctx: &mut Ctx, environ: c_int) {
|
||||
debug!("emscripten::___build_environment {}", environ);
|
||||
|
@ -83,6 +83,7 @@ pub struct EmscriptenData<'a> {
|
||||
pub dyn_call_ii: Option<Func<'a, (i32, i32), i32>>,
|
||||
pub dyn_call_iii: Option<Func<'a, (i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiii: Option<Func<'a, (i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iifi: Option<Func<'a, (i32, i32, f64, i32), i32>>,
|
||||
pub dyn_call_v: Option<Func<'a, (i32)>>,
|
||||
pub dyn_call_vi: Option<Func<'a, (i32, i32)>>,
|
||||
pub dyn_call_vii: Option<Func<'a, (i32, i32, i32)>>,
|
||||
@ -96,8 +97,11 @@ pub struct EmscriptenData<'a> {
|
||||
pub dyn_call_iiiiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiiiiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiiiiiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiiiiiiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiiiiiiiii:
|
||||
Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiiiiiiiiii:
|
||||
Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_vd: Option<Func<'a, (i32, f64)>>,
|
||||
pub dyn_call_viiiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32)>>,
|
||||
pub dyn_call_viiiiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32)>>,
|
||||
@ -106,7 +110,9 @@ pub struct EmscriptenData<'a> {
|
||||
pub dyn_call_viiiiiiiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)>>,
|
||||
pub dyn_call_viiiiiiiiii:
|
||||
Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)>>,
|
||||
pub dyn_call_iij: Option<Func<'a, (i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiji: Option<Func<'a, (i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_iiijj: Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32), i32>>,
|
||||
pub dyn_call_j: Option<Func<'a, i32, i32>>,
|
||||
pub dyn_call_ji: Option<Func<'a, (i32, i32), i32>>,
|
||||
pub dyn_call_jii: Option<Func<'a, (i32, i32, i32), i32>>,
|
||||
@ -125,7 +131,10 @@ pub struct EmscriptenData<'a> {
|
||||
pub dyn_call_viji: Option<Func<'a, (i32, i32, i32, i32, i32)>>,
|
||||
pub dyn_call_vijiii: Option<Func<'a, (i32, i32, i32, i32, i32, i32, i32)>>,
|
||||
pub dyn_call_vijj: Option<Func<'a, (i32, i32, i32, i32, i32, i32)>>,
|
||||
pub dyn_call_viid: Option<Func<'a, (i32, i32, i32, f64)>>,
|
||||
pub dyn_call_viidii: Option<Func<'a, (i32, i32, i32, f64, i32, i32)>>,
|
||||
pub dyn_call_viidddddddd:
|
||||
Option<Func<'a, (i32, i32, i32, f64, f64, f64, f64, f64, f64, f64, f64)>>,
|
||||
pub temp_ret_0: i32,
|
||||
|
||||
pub stack_save: Option<Func<'a, (), i32>>,
|
||||
@ -149,6 +158,7 @@ impl<'a> EmscriptenData<'a> {
|
||||
let dyn_call_ii = instance.func("dynCall_ii").ok();
|
||||
let dyn_call_iii = instance.func("dynCall_iii").ok();
|
||||
let dyn_call_iiii = instance.func("dynCall_iiii").ok();
|
||||
let dyn_call_iifi = instance.func("dynCall_iifi").ok();
|
||||
let dyn_call_v = instance.func("dynCall_v").ok();
|
||||
let dyn_call_vi = instance.func("dynCall_vi").ok();
|
||||
let dyn_call_vii = instance.func("dynCall_vii").ok();
|
||||
@ -162,7 +172,9 @@ impl<'a> EmscriptenData<'a> {
|
||||
let dyn_call_iiiiii = instance.func("dynCall_iiiiii").ok();
|
||||
let dyn_call_iiiiiii = instance.func("dynCall_iiiiiii").ok();
|
||||
let dyn_call_iiiiiiii = instance.func("dynCall_iiiiiiii").ok();
|
||||
let dyn_call_iiiiiiiii = instance.func("dynCall_iiiiiiiii").ok();
|
||||
let dyn_call_iiiiiiiiii = instance.func("dynCall_iiiiiiiiii").ok();
|
||||
let dyn_call_iiiiiiiiiii = instance.func("dynCall_iiiiiiiiiii").ok();
|
||||
let dyn_call_vd = instance.func("dynCall_vd").ok();
|
||||
let dyn_call_viiiii = instance.func("dynCall_viiiii").ok();
|
||||
let dyn_call_viiiiii = instance.func("dynCall_viiiiii").ok();
|
||||
@ -170,7 +182,9 @@ impl<'a> EmscriptenData<'a> {
|
||||
let dyn_call_viiiiiiii = instance.func("dynCall_viiiiiiii").ok();
|
||||
let dyn_call_viiiiiiiii = instance.func("dynCall_viiiiiiiii").ok();
|
||||
let dyn_call_viiiiiiiiii = instance.func("dynCall_viiiiiiiiii").ok();
|
||||
let dyn_call_iij = instance.func("dynCall_iij").ok();
|
||||
let dyn_call_iiji = instance.func("dynCall_iiji").ok();
|
||||
let dyn_call_iiijj = instance.func("dynCall_iiijj").ok();
|
||||
let dyn_call_j = instance.func("dynCall_j").ok();
|
||||
let dyn_call_ji = instance.func("dynCall_ji").ok();
|
||||
let dyn_call_jii = instance.func("dynCall_jii").ok();
|
||||
@ -188,7 +202,9 @@ impl<'a> EmscriptenData<'a> {
|
||||
let dyn_call_viji = instance.func("dynCall_viji").ok();
|
||||
let dyn_call_vijiii = instance.func("dynCall_vijiii").ok();
|
||||
let dyn_call_vijj = instance.func("dynCall_vijj").ok();
|
||||
let dyn_call_viid = instance.func("dynCall_viid").ok();
|
||||
let dyn_call_viidii = instance.func("dynCall_viidii").ok();
|
||||
let dyn_call_viidddddddd = instance.func("dynCall_viidddddddd").ok();
|
||||
|
||||
let stack_save = instance.func("stackSave").ok();
|
||||
let stack_restore = instance.func("stackRestore").ok();
|
||||
@ -205,6 +221,7 @@ impl<'a> EmscriptenData<'a> {
|
||||
dyn_call_ii,
|
||||
dyn_call_iii,
|
||||
dyn_call_iiii,
|
||||
dyn_call_iifi,
|
||||
dyn_call_v,
|
||||
dyn_call_vi,
|
||||
dyn_call_vii,
|
||||
@ -218,7 +235,9 @@ impl<'a> EmscriptenData<'a> {
|
||||
dyn_call_iiiiii,
|
||||
dyn_call_iiiiiii,
|
||||
dyn_call_iiiiiiii,
|
||||
dyn_call_iiiiiiiii,
|
||||
dyn_call_iiiiiiiiii,
|
||||
dyn_call_iiiiiiiiiii,
|
||||
dyn_call_vd,
|
||||
dyn_call_viiiii,
|
||||
dyn_call_viiiiii,
|
||||
@ -226,7 +245,9 @@ impl<'a> EmscriptenData<'a> {
|
||||
dyn_call_viiiiiiii,
|
||||
dyn_call_viiiiiiiii,
|
||||
dyn_call_viiiiiiiiii,
|
||||
dyn_call_iij,
|
||||
dyn_call_iiji,
|
||||
dyn_call_iiijj,
|
||||
dyn_call_j,
|
||||
dyn_call_ji,
|
||||
dyn_call_jii,
|
||||
@ -244,7 +265,9 @@ impl<'a> EmscriptenData<'a> {
|
||||
dyn_call_viji,
|
||||
dyn_call_vijiii,
|
||||
dyn_call_vijj,
|
||||
dyn_call_viid,
|
||||
dyn_call_viidii,
|
||||
dyn_call_viidddddddd,
|
||||
temp_ret_0: 0,
|
||||
|
||||
stack_save,
|
||||
@ -506,6 +529,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"_getpagesize" => func!(crate::env::_getpagesize),
|
||||
"_sysconf" => func!(crate::env::_sysconf),
|
||||
"_getaddrinfo" => func!(crate::env::_getaddrinfo),
|
||||
"_times" => func!(crate::env::_times),
|
||||
|
||||
// Syscalls
|
||||
"___syscall1" => func!(crate::syscalls::___syscall1),
|
||||
@ -657,6 +681,8 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"_llvm_log2_f32" => func!(crate::math::_llvm_log2_f64),
|
||||
"_llvm_sin_f64" => func!(crate::math::_llvm_sin_f64),
|
||||
"_llvm_cos_f64" => func!(crate::math::_llvm_cos_f64),
|
||||
"_llvm_exp2_f32" => func!(crate::math::_llvm_exp2_f32),
|
||||
"_llvm_exp2_f64" => func!(crate::math::_llvm_exp2_f64),
|
||||
"_emscripten_random" => func!(crate::math::_emscripten_random),
|
||||
|
||||
// Jump
|
||||
@ -681,6 +707,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"invoke_ii" => func!(crate::emscripten_target::invoke_ii),
|
||||
"invoke_iii" => func!(crate::emscripten_target::invoke_iii),
|
||||
"invoke_iiii" => func!(crate::emscripten_target::invoke_iiii),
|
||||
"invoke_iifi" => func!(crate::emscripten_target::invoke_iifi),
|
||||
"invoke_v" => func!(crate::emscripten_target::invoke_v),
|
||||
"invoke_vi" => func!(crate::emscripten_target::invoke_vi),
|
||||
"invoke_vj" => func!(crate::emscripten_target::invoke_vj),
|
||||
@ -727,7 +754,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"invoke_iiiiii" => func!(crate::emscripten_target::invoke_iiiiii),
|
||||
"invoke_iiiiiii" => func!(crate::emscripten_target::invoke_iiiiiii),
|
||||
"invoke_iiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiii),
|
||||
"invoke_iiiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiiii),
|
||||
"invoke_iiiiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiiiii),
|
||||
"invoke_iiiiiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiiiiii),
|
||||
"invoke_vd" => func!(crate::emscripten_target::invoke_vd),
|
||||
"invoke_viiiii" => func!(crate::emscripten_target::invoke_viiiii),
|
||||
"invoke_viiiiii" => func!(crate::emscripten_target::invoke_viiiiii),
|
||||
@ -736,7 +765,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"invoke_viiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiii),
|
||||
"invoke_viiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiii),
|
||||
"invoke_viiiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiiii),
|
||||
"invoke_iij" => func!(crate::emscripten_target::invoke_iij),
|
||||
"invoke_iiji" => func!(crate::emscripten_target::invoke_iiji),
|
||||
"invoke_iiijj" => func!(crate::emscripten_target::invoke_iiijj),
|
||||
"invoke_j" => func!(crate::emscripten_target::invoke_j),
|
||||
"invoke_ji" => func!(crate::emscripten_target::invoke_ji),
|
||||
"invoke_jii" => func!(crate::emscripten_target::invoke_jii),
|
||||
@ -753,7 +784,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"invoke_viji" => func!(crate::emscripten_target::invoke_viji),
|
||||
"invoke_vijiii" => func!(crate::emscripten_target::invoke_vijiii),
|
||||
"invoke_vijj" => func!(crate::emscripten_target::invoke_vijj),
|
||||
"invoke_viid" => func!(crate::emscripten_target::invoke_viid),
|
||||
"invoke_viidii" => func!(crate::emscripten_target::invoke_viidii),
|
||||
"invoke_viidddddddd" => func!(crate::emscripten_target::invoke_viidddddddd),
|
||||
};
|
||||
|
||||
for null_func_name in globals.null_func_names.iter() {
|
||||
|
@ -34,6 +34,16 @@ pub fn _llvm_log2_f32(_ctx: &mut Ctx, _value: f64) -> f64 {
|
||||
-1.0
|
||||
}
|
||||
|
||||
pub fn _llvm_exp2_f32(_ctx: &mut Ctx, value: f32) -> f32 {
|
||||
debug!("emscripten::_llvm_exp2_f32");
|
||||
2f32.powf(value)
|
||||
}
|
||||
|
||||
pub fn _llvm_exp2_f64(_ctx: &mut Ctx, value: f64) -> f64 {
|
||||
debug!("emscripten::_llvm_exp2_f64");
|
||||
2f64.powf(value)
|
||||
}
|
||||
|
||||
pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 {
|
||||
debug!("emscripten::_emscripten_random");
|
||||
-1.0
|
||||
|
@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "wasmer-llvm-backend"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
authors = ["Lachlan Sneff <lachlan.sneff@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||
inkwell = { git = "https://github.com/wasmerio/inkwell", branch = "llvm7-0" }
|
||||
wasmparser = "0.28.0"
|
||||
hashbrown = "0.1.8"
|
||||
@ -27,4 +27,4 @@ wabt = "0.7.4"
|
||||
|
||||
[features]
|
||||
debug = ["wasmer-runtime-core/debug"]
|
||||
disasm = ["capstone"]
|
||||
disasm = ["capstone"]
|
||||
|
@ -18,15 +18,12 @@ use std::{
|
||||
sync::Once,
|
||||
};
|
||||
use wasmer_runtime_core::{
|
||||
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
|
||||
error::{RuntimeError, RuntimeResult},
|
||||
export::Context,
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
backend::{RunnableModule, UserTrapper},
|
||||
module::ModuleInfo,
|
||||
structures::TypedIndex,
|
||||
typed_func::{Wasm, WasmTrapInfo},
|
||||
types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, Value},
|
||||
vm::{self, ImportBacking},
|
||||
vmcalls,
|
||||
types::{LocalFuncIndex, SigIndex},
|
||||
vm, vmcalls,
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
@ -216,7 +213,7 @@ pub struct LLVMBackend {
|
||||
}
|
||||
|
||||
impl LLVMBackend {
|
||||
pub fn new(module: Module, _intrinsics: Intrinsics) -> (Self, LLVMProtectedCaller) {
|
||||
pub fn new(module: Module, _intrinsics: Intrinsics) -> Self {
|
||||
Target::initialize_x86(&InitializationConfig {
|
||||
asm_parser: true,
|
||||
asm_printer: true,
|
||||
@ -265,16 +262,21 @@ impl LLVMBackend {
|
||||
panic!("failed to load object")
|
||||
}
|
||||
|
||||
(
|
||||
Self {
|
||||
module,
|
||||
memory_buffer,
|
||||
},
|
||||
LLVMProtectedCaller { module },
|
||||
)
|
||||
Self {
|
||||
module,
|
||||
memory_buffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_func(
|
||||
impl Drop for LLVMBackend {
|
||||
fn drop(&mut self) {
|
||||
unsafe { module_delete(self.module) }
|
||||
}
|
||||
}
|
||||
|
||||
impl RunnableModule for LLVMBackend {
|
||||
fn get_func(
|
||||
&self,
|
||||
info: &ModuleInfo,
|
||||
local_func_index: LocalFuncIndex,
|
||||
@ -291,126 +293,8 @@ impl LLVMBackend {
|
||||
|
||||
NonNull::new(ptr as _)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LLVMBackend {
|
||||
fn drop(&mut self) {
|
||||
unsafe { module_delete(self.module) }
|
||||
}
|
||||
}
|
||||
|
||||
impl FuncResolver for LLVMBackend {
|
||||
fn get(
|
||||
&self,
|
||||
module: &ModuleInner,
|
||||
local_func_index: LocalFuncIndex,
|
||||
) -> Option<NonNull<vm::Func>> {
|
||||
self.get_func(&module.info, local_func_index)
|
||||
}
|
||||
}
|
||||
|
||||
struct Placeholder;
|
||||
|
||||
unsafe impl Send for LLVMProtectedCaller {}
|
||||
unsafe impl Sync for LLVMProtectedCaller {}
|
||||
|
||||
pub struct LLVMProtectedCaller {
|
||||
module: *mut LLVMModule,
|
||||
}
|
||||
|
||||
impl ProtectedCaller for LLVMProtectedCaller {
|
||||
fn call(
|
||||
&self,
|
||||
module: &ModuleInner,
|
||||
func_index: FuncIndex,
|
||||
params: &[Value],
|
||||
import_backing: &ImportBacking,
|
||||
vmctx: *mut vm::Ctx,
|
||||
_: Token,
|
||||
) -> RuntimeResult<Vec<Value>> {
|
||||
let (func_ptr, ctx, signature, sig_index) =
|
||||
get_func_from_index(&module, import_backing, func_index);
|
||||
|
||||
let vmctx_ptr = match ctx {
|
||||
Context::External(external_vmctx) => external_vmctx,
|
||||
Context::Internal => vmctx,
|
||||
};
|
||||
|
||||
assert!(
|
||||
signature.returns().len() <= 1,
|
||||
"multi-value returns not yet supported"
|
||||
);
|
||||
|
||||
assert!(
|
||||
signature.check_param_value_types(params),
|
||||
"incorrect signature"
|
||||
);
|
||||
|
||||
let param_vec: Vec<u64> = params
|
||||
.iter()
|
||||
.map(|val| match val {
|
||||
Value::I32(x) => *x as u64,
|
||||
Value::I64(x) => *x as u64,
|
||||
Value::F32(x) => x.to_bits() as u64,
|
||||
Value::F64(x) => x.to_bits(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut return_vec = vec![0; signature.returns().len()];
|
||||
|
||||
let trampoline: unsafe extern "C" fn(
|
||||
*mut vm::Ctx,
|
||||
NonNull<vm::Func>,
|
||||
*const u64,
|
||||
*mut u64,
|
||||
) = unsafe {
|
||||
let name = if cfg!(target_os = "macos") {
|
||||
format!("_trmp{}", sig_index.index())
|
||||
} else {
|
||||
format!("trmp{}", sig_index.index())
|
||||
};
|
||||
|
||||
let c_str = CString::new(name).unwrap();
|
||||
let symbol = get_func_symbol(self.module, c_str.as_ptr());
|
||||
assert!(!symbol.is_null());
|
||||
|
||||
mem::transmute(symbol)
|
||||
};
|
||||
|
||||
let mut trap_out = WasmTrapInfo::Unknown;
|
||||
|
||||
// Here we go.
|
||||
let success = unsafe {
|
||||
invoke_trampoline(
|
||||
trampoline,
|
||||
vmctx_ptr,
|
||||
func_ptr,
|
||||
param_vec.as_ptr(),
|
||||
return_vec.as_mut_ptr(),
|
||||
&mut trap_out,
|
||||
None,
|
||||
)
|
||||
};
|
||||
|
||||
if success {
|
||||
Ok(return_vec
|
||||
.iter()
|
||||
.zip(signature.returns().iter())
|
||||
.map(|(&x, ty)| match ty {
|
||||
Type::I32 => Value::I32(x as i32),
|
||||
Type::I64 => Value::I64(x as i64),
|
||||
Type::F32 => Value::F32(f32::from_bits(x as u32)),
|
||||
Type::F64 => Value::F64(f64::from_bits(x as u64)),
|
||||
})
|
||||
.collect())
|
||||
} else {
|
||||
Err(RuntimeError::Trap {
|
||||
msg: trap_out.to_string().into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn get_wasm_trampoline(&self, _module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
||||
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||
let trampoline: unsafe extern "C" fn(
|
||||
*mut vm::Ctx,
|
||||
NonNull<vm::Func>,
|
||||
@ -438,46 +322,14 @@ impl ProtectedCaller for LLVMProtectedCaller {
|
||||
}
|
||||
}
|
||||
|
||||
struct Placeholder;
|
||||
|
||||
impl UserTrapper for Placeholder {
|
||||
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
|
||||
throw_any(Box::leak(data))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_func_from_index<'a>(
|
||||
module: &'a ModuleInner,
|
||||
import_backing: &ImportBacking,
|
||||
func_index: FuncIndex,
|
||||
) -> (NonNull<vm::Func>, Context, &'a FuncSig, SigIndex) {
|
||||
let sig_index = *module
|
||||
.info
|
||||
.func_assoc
|
||||
.get(func_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
|
||||
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
||||
LocalOrImport::Local(local_func_index) => (
|
||||
module
|
||||
.func_resolver
|
||||
.get(&module, local_func_index)
|
||||
.expect("broken invariant, func resolver not synced with module.exports")
|
||||
.cast(),
|
||||
Context::Internal,
|
||||
),
|
||||
LocalOrImport::Import(imported_func_index) => {
|
||||
let imported_func = import_backing.imported_func(imported_func_index);
|
||||
(
|
||||
NonNull::new(imported_func.func as *mut _).unwrap(),
|
||||
Context::External(imported_func.vmctx),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let signature = &module.info.signatures[sig_index];
|
||||
|
||||
(func_ptr, ctx, signature, sig_index)
|
||||
}
|
||||
|
||||
#[cfg(feature = "disasm")]
|
||||
unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) {
|
||||
use capstone::arch::BuildsCapstone;
|
||||
|
@ -38,7 +38,7 @@ impl Compiler for LLVMCompiler {
|
||||
let (info, code_reader) = read_info::read_module(wasm, compiler_config).unwrap();
|
||||
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
||||
|
||||
let (backend, protected_caller) = backend::LLVMBackend::new(module, intrinsics);
|
||||
let backend = backend::LLVMBackend::new(module, intrinsics);
|
||||
|
||||
// Create placeholder values here.
|
||||
let cache_gen = {
|
||||
@ -61,8 +61,7 @@ impl Compiler for LLVMCompiler {
|
||||
};
|
||||
|
||||
Ok(ModuleInner {
|
||||
func_resolver: Box::new(backend),
|
||||
protected_caller: Box::new(protected_caller),
|
||||
runnable_module: Box::new(backend),
|
||||
cache_gen,
|
||||
|
||||
info,
|
||||
@ -104,7 +103,9 @@ fn validate(bytes: &[u8]) -> Result<(), CompileError> {
|
||||
fn test_read_module() {
|
||||
use std::mem::transmute;
|
||||
use wabt::wat2wasm;
|
||||
use wasmer_runtime_core::{structures::TypedIndex, types::LocalFuncIndex, vm, vmcalls};
|
||||
use wasmer_runtime_core::{
|
||||
backend::RunnableModule, structures::TypedIndex, types::LocalFuncIndex, vm,
|
||||
};
|
||||
// let wasm = include_bytes!("../../spectests/examples/simple/simple.wasm") as &[u8];
|
||||
let wat = r#"
|
||||
(module
|
||||
@ -122,7 +123,7 @@ fn test_read_module() {
|
||||
|
||||
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
||||
|
||||
let (backend, _caller) = backend::LLVMBackend::new(module, intrinsics);
|
||||
let backend = backend::LLVMBackend::new(module, intrinsics);
|
||||
|
||||
let func_ptr = backend.get_func(&info, LocalFuncIndex::new(0)).unwrap();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-runtime-abi"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer runtime core library"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-runtime-c-api"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer C API library"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -16,15 +16,15 @@ libc = "0.2"
|
||||
|
||||
[dependencies.wasmer-runtime]
|
||||
path = "../runtime"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
|
||||
[dependencies.wasmer-runtime-core]
|
||||
path = "../runtime-core"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
|
||||
[features]
|
||||
debug = ["wasmer-runtime/debug"]
|
||||
llvm = ["wasmer-runtime/llvm"]
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.8"
|
||||
cbindgen = "0.8"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-runtime-core"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer runtime core library"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -17,6 +17,7 @@ indexmap = "1.0.2"
|
||||
errno = "0.2.4"
|
||||
libc = "0.2.49"
|
||||
hex = "0.3.2"
|
||||
smallvec = "0.6.9"
|
||||
|
||||
# Dependencies for caching.
|
||||
[dependencies.serde]
|
||||
|
@ -1,10 +1,8 @@
|
||||
use crate::{
|
||||
backing::ImportBacking,
|
||||
error::CompileResult,
|
||||
error::RuntimeResult,
|
||||
module::ModuleInner,
|
||||
typed_func::Wasm,
|
||||
types::{FuncIndex, LocalFuncIndex, SigIndex, Value},
|
||||
types::{LocalFuncIndex, SigIndex},
|
||||
vm,
|
||||
};
|
||||
|
||||
@ -67,59 +65,25 @@ pub trait Compiler {
|
||||
unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
|
||||
}
|
||||
|
||||
/// The functionality exposed by this trait is expected to be used
|
||||
/// for calling functions exported by a webassembly module from
|
||||
/// host code only.
|
||||
pub trait ProtectedCaller: Send + Sync {
|
||||
/// This calls the exported function designated by `local_func_index`.
|
||||
/// Important to note, this supports calling imported functions that are
|
||||
/// then exported.
|
||||
///
|
||||
/// It's invalid to attempt to call a local function that isn't exported and
|
||||
/// the implementation is expected to check for that. The implementation
|
||||
/// is also expected to check for correct parameter types and correct
|
||||
/// parameter number.
|
||||
///
|
||||
/// The `returns` parameter is filled with dummy values when passed in and upon function
|
||||
/// return, will be filled with the return values of the wasm function, as long as the
|
||||
/// call completed successfully.
|
||||
///
|
||||
/// The existance of the Token parameter ensures that this can only be called from
|
||||
/// within the runtime crate.
|
||||
///
|
||||
/// TODO(lachlan): Now that `get_wasm_trampoline` exists, `ProtectedCaller::call`
|
||||
/// can be removed. That should speed up calls a little bit, since sanity checks
|
||||
/// would only occur once.
|
||||
fn call(
|
||||
&self,
|
||||
module: &ModuleInner,
|
||||
func_index: FuncIndex,
|
||||
params: &[Value],
|
||||
import_backing: &ImportBacking,
|
||||
vmctx: *mut vm::Ctx,
|
||||
_: Token,
|
||||
) -> RuntimeResult<Vec<Value>>;
|
||||
|
||||
/// A wasm trampoline contains the necesarry data to dynamically call an exported wasm function.
|
||||
/// Given a particular signature index, we are returned a trampoline that is matched with that
|
||||
/// signature and an invoke function that can call the trampoline.
|
||||
fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm>;
|
||||
|
||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper>;
|
||||
}
|
||||
|
||||
pub trait UserTrapper {
|
||||
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> !;
|
||||
}
|
||||
|
||||
pub trait FuncResolver: Send + Sync {
|
||||
pub trait RunnableModule: Send + Sync {
|
||||
/// This returns a pointer to the function designated by the `local_func_index`
|
||||
/// parameter.
|
||||
fn get(
|
||||
fn get_func(
|
||||
&self,
|
||||
module: &ModuleInner,
|
||||
info: &ModuleInfo,
|
||||
local_func_index: LocalFuncIndex,
|
||||
) -> Option<NonNull<vm::Func>>;
|
||||
|
||||
/// A wasm trampoline contains the necesarry data to dynamically call an exported wasm function.
|
||||
/// Given a particular signature index, we are returned 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>;
|
||||
|
||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper>;
|
||||
}
|
||||
|
||||
pub trait CacheGen: Send + Sync {
|
||||
|
@ -72,8 +72,8 @@ impl LocalBacking {
|
||||
(0..module.info.func_assoc.len() - module.info.imported_functions.len())
|
||||
.map(|index| {
|
||||
module
|
||||
.func_resolver
|
||||
.get(module, LocalFuncIndex::new(index))
|
||||
.runnable_module
|
||||
.get_func(&module.info, LocalFuncIndex::new(index))
|
||||
.unwrap()
|
||||
.as_ptr() as *const _
|
||||
})
|
||||
@ -216,8 +216,8 @@ impl LocalBacking {
|
||||
let (func, ctx) = match func_index.local_or_import(&module.info) {
|
||||
LocalOrImport::Local(local_func_index) => (
|
||||
module
|
||||
.func_resolver
|
||||
.get(module, local_func_index)
|
||||
.runnable_module
|
||||
.get_func(&module.info, local_func_index)
|
||||
.unwrap()
|
||||
.as_ptr()
|
||||
as *const vm::Func,
|
||||
@ -255,8 +255,8 @@ impl LocalBacking {
|
||||
let (func, ctx) = match func_index.local_or_import(&module.info) {
|
||||
LocalOrImport::Local(local_func_index) => (
|
||||
module
|
||||
.func_resolver
|
||||
.get(module, local_func_index)
|
||||
.runnable_module
|
||||
.get_func(&module.info, local_func_index)
|
||||
.unwrap()
|
||||
.as_ptr()
|
||||
as *const vm::Func,
|
||||
|
@ -1,18 +1,19 @@
|
||||
use crate::{
|
||||
backend::Token,
|
||||
backend::RunnableModule,
|
||||
backing::{ImportBacking, LocalBacking},
|
||||
error::{CallError, CallResult, ResolveError, ResolveResult, Result},
|
||||
error::{CallError, CallResult, ResolveError, ResolveResult, Result, RuntimeError},
|
||||
export::{Context, Export, ExportIter, FuncPointer},
|
||||
global::Global,
|
||||
import::{ImportObject, LikeNamespace},
|
||||
memory::Memory,
|
||||
module::{ExportIndex, Module, ModuleInner},
|
||||
module::{ExportIndex, Module, ModuleInfo, ModuleInner},
|
||||
sig_registry::SigRegistry,
|
||||
table::Table,
|
||||
typed_func::{Func, Wasm, WasmTypeList},
|
||||
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
|
||||
typed_func::{Func, Wasm, WasmTrapInfo, WasmTypeList},
|
||||
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Type, Value},
|
||||
vm,
|
||||
};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::{mem, ptr::NonNull, sync::Arc};
|
||||
|
||||
pub(crate) struct InstanceInner {
|
||||
@ -82,7 +83,45 @@ impl Instance {
|
||||
};
|
||||
|
||||
if let Some(start_index) = instance.module.info.start_func {
|
||||
instance.call_with_index(start_index, &[])?;
|
||||
// We know that the start function takes no arguments and returns no values.
|
||||
// Therefore, we can call it without doing any signature checking, etc.
|
||||
|
||||
let func_ptr = match start_index.local_or_import(&instance.module.info) {
|
||||
LocalOrImport::Local(local_func_index) => instance
|
||||
.module
|
||||
.runnable_module
|
||||
.get_func(&instance.module.info, local_func_index)
|
||||
.unwrap(),
|
||||
LocalOrImport::Import(import_func_index) => NonNull::new(
|
||||
instance.inner.import_backing.vm_functions[import_func_index].func as *mut _,
|
||||
)
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
let ctx_ptr = match start_index.local_or_import(&instance.module.info) {
|
||||
LocalOrImport::Local(_) => instance.inner.vmctx,
|
||||
LocalOrImport::Import(imported_func_index) => {
|
||||
instance.inner.import_backing.vm_functions[imported_func_index].vmctx
|
||||
}
|
||||
};
|
||||
|
||||
let sig_index = *instance
|
||||
.module
|
||||
.info
|
||||
.func_assoc
|
||||
.get(start_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
|
||||
let wasm_trampoline = instance
|
||||
.module
|
||||
.runnable_module
|
||||
.get_trampoline(&instance.module.info, sig_index)
|
||||
.expect("wasm trampoline");
|
||||
|
||||
let start_func: Func<(), (), Wasm> =
|
||||
unsafe { Func::from_raw_parts(wasm_trampoline, func_ptr, ctx_ptr) };
|
||||
|
||||
start_func.call()?;
|
||||
}
|
||||
|
||||
Ok(instance)
|
||||
@ -147,15 +186,15 @@ impl Instance {
|
||||
|
||||
let func_wasm_inner = self
|
||||
.module
|
||||
.protected_caller
|
||||
.get_wasm_trampoline(&self.module, sig_index)
|
||||
.runnable_module
|
||||
.get_trampoline(&self.module.info, sig_index)
|
||||
.unwrap();
|
||||
|
||||
let func_ptr = match func_index.local_or_import(&self.module.info) {
|
||||
LocalOrImport::Local(local_func_index) => self
|
||||
.module
|
||||
.func_resolver
|
||||
.get(&self.module, local_func_index)
|
||||
.runnable_module
|
||||
.get_func(&self.module.info, local_func_index)
|
||||
.unwrap(),
|
||||
LocalOrImport::Import(import_func_index) => NonNull::new(
|
||||
self.inner.import_backing.vm_functions[import_func_index].func as *mut _,
|
||||
@ -245,7 +284,7 @@ impl Instance {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn call(&self, name: &str, args: &[Value]) -> CallResult<Vec<Value>> {
|
||||
pub fn call(&self, name: &str, params: &[Value]) -> CallResult<Vec<Value>> {
|
||||
let export_index =
|
||||
self.module
|
||||
.info
|
||||
@ -264,7 +303,19 @@ impl Instance {
|
||||
.into());
|
||||
};
|
||||
|
||||
self.call_with_index(func_index, args)
|
||||
let mut results = Vec::new();
|
||||
|
||||
call_func_with_index(
|
||||
&self.module.info,
|
||||
&*self.module.runnable_module,
|
||||
&self.inner.import_backing,
|
||||
self.inner.vmctx,
|
||||
func_index,
|
||||
params,
|
||||
&mut results,
|
||||
)?;
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
/// Returns an immutable reference to the
|
||||
@ -295,45 +346,6 @@ impl Instance {
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
fn call_with_index(&self, func_index: FuncIndex, args: &[Value]) -> CallResult<Vec<Value>> {
|
||||
let sig_index = *self
|
||||
.module
|
||||
.info
|
||||
.func_assoc
|
||||
.get(func_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
let signature = &self.module.info.signatures[sig_index];
|
||||
|
||||
if !signature.check_param_value_types(args) {
|
||||
Err(ResolveError::Signature {
|
||||
expected: signature.clone(),
|
||||
found: args.iter().map(|val| val.ty()).collect(),
|
||||
})?
|
||||
}
|
||||
|
||||
let vmctx = match func_index.local_or_import(&self.module.info) {
|
||||
LocalOrImport::Local(_) => self.inner.vmctx,
|
||||
LocalOrImport::Import(imported_func_index) => {
|
||||
self.inner.import_backing.vm_functions[imported_func_index].vmctx
|
||||
}
|
||||
};
|
||||
|
||||
let token = Token::generate();
|
||||
|
||||
let returns = self.module.protected_caller.call(
|
||||
&self.module,
|
||||
func_index,
|
||||
args,
|
||||
&self.inner.import_backing,
|
||||
vmctx,
|
||||
token,
|
||||
)?;
|
||||
|
||||
Ok(returns)
|
||||
}
|
||||
}
|
||||
|
||||
impl InstanceInner {
|
||||
pub(crate) fn get_export_from_index(
|
||||
&self,
|
||||
@ -382,8 +394,8 @@ impl InstanceInner {
|
||||
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
||||
LocalOrImport::Local(local_func_index) => (
|
||||
module
|
||||
.func_resolver
|
||||
.get(&module, local_func_index)
|
||||
.runnable_module
|
||||
.get_func(&module.info, local_func_index)
|
||||
.expect("broken invariant, func resolver not synced with module.exports")
|
||||
.cast()
|
||||
.as_ptr() as *const _,
|
||||
@ -452,6 +464,128 @@ impl LikeNamespace for Instance {
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn call_func_with_index(
|
||||
info: &ModuleInfo,
|
||||
runnable: &dyn RunnableModule,
|
||||
import_backing: &ImportBacking,
|
||||
local_ctx: *mut vm::Ctx,
|
||||
func_index: FuncIndex,
|
||||
args: &[Value],
|
||||
rets: &mut Vec<Value>,
|
||||
) -> CallResult<()> {
|
||||
rets.clear();
|
||||
|
||||
let sig_index = *info
|
||||
.func_assoc
|
||||
.get(func_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
|
||||
let signature = &info.signatures[sig_index];
|
||||
let num_results = signature.returns().len();
|
||||
rets.reserve(num_results);
|
||||
|
||||
if !signature.check_param_value_types(args) {
|
||||
Err(ResolveError::Signature {
|
||||
expected: signature.clone(),
|
||||
found: args.iter().map(|val| val.ty()).collect(),
|
||||
})?
|
||||
}
|
||||
|
||||
let func_ptr = match func_index.local_or_import(info) {
|
||||
LocalOrImport::Local(local_func_index) => {
|
||||
runnable.get_func(info, local_func_index).unwrap()
|
||||
}
|
||||
LocalOrImport::Import(import_func_index) => {
|
||||
NonNull::new(import_backing.vm_functions[import_func_index].func as *mut _).unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
let ctx_ptr = match func_index.local_or_import(info) {
|
||||
LocalOrImport::Local(_) => local_ctx,
|
||||
LocalOrImport::Import(imported_func_index) => {
|
||||
import_backing.vm_functions[imported_func_index].vmctx
|
||||
}
|
||||
};
|
||||
|
||||
let raw_args: SmallVec<[u64; 8]> = args
|
||||
.iter()
|
||||
.map(|v| match v {
|
||||
Value::I32(i) => *i as u64,
|
||||
Value::I64(i) => *i as u64,
|
||||
Value::F32(f) => f.to_bits() as u64,
|
||||
Value::F64(f) => f.to_bits(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let Wasm {
|
||||
trampoline,
|
||||
invoke,
|
||||
invoke_env,
|
||||
} = runnable
|
||||
.get_trampoline(info, sig_index)
|
||||
.expect("wasm trampoline");
|
||||
|
||||
let run_wasm = |result_space: *mut u64| unsafe {
|
||||
let mut trap_info = WasmTrapInfo::Unknown;
|
||||
|
||||
let success = invoke(
|
||||
trampoline,
|
||||
ctx_ptr,
|
||||
func_ptr,
|
||||
raw_args.as_ptr(),
|
||||
result_space,
|
||||
&mut trap_info,
|
||||
invoke_env,
|
||||
);
|
||||
|
||||
if success {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(RuntimeError::Trap {
|
||||
msg: trap_info.to_string().into(),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let raw_to_value = |raw, ty| match ty {
|
||||
Type::I32 => Value::I32(raw as i32),
|
||||
Type::I64 => Value::I64(raw as i64),
|
||||
Type::F32 => Value::F32(f32::from_bits(raw as u32)),
|
||||
Type::F64 => Value::F64(f64::from_bits(raw)),
|
||||
};
|
||||
|
||||
match signature.returns() {
|
||||
&[] => {
|
||||
run_wasm(0 as *mut u64)?;
|
||||
Ok(())
|
||||
}
|
||||
&[ty] => {
|
||||
let mut result = 0u64;
|
||||
|
||||
run_wasm(&mut result)?;
|
||||
|
||||
rets.push(raw_to_value(result, ty));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
result_tys @ _ => {
|
||||
let mut results: SmallVec<[u64; 8]> = smallvec![0; num_results];
|
||||
|
||||
run_wasm(results.as_mut_ptr())?;
|
||||
|
||||
rets.extend(
|
||||
results
|
||||
.iter()
|
||||
.zip(result_tys.iter())
|
||||
.map(|(&raw, &ty)| raw_to_value(raw, ty)),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A representation of an exported WebAssembly function.
|
||||
pub struct DynFunc<'a> {
|
||||
pub(crate) signature: Arc<FuncSig>,
|
||||
@ -484,32 +618,19 @@ impl<'a> DynFunc<'a> {
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn call(&self, params: &[Value]) -> CallResult<Vec<Value>> {
|
||||
if !self.signature.check_param_value_types(params) {
|
||||
Err(ResolveError::Signature {
|
||||
expected: (*self.signature).clone(),
|
||||
found: params.iter().map(|val| val.ty()).collect(),
|
||||
})?
|
||||
}
|
||||
let mut results = Vec::new();
|
||||
|
||||
let vmctx = match self.func_index.local_or_import(&self.module.info) {
|
||||
LocalOrImport::Local(_) => self.instance_inner.vmctx,
|
||||
LocalOrImport::Import(imported_func_index) => {
|
||||
self.instance_inner.import_backing.vm_functions[imported_func_index].vmctx
|
||||
}
|
||||
};
|
||||
|
||||
let token = Token::generate();
|
||||
|
||||
let returns = self.module.protected_caller.call(
|
||||
&self.module,
|
||||
call_func_with_index(
|
||||
&self.module.info,
|
||||
&*self.module.runnable_module,
|
||||
&self.instance_inner.import_backing,
|
||||
self.instance_inner.vmctx,
|
||||
self.func_index,
|
||||
params,
|
||||
&self.instance_inner.import_backing,
|
||||
vmctx,
|
||||
token,
|
||||
&mut results,
|
||||
)?;
|
||||
|
||||
Ok(returns)
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub fn signature(&self) -> &FuncSig {
|
||||
@ -520,8 +641,8 @@ impl<'a> DynFunc<'a> {
|
||||
match self.func_index.local_or_import(&self.module.info) {
|
||||
LocalOrImport::Local(local_func_index) => self
|
||||
.module
|
||||
.func_resolver
|
||||
.get(self.module, local_func_index)
|
||||
.runnable_module
|
||||
.get_func(&self.module.info, local_func_index)
|
||||
.unwrap()
|
||||
.as_ptr(),
|
||||
LocalOrImport::Import(import_func_index) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
backend::{Backend, FuncResolver, ProtectedCaller},
|
||||
backend::{Backend, RunnableModule},
|
||||
cache::{Artifact, Error as CacheError},
|
||||
error,
|
||||
import::ImportObject,
|
||||
@ -22,9 +22,7 @@ use std::sync::Arc;
|
||||
/// This is used to instantiate a new WebAssembly module.
|
||||
#[doc(hidden)]
|
||||
pub struct ModuleInner {
|
||||
pub func_resolver: Box<dyn FuncResolver>,
|
||||
pub protected_caller: Box<dyn ProtectedCaller>,
|
||||
|
||||
pub runnable_module: Box<dyn RunnableModule>,
|
||||
pub cache_gen: Box<dyn CacheGen>,
|
||||
|
||||
pub info: ModuleInfo,
|
||||
@ -96,7 +94,7 @@ impl Module {
|
||||
pub(crate) fn new(inner: Arc<ModuleInner>) -> Self {
|
||||
unsafe {
|
||||
EARLY_TRAPPER
|
||||
.with(|ucell| *ucell.get() = Some(inner.protected_caller.get_early_trapper()));
|
||||
.with(|ucell| *ucell.get() = Some(inner.runnable_module.get_early_trapper()));
|
||||
}
|
||||
Module { inner }
|
||||
}
|
||||
|
@ -71,9 +71,9 @@ pub type Invoke = unsafe extern "C" fn(
|
||||
/// as well as the environment that the invoke function may or may not require.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Wasm {
|
||||
trampoline: Trampoline,
|
||||
invoke: Invoke,
|
||||
invoke_env: Option<NonNull<c_void>>,
|
||||
pub(crate) trampoline: Trampoline,
|
||||
pub(crate) invoke: Invoke,
|
||||
pub(crate) invoke_env: Option<NonNull<c_void>>,
|
||||
}
|
||||
|
||||
impl Wasm {
|
||||
|
@ -544,42 +544,23 @@ mod vm_ctx_tests {
|
||||
|
||||
fn generate_module() -> ModuleInner {
|
||||
use super::Func;
|
||||
use crate::backend::{
|
||||
sys::Memory, Backend, CacheGen, FuncResolver, ProtectedCaller, Token, UserTrapper,
|
||||
};
|
||||
use crate::backend::{sys::Memory, Backend, CacheGen, RunnableModule, UserTrapper};
|
||||
use crate::cache::Error as CacheError;
|
||||
use crate::error::RuntimeResult;
|
||||
use crate::typed_func::Wasm;
|
||||
use crate::types::{FuncIndex, LocalFuncIndex, SigIndex, Value};
|
||||
use crate::types::{LocalFuncIndex, SigIndex};
|
||||
use hashbrown::HashMap;
|
||||
use std::ptr::NonNull;
|
||||
struct Placeholder;
|
||||
impl FuncResolver for Placeholder {
|
||||
fn get(
|
||||
impl RunnableModule for Placeholder {
|
||||
fn get_func(
|
||||
&self,
|
||||
_module: &ModuleInner,
|
||||
_module: &ModuleInfo,
|
||||
_local_func_index: LocalFuncIndex,
|
||||
) -> Option<NonNull<Func>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
impl ProtectedCaller for Placeholder {
|
||||
fn call(
|
||||
&self,
|
||||
_module: &ModuleInner,
|
||||
_func_index: FuncIndex,
|
||||
_params: &[Value],
|
||||
_import_backing: &ImportBacking,
|
||||
_vmctx: *mut Ctx,
|
||||
_: Token,
|
||||
) -> RuntimeResult<Vec<Value>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
fn get_wasm_trampoline(
|
||||
&self,
|
||||
_module: &ModuleInner,
|
||||
_sig_index: SigIndex,
|
||||
) -> Option<Wasm> {
|
||||
|
||||
fn get_trampoline(&self, _module: &ModuleInfo, _sig_index: SigIndex) -> Option<Wasm> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
|
||||
@ -596,8 +577,7 @@ mod vm_ctx_tests {
|
||||
}
|
||||
|
||||
ModuleInner {
|
||||
func_resolver: Box::new(Placeholder),
|
||||
protected_caller: Box::new(Placeholder),
|
||||
runnable_module: Box::new(Placeholder),
|
||||
cache_gen: Box::new(Placeholder),
|
||||
info: ModuleInfo {
|
||||
memories: Map::new(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-runtime"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer runtime library"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -9,17 +9,17 @@ edition = "2018"
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
wasmer-singlepass-backend = { path = "../singlepass-backend", optional = true }
|
||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.3.0", optional = true }
|
||||
lazy_static = "1.2.0"
|
||||
memmap = "0.7.0"
|
||||
|
||||
[dependencies.wasmer-runtime-core]
|
||||
path = "../runtime-core"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
|
||||
[dependencies.wasmer-clif-backend]
|
||||
path = "../clif-backend"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-singlepass-backend"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
repository = "https://github.com/wasmerio/wasmer"
|
||||
description = "Wasmer runtime single pass compiler backend"
|
||||
license = "MIT"
|
||||
@ -8,7 +8,7 @@ authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||
wasmparser = "0.28.0"
|
||||
dynasm = "0.3.1"
|
||||
dynasmrt = "0.3.1"
|
||||
|
@ -1,15 +1,15 @@
|
||||
use wasmer_runtime_core::{
|
||||
backend::{FuncResolver, ProtectedCaller},
|
||||
backend::RunnableModule,
|
||||
module::ModuleInfo,
|
||||
structures::Map,
|
||||
types::{FuncIndex, FuncSig, SigIndex},
|
||||
};
|
||||
use wasmparser::{Operator, Type as WpType};
|
||||
|
||||
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator, PC: ProtectedCaller, FR: FuncResolver> {
|
||||
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator, RM: RunnableModule> {
|
||||
fn check_precondition(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError>;
|
||||
fn next_function(&mut self) -> Result<&mut FCG, CodegenError>;
|
||||
fn finalize(self, module_info: &ModuleInfo) -> Result<(PC, FR), CodegenError>;
|
||||
fn finalize(self, module_info: &ModuleInfo) -> Result<RM, CodegenError>;
|
||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError>;
|
||||
fn feed_function_signatures(
|
||||
&mut self,
|
||||
|
@ -11,17 +11,16 @@ use smallvec::SmallVec;
|
||||
use std::ptr::NonNull;
|
||||
use std::{any::Any, collections::HashMap, sync::Arc};
|
||||
use wasmer_runtime_core::{
|
||||
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
|
||||
error::RuntimeResult,
|
||||
backend::{RunnableModule, UserTrapper},
|
||||
memory::MemoryType,
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
module::ModuleInfo,
|
||||
structures::{Map, TypedIndex},
|
||||
typed_func::Wasm,
|
||||
types::{
|
||||
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
||||
TableIndex, Type, Value,
|
||||
TableIndex, Type,
|
||||
},
|
||||
vm::{self, ImportBacking, LocalGlobal, LocalMemory, LocalTable},
|
||||
vm::{self, LocalGlobal, LocalMemory, LocalTable},
|
||||
vmcalls,
|
||||
};
|
||||
use wasmparser::{Operator, Type as WpType};
|
||||
@ -132,7 +131,6 @@ pub struct X64FunctionCode {
|
||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
||||
|
||||
begin_offset: AssemblyOffset,
|
||||
assembler: Option<Assembler>,
|
||||
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
|
||||
br_table_data: Option<Vec<Vec<usize>>>,
|
||||
@ -154,7 +152,9 @@ unsafe impl Send for FuncPtr {}
|
||||
unsafe impl Sync for FuncPtr {}
|
||||
|
||||
pub struct X64ExecutionContext {
|
||||
#[allow(dead_code)]
|
||||
code: ExecutableBuffer,
|
||||
#[allow(dead_code)]
|
||||
functions: Vec<X64FunctionCode>,
|
||||
function_pointers: Vec<FuncPtr>,
|
||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||
@ -162,10 +162,6 @@ pub struct X64ExecutionContext {
|
||||
func_import_count: usize,
|
||||
}
|
||||
|
||||
pub struct X64RuntimeResolver {
|
||||
local_function_pointers: Vec<FuncPtr>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ControlFrame {
|
||||
pub label: DynamicLabel,
|
||||
@ -182,86 +178,33 @@ pub enum IfElseState {
|
||||
Else,
|
||||
}
|
||||
|
||||
impl X64ExecutionContext {
|
||||
fn get_runtime_resolver(
|
||||
impl RunnableModule for X64ExecutionContext {
|
||||
fn get_func(
|
||||
&self,
|
||||
_module_info: &ModuleInfo,
|
||||
) -> Result<X64RuntimeResolver, CodegenError> {
|
||||
Ok(X64RuntimeResolver {
|
||||
local_function_pointers: self.function_pointers[self.func_import_count..].to_vec(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FuncResolver for X64RuntimeResolver {
|
||||
fn get(
|
||||
&self,
|
||||
_module: &ModuleInner,
|
||||
_local_func_index: LocalFuncIndex,
|
||||
_: &ModuleInfo,
|
||||
local_func_index: LocalFuncIndex,
|
||||
) -> Option<NonNull<vm::Func>> {
|
||||
NonNull::new(
|
||||
self.local_function_pointers[_local_func_index.index() as usize].0 as *mut vm::Func,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ProtectedCaller for X64ExecutionContext {
|
||||
fn call(
|
||||
&self,
|
||||
_module: &ModuleInner,
|
||||
_func_index: FuncIndex,
|
||||
_params: &[Value],
|
||||
_import_backing: &ImportBacking,
|
||||
_vmctx: *mut vm::Ctx,
|
||||
_: Token,
|
||||
) -> RuntimeResult<Vec<Value>> {
|
||||
let index = _func_index.index() - self.func_import_count;
|
||||
let ptr = self.code.ptr(self.functions[index].begin_offset);
|
||||
let return_ty = self.functions[index].returns.last().cloned();
|
||||
let buffer: Vec<u64> = _params
|
||||
.iter()
|
||||
.rev()
|
||||
.map(|x| match *x {
|
||||
Value::I32(x) => x as u32 as u64,
|
||||
Value::I64(x) => x as u64,
|
||||
Value::F32(x) => f32::to_bits(x) as u64,
|
||||
Value::F64(x) => f64::to_bits(x),
|
||||
})
|
||||
.collect();
|
||||
let ret = unsafe {
|
||||
protect_unix::call_protected(|| {
|
||||
CONSTRUCT_STACK_AND_CALL_WASM(
|
||||
buffer.as_ptr(),
|
||||
buffer.as_ptr().offset(buffer.len() as isize),
|
||||
_vmctx,
|
||||
ptr as _,
|
||||
)
|
||||
})
|
||||
}?;
|
||||
Ok(if let Some(ty) = return_ty {
|
||||
vec![match ty {
|
||||
WpType::I32 => Value::I32(ret as i32),
|
||||
WpType::I64 => Value::I64(ret as i64),
|
||||
WpType::F32 => Value::F32(f32::from_bits(ret as u32)),
|
||||
WpType::F64 => Value::F64(f64::from_bits(ret as u64)),
|
||||
_ => unreachable!(),
|
||||
}]
|
||||
} else {
|
||||
vec![]
|
||||
})
|
||||
self.function_pointers[self.func_import_count..]
|
||||
.get(local_func_index.index())
|
||||
.and_then(|ptr| NonNull::new(ptr.0 as *mut vm::Func))
|
||||
}
|
||||
|
||||
fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
||||
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||
use std::ffi::c_void;
|
||||
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||
|
||||
unsafe extern "C" fn invoke(
|
||||
trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64),
|
||||
_trampoline: unsafe extern "C" fn(
|
||||
*mut vm::Ctx,
|
||||
NonNull<vm::Func>,
|
||||
*const u64,
|
||||
*mut u64,
|
||||
),
|
||||
ctx: *mut vm::Ctx,
|
||||
func: NonNull<vm::Func>,
|
||||
args: *const u64,
|
||||
rets: *mut u64,
|
||||
trap_info: *mut WasmTrapInfo,
|
||||
_trap_info: *mut WasmTrapInfo,
|
||||
num_params_plus_one: Option<NonNull<c_void>>,
|
||||
) -> bool {
|
||||
let args = ::std::slice::from_raw_parts(
|
||||
@ -278,7 +221,9 @@ impl ProtectedCaller for X64ExecutionContext {
|
||||
)
|
||||
}) {
|
||||
Ok(x) => {
|
||||
*rets = x;
|
||||
if !rets.is_null() {
|
||||
*rets = x;
|
||||
}
|
||||
true
|
||||
}
|
||||
Err(_) => false,
|
||||
@ -330,9 +275,7 @@ impl X64ModuleCodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolver>
|
||||
for X64ModuleCodeGenerator
|
||||
{
|
||||
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext> for X64ModuleCodeGenerator {
|
||||
fn check_precondition(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -367,7 +310,6 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||
function_signatures: self.function_signatures.as_ref().unwrap().clone(),
|
||||
|
||||
begin_offset: begin_offset,
|
||||
assembler: Some(assembler),
|
||||
function_labels: Some(function_labels),
|
||||
br_table_data: Some(br_table_data),
|
||||
@ -384,10 +326,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
||||
Ok(self.functions.last_mut().unwrap())
|
||||
}
|
||||
|
||||
fn finalize(
|
||||
mut self,
|
||||
module_info: &ModuleInfo,
|
||||
) -> Result<(X64ExecutionContext, X64RuntimeResolver), CodegenError> {
|
||||
fn finalize(mut self, _: &ModuleInfo) -> Result<X64ExecutionContext, CodegenError> {
|
||||
let (assembler, mut br_table_data) = match self.functions.last_mut() {
|
||||
Some(x) => (x.assembler.take().unwrap(), x.br_table_data.take().unwrap()),
|
||||
None => {
|
||||
@ -431,17 +370,14 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
||||
out_labels.push(FuncPtr(output.ptr(*offset) as _));
|
||||
}
|
||||
|
||||
let ctx = X64ExecutionContext {
|
||||
Ok(X64ExecutionContext {
|
||||
code: output,
|
||||
functions: self.functions,
|
||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||
_br_table_data: br_table_data,
|
||||
func_import_count: self.func_import_count,
|
||||
function_pointers: out_labels,
|
||||
};
|
||||
let resolver = ctx.get_runtime_resolver(module_info)?;
|
||||
|
||||
Ok((ctx, resolver))
|
||||
})
|
||||
}
|
||||
|
||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
|
||||
|
@ -62,11 +62,10 @@ impl Compiler for SinglePassCompiler {
|
||||
) -> CompileResult<ModuleInner> {
|
||||
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
||||
let info = parse::read_module(wasm, Backend::Singlepass, &mut mcg, &compiler_config)?;
|
||||
let (ec, resolver) = mcg.finalize(&info)?;
|
||||
let exec_context = mcg.finalize(&info)?;
|
||||
Ok(ModuleInner {
|
||||
cache_gen: Box::new(Placeholder),
|
||||
func_resolver: Box::new(resolver),
|
||||
protected_caller: Box::new(ec),
|
||||
runnable_module: Box::new(exec_context),
|
||||
info: info,
|
||||
})
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator};
|
||||
use hashbrown::HashMap;
|
||||
use wasmer_runtime_core::{
|
||||
backend::{Backend, CompilerConfig, FuncResolver, ProtectedCaller},
|
||||
backend::{Backend, CompilerConfig, RunnableModule},
|
||||
module::{
|
||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
||||
TableInitializer,
|
||||
@ -63,10 +63,9 @@ fn validate(bytes: &[u8]) -> Result<(), LoadError> {
|
||||
}
|
||||
|
||||
pub fn read_module<
|
||||
MCG: ModuleCodeGenerator<FCG, PC, FR>,
|
||||
MCG: ModuleCodeGenerator<FCG, RM>,
|
||||
FCG: FunctionCodeGenerator,
|
||||
PC: ProtectedCaller,
|
||||
FR: FuncResolver,
|
||||
RM: RunnableModule,
|
||||
>(
|
||||
wasm: &[u8],
|
||||
backend: Backend,
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-spectests"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer spectests library"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -9,10 +9,10 @@ edition = "2018"
|
||||
build = "build/mod.rs"
|
||||
|
||||
[dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.0" }
|
||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.2.0" }
|
||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.1.0", optional = true }
|
||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.1.0", optional = true }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||
wasmer-clif-backend = { path = "../clif-backend", version = "0.3.0" }
|
||||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.3.0", optional = true }
|
||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.3.0", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
wabt = "0.7.2"
|
||||
|
@ -1,13 +1,14 @@
|
||||
[package]
|
||||
name = "wasmer-wasi"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer runtime WASI implementation library"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
repository = "https://github.com/wasmerio/wasmer"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||
libc = "0.2.50"
|
||||
rand = "0.6.5"
|
||||
# wasmer-runtime-abi = { path = "../runtime-abi" }
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-win-exception-handler"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
description = "Wasmer runtime exception handling for Windows"
|
||||
license = "MIT"
|
||||
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer"
|
||||
edition = "2018"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.0" }
|
||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" }
|
||||
winapi = { version = "0.3", features = ["winbase", "errhandlingapi", "minwindef", "minwinbase", "winnt"] }
|
||||
libc = "0.2.49"
|
||||
|
||||
|
@ -83,6 +83,9 @@ struct Run {
|
||||
#[structopt(long = "em-symbol-map", parse(from_os_str))]
|
||||
em_symbol_map: Option<PathBuf>,
|
||||
|
||||
#[structopt(long = "command-name", hidden = true)]
|
||||
command_name: Option<String>,
|
||||
|
||||
/// Application arguments
|
||||
#[structopt(name = "--", raw(multiple = "true"))]
|
||||
args: Vec<String>,
|
||||
@ -300,12 +303,16 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
(
|
||||
InstanceABI::WASI,
|
||||
wasmer_wasi::generate_import_object(
|
||||
[options.path.to_str().unwrap().to_owned()]
|
||||
.iter()
|
||||
.chain(options.args.iter())
|
||||
.cloned()
|
||||
.map(|arg| arg.into_bytes())
|
||||
.collect(),
|
||||
if let Some(cn) = &options.command_name {
|
||||
[cn.clone()]
|
||||
} else {
|
||||
[options.path.to_str().unwrap().to_owned()]
|
||||
}
|
||||
.iter()
|
||||
.chain(options.args.iter())
|
||||
.cloned()
|
||||
.map(|arg| arg.into_bytes())
|
||||
.collect(),
|
||||
env::vars()
|
||||
.map(|(k, v)| format!("{}={}", k, v).into_bytes())
|
||||
.collect(),
|
||||
@ -329,7 +336,11 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
&module,
|
||||
&mut instance,
|
||||
abi,
|
||||
options.path.to_str().unwrap(),
|
||||
if let Some(cn) = &options.command_name {
|
||||
cn
|
||||
} else {
|
||||
options.path.to_str().unwrap()
|
||||
},
|
||||
options.args.iter().map(|arg| arg.as_str()).collect(),
|
||||
)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
|
17
update_version_numbers.sh
Executable file
17
update_version_numbers.sh
Executable file
@ -0,0 +1,17 @@
|
||||
PREVIOUS_VERSION='0.2.1'
|
||||
NEXT_VERSION='0.3.0'
|
||||
|
||||
# quick hack
|
||||
fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/"
|
||||
echo "manually check changes to Cargo.toml"
|
||||
|
||||
# Order to upload packages in
|
||||
## runtime-core
|
||||
## win-exception-handler
|
||||
## clif-backend
|
||||
## llvm-backend
|
||||
## singlepass-backend
|
||||
## emscripten
|
||||
## wasi
|
||||
## runtime
|
||||
## runtime-c-api
|
Loading…
x
Reference in New Issue
Block a user