mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 05:38:19 +00:00
cargo fmt
This commit is contained in:
@@ -72,9 +72,7 @@ impl Abi for Aarch64SystemV {
|
||||
(
|
||||
context.create_enum_attribute(
|
||||
Attribute::get_named_enum_kind_id("align"),
|
||||
std::mem::align_of::<wasmer_vm::VMContext>()
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
std::mem::align_of::<wasmer_vm::VMContext>().try_into().unwrap(),
|
||||
),
|
||||
AttributeLoc::Param(i),
|
||||
),
|
||||
@@ -83,9 +81,7 @@ impl Abi for Aarch64SystemV {
|
||||
|
||||
Ok(match sig.results() {
|
||||
[] => (
|
||||
intrinsics
|
||||
.void_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[_] => {
|
||||
@@ -225,9 +221,7 @@ impl Abi for Aarch64SystemV {
|
||||
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
|
||||
|
||||
if let Some(sret) = sret {
|
||||
std::iter::once(sret.as_basic_value_enum())
|
||||
.chain(values)
|
||||
.collect()
|
||||
std::iter::once(sret.as_basic_value_enum()).chain(values).collect()
|
||||
} else {
|
||||
values.collect()
|
||||
}
|
||||
@@ -308,14 +302,9 @@ impl Abi for Aarch64SystemV {
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
let array_value = basic_value.into_array_value();
|
||||
let low = builder
|
||||
.build_extract_value(array_value, 0, "")
|
||||
.unwrap()
|
||||
.into_int_value();
|
||||
let high = builder
|
||||
.build_extract_value(array_value, 1, "")
|
||||
.unwrap()
|
||||
.into_int_value();
|
||||
let low = builder.build_extract_value(array_value, 0, "").unwrap().into_int_value();
|
||||
let high =
|
||||
builder.build_extract_value(array_value, 1, "").unwrap().into_int_value();
|
||||
let func_sig_returns_bitwidths = func_sig
|
||||
.results()
|
||||
.iter()
|
||||
@@ -473,9 +462,7 @@ impl Abi for Aarch64SystemV {
|
||||
if v.is_float_value() {
|
||||
let v = v.into_float_value();
|
||||
if v.get_type() == intrinsics.f32_ty {
|
||||
let v = builder
|
||||
.build_bitcast(v, intrinsics.i32_ty, "")
|
||||
.into_int_value();
|
||||
let v = builder.build_bitcast(v, intrinsics.i32_ty, "").into_int_value();
|
||||
let v = builder.build_int_z_extend(v, intrinsics.i64_ty, "");
|
||||
v.as_basic_value_enum()
|
||||
} else {
|
||||
@@ -522,10 +509,7 @@ impl Abi for Aarch64SystemV {
|
||||
&& v2.is_float_value()
|
||||
&& v1.into_float_value().get_type() == v2.into_float_value().get_type() =>
|
||||
{
|
||||
build_struct(
|
||||
func_type.get_return_type().unwrap().into_struct_type(),
|
||||
&[v1, v2],
|
||||
)
|
||||
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2])
|
||||
}
|
||||
[v1, v2] if is_32(v1) && is_32(v2) => {
|
||||
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
||||
@@ -541,10 +525,7 @@ impl Abi for Aarch64SystemV {
|
||||
&& v2.is_float_value()
|
||||
&& v3.is_float_value() =>
|
||||
{
|
||||
build_struct(
|
||||
func_type.get_return_type().unwrap().into_struct_type(),
|
||||
&[v1, v2, v3],
|
||||
)
|
||||
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2, v3])
|
||||
}
|
||||
[v1, v2, v3] if is_32(v1) && is_32(v2) => {
|
||||
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
||||
|
||||
@@ -25,12 +25,7 @@ use aarch64_systemv::Aarch64SystemV;
|
||||
use x86_64_systemv::X86_64SystemV;
|
||||
|
||||
pub fn get_abi(target_machine: &TargetMachine) -> Box<dyn Abi> {
|
||||
if target_machine
|
||||
.get_triple()
|
||||
.as_str()
|
||||
.to_string_lossy()
|
||||
.starts_with("aarch64")
|
||||
{
|
||||
if target_machine.get_triple().as_str().to_string_lossy().starts_with("aarch64") {
|
||||
Box::new(Aarch64SystemV {})
|
||||
} else {
|
||||
Box::new(X86_64SystemV {})
|
||||
|
||||
@@ -76,9 +76,7 @@ impl Abi for X86_64SystemV {
|
||||
(
|
||||
context.create_enum_attribute(
|
||||
Attribute::get_named_enum_kind_id("align"),
|
||||
std::mem::align_of::<wasmer_vm::VMContext>()
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
std::mem::align_of::<wasmer_vm::VMContext>().try_into().unwrap(),
|
||||
),
|
||||
AttributeLoc::Param(i),
|
||||
),
|
||||
@@ -98,9 +96,7 @@ impl Abi for X86_64SystemV {
|
||||
|
||||
Ok(match sig_returns_bitwidths.as_slice() {
|
||||
[] => (
|
||||
intrinsics
|
||||
.void_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[_] => {
|
||||
@@ -133,9 +129,7 @@ impl Abi for X86_64SystemV {
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[32, 32] => (
|
||||
intrinsics
|
||||
.i64_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.i64_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[32, 32, _] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => (
|
||||
@@ -213,9 +207,7 @@ impl Abi for X86_64SystemV {
|
||||
.map(|&ty| type_to_llvm(intrinsics, ty))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
let sret = context
|
||||
.struct_type(&basic_types, false)
|
||||
.ptr_type(AddressSpace::Generic);
|
||||
let sret = context.struct_type(&basic_types, false).ptr_type(AddressSpace::Generic);
|
||||
|
||||
let param_types = std::iter::once(Ok(sret.as_basic_type_enum())).chain(param_types);
|
||||
|
||||
@@ -226,9 +218,7 @@ impl Abi for X86_64SystemV {
|
||||
attributes.append(&mut vmctx_attributes(1));
|
||||
|
||||
(
|
||||
intrinsics
|
||||
.void_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
attributes,
|
||||
)
|
||||
}
|
||||
@@ -262,9 +252,7 @@ impl Abi for X86_64SystemV {
|
||||
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
|
||||
|
||||
if let Some(sret) = sret {
|
||||
std::iter::once(sret.as_basic_value_enum())
|
||||
.chain(values)
|
||||
.collect()
|
||||
std::iter::once(sret.as_basic_value_enum()).chain(values).collect()
|
||||
} else {
|
||||
values.collect()
|
||||
}
|
||||
@@ -541,10 +529,7 @@ impl Abi for X86_64SystemV {
|
||||
}
|
||||
[v1, v2] => {
|
||||
assert!(!(is_32(v1) && is_32(v2)));
|
||||
build_struct(
|
||||
func_type.get_return_type().unwrap().into_struct_type(),
|
||||
&[v1, v2],
|
||||
)
|
||||
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2])
|
||||
}
|
||||
[v1, v2, v3] if is_f32(v1) && is_f32(v2) => build_struct(
|
||||
func_type.get_return_type().unwrap().into_struct_type(),
|
||||
|
||||
@@ -61,12 +61,8 @@ impl SymbolRegistry for ShortNames {
|
||||
match ty.chars().next().unwrap() {
|
||||
'f' => Some(Symbol::LocalFunction(LocalFunctionIndex::from_u32(idx))),
|
||||
's' => Some(Symbol::Section(SectionIndex::from_u32(idx))),
|
||||
't' => Some(Symbol::FunctionCallTrampoline(SignatureIndex::from_u32(
|
||||
idx,
|
||||
))),
|
||||
'd' => Some(Symbol::DynamicFunctionTrampoline(FunctionIndex::from_u32(
|
||||
idx,
|
||||
))),
|
||||
't' => Some(Symbol::FunctionCallTrampoline(SignatureIndex::from_u32(idx))),
|
||||
'd' => Some(Symbol::DynamicFunctionTrampoline(FunctionIndex::from_u32(idx))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -123,10 +119,7 @@ impl LLVMCompiler {
|
||||
compile_info.module.functions.iter().par_bridge().map_init(
|
||||
|| {
|
||||
let target_machine = self.config().target_machine(target);
|
||||
(
|
||||
FuncTrampoline::new(target_machine),
|
||||
&compile_info.module.signatures,
|
||||
)
|
||||
(FuncTrampoline::new(target_machine), &compile_info.module.signatures)
|
||||
},
|
||||
|(func_trampoline, signatures), (i, sig)| {
|
||||
let sig = &signatures[*sig];
|
||||
@@ -176,9 +169,8 @@ impl LLVMCompiler {
|
||||
merged_module.verify().unwrap();
|
||||
}
|
||||
|
||||
let memory_buffer = target_machine
|
||||
.write_to_memory_buffer(&merged_module, FileType::Object)
|
||||
.unwrap();
|
||||
let memory_buffer =
|
||||
target_machine.write_to_memory_buffer(&merged_module, FileType::Object).unwrap();
|
||||
if let Some(ref callbacks) = self.config.callbacks {
|
||||
callbacks.obj_memory_buffer(&CompiledKind::Module, &memory_buffer);
|
||||
}
|
||||
@@ -274,10 +266,7 @@ impl Compiler for LLVMCompiler {
|
||||
)
|
||||
}
|
||||
}
|
||||
if compiled_function
|
||||
.eh_frame_section_indices
|
||||
.contains(§ion_index)
|
||||
{
|
||||
if compiled_function.eh_frame_section_indices.contains(§ion_index) {
|
||||
let offset = frame_section_bytes.len() as u32;
|
||||
for mut reloc in &mut custom_section.relocations {
|
||||
reloc.offset += offset;
|
||||
@@ -306,9 +295,8 @@ impl Compiler for LLVMCompiler {
|
||||
.collect::<PrimaryMap<LocalFunctionIndex, _>>();
|
||||
|
||||
let dwarf = if !frame_section_bytes.is_empty() {
|
||||
let dwarf = Some(Dwarf::new(SectionIndex::from_u32(
|
||||
module_custom_sections.len() as u32,
|
||||
)));
|
||||
let dwarf =
|
||||
Some(Dwarf::new(SectionIndex::from_u32(module_custom_sections.len() as u32)));
|
||||
// Terminating zero-length CIE.
|
||||
frame_section_bytes.extend(vec![
|
||||
0x00, 0x00, 0x00, 0x00, // Length
|
||||
|
||||
@@ -176,10 +176,8 @@ impl LLVM {
|
||||
// The CPU features formatted as LLVM strings
|
||||
// We can safely map to gcc-like features as the CPUFeatures
|
||||
// are compliant with the same string representations as gcc.
|
||||
let llvm_cpu_features = cpu_features
|
||||
.iter()
|
||||
.map(|feature| format!("+{}", feature.to_string()))
|
||||
.join(",");
|
||||
let llvm_cpu_features =
|
||||
cpu_features.iter().map(|feature| format!("+{}", feature.to_string())).join(",");
|
||||
|
||||
let target_triple = self.target_triple(&target);
|
||||
let llvm_target = InkwellTarget::from_triple(&target_triple).unwrap();
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![cfg_attr(
|
||||
all(not(target_os = "windows"), not(target_arch = "aarch64")),
|
||||
deny(dead_code)
|
||||
)]
|
||||
#![cfg_attr(all(not(target_os = "windows"), not(target_arch = "aarch64")), deny(dead_code))]
|
||||
#![cfg_attr(nightly, feature(unwind_attributes))]
|
||||
#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
|
||||
#![doc(html_logo_url = "https://github.com/wasmerio.png?size=200")]
|
||||
|
||||
@@ -71,45 +71,24 @@ where
|
||||
libcalls.insert("wasmer_vm_f32_trunc".to_string(), LibCall::TruncF32);
|
||||
libcalls.insert("wasmer_vm_f64_trunc".to_string(), LibCall::TruncF64);
|
||||
libcalls.insert("wasmer_vm_memory32_size".to_string(), LibCall::Memory32Size);
|
||||
libcalls.insert(
|
||||
"wasmer_vm_imported_memory32_size".to_string(),
|
||||
LibCall::ImportedMemory32Size,
|
||||
);
|
||||
libcalls.insert("wasmer_vm_imported_memory32_size".to_string(), LibCall::ImportedMemory32Size);
|
||||
libcalls.insert("wasmer_vm_table_copy".to_string(), LibCall::TableCopy);
|
||||
libcalls.insert("wasmer_vm_table_init".to_string(), LibCall::TableInit);
|
||||
libcalls.insert("wasmer_vm_table_fill".to_string(), LibCall::TableFill);
|
||||
libcalls.insert("wasmer_vm_table_size".to_string(), LibCall::TableSize);
|
||||
libcalls.insert(
|
||||
"wasmer_vm_imported_table_size".to_string(),
|
||||
LibCall::ImportedTableSize,
|
||||
);
|
||||
libcalls.insert("wasmer_vm_imported_table_size".to_string(), LibCall::ImportedTableSize);
|
||||
libcalls.insert("wasmer_vm_table_get".to_string(), LibCall::TableGet);
|
||||
libcalls.insert(
|
||||
"wasmer_vm_imported_table_get".to_string(),
|
||||
LibCall::ImportedTableGet,
|
||||
);
|
||||
libcalls.insert("wasmer_vm_imported_table_get".to_string(), LibCall::ImportedTableGet);
|
||||
libcalls.insert("wasmer_vm_table_set".to_string(), LibCall::TableSet);
|
||||
libcalls.insert(
|
||||
"wasmer_vm_imported_table_set".to_string(),
|
||||
LibCall::ImportedTableSet,
|
||||
);
|
||||
libcalls.insert("wasmer_vm_imported_table_set".to_string(), LibCall::ImportedTableSet);
|
||||
libcalls.insert("wasmer_vm_table_grow".to_string(), LibCall::TableGrow);
|
||||
libcalls.insert(
|
||||
"wasmer_vm_imported_table_grow".to_string(),
|
||||
LibCall::ImportedTableGrow,
|
||||
);
|
||||
libcalls.insert("wasmer_vm_imported_table_grow".to_string(), LibCall::ImportedTableGrow);
|
||||
libcalls.insert("wasmer_vm_func_ref".to_string(), LibCall::FuncRef);
|
||||
libcalls.insert("wasmer_vm_elem_drop".to_string(), LibCall::ElemDrop);
|
||||
libcalls.insert("wasmer_vm_memory32_copy".to_string(), LibCall::Memory32Copy);
|
||||
libcalls.insert(
|
||||
"wasmer_vm_imported_memory32_copy".to_string(),
|
||||
LibCall::ImportedMemory32Copy,
|
||||
);
|
||||
libcalls.insert("wasmer_vm_imported_memory32_copy".to_string(), LibCall::ImportedMemory32Copy);
|
||||
libcalls.insert("wasmer_vm_memory32_fill".to_string(), LibCall::Memory32Fill);
|
||||
libcalls.insert(
|
||||
"wasmer_vm_imported_memory32_fill".to_string(),
|
||||
LibCall::ImportedMemory32Fill,
|
||||
);
|
||||
libcalls.insert("wasmer_vm_imported_memory32_fill".to_string(), LibCall::ImportedMemory32Fill);
|
||||
libcalls.insert("wasmer_vm_memory32_init".to_string(), LibCall::Memory32Init);
|
||||
libcalls.insert("wasmer_vm_data_drop".to_string(), LibCall::DataDrop);
|
||||
libcalls.insert("wasmer_vm_raise_trap".to_string(), LibCall::RaiseTrap);
|
||||
@@ -274,15 +253,12 @@ where
|
||||
} else {
|
||||
unimplemented!("unknown relocation {:?} with target {:?}", reloc, target);
|
||||
};
|
||||
relocations
|
||||
.entry(section_index)
|
||||
.or_default()
|
||||
.push(Relocation {
|
||||
kind,
|
||||
reloc_target,
|
||||
offset,
|
||||
addend,
|
||||
});
|
||||
relocations.entry(section_index).or_default().push(Relocation {
|
||||
kind,
|
||||
reloc_target,
|
||||
offset,
|
||||
addend,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,15 +293,10 @@ where
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
custom_sections.sort_unstable_by_key(|a| a.0);
|
||||
let custom_sections = custom_sections
|
||||
.into_iter()
|
||||
.map(|(_, v)| v)
|
||||
.collect::<PrimaryMap<SectionIndex, _>>();
|
||||
let custom_sections =
|
||||
custom_sections.into_iter().map(|(_, v)| v).collect::<PrimaryMap<SectionIndex, _>>();
|
||||
|
||||
let function_body = FunctionBody {
|
||||
body: section_bytes(root_section_index),
|
||||
unwind_info: None,
|
||||
};
|
||||
let function_body = FunctionBody { body: section_bytes(root_section_index), unwind_info: None };
|
||||
|
||||
let address_map = FunctionAddressMap {
|
||||
instructions: vec![InstructionAddressMap {
|
||||
@@ -343,13 +314,8 @@ where
|
||||
compiled_function: wasmer_compiler::CompiledFunction {
|
||||
body: function_body,
|
||||
jt_offsets: SecondaryMap::new(),
|
||||
relocations: relocations
|
||||
.remove_entry(&root_section_index)
|
||||
.map_or(vec![], |(_, v)| v),
|
||||
frame_info: CompiledFunctionFrameInfo {
|
||||
address_map,
|
||||
traps: vec![],
|
||||
},
|
||||
relocations: relocations.remove_entry(&root_section_index).map_or(vec![], |(_, v)| v),
|
||||
frame_info: CompiledFunctionFrameInfo { address_map, traps: vec![] },
|
||||
},
|
||||
custom_sections,
|
||||
eh_frame_section_indices,
|
||||
|
||||
@@ -28,11 +28,7 @@ const FUNCTION_SECTION: &str = "__TEXT,wasmer_trmpl"; // Needs to be between 1 a
|
||||
impl FuncTrampoline {
|
||||
pub fn new(target_machine: TargetMachine) -> Self {
|
||||
let abi = get_abi(&target_machine);
|
||||
Self {
|
||||
ctx: Context::create(),
|
||||
target_machine,
|
||||
abi,
|
||||
}
|
||||
Self { ctx: Context::create(), target_machine, abi }
|
||||
}
|
||||
|
||||
pub fn trampoline_to_module(
|
||||
@@ -51,29 +47,20 @@ impl FuncTrampoline {
|
||||
let intrinsics = Intrinsics::declare(&module, &self.ctx);
|
||||
|
||||
let (callee_ty, callee_attrs) =
|
||||
self.abi
|
||||
.func_type_to_llvm(&self.ctx, &intrinsics, None, ty)?;
|
||||
self.abi.func_type_to_llvm(&self.ctx, &intrinsics, None, ty)?;
|
||||
let trampoline_ty = intrinsics.void_ty.fn_type(
|
||||
&[
|
||||
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // vmctx ptr
|
||||
callee_ty
|
||||
.ptr_type(AddressSpace::Generic)
|
||||
.as_basic_type_enum(), // callee function address
|
||||
intrinsics.i128_ptr_ty.as_basic_type_enum(), // in/out values ptr
|
||||
callee_ty.ptr_type(AddressSpace::Generic).as_basic_type_enum(), // callee function address
|
||||
intrinsics.i128_ptr_ty.as_basic_type_enum(), // in/out values ptr
|
||||
],
|
||||
false,
|
||||
);
|
||||
|
||||
let trampoline_func = module.add_function(name, trampoline_ty, Some(Linkage::External));
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_section(FUNCTION_SECTION);
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_linkage(Linkage::DLLExport);
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_dll_storage_class(DLLStorageClass::Export);
|
||||
trampoline_func.as_global_value().set_section(FUNCTION_SECTION);
|
||||
trampoline_func.as_global_value().set_linkage(Linkage::DLLExport);
|
||||
trampoline_func.as_global_value().set_dll_storage_class(DLLStorageClass::Export);
|
||||
self.generate_trampoline(trampoline_func, ty, &callee_attrs, &self.ctx, &intrinsics)?;
|
||||
|
||||
if let Some(ref callbacks) = config.callbacks {
|
||||
@@ -107,30 +94,26 @@ impl FuncTrampoline {
|
||||
let function = CompiledKind::FunctionCallTrampoline(ty.clone());
|
||||
let target_machine = &self.target_machine;
|
||||
|
||||
let memory_buffer = target_machine
|
||||
.write_to_memory_buffer(&module, FileType::Object)
|
||||
.unwrap();
|
||||
let memory_buffer =
|
||||
target_machine.write_to_memory_buffer(&module, FileType::Object).unwrap();
|
||||
|
||||
if let Some(ref callbacks) = config.callbacks {
|
||||
callbacks.obj_memory_buffer(&function, &memory_buffer);
|
||||
}
|
||||
|
||||
let mem_buf_slice = memory_buffer.as_slice();
|
||||
let CompiledFunction {
|
||||
compiled_function,
|
||||
custom_sections,
|
||||
eh_frame_section_indices,
|
||||
} = load_object_file(
|
||||
mem_buf_slice,
|
||||
FUNCTION_SECTION,
|
||||
RelocationTarget::LocalFunc(LocalFunctionIndex::from_u32(0)),
|
||||
|name: &String| {
|
||||
Err(CompileError::Codegen(format!(
|
||||
"trampoline generation produced reference to unknown function {}",
|
||||
name
|
||||
)))
|
||||
},
|
||||
)?;
|
||||
let CompiledFunction { compiled_function, custom_sections, eh_frame_section_indices } =
|
||||
load_object_file(
|
||||
mem_buf_slice,
|
||||
FUNCTION_SECTION,
|
||||
RelocationTarget::LocalFunc(LocalFunctionIndex::from_u32(0)),
|
||||
|name: &String| {
|
||||
Err(CompileError::Codegen(format!(
|
||||
"trampoline generation produced reference to unknown function {}",
|
||||
name
|
||||
)))
|
||||
},
|
||||
)?;
|
||||
let mut all_sections_are_eh_sections = true;
|
||||
if eh_frame_section_indices.len() != custom_sections.len() {
|
||||
all_sections_are_eh_sections = false;
|
||||
@@ -150,14 +133,10 @@ impl FuncTrampoline {
|
||||
));
|
||||
}
|
||||
if !compiled_function.relocations.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced relocations".into(),
|
||||
));
|
||||
return Err(CompileError::Codegen("trampoline generation produced relocations".into()));
|
||||
}
|
||||
if !compiled_function.jt_offsets.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced jump tables".into(),
|
||||
));
|
||||
return Err(CompileError::Codegen("trampoline generation produced jump tables".into()));
|
||||
}
|
||||
// Ignore CompiledFunctionFrameInfo. Extra frame info isn't a problem.
|
||||
|
||||
@@ -183,21 +162,14 @@ impl FuncTrampoline {
|
||||
let intrinsics = Intrinsics::declare(&module, &self.ctx);
|
||||
|
||||
let (trampoline_ty, trampoline_attrs) =
|
||||
self.abi
|
||||
.func_type_to_llvm(&self.ctx, &intrinsics, None, ty)?;
|
||||
self.abi.func_type_to_llvm(&self.ctx, &intrinsics, None, ty)?;
|
||||
let trampoline_func = module.add_function(name, trampoline_ty, Some(Linkage::External));
|
||||
for (attr, attr_loc) in trampoline_attrs {
|
||||
trampoline_func.add_attribute(attr_loc, attr);
|
||||
}
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_section(FUNCTION_SECTION);
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_linkage(Linkage::DLLExport);
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_dll_storage_class(DLLStorageClass::Export);
|
||||
trampoline_func.as_global_value().set_section(FUNCTION_SECTION);
|
||||
trampoline_func.as_global_value().set_linkage(Linkage::DLLExport);
|
||||
trampoline_func.as_global_value().set_dll_storage_class(DLLStorageClass::Export);
|
||||
self.generate_dynamic_trampoline(trampoline_func, ty, &self.ctx, &intrinsics)?;
|
||||
|
||||
if let Some(ref callbacks) = config.callbacks {
|
||||
@@ -231,30 +203,26 @@ impl FuncTrampoline {
|
||||
|
||||
let module = self.dynamic_trampoline_to_module(ty, config, name)?;
|
||||
|
||||
let memory_buffer = target_machine
|
||||
.write_to_memory_buffer(&module, FileType::Object)
|
||||
.unwrap();
|
||||
let memory_buffer =
|
||||
target_machine.write_to_memory_buffer(&module, FileType::Object).unwrap();
|
||||
|
||||
if let Some(ref callbacks) = config.callbacks {
|
||||
callbacks.obj_memory_buffer(&function, &memory_buffer);
|
||||
}
|
||||
|
||||
let mem_buf_slice = memory_buffer.as_slice();
|
||||
let CompiledFunction {
|
||||
compiled_function,
|
||||
custom_sections,
|
||||
eh_frame_section_indices,
|
||||
} = load_object_file(
|
||||
mem_buf_slice,
|
||||
FUNCTION_SECTION,
|
||||
RelocationTarget::LocalFunc(LocalFunctionIndex::from_u32(0)),
|
||||
|name: &String| {
|
||||
Err(CompileError::Codegen(format!(
|
||||
"trampoline generation produced reference to unknown function {}",
|
||||
name
|
||||
)))
|
||||
},
|
||||
)?;
|
||||
let CompiledFunction { compiled_function, custom_sections, eh_frame_section_indices } =
|
||||
load_object_file(
|
||||
mem_buf_slice,
|
||||
FUNCTION_SECTION,
|
||||
RelocationTarget::LocalFunc(LocalFunctionIndex::from_u32(0)),
|
||||
|name: &String| {
|
||||
Err(CompileError::Codegen(format!(
|
||||
"trampoline generation produced reference to unknown function {}",
|
||||
name
|
||||
)))
|
||||
},
|
||||
)?;
|
||||
let mut all_sections_are_eh_sections = true;
|
||||
if eh_frame_section_indices.len() != custom_sections.len() {
|
||||
all_sections_are_eh_sections = false;
|
||||
@@ -274,14 +242,10 @@ impl FuncTrampoline {
|
||||
));
|
||||
}
|
||||
if !compiled_function.relocations.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced relocations".into(),
|
||||
));
|
||||
return Err(CompileError::Codegen("trampoline generation produced relocations".into()));
|
||||
}
|
||||
if !compiled_function.jt_offsets.is_empty() {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline generation produced jump tables".into(),
|
||||
));
|
||||
return Err(CompileError::Codegen("trampoline generation produced jump tables".into()));
|
||||
}
|
||||
// Ignore CompiledFunctionFrameInfo. Extra frame info isn't a problem.
|
||||
|
||||
@@ -303,19 +267,19 @@ impl FuncTrampoline {
|
||||
let builder = context.create_builder();
|
||||
builder.position_at_end(entry_block);
|
||||
|
||||
let (callee_vmctx_ptr, func_ptr, args_rets_ptr) =
|
||||
match *trampoline_func.get_params().as_slice() {
|
||||
[callee_vmctx_ptr, func_ptr, args_rets_ptr] => (
|
||||
callee_vmctx_ptr,
|
||||
func_ptr.into_pointer_value(),
|
||||
args_rets_ptr.into_pointer_value(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline function unimplemented".to_string(),
|
||||
))
|
||||
}
|
||||
};
|
||||
let (callee_vmctx_ptr, func_ptr, args_rets_ptr) = match *trampoline_func
|
||||
.get_params()
|
||||
.as_slice()
|
||||
{
|
||||
[callee_vmctx_ptr, func_ptr, args_rets_ptr] => (
|
||||
callee_vmctx_ptr,
|
||||
func_ptr.into_pointer_value(),
|
||||
args_rets_ptr.into_pointer_value(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CompileError::Codegen("trampoline function unimplemented".to_string()))
|
||||
}
|
||||
};
|
||||
|
||||
let mut args_vec = Vec::with_capacity(func_sig.params().len() + 1);
|
||||
|
||||
@@ -351,17 +315,11 @@ impl FuncTrampoline {
|
||||
call_site.add_attribute(*attr_loc, *attr);
|
||||
}
|
||||
|
||||
let rets = self
|
||||
.abi
|
||||
.rets_from_call(&builder, intrinsics, call_site, func_sig);
|
||||
let rets = self.abi.rets_from_call(&builder, intrinsics, call_site, func_sig);
|
||||
let mut idx = 0;
|
||||
rets.iter().for_each(|v| {
|
||||
let ptr = unsafe {
|
||||
builder.build_gep(
|
||||
args_rets_ptr,
|
||||
&[intrinsics.i32_ty.const_int(idx, false)],
|
||||
"",
|
||||
)
|
||||
builder.build_gep(args_rets_ptr, &[intrinsics.i32_ty.const_int(idx, false)], "")
|
||||
};
|
||||
let ptr =
|
||||
builder.build_pointer_cast(ptr, v.get_type().ptr_type(AddressSpace::Generic), "");
|
||||
@@ -414,9 +372,7 @@ impl FuncTrampoline {
|
||||
.into_pointer_value();
|
||||
builder.build_store(
|
||||
ptr,
|
||||
trampoline_func
|
||||
.get_nth_param(i as u32 + first_user_param)
|
||||
.unwrap(),
|
||||
trampoline_func.get_nth_param(i as u32 + first_user_param).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -443,10 +399,7 @@ impl FuncTrampoline {
|
||||
let values_ptr = builder.build_pointer_cast(values, intrinsics.i128_ptr_ty, "");
|
||||
builder.build_call(
|
||||
callee,
|
||||
&[
|
||||
vmctx.as_basic_value_enum(),
|
||||
values_ptr.as_basic_value_enum(),
|
||||
],
|
||||
&[vmctx.as_basic_value_enum(), values_ptr.as_basic_value_enum()],
|
||||
"",
|
||||
);
|
||||
|
||||
@@ -475,15 +428,9 @@ impl FuncTrampoline {
|
||||
.collect::<Result<Vec<_>, CompileError>>()?;
|
||||
|
||||
if self.abi.is_sret(func_sig)? {
|
||||
let sret = trampoline_func
|
||||
.get_first_param()
|
||||
.unwrap()
|
||||
.into_pointer_value();
|
||||
let mut struct_value = sret
|
||||
.get_type()
|
||||
.get_element_type()
|
||||
.into_struct_type()
|
||||
.get_undef();
|
||||
let sret = trampoline_func.get_first_param().unwrap().into_pointer_value();
|
||||
let mut struct_value =
|
||||
sret.get_type().get_element_type().into_struct_type().get_undef();
|
||||
for (idx, value) in results.iter().enumerate() {
|
||||
let value = builder.build_bitcast(
|
||||
*value,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -259,11 +259,7 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
let sigindex_ty = i32_ty;
|
||||
|
||||
let anyfunc_ty = context.struct_type(
|
||||
&[
|
||||
i8_ptr_ty_basic,
|
||||
sigindex_ty.as_basic_type_enum(),
|
||||
ctx_ptr_ty.as_basic_type_enum(),
|
||||
],
|
||||
&[i8_ptr_ty_basic, sigindex_ty.as_basic_type_enum(), ctx_ptr_ty.as_basic_type_enum()],
|
||||
false,
|
||||
);
|
||||
let funcref_ty = anyfunc_ty.ptr_type(AddressSpace::Generic);
|
||||
@@ -461,13 +457,7 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
|
||||
experimental_stackmap: module.add_function(
|
||||
"llvm.experimental.stackmap",
|
||||
void_ty.fn_type(
|
||||
&[
|
||||
i64_ty_basic, /* id */
|
||||
i32_ty_basic, /* numShadowBytes */
|
||||
],
|
||||
true,
|
||||
),
|
||||
void_ty.fn_type(&[i64_ty_basic /* id */, i32_ty_basic /* numShadowBytes */], true),
|
||||
None,
|
||||
),
|
||||
|
||||
@@ -528,18 +518,14 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
),
|
||||
table_get: module.add_function(
|
||||
"wasmer_vm_table_get",
|
||||
anyref_ty.fn_type(
|
||||
&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic],
|
||||
false,
|
||||
),
|
||||
anyref_ty
|
||||
.fn_type(&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic], false),
|
||||
None,
|
||||
),
|
||||
imported_table_get: module.add_function(
|
||||
"wasmer_vm_imported_table_get",
|
||||
anyref_ty.fn_type(
|
||||
&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic],
|
||||
false,
|
||||
),
|
||||
anyref_ty
|
||||
.fn_type(&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic], false),
|
||||
None,
|
||||
),
|
||||
table_set: module.add_function(
|
||||
@@ -624,16 +610,10 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
vmmemory_definition_current_length_element: 1,
|
||||
|
||||
memory32_grow_ptr_ty: i32_ty
|
||||
.fn_type(
|
||||
&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic],
|
||||
false,
|
||||
)
|
||||
.fn_type(&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic], false)
|
||||
.ptr_type(AddressSpace::Generic),
|
||||
imported_memory32_grow_ptr_ty: i32_ty
|
||||
.fn_type(
|
||||
&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic],
|
||||
false,
|
||||
)
|
||||
.fn_type(&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic, i32_ty_basic], false)
|
||||
.ptr_type(AddressSpace::Generic),
|
||||
memory32_size_ptr_ty: i32_ty
|
||||
.fn_type(&[ctx_ptr_ty.as_basic_type_enum(), i32_ty_basic], false)
|
||||
@@ -647,12 +627,8 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
|
||||
let noreturn =
|
||||
context.create_enum_attribute(Attribute::get_named_enum_kind_id("noreturn"), 0);
|
||||
intrinsics
|
||||
.throw_trap
|
||||
.add_attribute(AttributeLoc::Function, noreturn);
|
||||
intrinsics
|
||||
.func_ref
|
||||
.add_attribute(AttributeLoc::Function, intrinsics.readonly);
|
||||
intrinsics.throw_trap.add_attribute(AttributeLoc::Function, noreturn);
|
||||
intrinsics.func_ref.add_attribute(AttributeLoc::Function, intrinsics.readonly);
|
||||
|
||||
intrinsics
|
||||
}
|
||||
@@ -661,10 +637,7 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum MemoryCache<'ctx> {
|
||||
/// The memory moves around.
|
||||
Dynamic {
|
||||
ptr_to_base_ptr: PointerValue<'ctx>,
|
||||
ptr_to_current_length: PointerValue<'ctx>,
|
||||
},
|
||||
Dynamic { ptr_to_base_ptr: PointerValue<'ctx>, ptr_to_current_length: PointerValue<'ctx> },
|
||||
/// The memory is always in the same place.
|
||||
Static { base_ptr: PointerValue<'ctx> },
|
||||
}
|
||||
@@ -752,40 +725,36 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
);
|
||||
let memory_style = &memory_styles[index];
|
||||
*cached_memories.entry(index).or_insert_with(|| {
|
||||
let memory_definition_ptr =
|
||||
if let Some(local_memory_index) = wasm_module.local_memory_index(index) {
|
||||
let offset = offsets.vmctx_vmmemory_definition(local_memory_index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") }
|
||||
} else {
|
||||
let offset = offsets.vmctx_vmmemory_import(index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
let memory_definition_ptr_ptr =
|
||||
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") };
|
||||
let memory_definition_ptr_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
memory_definition_ptr_ptr,
|
||||
intrinsics.i8_ptr_ty.ptr_type(AddressSpace::Generic),
|
||||
"",
|
||||
)
|
||||
.into_pointer_value();
|
||||
let memory_definition_ptr = cache_builder
|
||||
.build_load(memory_definition_ptr_ptr, "")
|
||||
.into_pointer_value();
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
format!("memory {} definition", index.as_u32()),
|
||||
memory_definition_ptr.as_instruction_value().unwrap(),
|
||||
);
|
||||
memory_definition_ptr
|
||||
};
|
||||
let memory_definition_ptr = if let Some(local_memory_index) =
|
||||
wasm_module.local_memory_index(index)
|
||||
{
|
||||
let offset = offsets.vmctx_vmmemory_definition(local_memory_index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") }
|
||||
} else {
|
||||
let offset = offsets.vmctx_vmmemory_import(index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
let memory_definition_ptr_ptr =
|
||||
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") };
|
||||
let memory_definition_ptr_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
memory_definition_ptr_ptr,
|
||||
intrinsics.i8_ptr_ty.ptr_type(AddressSpace::Generic),
|
||||
"",
|
||||
)
|
||||
.into_pointer_value();
|
||||
let memory_definition_ptr =
|
||||
cache_builder.build_load(memory_definition_ptr_ptr, "").into_pointer_value();
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
format!("memory {} definition", index.as_u32()),
|
||||
memory_definition_ptr.as_instruction_value().unwrap(),
|
||||
);
|
||||
memory_definition_ptr
|
||||
};
|
||||
let memory_definition_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
memory_definition_ptr,
|
||||
intrinsics.vmmemory_definition_ptr_ty,
|
||||
"",
|
||||
)
|
||||
.build_bitcast(memory_definition_ptr, intrinsics.vmmemory_definition_ptr_ty, "")
|
||||
.into_pointer_value();
|
||||
let base_ptr = cache_builder
|
||||
.build_struct_gep(
|
||||
@@ -832,16 +801,13 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
&self.cache_builder,
|
||||
&self.offsets,
|
||||
);
|
||||
let TableCache {
|
||||
ptr_to_base_ptr,
|
||||
ptr_to_bounds,
|
||||
} = *cached_tables.entry(table_index).or_insert_with(|| {
|
||||
let (ptr_to_base_ptr, ptr_to_bounds) =
|
||||
if let Some(local_table_index) = wasm_module.local_table_index(table_index) {
|
||||
let TableCache { ptr_to_base_ptr, ptr_to_bounds } =
|
||||
*cached_tables.entry(table_index).or_insert_with(|| {
|
||||
let (ptr_to_base_ptr, ptr_to_bounds) = if let Some(local_table_index) =
|
||||
wasm_module.local_table_index(table_index)
|
||||
{
|
||||
let offset = intrinsics.i64_ty.const_int(
|
||||
offsets
|
||||
.vmctx_vmtable_definition_base(local_table_index)
|
||||
.into(),
|
||||
offsets.vmctx_vmtable_definition_base(local_table_index).into(),
|
||||
false,
|
||||
);
|
||||
let ptr_to_base_ptr =
|
||||
@@ -854,9 +820,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
)
|
||||
.into_pointer_value();
|
||||
let offset = intrinsics.i64_ty.const_int(
|
||||
offsets
|
||||
.vmctx_vmtable_definition_current_elements(local_table_index)
|
||||
.into(),
|
||||
offsets.vmctx_vmtable_definition_current_elements(local_table_index).into(),
|
||||
false,
|
||||
);
|
||||
let ptr_to_bounds =
|
||||
@@ -879,9 +843,8 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
"",
|
||||
)
|
||||
.into_pointer_value();
|
||||
let definition_ptr = cache_builder
|
||||
.build_load(definition_ptr_ptr, "")
|
||||
.into_pointer_value();
|
||||
let definition_ptr =
|
||||
cache_builder.build_load(definition_ptr_ptr, "").into_pointer_value();
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
@@ -911,11 +874,8 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
.into_pointer_value();
|
||||
(ptr_to_base_ptr, ptr_to_bounds)
|
||||
};
|
||||
TableCache {
|
||||
ptr_to_base_ptr,
|
||||
ptr_to_bounds,
|
||||
}
|
||||
});
|
||||
TableCache { ptr_to_base_ptr, ptr_to_bounds }
|
||||
});
|
||||
|
||||
(ptr_to_base_ptr, ptr_to_bounds)
|
||||
}
|
||||
@@ -927,14 +887,9 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
module: &Module<'ctx>,
|
||||
) -> (PointerValue<'ctx>, IntValue<'ctx>) {
|
||||
let (ptr_to_base_ptr, ptr_to_bounds) = self.table_prepare(index, intrinsics, module);
|
||||
let base_ptr = self
|
||||
.cache_builder
|
||||
.build_load(ptr_to_base_ptr, "base_ptr")
|
||||
.into_pointer_value();
|
||||
let bounds = self
|
||||
.cache_builder
|
||||
.build_load(ptr_to_bounds, "bounds")
|
||||
.into_int_value();
|
||||
let base_ptr =
|
||||
self.cache_builder.build_load(ptr_to_base_ptr, "base_ptr").into_pointer_value();
|
||||
let bounds = self.cache_builder.build_load(ptr_to_bounds, "bounds").into_int_value();
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
@@ -956,12 +911,8 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
intrinsics: &Intrinsics<'ctx>,
|
||||
module: &Module<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let (cached_sigindices, ctx_ptr_value, cache_builder, offsets) = (
|
||||
&mut self.cached_sigindices,
|
||||
self.ctx_ptr_value,
|
||||
&self.cache_builder,
|
||||
&self.offsets,
|
||||
);
|
||||
let (cached_sigindices, ctx_ptr_value, cache_builder, offsets) =
|
||||
(&mut self.cached_sigindices, self.ctx_ptr_value, &self.cache_builder, &self.offsets);
|
||||
*cached_sigindices.entry(index).or_insert_with(|| {
|
||||
let byte_offset = intrinsics
|
||||
.i64_ty
|
||||
@@ -973,9 +924,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
.build_bitcast(sigindex_ptr, intrinsics.i32_ptr_ty, "")
|
||||
.into_pointer_value();
|
||||
|
||||
let sigindex = cache_builder
|
||||
.build_load(sigindex_ptr, "sigindex")
|
||||
.into_int_value();
|
||||
let sigindex = cache_builder.build_load(sigindex_ptr, "sigindex").into_int_value();
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
@@ -1023,9 +972,8 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
"",
|
||||
)
|
||||
.into_pointer_value();
|
||||
let global_ptr = cache_builder
|
||||
.build_load(global_ptr_ptr, "")
|
||||
.into_pointer_value();
|
||||
let global_ptr =
|
||||
cache_builder.build_load(global_ptr_ptr, "").into_pointer_value();
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
@@ -1053,9 +1001,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
);
|
||||
GlobalCache::Const { value }
|
||||
}
|
||||
Mutability::Var => GlobalCache::Mut {
|
||||
ptr_to_value: global_ptr,
|
||||
},
|
||||
Mutability::Var => GlobalCache::Mut { ptr_to_value: global_ptr },
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1071,11 +1017,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
match self.cached_functions.entry(function_index) {
|
||||
Entry::Occupied(_) => unreachable!("duplicate function"),
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(FunctionCache {
|
||||
func,
|
||||
vmctx,
|
||||
attrs: attrs.to_vec(),
|
||||
});
|
||||
entry.insert(FunctionCache { func, vmctx, attrs: attrs.to_vec() });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1090,18 +1032,14 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
func_type: &FuncType,
|
||||
function_name: &str,
|
||||
) -> Result<&FunctionCache<'ctx>, CompileError> {
|
||||
let (cached_functions, ctx_ptr_value, offsets) = (
|
||||
&mut self.cached_functions,
|
||||
&self.ctx_ptr_value,
|
||||
&self.offsets,
|
||||
);
|
||||
let (cached_functions, ctx_ptr_value, offsets) =
|
||||
(&mut self.cached_functions, &self.ctx_ptr_value, &self.offsets);
|
||||
Ok(match cached_functions.entry(function_index) {
|
||||
Entry::Occupied(entry) => entry.into_mut(),
|
||||
Entry::Vacant(entry) => {
|
||||
debug_assert!(module.get_function(function_name).is_none());
|
||||
let (llvm_func_type, llvm_func_attrs) =
|
||||
self.abi
|
||||
.func_type_to_llvm(context, intrinsics, Some(offsets), func_type)?;
|
||||
self.abi.func_type_to_llvm(context, intrinsics, Some(offsets), func_type)?;
|
||||
let func =
|
||||
module.add_function(function_name, llvm_func_type, Some(Linkage::External));
|
||||
for (attr, attr_loc) in &llvm_func_attrs {
|
||||
@@ -1134,19 +1072,14 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
Entry::Occupied(entry) => entry.into_mut(),
|
||||
Entry::Vacant(entry) => {
|
||||
let (llvm_func_type, llvm_func_attrs) =
|
||||
self.abi
|
||||
.func_type_to_llvm(context, intrinsics, Some(offsets), func_type)?;
|
||||
self.abi.func_type_to_llvm(context, intrinsics, Some(offsets), func_type)?;
|
||||
debug_assert!(wasm_module.local_func_index(function_index).is_none());
|
||||
let offset = offsets.vmctx_vmfunction_import(function_index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
let vmfunction_import_ptr =
|
||||
unsafe { cache_builder.build_gep(*ctx_ptr_value, &[offset], "") };
|
||||
let vmfunction_import_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
vmfunction_import_ptr,
|
||||
intrinsics.vmfunction_import_ptr_ty,
|
||||
"",
|
||||
)
|
||||
.build_bitcast(vmfunction_import_ptr, intrinsics.vmfunction_import_ptr_ty, "")
|
||||
.into_pointer_value();
|
||||
|
||||
let body_ptr_ptr = cache_builder
|
||||
@@ -1191,10 +1124,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
);
|
||||
*cached_memory_grow.entry(memory_index).or_insert_with(|| {
|
||||
let (grow_fn, grow_fn_ty) = if wasm_module.local_memory_index(memory_index).is_some() {
|
||||
(
|
||||
VMBuiltinFunctionIndex::get_memory32_grow_index(),
|
||||
intrinsics.memory32_grow_ptr_ty,
|
||||
)
|
||||
(VMBuiltinFunctionIndex::get_memory32_grow_index(), intrinsics.memory32_grow_ptr_ty)
|
||||
} else {
|
||||
(
|
||||
VMBuiltinFunctionIndex::get_imported_memory32_grow_index(),
|
||||
@@ -1206,15 +1136,9 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
let grow_fn_ptr_ptr = unsafe { cache_builder.build_gep(*ctx_ptr_value, &[offset], "") };
|
||||
|
||||
let grow_fn_ptr_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
grow_fn_ptr_ptr,
|
||||
grow_fn_ty.ptr_type(AddressSpace::Generic),
|
||||
"",
|
||||
)
|
||||
.build_bitcast(grow_fn_ptr_ptr, grow_fn_ty.ptr_type(AddressSpace::Generic), "")
|
||||
.into_pointer_value();
|
||||
cache_builder
|
||||
.build_load(grow_fn_ptr_ptr, "")
|
||||
.into_pointer_value()
|
||||
cache_builder.build_load(grow_fn_ptr_ptr, "").into_pointer_value()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1232,10 +1156,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
);
|
||||
*cached_memory_size.entry(memory_index).or_insert_with(|| {
|
||||
let (size_fn, size_fn_ty) = if wasm_module.local_memory_index(memory_index).is_some() {
|
||||
(
|
||||
VMBuiltinFunctionIndex::get_memory32_size_index(),
|
||||
intrinsics.memory32_size_ptr_ty,
|
||||
)
|
||||
(VMBuiltinFunctionIndex::get_memory32_size_index(), intrinsics.memory32_size_ptr_ty)
|
||||
} else {
|
||||
(
|
||||
VMBuiltinFunctionIndex::get_imported_memory32_size_index(),
|
||||
@@ -1247,16 +1168,10 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
let size_fn_ptr_ptr = unsafe { cache_builder.build_gep(*ctx_ptr_value, &[offset], "") };
|
||||
|
||||
let size_fn_ptr_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
size_fn_ptr_ptr,
|
||||
size_fn_ty.ptr_type(AddressSpace::Generic),
|
||||
"",
|
||||
)
|
||||
.build_bitcast(size_fn_ptr_ptr, size_fn_ty.ptr_type(AddressSpace::Generic), "")
|
||||
.into_pointer_value();
|
||||
|
||||
cache_builder
|
||||
.build_load(size_fn_ptr_ptr, "")
|
||||
.into_pointer_value()
|
||||
cache_builder.build_load(size_fn_ptr_ptr, "").into_pointer_value()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1296,27 +1211,21 @@ pub fn tbaa_label<'ctx>(
|
||||
};
|
||||
|
||||
// `!wasmer_tbaa_root = {}`, the TBAA root node for wasmer.
|
||||
let tbaa_root = module
|
||||
.get_global_metadata("wasmer_tbaa_root")
|
||||
.pop()
|
||||
.unwrap_or_else(|| {
|
||||
module.add_global_metadata("wasmer_tbaa_root", &context.metadata_node(&[]));
|
||||
module.get_global_metadata("wasmer_tbaa_root")[0]
|
||||
});
|
||||
let tbaa_root = module.get_global_metadata("wasmer_tbaa_root").pop().unwrap_or_else(|| {
|
||||
module.add_global_metadata("wasmer_tbaa_root", &context.metadata_node(&[]));
|
||||
module.get_global_metadata("wasmer_tbaa_root")[0]
|
||||
});
|
||||
|
||||
// Construct (or look up) the type descriptor, for example
|
||||
// `!"local 0" = !{!"local 0", !wasmer_tbaa_root}`.
|
||||
let type_label = context.metadata_string(label.as_str());
|
||||
let type_tbaa = module
|
||||
.get_global_metadata(label.as_str())
|
||||
.pop()
|
||||
.unwrap_or_else(|| {
|
||||
module.add_global_metadata(
|
||||
label.as_str(),
|
||||
&context.metadata_node(&[type_label.into(), tbaa_root.into()]),
|
||||
);
|
||||
module.get_global_metadata(label.as_str())[0]
|
||||
});
|
||||
let type_tbaa = module.get_global_metadata(label.as_str()).pop().unwrap_or_else(|| {
|
||||
module.add_global_metadata(
|
||||
label.as_str(),
|
||||
&context.metadata_node(&[type_label.into(), tbaa_root.into()]),
|
||||
);
|
||||
module.get_global_metadata(label.as_str())[0]
|
||||
});
|
||||
|
||||
// Construct (or look up) the access tag, which is a struct of the form
|
||||
// (base type, access type, offset).
|
||||
@@ -1325,20 +1234,17 @@ pub fn tbaa_label<'ctx>(
|
||||
// must be the same".
|
||||
// -- https://llvm.org/docs/LangRef.html#tbaa-metadata
|
||||
let label = label + "_memop";
|
||||
let type_tbaa = module
|
||||
.get_global_metadata(label.as_str())
|
||||
.pop()
|
||||
.unwrap_or_else(|| {
|
||||
module.add_global_metadata(
|
||||
label.as_str(),
|
||||
&context.metadata_node(&[
|
||||
type_tbaa.into(),
|
||||
type_tbaa.into(),
|
||||
intrinsics.i64_zero.into(),
|
||||
]),
|
||||
);
|
||||
module.get_global_metadata(label.as_str())[0]
|
||||
});
|
||||
let type_tbaa = module.get_global_metadata(label.as_str()).pop().unwrap_or_else(|| {
|
||||
module.add_global_metadata(
|
||||
label.as_str(),
|
||||
&context.metadata_node(&[
|
||||
type_tbaa.into(),
|
||||
type_tbaa.into(),
|
||||
intrinsics.i64_zero.into(),
|
||||
]),
|
||||
);
|
||||
module.get_global_metadata(label.as_str())[0]
|
||||
});
|
||||
|
||||
// Attach the access tag to the instruction.
|
||||
let tbaa_kind = context.get_kind_id("tbaa");
|
||||
|
||||
@@ -67,9 +67,7 @@ impl<'ctx> ControlFrame<'ctx> {
|
||||
pub fn loop_body_phis(&self) -> &[PhiValue<'ctx>] {
|
||||
match self {
|
||||
ControlFrame::Block { .. } | ControlFrame::IfElse { .. } => &[],
|
||||
ControlFrame::Loop {
|
||||
ref loop_body_phis, ..
|
||||
} => loop_body_phis.as_slice(),
|
||||
ControlFrame::Loop { ref loop_body_phis, .. } => loop_body_phis.as_slice(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,11 +209,7 @@ pub struct State<'ctx> {
|
||||
|
||||
impl<'ctx> State<'ctx> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
stack: vec![],
|
||||
control_stack: vec![],
|
||||
reachable: true,
|
||||
}
|
||||
Self { stack: vec![], control_stack: vec![], reachable: true }
|
||||
}
|
||||
|
||||
pub fn has_control_frames(&self) -> bool {
|
||||
@@ -224,18 +218,9 @@ impl<'ctx> State<'ctx> {
|
||||
|
||||
pub fn reset_stack(&mut self, frame: &ControlFrame<'ctx>) {
|
||||
let stack_size_snapshot = match frame {
|
||||
ControlFrame::Block {
|
||||
stack_size_snapshot,
|
||||
..
|
||||
}
|
||||
| ControlFrame::Loop {
|
||||
stack_size_snapshot,
|
||||
..
|
||||
}
|
||||
| ControlFrame::IfElse {
|
||||
stack_size_snapshot,
|
||||
..
|
||||
} => *stack_size_snapshot,
|
||||
ControlFrame::Block { stack_size_snapshot, .. }
|
||||
| ControlFrame::Loop { stack_size_snapshot, .. }
|
||||
| ControlFrame::IfElse { stack_size_snapshot, .. } => *stack_size_snapshot,
|
||||
};
|
||||
self.stack.truncate(stack_size_snapshot);
|
||||
}
|
||||
@@ -247,11 +232,8 @@ impl<'ctx> State<'ctx> {
|
||||
}
|
||||
|
||||
pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, CompileError> {
|
||||
let index = self
|
||||
.control_stack
|
||||
.len()
|
||||
.checked_sub(1 + (depth as usize))
|
||||
.ok_or_else(|| {
|
||||
let index =
|
||||
self.control_stack.len().checked_sub(1 + (depth as usize)).ok_or_else(|| {
|
||||
CompileError::Codegen("frame_at_depth: invalid control stack depth".to_string())
|
||||
})?;
|
||||
Ok(&self.control_stack[index])
|
||||
@@ -261,11 +243,8 @@ impl<'ctx> State<'ctx> {
|
||||
&mut self,
|
||||
depth: u32,
|
||||
) -> Result<&mut ControlFrame<'ctx>, CompileError> {
|
||||
let index = self
|
||||
.control_stack
|
||||
.len()
|
||||
.checked_sub(1 + (depth as usize))
|
||||
.ok_or_else(|| {
|
||||
let index =
|
||||
self.control_stack.len().checked_sub(1 + (depth as usize)).ok_or_else(|| {
|
||||
CompileError::Codegen("frame_at_depth_mut: invalid control stack depth".to_string())
|
||||
})?;
|
||||
Ok(&mut self.control_stack[index])
|
||||
@@ -303,13 +282,8 @@ impl<'ctx> State<'ctx> {
|
||||
|
||||
pub fn pop2_extra(
|
||||
&mut self,
|
||||
) -> Result<
|
||||
(
|
||||
(BasicValueEnum<'ctx>, ExtraInfo),
|
||||
(BasicValueEnum<'ctx>, ExtraInfo),
|
||||
),
|
||||
CompileError,
|
||||
> {
|
||||
) -> Result<((BasicValueEnum<'ctx>, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo)), CompileError>
|
||||
{
|
||||
let v2 = self.pop1_extra()?;
|
||||
let v1 = self.pop1_extra()?;
|
||||
Ok((v1, v2))
|
||||
@@ -317,14 +291,8 @@ impl<'ctx> State<'ctx> {
|
||||
|
||||
pub fn pop3(
|
||||
&mut self,
|
||||
) -> Result<
|
||||
(
|
||||
BasicValueEnum<'ctx>,
|
||||
BasicValueEnum<'ctx>,
|
||||
BasicValueEnum<'ctx>,
|
||||
),
|
||||
CompileError,
|
||||
> {
|
||||
) -> Result<(BasicValueEnum<'ctx>, BasicValueEnum<'ctx>, BasicValueEnum<'ctx>), CompileError>
|
||||
{
|
||||
let v3 = self.pop1()?;
|
||||
let v2 = self.pop1()?;
|
||||
let v1 = self.pop1()?;
|
||||
|
||||
Reference in New Issue
Block a user