WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

Commit 2324778f authored by qinsoon's avatar qinsoon
Browse files

allow load/store funcref

parent d216bf15
......@@ -3767,8 +3767,9 @@ impl <'a> InstructionSelection {
self.backend.emit_mov_r64_imm64(&tmp, val as i64);
}
},
&Constant::FuncRef(_) => {
unimplemented!()
&Constant::FuncRef(func_id) => {
let mem = self.get_mem_for_funcref(func_id, vm);
self.backend.emit_lea_r64(&tmp, &mem);
},
&Constant::NullRef => {
// xor a, a -> a will mess up register allocation validation
......@@ -4545,6 +4546,24 @@ impl <'a> InstructionSelection {
}
}
#[cfg(feature = "aot")]
fn get_mem_for_funcref(&mut self, func_id: MuID, vm: &VM) -> P<Value> {
// use compiler::backend::x86_64::asm_backend;
//
let func_name = vm.name_of(func_id);
// let label = asm_backend::symbol(func_name);
P(Value {
hdr: MuEntityHeader::unnamed(vm.next_id()),
ty : ADDRESS_TYPE.clone(),
v : Value_::Memory(MemoryLocation::Symbolic {
base: Some(x86_64::RIP.clone()),
label: func_name,
is_global: true
})
})
}
fn split_int128(&mut self, int128: &P<Value>, f_context: &mut FunctionContext, vm: &VM) -> (P<Value>, P<Value>){
if f_context.get_value(int128.id()).unwrap().has_split() {
let vec = f_context.get_value(int128.id()).unwrap().get_split().as_ref().unwrap();
......
......@@ -6,7 +6,7 @@ pub mod inst_sel;
mod codegen;
pub use compiler::backend::x86_64::codegen::CodeGenerator;
mod asm_backend;
pub mod asm_backend;
pub use compiler::backend::x86_64::asm_backend::ASMCodeGen;
pub use compiler::backend::x86_64::asm_backend::emit_code;
pub use compiler::backend::x86_64::asm_backend::emit_context;
......
......@@ -742,5 +742,100 @@ fn pass_fp_arg() -> VM {
blk_entry
});
vm
}
#[test]
fn test_store_funcref() {
let lib = testutil::compile_fncs("store_funcref", vec!["store_funcref", "foo"], &store_funcref);
unsafe {
use mu::utils::mem::memsec::malloc;
let ptr = match malloc::<u64>(8) {
Some(ptr) => ptr,
None => panic!("failed to alloc memory for testing")
};
let store_funcref : libloading::Symbol<unsafe extern fn (*mut u64) -> (u64)> = lib.get(b"store_funcref").unwrap();
let res = store_funcref(ptr);
println!("store_funcref() = {}", res);
assert!(res == 1);
}
}
fn store_funcref() -> VM {
let vm = VM::new();
typedef! ((vm) int64 = mu_int(64));
constdef! ((vm) <int64> int64_1 = Constant::Int(1));
// foo
funcsig! ((vm) foo_sig = () -> (int64));
funcdecl! ((vm) <foo_sig> foo);
funcdef! ((vm) <foo_sig> foo VERSION foo_v1);
block! ((vm, foo_v1) blk_entry);
consta! ((vm, foo_v1) int64_1_local = int64_1);
inst! ((vm, foo_v1) blk_entry_ret:
RET (int64_1_local)
);
define_block!((vm, foo_v1) blk_entry() {
blk_entry_ret
});
define_func_ver!((vm) foo_v1(entry: blk_entry) {
blk_entry
});
// store_funcref
typedef! ((vm) type_funcref_foo = mu_funcref(foo_sig));
constdef! ((vm) <type_funcref_foo> const_funcref_foo = Constant::FuncRef(vm.id_of("foo")));
typedef! ((vm) uptr_funcref_foo = mu_uptr(type_funcref_foo));
funcsig! ((vm) store_funcref_sig = (uptr_funcref_foo) -> (int64));
funcdecl! ((vm) <store_funcref_sig> store_funcref);
funcdef! ((vm) <store_funcref_sig> store_funcref VERSION store_funcref_v1);
// blk_entry(loc):
block! ((vm, store_funcref_v1) blk_entry);
ssa! ((vm, store_funcref_v1) <uptr_funcref_foo> loc);
// STORE funcref_foo loc
consta! ((vm, store_funcref_v1) const_funcref_foo_local = const_funcref_foo);
inst! ((vm, store_funcref_v1) blk_entry_store:
STORE loc const_funcref_foo_local (is_ptr: true, order: MemoryOrder::Relaxed)
);
// f = LOAD loc
ssa! ((vm, store_funcref_v1) <type_funcref_foo> f);
inst! ((vm, store_funcref_v1) blk_entry_load:
f = LOAD loc (is_ptr: true, order: MemoryOrder::Relaxed)
);
// res = EXPRCALL f ()
ssa! ((vm, store_funcref_v1) <int64> res);
inst! ((vm, store_funcref_v1) blk_entry_call:
res = EXPRCALL (CallConvention::Mu, is_abort: false) f ()
);
// RET res
inst! ((vm, store_funcref_v1) blk_entry_ret:
RET (res)
);
define_block!((vm, store_funcref_v1) blk_entry(loc) {
blk_entry_store,
blk_entry_load,
blk_entry_call,
blk_entry_ret
});
define_func_ver!((vm) store_funcref_v1 (entry: blk_entry) {
blk_entry
});
vm
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment