Skip to content

Commit

Permalink
Start running spectests
Browse files Browse the repository at this point in the history
Additional info:
- Execution is turned off, this is just to make sure the backend can compile the entire specsuite.
- That being said, trampolines are implemented and protected call works (just doesn't protect).
  • Loading branch information
lachlansneff committed Mar 2, 2019
1 parent 3717c57 commit f0ac765
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 38 deletions.
8 changes: 6 additions & 2 deletions lib/llvm-backend/cpp/object_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ struct MemoryManager : llvm::RuntimeDyld::MemoryManager {

struct SymbolLookup : llvm::JITSymbolResolver {
public:
SymbolLookup(callbacks_t callbacks) : callbacks(callbacks) {}

virtual llvm::Expected<LookupResult> lookup(const LookupSet& symbols) override {
LookupResult result;

Expand All @@ -140,10 +142,12 @@ struct SymbolLookup : llvm::JITSymbolResolver {
private:
llvm::JITEvaluatedSymbol symbol_lookup(llvm::StringRef name) {
std::cout << "symbol name: " << (std::string)name << std::endl;
uint64_t addr = 0;
uint64_t addr = callbacks.lookup_vm_symbol(name.data(), name.size());

return llvm::JITEvaluatedSymbol(addr, llvm::JITSymbolFlags::None);
}

callbacks_t callbacks;
};

WasmModule::WasmModule(
Expand All @@ -156,7 +160,7 @@ WasmModule::WasmModule(
llvm::StringRef((const char *)object_start, object_size), "object"
)));

SymbolLookup symbol_resolver;
SymbolLookup symbol_resolver(callbacks);
runtime_dyld = std::unique_ptr<llvm::RuntimeDyld>(new llvm::RuntimeDyld(*memory_manager, symbol_resolver));

runtime_dyld->setProcessAllSections(true);
Expand Down
2 changes: 1 addition & 1 deletion lib/llvm-backend/cpp/object_loader.hh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ typedef enum {
typedef result_t (*alloc_memory_t)(size_t size, mem_protect_t protect, uint8_t** ptr_out, size_t* size_out);
typedef result_t (*protect_memory_t)(uint8_t* ptr, size_t size, mem_protect_t protect);
typedef result_t (*dealloc_memory_t)(uint8_t* ptr, size_t size);
typedef uintptr_t (*lookup_vm_symbol_t)(char* name_ptr);
typedef uintptr_t (*lookup_vm_symbol_t)(const char* name_ptr, size_t length);

typedef struct {
/* Memory management. */
Expand Down
33 changes: 30 additions & 3 deletions lib/llvm-backend/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::{
ffi::CString,
mem,
ptr::{self, NonNull},
slice, str,
};
use wasmer_runtime_core::{
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
Expand All @@ -22,6 +23,7 @@ use wasmer_runtime_core::{
structures::TypedIndex,
types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, Value},
vm::{self, ImportBacking},
vmcalls,
};

#[repr(C)]
Expand Down Expand Up @@ -56,7 +58,7 @@ struct Callbacks {
protect_memory: extern "C" fn(*mut u8, usize, MemProtect) -> LLVMResult,
dealloc_memory: extern "C" fn(*mut u8, usize) -> LLVMResult,

lookup_vm_symbol: extern "C" fn(*const c_char) -> *const vm::Func,
lookup_vm_symbol: extern "C" fn(*const c_char, usize) -> *const vm::Func,
}

extern "C" {
Expand Down Expand Up @@ -136,8 +138,31 @@ fn get_callbacks() -> Callbacks {
}
}

extern "C" fn lookup_vm_symbol(_name_ptr: *const c_char) -> *const vm::Func {
ptr::null()
extern "C" fn lookup_vm_symbol(name_ptr: *const c_char, length: usize) -> *const vm::Func {
#[cfg(target_os = "macos")]
macro_rules! fn_name {
($s:literal) => {
concat!("_", $s)
};
}

#[cfg(not(target_os = "macos"))]
macro_rules! fn_name {
($s:literal) => {
$s
};
}

let name_slice = unsafe { slice::from_raw_parts(name_ptr as *const u8, length) };
let name = str::from_utf8(name_slice).unwrap();

match name {
fn_name!("vm.memory.grow.dynamic.local") => vmcalls::local_dynamic_memory_grow as _,
fn_name!("vm.memory.size.dynamic.local") => vmcalls::local_dynamic_memory_size as _,
fn_name!("vm.memory.grow.static.local") => vmcalls::local_static_memory_grow as _,
fn_name!("vm.memory.size.static.local") => vmcalls::local_static_memory_size as _,
_ => ptr::null(),
}
}

Callbacks {
Expand Down Expand Up @@ -241,6 +266,7 @@ impl FuncResolver for LLVMBackend {
module: &ModuleInner,
local_func_index: LocalFuncIndex,
) -> Option<NonNull<vm::Func>> {
unimplemented!();
self.get_func(&module.info, local_func_index)
}
}
Expand All @@ -264,6 +290,7 @@ impl ProtectedCaller for LLVMProtectedCaller {
vmctx: *mut vm::Ctx,
_: Token,
) -> RuntimeResult<Vec<Value>> {
unimplemented!();
let (func_ptr, ctx, signature, sig_index) =
get_func_from_index(&module, import_backing, func_index);

Expand Down
44 changes: 16 additions & 28 deletions lib/llvm-backend/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub fn parse_function_bodies(
})?;
}

// module.print_to_stderr();
module.print_to_stderr();

generate_trampolines(info, &signatures, &module, &context, &builder, &intrinsics);

Expand Down Expand Up @@ -475,22 +475,8 @@ fn parse_function(
builder.build_unconditional_branch(frame.code_after());

for phi in frame.phis().iter().rev() {
if phi.count_incoming() != 0 {
let value = state.pop1()?;
phi.add_incoming(&[(&value, &current_block)])
} else {
let basic_ty = phi.as_basic_value().get_type();
let placeholder_value = match basic_ty {
BasicTypeEnum::IntType(int_ty) => {
int_ty.const_int(0, false).as_basic_value_enum()
}
BasicTypeEnum::FloatType(float_ty) => {
float_ty.const_float(0.0).as_basic_value_enum()
}
_ => unimplemented!(),
};
phi.add_incoming(&[(&placeholder_value, &current_block)]);
}
let value = state.pop1()?;
phi.add_incoming(&[(&value, &current_block)]);
}
}

Expand Down Expand Up @@ -558,6 +544,7 @@ fn parse_function(
// it will emit a `ud2` instruction on x86_64 arches.
ctx.build_trap();
builder.build_unreachable();

state.reachable = false;
}

Expand Down Expand Up @@ -747,12 +734,13 @@ fn parse_function(
)
};

let sigindices_equal = builder.build_int_compare(
IntPredicate::EQ,
expected_dynamic_sigindex,
found_dynamic_sigindex,
"sigindices_equal",
);
// let sigindices_equal = builder.build_int_compare(
// IntPredicate::EQ,
// expected_dynamic_sigindex,
// found_dynamic_sigindex,
// "sigindices_equal",
// );
let sigindices_equal = intrinsics.i1_ty.const_int(1, false);

// Tell llvm that `expected_dynamic_sigindex` should equal `found_dynamic_sigindex`.
let sigindices_equal = builder
Expand Down Expand Up @@ -1227,18 +1215,18 @@ fn parse_function(
state.push1(res);
}
Operator::F32Copysign => {
let input = state.pop1()?;
let (mag, sgn) = state.pop2()?;
let res = builder
.build_call(intrinsics.copysign_f32, &[input], &state.var_name())
.build_call(intrinsics.copysign_f32, &[mag, sgn], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
state.push1(res);
}
Operator::F64Copysign => {
let input = state.pop1()?;
let (msg, sgn) = state.pop2()?;
let res = builder
.build_call(intrinsics.copysign_f64, &[input], &state.var_name())
.build_call(intrinsics.copysign_f64, &[msg, sgn], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
Expand Down Expand Up @@ -1549,7 +1537,7 @@ fn parse_function(
&mut state,
&mut ctx,
memarg,
intrinsics.i32_ptr_ty,
intrinsics.f32_ptr_ty,
)?;
let result = builder.build_load(effective_address, &state.var_name());
state.push1(result);
Expand Down
8 changes: 4 additions & 4 deletions lib/llvm-backend/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,11 @@ impl Intrinsics {
sqrt_f32: module.add_function("llvm.sqrt.f32", ret_f32_take_f32, None),
sqrt_f64: module.add_function("llvm.sqrt.f64", ret_f64_take_f64, None),

minimum_f32: module.add_function("llvm.minimum.f32", ret_f32_take_f32_f32, None),
minimum_f64: module.add_function("llvm.minimum.f64", ret_f64_take_f64_f64, None),
minimum_f32: module.add_function("llvm.minnum.f32", ret_f32_take_f32_f32, None),
minimum_f64: module.add_function("llvm.minnum.f64", ret_f64_take_f64_f64, None),

maximum_f32: module.add_function("llvm.maximum.f32", ret_f32_take_f32_f32, None),
maximum_f64: module.add_function("llvm.maximum.f64", ret_f64_take_f64_f64, None),
maximum_f32: module.add_function("llvm.maxnum.f32", ret_f32_take_f32_f32, None),
maximum_f64: module.add_function("llvm.maxnum.f64", ret_f64_take_f64_f64, None),

ceil_f32: module.add_function("llvm.ceil.f32", ret_f32_take_f32, None),
ceil_f64: module.add_function("llvm.ceil.f64", ret_f64_take_f64, None),
Expand Down

0 comments on commit f0ac765

Please sign in to comment.