Merge remote-tracking branch 'origin/master' into feature/singlepass-aarch64

This commit is contained in:
losfair
2019-11-17 04:36:22 +08:00
15 changed files with 241 additions and 66 deletions

View File

@ -2,5 +2,6 @@
**
!lib/**
!src/**
!examples/**
!Cargo.toml
!Cargo.lock

View File

@ -2,6 +2,9 @@
## **[Unreleased]**
- [#968](https://github.com/wasmerio/wasmer/pull/968) Added `--invoke` option to the command
- [#971](https://github.com/wasmerio/wasmer/pull/971) In LLVM backend, use unaligned loads and stores for non-atomic accesses to wasmer memory.
- [#960](https://github.com/wasmerio/wasmer/pull/960) Fix `runtime-c-api` header files when compiled by clang.
- [#925](https://github.com/wasmerio/wasmer/pull/925) Host functions can be closures with a captured environment.
- [#917](https://github.com/wasmerio/wasmer/pull/917) Host functions (aka imported functions) may not have `&mut vm::Ctx` as first argument, i.e. the presence of the `&mut vm::Ctx` argument is optional.
- [#915](https://github.com/wasmerio/wasmer/pull/915) All backends share the same definition of `Trampoline` (defined in `wasmer-runtime-core`).

View File

@ -1,4 +1,4 @@
FROM circleci/rust:1.33.0-stretch as wasmer-build-env
FROM circleci/rust:1.38.0-stretch as wasmer-build-env
RUN sudo apt-get update && \
sudo apt-get install -y --no-install-recommends \
cmake \

View File

@ -54,6 +54,10 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
}
}
fn new_with_target(_: Option<String>, _: Option<String>, _: Option<String>) -> Self {
unimplemented!("cross compilation is not available for clif backend")
}
fn backend_id() -> Backend {
Backend::Cranelift
}

View File

@ -4469,6 +4469,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
4,
)?;
let result = builder.build_load(effective_address, &state.var_name());
result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4492,6 +4497,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
8,
)?;
let result = builder.build_load(effective_address, &state.var_name());
result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4515,6 +4525,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
4,
)?;
let result = builder.build_load(effective_address, &state.var_name());
result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4538,6 +4553,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
8,
)?;
let result = builder.build_load(effective_address, &state.var_name());
result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4561,6 +4581,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
16,
)?;
let result = builder.build_load(effective_address, &state.var_name());
result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4586,6 +4611,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
4,
)?;
let store = builder.build_store(effective_address, value);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::I64Store { ref memarg } => {
@ -4603,6 +4629,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
8,
)?;
let store = builder.build_store(effective_address, value);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::F32Store { ref memarg } => {
@ -4621,6 +4648,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
4,
)?;
let store = builder.build_store(effective_address, v);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::F64Store { ref memarg } => {
@ -4639,6 +4667,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
8,
)?;
let store = builder.build_store(effective_address, v);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::V128Store { ref memarg } => {
@ -4657,6 +4686,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
16,
)?;
let store = builder.build_store(effective_address, v);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::I32Load8S { ref memarg } => {
@ -4672,9 +4702,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
intrinsics.i8_ptr_ty,
1,
)?;
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4682,8 +4715,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
narrow_result.as_instruction_value().unwrap(),
Some(0),
);
let result =
builder.build_int_s_extend(narrow_result, intrinsics.i32_ty, &state.var_name());
let result = builder.build_int_s_extend(
narrow_result.into_int_value(),
intrinsics.i32_ty,
&state.var_name(),
);
state.push1(result);
}
Operator::I32Load16S { ref memarg } => {
@ -4700,6 +4736,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
2,
)?;
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4730,6 +4771,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4757,6 +4803,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4781,9 +4832,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
intrinsics.i32_ptr_ty,
4,
)?;
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4791,8 +4845,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
narrow_result.as_instruction_value().unwrap(),
Some(0),
);
let result =
builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name());
let result = builder.build_int_s_extend(
narrow_result.into_int_value(),
intrinsics.i64_ty,
&state.var_name(),
);
state.push1(result);
}
@ -4809,9 +4866,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
intrinsics.i8_ptr_ty,
1,
)?;
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4819,8 +4879,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
narrow_result.as_instruction_value().unwrap(),
Some(0),
);
let result =
builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name());
let result = builder.build_int_z_extend(
narrow_result.into_int_value(),
intrinsics.i32_ty,
&state.var_name(),
);
state.push1(result);
}
Operator::I32Load16U { ref memarg } => {
@ -4836,9 +4899,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
intrinsics.i16_ptr_ty,
2,
)?;
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4846,8 +4912,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
narrow_result.as_instruction_value().unwrap(),
Some(0),
);
let result =
builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name());
let result = builder.build_int_z_extend(
narrow_result.into_int_value(),
intrinsics.i32_ty,
&state.var_name(),
);
state.push1(result);
}
Operator::I64Load8U { ref memarg } => {
@ -4863,9 +4932,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
intrinsics.i8_ptr_ty,
1,
)?;
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4873,8 +4945,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
narrow_result.as_instruction_value().unwrap(),
Some(0),
);
let result =
builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name());
let result = builder.build_int_z_extend(
narrow_result.into_int_value(),
intrinsics.i64_ty,
&state.var_name(),
);
state.push1(result);
}
Operator::I64Load16U { ref memarg } => {
@ -4890,9 +4965,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
intrinsics.i16_ptr_ty,
2,
)?;
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4900,8 +4978,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
narrow_result.as_instruction_value().unwrap(),
Some(0),
);
let result =
builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name());
let result = builder.build_int_z_extend(
narrow_result.into_int_value(),
intrinsics.i64_ty,
&state.var_name(),
);
state.push1(result);
}
Operator::I64Load32U { ref memarg } => {
@ -4917,9 +4998,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
intrinsics.i32_ptr_ty,
4,
)?;
let narrow_result = builder
.build_load(effective_address, &state.var_name())
.into_int_value();
let narrow_result = builder.build_load(effective_address, &state.var_name());
narrow_result
.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -4927,8 +5011,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
narrow_result.as_instruction_value().unwrap(),
Some(0),
);
let result =
builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name());
let result = builder.build_int_z_extend(
narrow_result.into_int_value(),
intrinsics.i64_ty,
&state.var_name(),
);
state.push1(result);
}
@ -4949,6 +5036,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let narrow_value =
builder.build_int_truncate(value, intrinsics.i8_ty, &state.var_name());
let store = builder.build_store(effective_address, narrow_value);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => {
@ -4968,6 +5056,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let narrow_value =
builder.build_int_truncate(value, intrinsics.i16_ty, &state.var_name());
let store = builder.build_store(effective_address, narrow_value);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::I64Store32 { ref memarg } => {
@ -4987,6 +5076,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let narrow_value =
builder.build_int_truncate(value, intrinsics.i32_ty, &state.var_name());
let store = builder.build_store(effective_address, narrow_value);
store.set_alignment(1).unwrap();
tbaa_label(self.module.clone(), intrinsics, "memory", store, Some(0));
}
Operator::I8x16Neg => {
@ -5291,6 +5381,10 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
1,
)?;
let elem = builder.build_load(effective_address, "");
elem.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -5322,6 +5416,10 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
2,
)?;
let elem = builder.build_load(effective_address, "");
elem.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -5353,6 +5451,10 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
4,
)?;
let elem = builder.build_load(effective_address, "");
elem.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -5384,6 +5486,10 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
8,
)?;
let elem = builder.build_load(effective_address, "");
elem.as_instruction_value()
.unwrap()
.set_alignment(1)
.unwrap();
tbaa_label(
self.module.clone(),
intrinsics,
@ -7969,24 +8075,37 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
for LLVMModuleCodeGenerator
{
fn new() -> LLVMModuleCodeGenerator {
Self::new_with_target(None, None, None)
}
fn new_with_target(
triple: Option<String>,
cpu_name: Option<String>,
cpu_features: Option<String>,
) -> LLVMModuleCodeGenerator {
let context = Context::create();
let module = context.create_module("module");
Target::initialize_x86(&InitializationConfig {
asm_parser: true,
asm_printer: true,
base: true,
disassembler: true,
info: true,
machine_code: true,
});
let triple = TargetMachine::get_default_triple().to_string();
let triple = triple.unwrap_or(TargetMachine::get_default_triple().to_string());
match triple {
_ if triple.starts_with("x86") => Target::initialize_x86(&InitializationConfig {
asm_parser: true,
asm_printer: true,
base: true,
disassembler: true,
info: true,
machine_code: true,
}),
_ => unimplemented!("compile to target other than x86-64 is not supported"),
}
let target = Target::from_triple(&triple).unwrap();
let target_machine = target
.create_target_machine(
&triple,
&TargetMachine::get_host_cpu_name().to_string(),
&TargetMachine::get_host_cpu_features().to_string(),
&cpu_name.unwrap_or(TargetMachine::get_host_cpu_name().to_string()),
&cpu_features.unwrap_or(TargetMachine::get_host_cpu_features().to_string()),
OptimizationLevel::Aggressive,
RelocMode::Static,
CodeModel::Large,

View File

@ -13,19 +13,21 @@ fn main() {
out_wasmer_header_file.push("wasmer");
const WASMER_PRE_HEADER: &str = r#"
#ifndef WASMER_H_MACROS
#if !defined(WASMER_H_MACROS)
#define WASMER_H_MACROS
#if MSVC
#ifdef _M_AMD64
#if defined(MSVC)
#if defined(_M_AMD64)
#define ARCH_X86_64
#endif
#endif
#if GCC
#ifdef __x86_64__
#if defined(GCC) || defined(__clang__)
#if defined(__x86_64__)
#define ARCH_X86_64
#endif
#endif
#endif // WASMER_H_MACROS
"#;
// Generate the C bindings in the `OUT_DIR`.

View File

@ -1,17 +1,19 @@
#ifndef WASMER_H_MACROS
#if !defined(WASMER_H_MACROS)
#define WASMER_H_MACROS
#if MSVC
#ifdef _M_AMD64
#if defined(MSVC)
#if defined(_M_AMD64)
#define ARCH_X86_64
#endif
#endif
#if GCC
#ifdef __x86_64__
#if defined(GCC) || defined(__clang__)
#if defined(__x86_64__)
#define ARCH_X86_64
#endif
#endif
#endif // WASMER_H_MACROS

View File

@ -1,17 +1,19 @@
#ifndef WASMER_H_MACROS
#if !defined(WASMER_H_MACROS)
#define WASMER_H_MACROS
#if MSVC
#ifdef _M_AMD64
#if defined(MSVC)
#if defined(_M_AMD64)
#define ARCH_X86_64
#endif
#endif
#if GCC
#ifdef __x86_64__
#if defined(GCC) || defined(__clang__)
#if defined(__x86_64__)
#define ARCH_X86_64
#endif
#endif
#endif // WASMER_H_MACROS

View File

@ -205,6 +205,11 @@ pub struct CompilerConfig {
pub enforce_stack_check: bool,
pub track_state: bool,
pub features: Features,
// target info used by LLVM
pub triple: Option<String>,
pub cpu_name: Option<String>,
pub cpu_features: Option<String>,
}
pub trait Compiler {

View File

@ -75,6 +75,13 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
/// Creates a new module code generator.
fn new() -> Self;
/// Creates a new module code generator for specified target.
fn new_with_target(
triple: Option<String>,
cpu_name: Option<String>,
cpu_features: Option<String>,
) -> Self;
/// Returns the backend id associated with this MCG.
fn backend_id() -> Backend;
@ -207,7 +214,14 @@ impl<
validate_with_features(wasm, &compiler_config.features)?;
}
let mut mcg = MCG::new();
let mut mcg = match MCG::backend_id() {
Backend::LLVM => MCG::new_with_target(
compiler_config.triple.clone(),
compiler_config.cpu_name.clone(),
compiler_config.cpu_features.clone(),
),
_ => MCG::new(),
};
let mut chain = (self.middleware_chain_generator)();
let info = crate::parse::read_module(
wasm,

View File

@ -1,3 +1,7 @@
//! The cache module provides the common data structures used by compiler backends to allow
//! serializing compiled wasm code to a binary format. The binary format can be persisted,
//! and loaded to allow skipping compilation and fast startup.
use crate::Module;
use memmap::Mmap;
use std::{

View File

@ -1,5 +1,6 @@
#![deny(
dead_code,
missing_docs,
nonstandard_style,
unused_imports,
unused_mut,
@ -104,6 +105,8 @@ pub use wasmer_runtime_core::{compile_with, validate};
pub use wasmer_runtime_core::{func, imports};
pub mod memory {
//! The memory module contains the implementation data structures and helper functions used to
//! manipulate and access wasm memory.
pub use wasmer_runtime_core::memory::{Atomically, Memory, MemoryView};
}
@ -117,6 +120,8 @@ pub mod wasm {
}
pub mod error {
//! The error module contains the data structures and helper functions used to implement errors that
//! are produced and returned from the wasmer runtime.
pub use wasmer_runtime_core::cache::Error as CacheError;
pub use wasmer_runtime_core::error::*;
}

View File

@ -483,6 +483,10 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
}
}
fn new_with_target(_: Option<String>, _: Option<String>, _: Option<String>) -> Self {
unimplemented!("cross compilation is not available for singlepass backend")
}
fn backend_id() -> Backend {
Backend::Singlepass
}

View File

@ -63,6 +63,7 @@ fn handle_client(mut stream: UnixStream) {
enforce_stack_check: true,
track_state: false,
features: Default::default(),
..Default::default()
},
&SinglePassCompiler::new(),
)

View File

@ -130,6 +130,10 @@ struct Run {
)]
backend: Backend,
/// Invoke a specified function
#[structopt(long = "invoke", short = "i")]
invoke: Option<String>,
/// Emscripten symbol map
#[structopt(long = "em-symbol-map", parse(from_os_str), group = "emscripten")]
em_symbol_map: Option<PathBuf>,
@ -449,6 +453,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
simd: options.features.simd || options.features.all,
threads: options.features.threads || options.features.all,
},
..Default::default()
},
&*compiler,
)
@ -714,8 +719,12 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
args.push(Value::I32(x));
}
let result = instance
.dyn_func("main")
let invoke_fn = match options.invoke.as_ref() {
Some(fun) => fun,
_ => "main",
};
instance
.dyn_func(&invoke_fn)
.map_err(|e| format!("{:?}", e))?
.call(&args)
.map_err(|e| format!("{:?}", e))?;