To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 5bd96183 authored by Javad Ebrahimian Amiri's avatar Javad Ebrahimian Amiri
Browse files

New working test groups: test_mem_inst

parent 84aa0eeb
......@@ -49,4 +49,8 @@ void muentry_set_retval(int32_t x) {
int32_t c_check_result() {
return mu_retval;
}
\ No newline at end of file
}
char * alloc_mem(size_t size){
return (char *) malloc(size);
}
......@@ -1066,21 +1066,22 @@ fn pass_fp_arg() -> 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);
}
// 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);
// }
build_and_run_test!(store_funcref AND foo, current_tester);
}
fn store_funcref() -> VM {
......@@ -1155,7 +1156,89 @@ fn store_funcref() -> VM {
define_func_ver!((vm) store_funcref_v1 (entry: blk_entry) {
blk_entry
});
/*
tester function goes here
*/
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) int1 = mu_int(1));
typedef! ((vm) u64_ref = mu_ref(int64));
constdef! ((vm) <int64> alloc_size_const = Constant::Int(8));
constdef! ((vm) <int64> expected_result_const = Constant::Int(1));
constdef! ((vm) <int64> int64_pass = Constant::Int(0));
constdef! ((vm) <int64> int64_fail = Constant::Int(1));
funcsig! ((vm) tester_sig = () -> ());
funcdecl! ((vm) <tester_sig> current_tester);
funcdef! ((vm) <tester_sig> current_tester VERSION current_tester_v1);
funcsig! ((vm) alloc_sig = (int64) -> (u64_ref));
typedef! ((vm) ufp_alloc = mu_ufuncptr(alloc_sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_alloc> const_alloc = Constant::ExternSym(C ("alloc_mem")));
typedef! ((vm) ufp_test = mu_ufuncptr(store_funcref_sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_test> const_test = Constant::FuncRef(vm.id_of("store_funcref")));
block! ((vm, current_tester_v1) blk_entry);
consta! ((vm, current_tester_v1) const_alloc_local = const_alloc);
consta! ((vm, current_tester_v1) const_test_local = const_test);
consta! ((vm, current_tester_v1) alloc_size_const_local = alloc_size_const);
consta! ((vm, current_tester_v1) expected_result_const_local = expected_result_const);
consta! ((vm, current_tester_v1) int64_pass_local = int64_pass);
consta! ((vm, current_tester_v1) int64_fail_local = int64_fail);
ssa! ((vm, current_tester_v1) <u64_ref> alloc_ref);
/*
Allocate the structure before running the test function
*/
inst! ((vm, current_tester_v1) blk_entry_alloc:
alloc_ref = EXPRCCALL (CallConvention::Foreign(ForeignFFI::C), is_abort: false) const_alloc_local (alloc_size_const_local)
);
/*
Run the test function on the object allocated in the previous instruction
*/
ssa! ((vm, current_tester_v1) <int64> result);
inst! ((vm, current_tester_v1) blk_entry_call:
result = EXPRCALL (CallConvention::Mu, is_abort: false) const_test_local (alloc_ref)
);
/*
Just compare the returned result with the expected one (1)
*/
ssa! ((vm, current_tester_v1) <int1> cmp_res);
inst! ((vm, current_tester_v1) blk_entry_cmp:
cmp_res = CMPOP (CmpOp::EQ) result expected_result_const_local
);
ssa! ((vm, current_tester_v1) <int64> blk_entry_ret);
inst! ((vm, current_tester_v1) blk_entry_inst_select:
blk_entry_ret = SELECT cmp_res int64_pass_local int64_fail_local
);
inst! ((vm, current_tester_v1) blk_entry_inst_ret:
SET_RETVAL blk_entry_ret
);
inst! ((vm, current_tester_v1) blk_entry_inst_exit:
THREADEXIT
);
define_block! ((vm, current_tester_v1) blk_entry() {
blk_entry_alloc,
blk_entry_call,
blk_entry_cmp,
blk_entry_inst_select,
blk_entry_inst_ret,
blk_entry_inst_exit
});
define_func_ver! ((vm) current_tester_v1 (entry: blk_entry) {
blk_entry
});
vm
}
......@@ -1189,16 +1272,28 @@ fn test_call_int128_arg() {
compiler.compile(&mut func_ver);
}
}
vm.make_primordial_thread(func_call, true, vec![]);
let func_id = vm.id_of("call_add_u128_test1");
{
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&func.cur_ver.unwrap()).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
}
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec![Mu("add_u128"), Mu("call_add_u128")], "test_call_int128_arg", &vm);
let output = aot::execute_nocheck(executable);
// exit with (84)
assert!(output.status.code().is_some());
assert_eq!(output.status.code().unwrap(), 84);
aot::run_test_2f(&vm, "call_add_u128", "add_u128", "call_add_u128_test1");
// let executable = aot::link_primordial(vec![Mu("add_u128"), Mu("call_add_u128")], "test_call_int128_arg", &vm);
// let output = aot::execute_nocheck(executable);
//
// // exit with (84)
// assert!(output.status.code().is_some());
// assert_eq!(output.status.code().unwrap(), 84);
}
fn call_add_u128(vm: &VM) {
......@@ -1213,7 +1308,7 @@ fn call_add_u128(vm: &VM) {
typedef! ((vm) funcref_add_u128 = mu_funcref(add_u128_sig));
constdef! ((vm) <funcref_add_u128> const_funcref_add_u128 = Constant::FuncRef(add_u128_id));
funcsig! ((vm) call_add_u128_sig = () -> ());
funcsig! ((vm) call_add_u128_sig = () -> (int64));
funcdecl! ((vm) <call_add_u128_sig> call_add_u128);
funcdef! ((vm) <call_add_u128_sig> call_add_u128 VERSION call_add_u128_v1);
......@@ -1233,20 +1328,21 @@ fn call_add_u128(vm: &VM) {
trunc_res = CONVOP (ConvOp::TRUNC) <int128 int64> res
);
let blk_entry_exit = gen_ccall_exit(trunc_res.clone(), &mut call_add_u128_v1, &vm);
// let blk_entry_exit = gen_ccall_exit(trunc_res.clone(), &mut call_add_u128_v1, &vm);
inst! ((vm, call_add_u128_v1) blk_entry_ret:
RET
RET (trunc_res)
);
define_block!((vm, call_add_u128_v1) blk_entry() {
blk_entry_call,
blk_entry_trunc,
blk_entry_exit,
blk_entry_ret
});
define_func_ver!((vm) call_add_u128_v1 (entry: blk_entry) {
blk_entry
});
emit_test! ((vm) (call_add_u128 call_add_u128_test1 call_add_u128_test1_v1 Int,EQ (call_add_u128_sig, int64(84u64))));
}
\ No newline at end of file
......@@ -366,21 +366,22 @@ fn ashr_u128() -> VM {
#[test]
fn test_store_load_u128() {
let lib = testutil::compile_fnc("store_load_u128", &store_load_u128);
unsafe {
use mu::utils::mem::memsec::malloc;
let ptr = match malloc::<u64>(16) {
Some(ptr) => ptr,
None => panic!("failed to alloc memory for testing")
};
let store_load_u128 : libloading::Symbol<unsafe extern fn(u64, u64, *mut u64) -> (u64, u64)> = lib.get(b"store_load_u128").unwrap();
let res = store_load_u128(1, 2, ptr);
println!("store_load(1, 2, ptr) = {:?}", res);
assert!(res == (1, 2));
}
// let lib = testutil::compile_fnc("store_load_u128", &store_load_u128);
//
// unsafe {
// use mu::utils::mem::memsec::malloc;
// let ptr = match malloc::<u64>(16) {
// Some(ptr) => ptr,
// None => panic!("failed to alloc memory for testing")
// };
//
// let store_load_u128 : libloading::Symbol<unsafe extern fn(u64, u64, *mut u64) -> (u64, u64)> = lib.get(b"store_load_u128").unwrap();
//
// let res = store_load_u128(1, 2, ptr);
// println!("store_load(1, 2, ptr) = {:?}", res);
// assert!(res == (1, 2));
// }
build_and_run_test!(store_load_u128, current_tester);
}
fn store_load_u128() -> VM {
......@@ -422,7 +423,90 @@ fn store_load_u128() -> VM {
define_func_ver!((vm) store_load_u128_v1(entry: blk_entry) {
blk_entry
});
/*
tester function goes here
*/
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) int1 = mu_int(1));
typedef! ((vm) int128 = mu_int(128));
typedef! ((vm) int128_ref = mu_ref(int128));
constdef! ((vm) <int64> alloc_size_const = Constant::Int(16));
constdef! ((vm) <int128> expected_result_const = Constant::IntEx(vec![1, 2]));
constdef! ((vm) <int64> int64_pass = Constant::Int(0));
constdef! ((vm) <int64> int64_fail = Constant::Int(1));
funcsig! ((vm) tester_sig = () -> ());
funcdecl! ((vm) <tester_sig> current_tester);
funcdef! ((vm) <tester_sig> current_tester VERSION current_tester_v1);
funcsig! ((vm) alloc_sig = (int64) -> (int128_ref));
typedef! ((vm) ufp_alloc = mu_ufuncptr(alloc_sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_alloc> const_alloc = Constant::ExternSym(C ("alloc_mem")));
typedef! ((vm) ufp_test = mu_ufuncptr(sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_test> const_test = Constant::FuncRef(vm.id_of("store_load_u128")));
block! ((vm, current_tester_v1) blk_entry);
consta! ((vm, current_tester_v1) const_alloc_local = const_alloc);
consta! ((vm, current_tester_v1) const_test_local = const_test);
consta! ((vm, current_tester_v1) alloc_size_const_local = alloc_size_const);
consta! ((vm, current_tester_v1) expected_result_const_local = expected_result_const);
consta! ((vm, current_tester_v1) int64_pass_local = int64_pass);
consta! ((vm, current_tester_v1) int64_fail_local = int64_fail);
ssa! ((vm, current_tester_v1) <int128_ref> alloc_ref);
/*
Allocate the structure before running the test function
*/
inst! ((vm, current_tester_v1) blk_entry_alloc:
alloc_ref = EXPRCCALL (CallConvention::Foreign(ForeignFFI::C), is_abort: false) const_alloc_local (alloc_size_const_local)
);
/*
Run the test function on the object allocated in the previous instruction
*/
ssa! ((vm, current_tester_v1) <int128> result);
inst! ((vm, current_tester_v1) blk_entry_call:
result = EXPRCALL (CallConvention::Mu, is_abort: false) const_test_local (expected_result_const_local, alloc_ref)
);
/*
Just compare the returned result with the expected one (1)
*/
ssa! ((vm, current_tester_v1) <int1> cmp_res);
inst! ((vm, current_tester_v1) blk_entry_cmp:
cmp_res = CMPOP (CmpOp::EQ) result expected_result_const_local
);
ssa! ((vm, current_tester_v1) <int64> blk_entry_ret);
inst! ((vm, current_tester_v1) blk_entry_inst_select:
blk_entry_ret = SELECT cmp_res int64_pass_local int64_fail_local
);
inst! ((vm, current_tester_v1) blk_entry_inst_ret:
SET_RETVAL blk_entry_ret
);
inst! ((vm, current_tester_v1) blk_entry_inst_exit:
THREADEXIT
);
define_block! ((vm, current_tester_v1) blk_entry() {
blk_entry_alloc,
blk_entry_call,
blk_entry_cmp,
blk_entry_inst_select,
blk_entry_inst_ret,
blk_entry_inst_exit
});
define_func_ver! ((vm) current_tester_v1 (entry: blk_entry) {
blk_entry
});
vm
}
......
......@@ -34,29 +34,7 @@ struct Foo (i8, i8, i8);
#[test]
#[allow(unused_variables)]
fn test_write_int8_val() {
let lib = testutil::compile_fnc("write_int8", &write_int8);
unsafe {
let ptr : *mut Foo = Box::into_raw(Box::new(Foo(1, 2, 3)));
let a = (*ptr).0;
let b = (*ptr).1;
let c = (*ptr).2;
println!("foo.0 = {}", (*ptr).0);
println!("foo.1 = {}", (*ptr).1);
println!("foo.2 = {}", (*ptr).2);
let write_int8 : libloading::Symbol<unsafe extern fn(*mut Foo, i8)> = lib.get(b"write_int8").unwrap();
write_int8(ptr, 42);
println!("foo.0 = {}", (*ptr).0);
println!("foo.1 = {}", (*ptr).1);
println!("foo.2 = {}", (*ptr).2);
assert_eq!((*ptr).0, a);
assert_eq!((*ptr).1, 42);
assert_eq!((*ptr).2, c);
}
build_and_run_test!(write_int8, current_tester);
}
fn write_int8() -> VM {
......@@ -100,35 +78,111 @@ fn write_int8() -> VM {
define_func_ver!((vm) write_int8_v1 (entry: blk_entry) {blk_entry});
/*
tester function goes here
*/
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) int1 = mu_int(1));
constdef! ((vm) <int64> alloc_size_const = Constant::Int(3));
constdef! ((vm) <int64> test_arg2_const = Constant::Int(42));
constdef! ((vm) <int64> int64_pass = Constant::Int(0));
constdef! ((vm) <int64> int64_fail = Constant::Int(1));
funcsig! ((vm) tester_sig = () -> ());
funcdecl! ((vm) <tester_sig> current_tester);
funcdef! ((vm) <tester_sig> current_tester VERSION current_tester_v1);
funcsig! ((vm) alloc_sig = (int64) -> (ref_foo));
typedef! ((vm) ufp_alloc = mu_ufuncptr(alloc_sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_alloc> const_alloc = Constant::ExternSym(C ("alloc_mem")));
typedef! ((vm) ufp_test = mu_ufuncptr(write_int8_sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_test> const_test = Constant::FuncRef(vm.id_of("write_int8")));
block! ((vm, current_tester_v1) blk_entry);
consta! ((vm, current_tester_v1) const_alloc_local = const_alloc);
consta! ((vm, current_tester_v1) const_test_local = const_test);
consta! ((vm, current_tester_v1) alloc_size_const_local = alloc_size_const);
consta! ((vm, current_tester_v1) test_arg2_const_local = test_arg2_const);
consta! ((vm, current_tester_v1) int64_pass_local = int64_pass);
consta! ((vm, current_tester_v1) int64_fail_local = int64_fail);
ssa! ((vm, current_tester_v1) <ref_foo> alloc_ref);
/*
Allocate the structure before running the test function
*/
inst! ((vm, current_tester_v1) blk_entry_alloc:
alloc_ref = EXPRCCALL (CallConvention::Foreign(ForeignFFI::C), is_abort: false) const_alloc_local (alloc_size_const_local)
);
/*
Run the test function on the object allocated in the previous instruction
*/
inst! ((vm, current_tester_v1) blk_entry_call:
EXPRCALL (CallConvention::Mu, is_abort: false) const_test_local (alloc_ref, test_arg2_const_local)
);
/*
Get the iref for that specific element \
and put it in iref_field1
*/
ssa! ((vm, current_tester_v1) <iref_foo> alloc_iref);
inst! ((vm, current_tester_v1) blk_entry_getiref:
alloc_iref = GETIREF alloc_ref
);
ssa! ((vm, current_tester_v1) <iref_int8> iref_field1);
inst! ((vm, current_tester_v1) blk_entry_getfieldiref:
iref_field1 = GETFIELDIREF alloc_iref (is_ptr: false, index: 1)
);
// load the actual value written
ssa! ((vm, current_tester_v1) <int8> result);
inst! ((vm, current_tester_v1) blk_entry_load:
result = LOAD iref_field1 (is_ptr: false, order: MemoryOrder::Relaxed)
);
ssa! ((vm, current_tester_v1) <int1> cmp_res);
inst! ((vm, current_tester_v1) blk_entry_cmp:
cmp_res = CMPOP (CmpOp::EQ) result test_arg2_const_local
);
ssa! ((vm, current_tester_v1) <int64> blk_entry_ret);
inst! ((vm, current_tester_v1) blk_entry_inst_select:
blk_entry_ret = SELECT cmp_res int64_pass_local int64_fail_local
);
inst! ((vm, current_tester_v1) blk_entry_inst_ret:
SET_RETVAL blk_entry_ret
);
inst! ((vm, current_tester_v1) blk_entry_inst_exit:
THREADEXIT
);
define_block! ((vm, current_tester_v1) blk_entry() {
blk_entry_alloc,
blk_entry_call,
blk_entry_getiref,
blk_entry_getfieldiref,
blk_entry_load,
blk_entry_cmp,
blk_entry_inst_select,
blk_entry_inst_ret,
blk_entry_inst_exit
});
define_func_ver! ((vm) current_tester_v1 (entry: blk_entry) {
blk_entry
});
vm
}
#[allow(unused_variables)]
#[test]
fn test_write_int8_const() {
let lib = testutil::compile_fnc("write_int8_const", &write_int8_const);
unsafe {
let ptr : *mut Foo = Box::into_raw(Box::new(Foo(1, 2, 3)));
let a = (*ptr).0;
let b = (*ptr).1;
let c = (*ptr).2;
println!("foo.0 = {}", (*ptr).0);
println!("foo.1 = {}", (*ptr).1);
println!("foo.2 = {}", (*ptr).2);
let write_int8 : libloading::Symbol<unsafe extern fn(*mut Foo)> = lib.get(b"write_int8_const").unwrap();
write_int8(ptr);
println!("foo.0 = {}", (*ptr).0);
println!("foo.1 = {}", (*ptr).1);
println!("foo.2 = {}", (*ptr).2);
assert_eq!((*ptr).0, a);
assert_eq!((*ptr).1, 42);
assert_eq!((*ptr).2, c);
}
build_and_run_test!(write_int8_const, current_tester);
}
fn write_int8_const() -> VM {
......@@ -173,23 +227,122 @@ fn write_int8_const() -> VM {
});
define_func_ver!((vm) write_int8_const_v1 (entry: blk_entry) {blk_entry});
/*
tester function goes here
*/
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) int1 = mu_int(1));
constdef! ((vm) <int64> alloc_size_const = Constant::Int(3));
constdef! ((vm) <int64> test_arg2_const = Constant::Int(42));
constdef! ((vm) <int64> int64_pass = Constant::Int(0));
constdef! ((vm) <int64> int64_fail = Constant::Int(1));
funcsig! ((vm) tester_sig = () -> ());
funcdecl! ((vm) <tester_sig> current_tester);
funcdef! ((vm) <tester_sig> current_tester VERSION current_tester_v1);
funcsig! ((vm) alloc_sig = (int64) -> (ref_foo));
typedef! ((vm) ufp_alloc = mu_ufuncptr(alloc_sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_alloc> const_alloc = Constant::ExternSym(C ("alloc_mem")));
typedef! ((vm) ufp_test = mu_ufuncptr(write_int8_const_sig));
// .const @alloc = EXTERN SYMBOL "alloc_mem"
constdef! ((vm) <ufp_test> const_test = Constant::FuncRef(vm.id_of("write_int8_const")));
block! ((vm, current_tester_v1) blk_entry);
consta! ((vm, current_tester_v1) const_alloc_local = const_alloc);
consta! ((vm, current_tester_v1) const_test_local = const_test);
consta! ((vm, current_tester_v1) alloc_size_const_local = alloc_size_const);
consta! ((vm, current_tester_v1) test_arg2_const_local = test_arg2_const);
consta! ((vm, current_tester_v1) int64_pass_local = int64_pass);
consta! ((vm, current_tester_v1) int64_fail_local = int64_fail);
ssa! ((vm, current_tester_v1) <ref_foo> alloc_ref);
/*
Allocate the structure before running the test function
*/
inst! ((vm, current_tester_v1) blk_entry_alloc:
alloc_ref = EXPRCCALL (CallConvention::Foreign(ForeignFFI::C), is_abort: false) const_alloc_local (alloc_size_const_local)
);
/*
Run the test function on the object allocated in the previous instruction
*/
inst! ((vm, current_tester_v1) blk_entry_call:
EXPRCALL (CallConvention::Mu, is_abort: false) const_test_local (alloc_ref)
);
/*
Get the iref for that specific element \
and put it in iref_field1
*/
ssa! ((vm, current_tester_v1) <iref_foo> alloc_iref);
inst! ((vm, current_tester_v1) blk_entry_getiref:
alloc_iref = GETIREF alloc_ref
);
ssa! ((vm, current_tester_v1) <iref_int8> iref_field1);
inst! ((vm, current_tester_v1) blk_entry_getfieldiref:
iref_field1 = GETFIELDIREF alloc_iref (is_ptr: false, index: 1)
);
// load the actual value written
ssa! ((vm, current_tester_v1) <int8> result);
inst! ((vm, current_tester_v1) blk_entry_load:
result = LOAD iref_field1 (is_ptr: false, order: MemoryOrder::Relaxed)
);
ssa! ((vm, current_tester_v1) <int1> cmp_res);
inst! ((vm, current_tester_v1) blk_entry_cmp:
cmp_res = CMPOP (CmpOp::EQ) result test_arg2_const_local
);
ssa! ((vm, current_tester_v1) <int64> blk_entry_ret);
inst! ((vm, current_tester_v1) blk_entry_inst_select:
blk_entry_ret = SELECT cmp_res int64_pass_local int64_fail_local
);
inst! ((vm, current_tester_v1) blk_entry_inst_ret:
SET_RETVAL blk_entry_ret
);
inst! ((vm, current_tester_v1) blk_entry_inst_exit:
THREADEXIT
);
define_block! ((vm, current_tester_v1) blk_entry() {
blk_entry_alloc,
blk_entry_call,
blk_entry_getiref,