mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 12:48:20 +00:00
Merge remote-tracking branch 'origin/master' into wasix
This commit is contained in:
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
@@ -102,6 +102,11 @@ jobs:
|
||||
with:
|
||||
toolchain: 1.64
|
||||
target: ${{ matrix.target }}
|
||||
- name: Install Rust nightly (to build capi-headless)
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly
|
||||
target: ${{ matrix.metadata.target }}
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
if: matrix.use_sccache != true
|
||||
- name: Install LLVM (macOS Apple Silicon)
|
||||
@@ -273,6 +278,11 @@ jobs:
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
target: x86_64-pc-windows-gnu
|
||||
- name: Install Rust nightly (to build capi-headless)
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly
|
||||
target: x86_64-pc-windows-gnu
|
||||
- name: Install Windows-GNU target
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -301,9 +311,19 @@ jobs:
|
||||
- name: Build Wasmer C-API without LLVM
|
||||
shell: bash
|
||||
run: |
|
||||
cargo build --release --target x86_64-pc-windows-gnu --manifest-path lib/c-api/Cargo.toml --no-default-features --features wat,compiler,wasi,middlewares,webc_runner --features cranelift,singlepass,wasmer-artifact-create,static-artifact-create,wasmer-artifact-load,static-artifact-load
|
||||
make build-capi
|
||||
env:
|
||||
RUSTFLAGS: -Cpanic=abort
|
||||
CARGO_TARGET: x86_64-pc-windows-gnu
|
||||
ENABLE_LLVM: 0
|
||||
- name: Build Wasmer C-API headless without LLVM
|
||||
shell: bash
|
||||
run: |
|
||||
make build-capi-headless
|
||||
env:
|
||||
RUSTFLAGS: -Cpanic=abort
|
||||
CARGO_TARGET: x86_64-pc-windows-gnu
|
||||
ENABLE_LLVM: 0
|
||||
- name: Dist
|
||||
run: |
|
||||
make distribution-gnu
|
||||
|
||||
5
.github/workflows/test.yaml
vendored
5
.github/workflows/test.yaml
vendored
@@ -263,6 +263,11 @@ jobs:
|
||||
with:
|
||||
toolchain: 1.64
|
||||
target: ${{ matrix.metadata.target }}
|
||||
- name: Install Rust nightly (to build capi-headless)
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly
|
||||
target: ${{ matrix.metadata.target }}
|
||||
- name: Install Windows-GNU linker
|
||||
if: ${{ matrix.metadata.build == 'windows-gnu' }}
|
||||
shell: bash
|
||||
|
||||
556
Cargo.lock
generated
556
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
60
Makefile
60
Makefile
@@ -361,7 +361,7 @@ endif
|
||||
|
||||
# Not really "all", just the default target that builds enough so make
|
||||
# install will go through.
|
||||
all: build-wasmer build-capi
|
||||
all: build-wasmer build-capi build-capi-headless
|
||||
|
||||
check: check-wasmer check-wasmer-wasm check-capi
|
||||
|
||||
@@ -565,10 +565,10 @@ test-wasi-unit:
|
||||
test-wasi:
|
||||
$(CARGO_BINARY) test $(CARGO_TARGET_FLAG) --release --tests $(compiler_features) -- wasi::wasitests
|
||||
|
||||
test-integration-cli: build-wasmer build-capi package distribution
|
||||
test-integration-cli: build-wasmer build-capi package-capi-headless package distribution
|
||||
cp ./dist/wasmer.tar.gz ./link.tar.gz
|
||||
rustup target add wasm32-wasi
|
||||
$(CARGO_BINARY) test $(CARGO_TARGET_FLAG) --features webc_runner --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture --test-threads=1
|
||||
WASMER_DIR=`pwd`/package $(CARGO_BINARY) test $(CARGO_TARGET_FLAG) --features webc_runner --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture --test-threads=1
|
||||
|
||||
# Before running this in the CI, we need to set up link.tar.gz and /cache/wasmer-[target].tar.gz
|
||||
test-integration-cli-ci:
|
||||
@@ -621,6 +621,8 @@ ifeq ($(IS_DARWIN), 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
package-capi-headless: build-capi-headless package-capi
|
||||
|
||||
package-capi:
|
||||
mkdir -p "package/include"
|
||||
mkdir -p "package/lib"
|
||||
@@ -637,6 +639,10 @@ package-capi:
|
||||
cp target/headless/$(CARGO_TARGET)/release/wasmer.dll package/lib/wasmer-headless.dll ;\
|
||||
fi
|
||||
|
||||
if [ -f target/headless/$(HOST_TARGET)/release/wasmer.dll ]; then \
|
||||
cp target/headless/$(HOST_TARGET)/release/wasmer.dll package/lib/wasmer-headless.dll ;\
|
||||
fi
|
||||
|
||||
if [ -f $(TARGET_DIR)/wasmer.dll.lib ]; then \
|
||||
cp $(TARGET_DIR)/wasmer.dll.lib package/lib/wasmer.dll.lib ;\
|
||||
fi
|
||||
@@ -645,6 +651,10 @@ package-capi:
|
||||
cp target/headless/$(CARGO_TARGET)/release/wasmer.dll.lib package/lib/wasmer-headless.dll.lib ;\
|
||||
fi
|
||||
|
||||
if [ -f target/headless/$(HOST_TARGET)/release/wasmer.dll.lib ]; then \
|
||||
cp target/headless/$(HOST_TARGET)/release/wasmer.dll.lib package/lib/wasmer-headless.dll.lib ;\
|
||||
fi
|
||||
|
||||
if [ -f $(TARGET_DIR)/wasmer.lib ]; then \
|
||||
cp $(TARGET_DIR)/wasmer.lib package/lib/wasmer.lib ;\
|
||||
fi
|
||||
@@ -653,6 +663,10 @@ package-capi:
|
||||
cp target/headless/$(CARGO_TARGET)/release/wasmer.lib package/lib/wasmer-headless.lib ;\
|
||||
fi
|
||||
|
||||
if [ -f target/headless/$(HOST_TARGET)/release/wasmer.lib ]; then \
|
||||
cp target/headless/$(HOST_TARGET)/release/wasmer.lib package/lib/wasmer-headless.lib ;\
|
||||
fi
|
||||
|
||||
if [ -f $(TARGET_DIR)/libwasmer.dylib ]; then \
|
||||
cp $(TARGET_DIR)/libwasmer.dylib package/lib/libwasmer.dylib ;\
|
||||
fi
|
||||
@@ -661,6 +675,10 @@ package-capi:
|
||||
cp target/headless/$(CARGO_TARGET)/release/libwasmer.dylib package/lib/libwasmer-headless.dylib ;\
|
||||
fi
|
||||
|
||||
if [ -f target/headless/$(HOST_TARGET)/release/libwasmer.dylib ]; then \
|
||||
cp target/headless/$(HOST_TARGET)/release/libwasmer.dylib package/lib/libwasmer-headless.dylib ;\
|
||||
fi
|
||||
|
||||
if [ -f $(TARGET_DIR)/libwasmer.so ]; then \
|
||||
cp $(TARGET_DIR)/libwasmer.so package/lib/libwasmer.so ;\
|
||||
fi
|
||||
@@ -669,6 +687,10 @@ package-capi:
|
||||
cp target/headless/$(CARGO_TARGET)/release/libwasmer.so package/lib/libwasmer-headless.so ;\
|
||||
fi
|
||||
|
||||
if [ -f target/headless/$(HOST_TARGET)/release/libwasmer.so ]; then \
|
||||
cp target/headless/$(HOST_TARGET)/release/libwasmer.so package/lib/libwasmer-headless.so ;\
|
||||
fi
|
||||
|
||||
if [ -f $(TARGET_DIR)/libwasmer.a ]; then \
|
||||
cp $(TARGET_DIR)/libwasmer.a package/lib/libwasmer.a ;\
|
||||
fi
|
||||
@@ -677,6 +699,10 @@ package-capi:
|
||||
cp target/headless/$(CARGO_TARGET)/release/libwasmer.a package/lib/libwasmer-headless.a ;\
|
||||
fi
|
||||
|
||||
if [ -f target/headless/$(HOST_TARGET)/release/libwasmer.a ]; then \
|
||||
cp target/headless/$(HOST_TARGET)/release/libwasmer.a package/lib/libwasmer-headless.a ;\
|
||||
fi
|
||||
|
||||
if [ -f target/$(HOST_TARGET)/release/wasmer.dll ]; then \
|
||||
cp target/$(HOST_TARGET)/release/wasmer.dll package/lib/wasmer.dll ;\
|
||||
fi
|
||||
@@ -699,39 +725,13 @@ package-capi:
|
||||
cp target/$(HOST_TARGET)/release/libwasmer.a package/lib/libwasmer.a ;\
|
||||
fi
|
||||
|
||||
package-capi-headless: build-capi-headless
|
||||
mkdir -p "package/include"
|
||||
mkdir -p "package/lib"
|
||||
cp lib/c-api/wasmer.h* package/include
|
||||
cp lib/c-api/wasmer_wasm.h* package/include
|
||||
cp lib/c-api/wasm.h* package/include
|
||||
cp lib/c-api/README.md package/include/README.md
|
||||
|
||||
if [ -f $(TARGET_DIR)/wasmer.dll ]; then \
|
||||
cp $(TARGET_DIR)/wasmer.dll package/lib/wasmer-headless.dll ;\
|
||||
fi
|
||||
if [ -f $(TARGET_DIR)/wasmer.lib ]; then \
|
||||
cp $(TARGET_DIR)/wasmer.lib package/lib/wasmer-headless.lib ;\
|
||||
fi
|
||||
|
||||
if [ -f $(TARGET_DIR)/libwasmer.dylib ]; then \
|
||||
cp $(TARGET_DIR)/libwasmer.dylib package/lib/libwasmer-headless.dylib ;\
|
||||
fi
|
||||
|
||||
if [ -f $(TARGET_DIR)/libwasmer.so ]; then \
|
||||
cp $(TARGET_DIR)/libwasmer.so package/lib/libwasmer-headless.so ;\
|
||||
fi
|
||||
if [ -f $(TARGET_DIR)/libwasmer.a ]; then \
|
||||
cp $(TARGET_DIR)/libwasmer.a package/lib/libwasmer-headless.a ;\
|
||||
fi
|
||||
|
||||
package-docs: build-docs build-docs-capi
|
||||
mkdir -p "package/docs/crates"
|
||||
cp -R target/doc/ package/docs/crates
|
||||
echo '<meta http-equiv="refresh" content="0; url=crates/wasmer/index.html">' > package/docs/index.html
|
||||
echo '<meta http-equiv="refresh" content="0; url=wasmer/index.html">' > package/docs/crates/index.html
|
||||
|
||||
package: package-wasmer package-minimal-headless-wasmer package-capi package-capi-headless
|
||||
package: package-wasmer package-minimal-headless-wasmer package-capi
|
||||
|
||||
tar-capi:
|
||||
ls -R package
|
||||
|
||||
@@ -33,7 +33,7 @@ impl Login {
|
||||
registry_tld.suffix.as_deref(),
|
||||
) {
|
||||
(Some(d), Some(s)) => {
|
||||
format!("Please paste the login token for https://{d}.{s}/me")
|
||||
format!("Please paste the login token from https://{d}.{s}/settings/access-tokens")
|
||||
}
|
||||
_ => "Please paste the login token".to_string(),
|
||||
};
|
||||
|
||||
@@ -14,9 +14,9 @@ edition = "2018"
|
||||
[dependencies]
|
||||
wasmer-compiler = { path = "../compiler", version = "=3.2.0-alpha.1", features = ["translator", "compiler"], default-features = false }
|
||||
wasmer-types = { path = "../types", version = "=3.2.0-alpha.1", default-features = false, features = ["std"] }
|
||||
cranelift-entity = { version = "0.86.1", default-features = false }
|
||||
cranelift-codegen = { version = "0.86.1", default-features = false, features = ["x86", "arm64"] }
|
||||
cranelift-frontend = { version = "0.86.1", default-features = false }
|
||||
cranelift-entity = { version = "0.91.0", default-features = false }
|
||||
cranelift-codegen = { version = "0.91.0", default-features = false, features = ["x86", "arm64"] }
|
||||
cranelift-frontend = { version = "0.91.0", default-features = false }
|
||||
tracing = "0.1"
|
||||
hashbrown = { version = "0.11", optional = true }
|
||||
rayon = { version = "1.5", optional = true }
|
||||
@@ -26,7 +26,7 @@ smallvec = "1.6"
|
||||
target-lexicon = { version = "0.12.2", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
cranelift-codegen = { version = "0.86.1", features = ["all-arch"] }
|
||||
cranelift-codegen = { version = "0.91.0", features = ["all-arch"] }
|
||||
lazy_static = "1.4"
|
||||
|
||||
[badges]
|
||||
|
||||
@@ -15,7 +15,7 @@ pub fn get_function_address_map(
|
||||
|
||||
// New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping
|
||||
// tuples.
|
||||
let mcr = context.mach_compile_result.as_ref().unwrap();
|
||||
let mcr = context.compiled_code().unwrap();
|
||||
for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() {
|
||||
instructions.push(InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(loc.bits()),
|
||||
|
||||
@@ -12,8 +12,7 @@ use crate::translator::{
|
||||
compiled_function_unwind_info, irlibcall_to_libcall, irreloc_to_relocationkind,
|
||||
signature_to_cranelift_ir, CraneliftUnwindInfo, FuncTranslator,
|
||||
};
|
||||
use cranelift_codegen::ir::ExternalName;
|
||||
use cranelift_codegen::print_errors::pretty_error;
|
||||
use cranelift_codegen::ir::{ExternalName, UserFuncName};
|
||||
use cranelift_codegen::{ir, MachReloc};
|
||||
use cranelift_codegen::{Context, MachTrap};
|
||||
#[cfg(feature = "unwind")]
|
||||
@@ -127,7 +126,18 @@ impl Compiler for CraneliftCompiler {
|
||||
&memory_styles,
|
||||
&table_styles,
|
||||
);
|
||||
context.func.name = get_function_name(func_index);
|
||||
context.func.name = match get_function_name(func_index) {
|
||||
ExternalName::User(nameref) => {
|
||||
if context.func.params.user_named_funcs().is_valid(nameref) {
|
||||
let name = &context.func.params.user_named_funcs()[nameref];
|
||||
UserFuncName::User(name.clone())
|
||||
} else {
|
||||
UserFuncName::default()
|
||||
}
|
||||
}
|
||||
ExternalName::TestCase(testcase) => UserFuncName::Testcase(testcase),
|
||||
_ => UserFuncName::default(),
|
||||
};
|
||||
context.func.signature = signatures[module.functions[func_index]].clone();
|
||||
// if generate_debug_info {
|
||||
// context.func.collect_debug_info();
|
||||
@@ -151,9 +161,9 @@ impl Compiler for CraneliftCompiler {
|
||||
let mut code_buf: Vec<u8> = Vec::new();
|
||||
context
|
||||
.compile_and_emit(&*isa, &mut code_buf)
|
||||
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
|
||||
.map_err(|error| CompileError::Codegen(error.inner.to_string()))?;
|
||||
|
||||
let result = context.mach_compile_result.as_ref().unwrap();
|
||||
let result = context.compiled_code().unwrap();
|
||||
let func_relocs = result
|
||||
.buffer
|
||||
.relocs()
|
||||
@@ -228,7 +238,18 @@ impl Compiler for CraneliftCompiler {
|
||||
memory_styles,
|
||||
table_styles,
|
||||
);
|
||||
context.func.name = get_function_name(func_index);
|
||||
context.func.name = match get_function_name(func_index) {
|
||||
ExternalName::User(nameref) => {
|
||||
if context.func.params.user_named_funcs().is_valid(nameref) {
|
||||
let name = &context.func.params.user_named_funcs()[nameref];
|
||||
UserFuncName::User(name.clone())
|
||||
} else {
|
||||
UserFuncName::default()
|
||||
}
|
||||
}
|
||||
ExternalName::TestCase(testcase) => UserFuncName::Testcase(testcase),
|
||||
_ => UserFuncName::default(),
|
||||
};
|
||||
context.func.signature = signatures[module.functions[func_index]].clone();
|
||||
// if generate_debug_info {
|
||||
// context.func.collect_debug_info();
|
||||
@@ -252,9 +273,9 @@ impl Compiler for CraneliftCompiler {
|
||||
let mut code_buf: Vec<u8> = Vec::new();
|
||||
context
|
||||
.compile_and_emit(&*isa, &mut code_buf)
|
||||
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
|
||||
.map_err(|error| CompileError::Codegen(error.inner.to_string()))?;
|
||||
|
||||
let result = context.mach_compile_result.as_ref().unwrap();
|
||||
let result = context.compiled_code().unwrap();
|
||||
let func_relocs = result
|
||||
.buffer
|
||||
.relocs()
|
||||
@@ -401,11 +422,11 @@ fn mach_reloc_to_reloc(module: &ModuleInfo, reloc: &MachReloc) -> Relocation {
|
||||
ref name,
|
||||
addend,
|
||||
} = reloc;
|
||||
let reloc_target = if let ExternalName::User { namespace, index } = *name {
|
||||
debug_assert_eq!(namespace, 0);
|
||||
let reloc_target = if let ExternalName::User(extname_ref) = *name {
|
||||
//debug_assert_eq!(namespace, 0);
|
||||
RelocationTarget::LocalFunc(
|
||||
module
|
||||
.local_func_index(FunctionIndex::from_u32(index))
|
||||
.local_func_index(FunctionIndex::from_u32(extname_ref.as_u32()))
|
||||
.expect("The provided function should be local"),
|
||||
)
|
||||
} else if let ExternalName::LibCall(libcall) = *name {
|
||||
|
||||
@@ -124,6 +124,11 @@ impl Cranelift {
|
||||
pub fn flags(&self) -> settings::Flags {
|
||||
let mut flags = settings::builder();
|
||||
|
||||
// Enable probestack
|
||||
flags
|
||||
.enable("enable_probestack")
|
||||
.expect("should be valid flag");
|
||||
|
||||
// There are two possible traps for division, and this way
|
||||
// we get the proper one if code traps.
|
||||
flags
|
||||
|
||||
@@ -27,7 +27,7 @@ use wasmer_types::{WasmError, WasmResult};
|
||||
|
||||
/// Compute an `ir::ExternalName` for a given wasm function index.
|
||||
pub fn get_function_name(func_index: FunctionIndex) -> ir::ExternalName {
|
||||
ir::ExternalName::user(0, func_index.as_u32())
|
||||
ir::ExternalName::user(ir::UserExternalNameRef::from_u32(func_index.as_u32()))
|
||||
}
|
||||
|
||||
/// The type of the `current_elements` field.
|
||||
@@ -1028,7 +1028,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Ok(pos.ins().bint(ir::types::I32, bool_is_null))
|
||||
Ok(pos.ins().uextend(ir::types::I32, bool_is_null))
|
||||
}
|
||||
|
||||
fn translate_ref_func(
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
use crate::translator::{compiled_function_unwind_info, signature_to_cranelift_ir};
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_codegen::ir::{
|
||||
ExternalName, Function, InstBuilder, MemFlags, StackSlotData, StackSlotKind,
|
||||
Function, InstBuilder, MemFlags, StackSlotData, StackSlotKind, UserFuncName,
|
||||
};
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::print_errors::pretty_error;
|
||||
use cranelift_codegen::Context;
|
||||
use std::cmp;
|
||||
use std::mem;
|
||||
@@ -43,9 +42,9 @@ pub fn make_trampoline_dynamic_function(
|
||||
(value_size * cmp::max(signature.params.len() - 1, signature.returns.len())) as u32;
|
||||
|
||||
let mut context = Context::new();
|
||||
context.func = Function::with_name_signature(ExternalName::user(0, 0), signature.clone());
|
||||
context.func = Function::with_name_signature(UserFuncName::user(0, 0), signature.clone());
|
||||
|
||||
let ss = context.func.create_stack_slot(StackSlotData::new(
|
||||
let ss = context.func.create_sized_stack_slot(StackSlotData::new(
|
||||
StackSlotKind::ExplicitSlot,
|
||||
values_vec_len,
|
||||
));
|
||||
@@ -107,7 +106,7 @@ pub fn make_trampoline_dynamic_function(
|
||||
let mut code_buf = Vec::new();
|
||||
context
|
||||
.compile_and_emit(isa, &mut code_buf)
|
||||
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
|
||||
.map_err(|error| CompileError::Codegen(error.inner.to_string()))?;
|
||||
|
||||
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ use crate::translator::{compiled_function_unwind_info, signature_to_cranelift_ir
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_codegen::ir::InstBuilder;
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::print_errors::pretty_error;
|
||||
use cranelift_codegen::Context;
|
||||
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
|
||||
use std::mem;
|
||||
@@ -42,7 +41,7 @@ pub fn make_trampoline_function_call(
|
||||
wrapper_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||
|
||||
let mut context = Context::new();
|
||||
context.func = ir::Function::with_name_signature(ir::ExternalName::user(0, 0), wrapper_sig);
|
||||
context.func = ir::Function::with_name_signature(ir::UserFuncName::user(0, 0), wrapper_sig);
|
||||
|
||||
let value_size = mem::size_of::<u128>();
|
||||
{
|
||||
@@ -105,7 +104,7 @@ pub fn make_trampoline_function_call(
|
||||
|
||||
context
|
||||
.compile_and_emit(isa, &mut code_buf)
|
||||
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
|
||||
.map_err(|error| CompileError::Codegen(error.inner.to_string()))?;
|
||||
|
||||
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
* disappear in the Cranelift Code
|
||||
***********************************************************************************/
|
||||
Operator::LocalGet { local_index } => {
|
||||
let val = builder.use_var(Variable::with_u32(*local_index));
|
||||
let val = builder.use_var(Variable::from_u32(*local_index));
|
||||
state.push1(val);
|
||||
let label = ValueLabel::from_u32(*local_index);
|
||||
builder.set_val_label(val, label);
|
||||
@@ -138,7 +138,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
val = optionally_bitcast_vector(val, I8X16, builder);
|
||||
}
|
||||
|
||||
builder.def_var(Variable::with_u32(*local_index), val);
|
||||
builder.def_var(Variable::from_u32(*local_index), val);
|
||||
let label = ValueLabel::from_u32(*local_index);
|
||||
builder.set_val_label(val, label);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
val = optionally_bitcast_vector(val, I8X16, builder);
|
||||
}
|
||||
|
||||
builder.def_var(Variable::with_u32(*local_index), val);
|
||||
builder.def_var(Variable::from_u32(*local_index), val);
|
||||
let label = ValueLabel::from_u32(*local_index);
|
||||
builder.set_val_label(val, label);
|
||||
}
|
||||
@@ -368,8 +368,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
Operator::End => {
|
||||
let frame = state.control_stack.pop().unwrap();
|
||||
let next_block = frame.following_code();
|
||||
|
||||
if !builder.is_unreachable() || !builder.is_pristine() {
|
||||
if !builder.is_unreachable() || builder.func.layout.first_inst(next_block).is_some() {
|
||||
let return_count = frame.num_return_values();
|
||||
let return_args = state.peekn(return_count);
|
||||
canonicalise_then_jump(builder, frame.following_code(), return_args);
|
||||
@@ -519,11 +518,8 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
state.reachable = false;
|
||||
}
|
||||
Operator::Return => {
|
||||
let (return_count, br_destination) = {
|
||||
let (return_count, _br_destination) = {
|
||||
let frame = &mut state.control_stack[0];
|
||||
if environ.return_mode() == ReturnMode::FallthroughReturn {
|
||||
frame.set_branched_to_exit();
|
||||
}
|
||||
let return_count = frame.num_return_values();
|
||||
(return_count, frame.br_destination())
|
||||
};
|
||||
@@ -536,9 +532,6 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
bitcast_arguments(return_args, &return_types, builder);
|
||||
match environ.return_mode() {
|
||||
ReturnMode::NormalReturns => builder.ins().return_(return_args),
|
||||
ReturnMode::FallthroughReturn => {
|
||||
canonicalise_then_jump(builder, br_destination, return_args)
|
||||
}
|
||||
};
|
||||
}
|
||||
state.popn(return_count);
|
||||
@@ -861,19 +854,19 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
}
|
||||
Operator::F32ReinterpretI32 => {
|
||||
let val = state.pop1();
|
||||
state.push1(builder.ins().bitcast(F32, val));
|
||||
state.push1(builder.ins().bitcast(F32, MemFlags::new(), val));
|
||||
}
|
||||
Operator::F64ReinterpretI64 => {
|
||||
let val = state.pop1();
|
||||
state.push1(builder.ins().bitcast(F64, val));
|
||||
state.push1(builder.ins().bitcast(F64, MemFlags::new(), val));
|
||||
}
|
||||
Operator::I32ReinterpretF32 => {
|
||||
let val = state.pop1();
|
||||
state.push1(builder.ins().bitcast(I32, val));
|
||||
state.push1(builder.ins().bitcast(I32, MemFlags::new(), val));
|
||||
}
|
||||
Operator::I64ReinterpretF64 => {
|
||||
let val = state.pop1();
|
||||
state.push1(builder.ins().bitcast(I64, val));
|
||||
state.push1(builder.ins().bitcast(I64, MemFlags::new(), val));
|
||||
}
|
||||
Operator::I32Extend8S => {
|
||||
let val = state.pop1();
|
||||
@@ -1022,7 +1015,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
Operator::I32Eqz | Operator::I64Eqz => {
|
||||
let arg = state.pop1();
|
||||
let val = builder.ins().icmp_imm(IntCC::Equal, arg, 0);
|
||||
state.push1(builder.ins().bint(I32, val));
|
||||
state.push1(builder.ins().uextend(I32, val));
|
||||
}
|
||||
Operator::I32Eq | Operator::I64Eq => translate_icmp(IntCC::Equal, builder, state),
|
||||
Operator::F32Eq | Operator::F64Eq => translate_fcmp(FloatCC::Equal, builder, state),
|
||||
@@ -1583,7 +1576,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
}
|
||||
Operator::I8x16MinS | Operator::I16x8MinS | Operator::I32x4MinS => {
|
||||
let (a, b) = pop2_with_bitcast(state, type_of(op), builder);
|
||||
state.push1(builder.ins().imin(a, b))
|
||||
state.push1(builder.ins().smin(a, b))
|
||||
}
|
||||
Operator::I8x16MinU | Operator::I16x8MinU | Operator::I32x4MinU => {
|
||||
let (a, b) = pop2_with_bitcast(state, type_of(op), builder);
|
||||
@@ -1591,7 +1584,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
}
|
||||
Operator::I8x16MaxS | Operator::I16x8MaxS | Operator::I32x4MaxS => {
|
||||
let (a, b) = pop2_with_bitcast(state, type_of(op), builder);
|
||||
state.push1(builder.ins().imax(a, b))
|
||||
state.push1(builder.ins().smax(a, b))
|
||||
}
|
||||
Operator::I8x16MaxU | Operator::I16x8MaxU | Operator::I32x4MaxU => {
|
||||
let (a, b) = pop2_with_bitcast(state, type_of(op), builder);
|
||||
@@ -1672,7 +1665,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
Operator::V128AnyTrue => {
|
||||
let a = pop1_with_bitcast(state, type_of(op), builder);
|
||||
let bool_result = builder.ins().vany_true(a);
|
||||
state.push1(builder.ins().bint(I32, bool_result))
|
||||
state.push1(builder.ins().uextend(I32, bool_result))
|
||||
}
|
||||
Operator::I8x16AllTrue
|
||||
| Operator::I16x8AllTrue
|
||||
@@ -1680,7 +1673,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
| Operator::I64x2AllTrue => {
|
||||
let a = pop1_with_bitcast(state, type_of(op), builder);
|
||||
let bool_result = builder.ins().vall_true(a);
|
||||
state.push1(builder.ins().bint(I32, bool_result))
|
||||
state.push1(builder.ins().uextend(I32, bool_result))
|
||||
}
|
||||
Operator::I8x16Bitmask
|
||||
| Operator::I16x8Bitmask
|
||||
@@ -2253,7 +2246,9 @@ fn get_heap_addr(
|
||||
};
|
||||
debug_assert!(adjusted_offset > 0); // want to bounds check at least 1 byte
|
||||
let check_size = u32::try_from(adjusted_offset).unwrap_or(u32::MAX);
|
||||
let base = builder.ins().heap_addr(addr_ty, heap, addr32, check_size);
|
||||
let base = builder
|
||||
.ins()
|
||||
.heap_addr(addr_ty, heap, addr32, 0u32, check_size as u8);
|
||||
|
||||
// Native load/store instructions take a signed `Offset32` immediate, so adjust the base
|
||||
// pointer if necessary.
|
||||
@@ -2359,7 +2354,7 @@ fn mem_op_size(opcode: ir::Opcode, ty: Type) -> u32 {
|
||||
fn translate_icmp(cc: IntCC, builder: &mut FunctionBuilder, state: &mut FuncTranslationState) {
|
||||
let (arg0, arg1) = state.pop2();
|
||||
let val = builder.ins().icmp(cc, arg0, arg1);
|
||||
state.push1(builder.ins().bint(I32, val));
|
||||
state.push1(builder.ins().uextend(I32, val));
|
||||
}
|
||||
|
||||
fn fold_atomic_mem_addr(
|
||||
@@ -2375,12 +2370,10 @@ fn fold_atomic_mem_addr(
|
||||
let a = builder
|
||||
.ins()
|
||||
.iadd_imm(linear_mem_addr, memarg.offset as i64);
|
||||
let cflags = builder.ins().ifcmp_imm(a, 0x1_0000_0000i64);
|
||||
builder.ins().trapif(
|
||||
IntCC::UnsignedGreaterThanOrEqual,
|
||||
cflags,
|
||||
ir::TrapCode::HeapOutOfBounds,
|
||||
);
|
||||
let r = builder
|
||||
.ins()
|
||||
.icmp_imm(IntCC::UnsignedGreaterThanOrEqual, a, 0x1_0000_0000i64);
|
||||
builder.ins().trapnz(r, ir::TrapCode::HeapOutOfBounds);
|
||||
builder.ins().ireduce(I32, a)
|
||||
} else {
|
||||
linear_mem_addr
|
||||
@@ -2391,10 +2384,8 @@ fn fold_atomic_mem_addr(
|
||||
.band_imm(final_lma, i64::from(access_ty_bytes - 1));
|
||||
let f = builder
|
||||
.ins()
|
||||
.ifcmp_imm(final_lma_misalignment, i64::from(0));
|
||||
builder
|
||||
.ins()
|
||||
.trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned);
|
||||
.icmp_imm(IntCC::Equal, final_lma_misalignment, i64::from(0));
|
||||
builder.ins().trapz(f, ir::TrapCode::HeapMisaligned);
|
||||
final_lma
|
||||
}
|
||||
|
||||
@@ -2415,12 +2406,10 @@ fn finalise_atomic_mem_addr<FE: FuncEnvironment + ?Sized>(
|
||||
let a = builder
|
||||
.ins()
|
||||
.iadd_imm(linear_mem_addr, memarg.offset as i64);
|
||||
let cflags = builder.ins().ifcmp_imm(a, 0x1_0000_0000i64);
|
||||
builder.ins().trapif(
|
||||
IntCC::UnsignedGreaterThanOrEqual,
|
||||
cflags,
|
||||
ir::TrapCode::HeapOutOfBounds,
|
||||
);
|
||||
let r = builder
|
||||
.ins()
|
||||
.icmp_imm(IntCC::UnsignedGreaterThanOrEqual, a, 0x1_0000_0000i64);
|
||||
builder.ins().trapnz(r, ir::TrapCode::HeapOutOfBounds);
|
||||
builder.ins().ireduce(I32, a)
|
||||
} else {
|
||||
linear_mem_addr
|
||||
@@ -2433,10 +2422,8 @@ fn finalise_atomic_mem_addr<FE: FuncEnvironment + ?Sized>(
|
||||
.band_imm(final_lma, i64::from(access_ty_bytes - 1));
|
||||
let f = builder
|
||||
.ins()
|
||||
.ifcmp_imm(final_lma_misalignment, i64::from(0));
|
||||
builder
|
||||
.ins()
|
||||
.trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned);
|
||||
.icmp_imm(IntCC::Equal, final_lma_misalignment, i64::from(0));
|
||||
builder.ins().trapz(f, ir::TrapCode::HeapMisaligned);
|
||||
}
|
||||
|
||||
// Compute the final effective address.
|
||||
@@ -2647,7 +2634,7 @@ fn translate_vector_icmp(
|
||||
fn translate_fcmp(cc: FloatCC, builder: &mut FunctionBuilder, state: &mut FuncTranslationState) {
|
||||
let (arg0, arg1) = state.pop2();
|
||||
let val = builder.ins().fcmp(cc, arg0, arg1);
|
||||
state.push1(builder.ins().bint(I32, val));
|
||||
state.push1(builder.ins().uextend(I32, val));
|
||||
}
|
||||
|
||||
fn translate_vector_fcmp(
|
||||
@@ -2913,7 +2900,11 @@ fn optionally_bitcast_vector(
|
||||
builder: &mut FunctionBuilder,
|
||||
) -> Value {
|
||||
if builder.func.dfg.value_type(value) != needed_type {
|
||||
builder.ins().raw_bitcast(needed_type, value)
|
||||
builder.ins().bitcast(
|
||||
needed_type,
|
||||
MemFlags::new().with_endianness(ir::Endianness::Little),
|
||||
value,
|
||||
)
|
||||
} else {
|
||||
value
|
||||
}
|
||||
@@ -2921,10 +2912,7 @@ fn optionally_bitcast_vector(
|
||||
|
||||
#[inline(always)]
|
||||
fn is_non_canonical_v128(ty: ir::Type) -> bool {
|
||||
matches!(
|
||||
ty,
|
||||
B8X16 | B16X8 | B32X4 | B64X2 | I64X2 | I32X4 | I16X8 | F32X4 | F64X2
|
||||
)
|
||||
matches!(ty, I64X2 | I32X4 | I16X8 | F32X4 | F64X2)
|
||||
}
|
||||
|
||||
/// Cast to I8X16, any vector values in `values` that are of "non-canonical" type (meaning, not
|
||||
@@ -2948,7 +2936,11 @@ fn canonicalise_v128_values<'a>(
|
||||
// Otherwise we'll have to cast, and push the resulting `Value`s into `canonicalised`.
|
||||
for v in values {
|
||||
tmp_canonicalised.push(if is_non_canonical_v128(builder.func.dfg.value_type(*v)) {
|
||||
builder.ins().raw_bitcast(I8X16, *v)
|
||||
builder.ins().bitcast(
|
||||
I8X16,
|
||||
MemFlags::new().with_endianness(ir::Endianness::Little),
|
||||
*v,
|
||||
)
|
||||
} else {
|
||||
*v
|
||||
});
|
||||
|
||||
@@ -46,8 +46,6 @@ pub enum GlobalVariable {
|
||||
pub enum ReturnMode {
|
||||
/// Use normal return instructions as needed.
|
||||
NormalReturns,
|
||||
/// Use a single fallthrough return at the end of the function.
|
||||
FallthroughReturn,
|
||||
}
|
||||
|
||||
/// Environment affecting the translation of a WebAssembly.
|
||||
@@ -381,7 +379,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
value: ir::Value,
|
||||
) -> WasmResult<ir::Value> {
|
||||
let is_null = pos.ins().is_null(value);
|
||||
Ok(pos.ins().bint(ir::types::I64, is_null))
|
||||
Ok(pos.ins().uextend(ir::types::I64, is_null))
|
||||
}
|
||||
|
||||
/// Translate a `ref.func` WebAssembly instruction.
|
||||
|
||||
@@ -243,7 +243,7 @@ fn parse_function_body<FE: FuncEnvironment + ?Sized>(
|
||||
// If the exit block is unreachable, it may not have the correct arguments, so we would
|
||||
// generate a return instruction that doesn't match the signature.
|
||||
if state.reachable {
|
||||
debug_assert!(builder.is_pristine());
|
||||
//debug_assert!(builder.is_pristine());
|
||||
if !builder.is_unreachable() {
|
||||
match environ.return_mode() {
|
||||
ReturnMode::NormalReturns => {
|
||||
@@ -253,7 +253,6 @@ fn parse_function_body<FE: FuncEnvironment + ?Sized>(
|
||||
bitcast_arguments(&mut state.stack, &return_types, builder);
|
||||
builder.ins().return_(&state.stack)
|
||||
}
|
||||
ReturnMode::FallthroughReturn => builder.ins().fallthrough_return(&state.stack),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ pub(crate) fn compiled_function_unwind_info(
|
||||
context: &Context,
|
||||
) -> Result<CraneliftUnwindInfo, CompileError> {
|
||||
let unwind_info = context
|
||||
.compiled_code()
|
||||
.unwrap()
|
||||
.create_unwind_info(isa)
|
||||
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, error)))?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user