Commit 9f368125 authored by qinsoon's avatar qinsoon

add SetRetval instruction to help returning values for debugging use

parent f28b96b1
...@@ -128,7 +128,8 @@ impl Instruction { ...@@ -128,7 +128,8 @@ impl Instruction {
| CommonInst_Pin(_) | CommonInst_Pin(_)
| CommonInst_Unpin(_) | CommonInst_Unpin(_)
| Move(_) | Move(_)
| PrintHex(_) => None | PrintHex(_)
| SetRetval(_) => None
} }
} }
...@@ -343,7 +344,9 @@ pub enum Instruction_ { ...@@ -343,7 +344,9 @@ pub enum Instruction_ {
// internal use: mov from ops[0] to value // internal use: mov from ops[0] to value
Move(OpIndex), Move(OpIndex),
// internal use: print op as hex value // internal use: print op as hex value
PrintHex(OpIndex) PrintHex(OpIndex),
// internal use: set return value for main
SetRetval(OpIndex),
} }
impl Instruction_ { impl Instruction_ {
...@@ -470,7 +473,9 @@ impl Instruction_ { ...@@ -470,7 +473,9 @@ impl Instruction_ {
// move // move
&Instruction_::Move(from) => format!("MOVE {}", ops[from]), &Instruction_::Move(from) => format!("MOVE {}", ops[from]),
// print hex // print hex
&Instruction_::PrintHex(i) => format!("PRINTHEX {}", ops[i]) &Instruction_::PrintHex(i) => format!("PRINTHEX {}", ops[i]),
// set retval
&Instruction_::SetRetval(val) => format!("SETRETVAL {}", ops[val]),
} }
} }
} }
......
...@@ -33,7 +33,8 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool { ...@@ -33,7 +33,8 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool {
| &CommonInst_Pin(_) | &CommonInst_Pin(_)
| &CommonInst_Unpin(_) | &CommonInst_Unpin(_)
| &Move(_) | &Move(_)
| &PrintHex(_) => false, | &PrintHex(_)
| &SetRetval(_) => false,
&Return(_) &Return(_)
| &ThreadExit | &ThreadExit
| &Throw(_) | &Throw(_)
...@@ -100,7 +101,8 @@ pub fn has_side_effect(inst: &Instruction_) -> bool { ...@@ -100,7 +101,8 @@ pub fn has_side_effect(inst: &Instruction_) -> bool {
&CommonInst_Pin(_) => true, &CommonInst_Pin(_) => true,
&CommonInst_Unpin(_) => true, &CommonInst_Unpin(_) => true,
&Move(_) => false, &Move(_) => false,
&PrintHex(_) => true &PrintHex(_) => true,
&SetRetval(_) => true,
} }
} }
...@@ -150,6 +152,7 @@ pub fn is_potentially_excepting_instruction(inst: &Instruction_) -> bool { ...@@ -150,6 +152,7 @@ pub fn is_potentially_excepting_instruction(inst: &Instruction_) -> bool {
| &CommonInst_Pin(_) | &CommonInst_Pin(_)
| &CommonInst_Unpin(_) | &CommonInst_Unpin(_)
| &Move(_) | &Move(_)
| &PrintHex(_) => false | &PrintHex(_)
| &SetRetval(_) => false
} }
} }
\ No newline at end of file
...@@ -66,7 +66,8 @@ pub enum OpCode { ...@@ -66,7 +66,8 @@ pub enum OpCode {
CommonInst_Unpin, CommonInst_Unpin,
Move, Move,
PrintHex PrintHex,
SetRetval
} }
pub fn pick_op_code_for_ssa(ty: &P<MuType>) -> OpCode { pub fn pick_op_code_for_ssa(ty: &P<MuType>) -> OpCode {
...@@ -358,5 +359,6 @@ pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode { ...@@ -358,5 +359,6 @@ pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode {
Instruction_::CommonInst_Unpin(_) => OpCode::CommonInst_Unpin, Instruction_::CommonInst_Unpin(_) => OpCode::CommonInst_Unpin,
Instruction_::Move(_) => OpCode::Move, Instruction_::Move(_) => OpCode::Move,
Instruction_::PrintHex(_) => OpCode::PrintHex, Instruction_::PrintHex(_) => OpCode::PrintHex,
Instruction_::SetRetval(_) => OpCode::SetRetval
} }
} }
...@@ -903,6 +903,21 @@ impl <'a> InstructionSelection { ...@@ -903,6 +903,21 @@ impl <'a> InstructionSelection {
); );
} }
// Runtime Entry
Instruction_::SetRetval(index) => {
trace!("instsel on SETRETVAL");
let ref ops = inst.ops.read().unwrap();
let ref op = ops[index];
self.emit_runtime_entry(
&entrypoints::SET_RETVAL,
vec![op.clone_value()],
None,
Some(node), f_content, f_context, vm
);
}
_ => unimplemented!() _ => unimplemented!()
} // main switch } // main switch
}, },
......
...@@ -1430,6 +1430,20 @@ impl <'a> InstructionSelection { ...@@ -1430,6 +1430,20 @@ impl <'a> InstructionSelection {
Some(node), f_content, f_context, vm Some(node), f_content, f_context, vm
); );
} }
Instruction_::SetRetval(index) => {
trace!("instsel on SETRETVAL");
let ref ops = inst.ops;
let ref op = ops[index];
self.emit_runtime_entry(
&entrypoints::SET_RETVAL,
vec![op.clone_value()],
None,
Some(node), f_content, f_context, vm
);
}
_ => unimplemented!() _ => unimplemented!()
} // main switch } // main switch
......
...@@ -514,7 +514,8 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize { ...@@ -514,7 +514,8 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
// others // others
Move(_) => 0, Move(_) => 0,
PrintHex(_) => 10, PrintHex(_) => 10,
SetRetval(_) => 10,
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner) ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner)
} }
} }
...@@ -28,6 +28,18 @@ lazy_static! { ...@@ -28,6 +28,18 @@ lazy_static! {
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_get_thread_local")), aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_get_thread_local")),
jit: RwLock::new(None), jit: RwLock::new(None),
}; };
// impl: runtime_x64_sysv.c
// decl: thread.rs
pub static ref SET_RETVAL : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![],
arg_tys: vec![UINT32_TYPE.clone()]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_set_retval")),
jit: RwLock::new(None)
};
// impl: swap_stack_x64_macos.s // impl: swap_stack_x64_macos.s
// decl: thread.rs // decl: thread.rs
......
...@@ -5,8 +5,11 @@ ...@@ -5,8 +5,11 @@
extern void* vm; extern void* vm;
extern void mu_main(char*, int, char**); extern void mu_main(char*, int, char**);
extern uint32_t mu_retval;
int main(int argc, char** argv) { int main(int argc, char** argv) {
char* serialize_vm = (char*) &vm; char* serialize_vm = (char*) &vm;
mu_main(serialize_vm, argc, argv); mu_main(serialize_vm, argc, argv);
return (int) mu_retval;
} }
...@@ -10,6 +10,11 @@ ...@@ -10,6 +10,11 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <pthread.h> #include <pthread.h>
uint32_t mu_retval;
void muentry_set_retval(uint32_t x) {
mu_retval = x;
}
/* /*
* .type mu_tls,@object // @mu_tls * .type mu_tls,@object // @mu_tls
.section .tbss,"awT",@nobits .section .tbss,"awT",@nobits
......
...@@ -10,8 +10,14 @@ ...@@ -10,8 +10,14 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <pthread.h> #include <pthread.h>
uint32_t mu_retval;
__thread void* mu_tls; __thread void* mu_tls;
void muentry_set_retval(uint32_t x) {
mu_retval = x;
}
void set_thread_local(void* thread) { void set_thread_local(void* thread) {
// printf("Thread%p: setting mu_tls to %p\n", (void*) pthread_self(), thread); // printf("Thread%p: setting mu_tls to %p\n", (void*) pthread_self(), thread);
mu_tls = thread; mu_tls = thread;
......
...@@ -315,6 +315,7 @@ extern "C" { ...@@ -315,6 +315,7 @@ extern "C" {
extern "C" { extern "C" {
pub fn set_thread_local(thread: *mut MuThread); pub fn set_thread_local(thread: *mut MuThread);
pub fn muentry_get_thread_local() -> Address; pub fn muentry_get_thread_local() -> Address;
pub fn muentry_set_retval(val: u32);
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
...@@ -323,6 +324,7 @@ extern "C" { ...@@ -323,6 +324,7 @@ extern "C" {
extern "C" { extern "C" {
pub fn set_thread_local(thread: *mut MuThread); pub fn set_thread_local(thread: *mut MuThread);
pub fn muentry_get_thread_local() -> Address; pub fn muentry_get_thread_local() -> Address;
pub fn muentry_set_retval(val: u32);
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
......
...@@ -573,5 +573,15 @@ macro_rules! inst { ...@@ -573,5 +573,15 @@ macro_rules! inst {
ops: vec![$val.clone()], ops: vec![$val.clone()],
v: Instruction_::PrintHex(0) v: Instruction_::PrintHex(0)
}); });
} };
// SET_RETVAL
(($vm: expr, $fv: ident) $name: ident: SET_RETVAL $val: ident) => {
let $name = $fv.new_inst(Instruction{
hdr: MuEntityHeader::unnamed($vm.next_id()),
value: None,
ops: vec![$val.clone()],
v: Instruction_::SetRetval(0)
});
};
} }
...@@ -61,3 +61,68 @@ fn primordial_main() -> VM { ...@@ -61,3 +61,68 @@ fn primordial_main() -> VM {
vm vm
} }
#[test]
fn test_main_with_retval() {
let vm = Arc::new(main_with_retval());
let func_id = vm.id_of("main_with_retval");
let func_handle = vm.handle_from_func(func_id);
vm.make_boot_image(
vec![func_id],
Some(&func_handle), None,
None,
vec![], vec![],
vec![], vec![],
"test_main_with_retval".to_string()
);
// run
let executable = {
use std::path;
let mut path = path::PathBuf::new();
path.push(&vm.vm_options.flag_aot_emit_dir);
path.push("test_main_with_retval");
path
};
let output = aot::execute_nocheck(executable);
assert!(output.status.code().is_some());
let ret_code = output.status.code().unwrap();
println!("return code: {}", ret_code);
assert!(ret_code == 42);
}
fn main_with_retval() -> VM {
let vm = VM::new();
typedef! ((vm) int32 = mu_int(32));
constdef! ((vm) <int32> int32_42 = Constant::Int(42));
funcsig! ((vm) sig = () -> ());
funcdecl! ((vm) <sig> main_with_retval);
funcdef! ((vm) <sig> main_with_retval VERSION main_with_retval_v1);
block! ((vm, main_with_retval_v1) blk_entry);
consta! ((vm, main_with_retval_v1) int32_42_local = int32_42);
inst! ((vm, main_with_retval_v1) blk_entry_set_retval:
SET_RETVAL int32_42_local
);
inst! ((vm, main_with_retval_v1) blk_entry_threadexit:
THREADEXIT
);
define_block!((vm, main_with_retval_v1) blk_entry() {
blk_entry_set_retval,
blk_entry_threadexit
});
define_func_ver!((vm) main_with_retval_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