Commit f79120b2 authored by qinsoon's avatar qinsoon

add VMOptions

1. see vm/vm_options.rs for usage and default values
2. added mu_fastimpl_new_with_opts under vm/api/api_impl/muvm.rs
parent 05e7b1cc
...@@ -32,3 +32,4 @@ memsec = "0.1.9" ...@@ -32,3 +32,4 @@ memsec = "0.1.9"
rustc-serialize = "*" rustc-serialize = "*"
time = "0.1.34" time = "0.1.34"
maplit = "0.1.4" maplit = "0.1.4"
docopt = "0.6"
\ No newline at end of file
...@@ -21,6 +21,6 @@ impl CompilerPass for InstructionSelection { ...@@ -21,6 +21,6 @@ impl CompilerPass for InstructionSelection {
#[allow(unused_variables)] #[allow(unused_variables)]
fn start_function(&mut self, vm: &VM, func: &mut MuFunctionVersion) { fn start_function(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
println!("{}", self.name()); debug!("{}", self.name());
} }
} }
#![allow(unused_variables)] #![allow(unused_variables)]
use compiler::backend::AOT_EMIT_CONTEXT_FILE; use compiler::backend::AOT_EMIT_CONTEXT_FILE;
use compiler::backend::AOT_EMIT_DIR;
use compiler::backend::RegGroup; use compiler::backend::RegGroup;
use utils::ByteSize; use utils::ByteSize;
use compiler::backend::x86_64; use compiler::backend::x86_64;
...@@ -1525,22 +1524,22 @@ impl CodeGenerator for ASMCodeGen { ...@@ -1525,22 +1524,22 @@ impl CodeGenerator for ASMCodeGen {
} }
fn print_cur_code(&self) { fn print_cur_code(&self) {
println!(""); debug!("");
if self.cur.is_some() { if self.cur.is_some() {
let code = self.cur.as_ref().unwrap(); let code = self.cur.as_ref().unwrap();
println!("code for {}: ", code.name); debug!("code for {}: ", code.name);
let n_insts = code.code.len(); let n_insts = code.code.len();
for i in 0..n_insts { for i in 0..n_insts {
let ref line = code.code[i]; let ref line = code.code[i];
println!("#{}\t{}", i, line.code); debug!("#{}\t{}", i, line.code);
} }
} else { } else {
println!("no current code"); debug!("no current code");
} }
println!(""); debug!("");
} }
fn start_block(&mut self, block_name: MuName) { fn start_block(&mut self, block_name: MuName) {
...@@ -2532,9 +2531,9 @@ impl CodeGenerator for ASMCodeGen { ...@@ -2532,9 +2531,9 @@ impl CodeGenerator for ASMCodeGen {
} }
} }
fn create_emit_directory() { fn create_emit_directory(vm: &VM) {
use std::fs; use std::fs;
match fs::create_dir(AOT_EMIT_DIR) { match fs::create_dir(&vm.vm_options.flag_aot_emit_dir) {
Ok(_) => {}, Ok(_) => {},
Err(_) => {} Err(_) => {}
} }
...@@ -2554,10 +2553,10 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) { ...@@ -2554,10 +2553,10 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
let code = cf.mc.as_ref().unwrap().emit(); let code = cf.mc.as_ref().unwrap().emit();
// create 'emit' directory // create 'emit' directory
create_emit_directory(); create_emit_directory(vm);
let mut file_path = path::PathBuf::new(); let mut file_path = path::PathBuf::new();
file_path.push(AOT_EMIT_DIR); file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push(func.name().unwrap().to_string() + ".s"); file_path.push(func.name().unwrap().to_string() + ".s");
let mut file = match File::create(file_path.as_path()) { let mut file = match File::create(file_path.as_path()) {
Err(why) => panic!("couldn't create emission file {}: {}", file_path.to_str().unwrap(), why), Err(why) => panic!("couldn't create emission file {}: {}", file_path.to_str().unwrap(), why),
...@@ -2566,7 +2565,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) { ...@@ -2566,7 +2565,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
match file.write_all(code.as_slice()) { match file.write_all(code.as_slice()) {
Err(why) => panic!("couldn'd write to file {}: {}", file_path.to_str().unwrap(), why), Err(why) => panic!("couldn'd write to file {}: {}", file_path.to_str().unwrap(), why),
Ok(_) => println!("emit code to {}", file_path.to_str().unwrap()) Ok(_) => info!("emit code to {}", file_path.to_str().unwrap())
} }
} }
...@@ -2577,10 +2576,10 @@ pub fn emit_context(vm: &VM) { ...@@ -2577,10 +2576,10 @@ pub fn emit_context(vm: &VM) {
use rustc_serialize::json; use rustc_serialize::json;
debug!("---Emit VM Context---"); debug!("---Emit VM Context---");
create_emit_directory(); create_emit_directory(vm);
let mut file_path = path::PathBuf::new(); let mut file_path = path::PathBuf::new();
file_path.push(AOT_EMIT_DIR); file_path.push(&vm.vm_options.flag_aot_emit_dir);
file_path.push(AOT_EMIT_CONTEXT_FILE); file_path.push(AOT_EMIT_CONTEXT_FILE);
let mut file = match File::create(file_path.as_path()) { let mut file = match File::create(file_path.as_path()) {
......
...@@ -8,7 +8,6 @@ use utils::ByteSize; ...@@ -8,7 +8,6 @@ use utils::ByteSize;
pub type Word = usize; pub type Word = usize;
pub const WORD_SIZE : ByteSize = 8; pub const WORD_SIZE : ByteSize = 8;
pub const AOT_EMIT_DIR : &'static str = "emit";
pub const AOT_EMIT_CONTEXT_FILE : &'static str = "context.s"; pub const AOT_EMIT_CONTEXT_FILE : &'static str = "context.s";
// this is not full name, but pro/epilogue name is generated from this // this is not full name, but pro/epilogue name is generated from this
......
...@@ -200,26 +200,26 @@ impl InterferenceGraph { ...@@ -200,26 +200,26 @@ impl InterferenceGraph {
} }
pub fn print(&self, context: &FunctionContext) { pub fn print(&self, context: &FunctionContext) {
println!(""); debug!("");
println!("Interference Graph"); debug!("Interference Graph");
println!("nodes:"); debug!("nodes:");
for id in self.nodes.keys() { for id in self.nodes.keys() {
let val = context.get_value(*id).unwrap().value(); let val = context.get_value(*id).unwrap().value();
println!("Reg {} -> {:?}", val, self.nodes.get(&id).unwrap()); debug!("Reg {} -> {:?}", val, self.nodes.get(&id).unwrap());
} }
println!("color:"); debug!("color:");
for (node, color) in self.nodes_property.iter() { for (node, color) in self.nodes_property.iter() {
let node_val = context.get_value(self.get_temp_of(*node)).unwrap().value(); let node_val = context.get_value(self.get_temp_of(*node)).unwrap().value();
let color_val = context.get_value(color.temp).unwrap().value(); let color_val = context.get_value(color.temp).unwrap().value();
println!("Reg {} of {:?} -> Color/Reg {}", node_val, node, color_val); debug!("Reg {} of {:?} -> Color/Reg {}", node_val, node, color_val);
} }
println!("moves:"); debug!("moves:");
for mov in self.moves.iter() { for mov in self.moves.iter() {
println!("Move {:?} -> {:?}", mov.from, mov.to); debug!("Move {:?} -> {:?}", mov.from, mov.to);
} }
println!("graph:"); debug!("graph:");
{ {
let node_to_reg_id = { let node_to_reg_id = {
let mut ret : HashMap<Node, MuID> = HashMap::new(); let mut ret : HashMap<Node, MuID> = HashMap::new();
...@@ -241,12 +241,12 @@ impl InterferenceGraph { ...@@ -241,12 +241,12 @@ impl InterferenceGraph {
let from_val = context.get_value(*from_node).unwrap().value(); let from_val = context.get_value(*from_node).unwrap().value();
let to_val = context.get_value(*to_node).unwrap().value(); let to_val = context.get_value(*to_node).unwrap().value();
println!("Reg {} -> Reg {}", from_val, to_val); debug!("Reg {} -> Reg {}", from_val, to_val);
} }
} }
} }
} }
println!(""); debug!("");
} }
} }
......
...@@ -22,7 +22,6 @@ impl <T> AddressMap<T> where T: Copy{ ...@@ -22,7 +22,6 @@ impl <T> AddressMap<T> where T: Copy{
} }
pub fn init_all (&self, init: T) { pub fn init_all (&self, init: T) {
println!("check valid");
let mut cursor = self.start; let mut cursor = self.start;
while cursor < self.end { while cursor < self.end {
......
...@@ -113,7 +113,7 @@ impl Bitmap { ...@@ -113,7 +113,7 @@ impl Bitmap {
}; };
for i in 0..nwords { for i in 0..nwords {
println!("{}\t0b{:64b}", i * 64, unsafe {*ptr}); debug!("{}\t0b{:64b}", i * 64, unsafe {*ptr});
ptr = unsafe{ptr.offset(1)}; ptr = unsafe{ptr.offset(1)};
} }
} }
......
...@@ -112,7 +112,7 @@ impl ImmixMutatorLocal { ...@@ -112,7 +112,7 @@ impl ImmixMutatorLocal {
*mutator_count_lock = *mutator_count_lock - 1; *mutator_count_lock = *mutator_count_lock - 1;
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
println!("destroy mutator. Now live mutators = {}", *mutator_count_lock); debug!("destroy mutator. Now live mutators = {}", *mutator_count_lock);
} }
} }
...@@ -131,12 +131,9 @@ impl ImmixMutatorLocal { ...@@ -131,12 +131,9 @@ impl ImmixMutatorLocal {
#[inline(always)] #[inline(always)]
pub fn alloc(&mut self, size: usize, align: usize) -> Address { pub fn alloc(&mut self, size: usize, align: usize) -> Address {
// println!("Fastpath allocation");
let start = self.cursor.align_up(align); let start = self.cursor.align_up(align);
let end = start.plus(size); let end = start.plus(size);
// println!("cursor = {:#X}, after align = {:#X}", c, start);
if end > self.limit { if end > self.limit {
let ret = self.try_alloc_from_local(size, align); let ret = self.try_alloc_from_local(size, align);
...@@ -177,8 +174,6 @@ impl ImmixMutatorLocal { ...@@ -177,8 +174,6 @@ impl ImmixMutatorLocal {
#[inline(never)] #[inline(never)]
pub fn try_alloc_from_local(&mut self, size : usize, align: usize) -> Address { pub fn try_alloc_from_local(&mut self, size : usize, align: usize) -> Address {
// println!("Trying to allocate from local");
if self.line < immix::LINES_IN_BLOCK { if self.line < immix::LINES_IN_BLOCK {
let opt_next_available_line = { let opt_next_available_line = {
let cur_line = self.line; let cur_line = self.line;
...@@ -187,17 +182,13 @@ impl ImmixMutatorLocal { ...@@ -187,17 +182,13 @@ impl ImmixMutatorLocal {
match opt_next_available_line { match opt_next_available_line {
Some(next_available_line) => { Some(next_available_line) => {
// println!("next available line is {}", next_available_line);
// we can alloc from local blocks // we can alloc from local blocks
let end_line = self.block().get_next_unavailable_line(next_available_line); let end_line = self.block().get_next_unavailable_line(next_available_line);
// println!("next unavailable line is {}", end_line);
self.cursor = self.block().start().plus(next_available_line << immix::LOG_BYTES_IN_LINE); self.cursor = self.block().start().plus(next_available_line << immix::LOG_BYTES_IN_LINE);
self.limit = self.block().start().plus(end_line << immix::LOG_BYTES_IN_LINE); self.limit = self.block().start().plus(end_line << immix::LOG_BYTES_IN_LINE);
self.line = end_line; self.line = end_line;
// println!("{}", self);
self.cursor.memset(0, self.limit.diff(self.cursor)); self.cursor.memset(0, self.limit.diff(self.cursor));
for line in next_available_line..end_line { for line in next_available_line..end_line {
...@@ -207,7 +198,6 @@ impl ImmixMutatorLocal { ...@@ -207,7 +198,6 @@ impl ImmixMutatorLocal {
self.alloc(size, align) self.alloc(size, align)
}, },
None => { None => {
// println!("no availalbe line in current block");
self.alloc_from_global(size, align) self.alloc_from_global(size, align)
} }
} }
...@@ -265,14 +255,14 @@ impl ImmixMutatorLocal { ...@@ -265,14 +255,14 @@ impl ImmixMutatorLocal {
} }
pub fn print_object_static(obj: Address, length: usize) { pub fn print_object_static(obj: Address, length: usize) {
println!("===Object {:#X} size: {} bytes===", obj, length); debug!("===Object {:#X} size: {} bytes===", obj, length);
let mut cur_addr = obj; let mut cur_addr = obj;
while cur_addr < obj.plus(length) { while cur_addr < obj.plus(length) {
println!("Address: {:#X} {:#X}", cur_addr, unsafe {cur_addr.load::<u64>()}); debug!("Address: {:#X} {:#X}", cur_addr, unsafe {cur_addr.load::<u64>()});
cur_addr = cur_addr.plus(8); cur_addr = cur_addr.plus(8);
} }
println!("----"); debug!("----");
println!("========="); debug!("=========");
} }
} }
......
...@@ -269,9 +269,9 @@ impl ImmixSpace { ...@@ -269,9 +269,9 @@ impl ImmixSpace {
used_blocks_lock.append(&mut live_blocks); used_blocks_lock.append(&mut live_blocks);
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
println!("free lines = {} of {} total ({} blocks)", free_lines, self.total_blocks * immix::LINES_IN_BLOCK, self.total_blocks); debug!("free lines = {} of {} total ({} blocks)", free_lines, self.total_blocks * immix::LINES_IN_BLOCK, self.total_blocks);
println!("usable blocks = {}", usable_blocks); debug!("usable blocks = {}", usable_blocks);
println!("full blocks = {}", full_blocks); debug!("full blocks = {}", full_blocks);
} }
if full_blocks == self.total_blocks { if full_blocks == self.total_blocks {
......
...@@ -82,11 +82,11 @@ pub extern fn gc_init(immix_size: usize, lo_size: usize, n_gcthreads: usize) { ...@@ -82,11 +82,11 @@ pub extern fn gc_init(immix_size: usize, lo_size: usize, n_gcthreads: usize) {
}; };
*MY_GC.write().unwrap() = Some(GC {immix_space: immix_space, lo_space: lo_space}); *MY_GC.write().unwrap() = Some(GC {immix_space: immix_space, lo_space: lo_space});
println!("heap is {} bytes (immix: {} bytes, lo: {} bytes) . ", immix_size + lo_size, immix_size, lo_size); info!("heap is {} bytes (immix: {} bytes, lo: {} bytes) . ", immix_size + lo_size, immix_size, lo_size);
// gc threads // gc threads
heap::gc::GC_THREADS.store(n_gcthreads, Ordering::SeqCst); heap::gc::GC_THREADS.store(n_gcthreads, Ordering::SeqCst);
println!("{} gc threads", n_gcthreads); info!("{} gc threads", n_gcthreads);
// init object model // init object model
objectmodel::init(); objectmodel::init();
......
...@@ -23,35 +23,35 @@ pub fn flip_mark_state() { ...@@ -23,35 +23,35 @@ pub fn flip_mark_state() {
#[allow(unused_variables)] #[allow(unused_variables)]
pub fn print_object(obj: Address, space_start: Address, trace_map: *mut u8, alloc_map: *mut u8) { pub fn print_object(obj: Address, space_start: Address, trace_map: *mut u8, alloc_map: *mut u8) {
let mut cursor = obj; let mut cursor = obj;
println!("OBJECT 0x{:x}", obj); trace!("OBJECT 0x{:x}", obj);
loop { loop {
let hdr = get_ref_byte(alloc_map, space_start, unsafe {cursor.to_object_reference()}); let hdr = get_ref_byte(alloc_map, space_start, unsafe {cursor.to_object_reference()});
let (ref_bits, short_encode) = ( let (ref_bits, short_encode) = (
bit_utils::lower_bits(hdr, REF_BITS_LEN), bit_utils::lower_bits(hdr, REF_BITS_LEN),
bit_utils::test_nth_bit(hdr, SHORT_ENCODE_BIT) bit_utils::test_nth_bit(hdr, SHORT_ENCODE_BIT)
); );
println!("0x{:x} | val: 0x{:15x} | {}, hdr: {:b}", trace!("0x{:x} | val: 0x{:15x} | {}, hdr: {:b}",
cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 0), hdr); cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 0), hdr);
cursor = cursor.plus(POINTER_SIZE); cursor = cursor.plus(POINTER_SIZE);
println!("0x{:x} | val: 0x{:15x} | {}", trace!("0x{:x} | val: 0x{:15x} | {}",
cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 1)); cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 1));
cursor = cursor.plus(POINTER_SIZE); cursor = cursor.plus(POINTER_SIZE);
println!("0x{:x} | val: 0x{:15x} | {}", trace!("0x{:x} | val: 0x{:15x} | {}",
cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 2)); cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 2));
cursor = cursor.plus(POINTER_SIZE); cursor = cursor.plus(POINTER_SIZE);
println!("0x{:x} | val: 0x{:15x} | {}", trace!("0x{:x} | val: 0x{:15x} | {}",
cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 3)); cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 3));
cursor = cursor.plus(POINTER_SIZE); cursor = cursor.plus(POINTER_SIZE);
println!("0x{:x} | val: 0x{:15x} | {}", trace!("0x{:x} | val: 0x{:15x} | {}",
cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 4)); cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 4));
cursor = cursor.plus(POINTER_SIZE); cursor = cursor.plus(POINTER_SIZE);
println!("0x{:x} | val: 0x{:15x} | {} {}", trace!("0x{:x} | val: 0x{:15x} | {} {}",
cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 5), cursor, unsafe{cursor.load::<u64>()}, interpret_hdr_for_print_object(hdr, 5),
{ {
if !short_encode { if !short_encode {
......
...@@ -13,16 +13,16 @@ ...@@ -13,16 +13,16 @@
__thread void* mu_tls; __thread void* mu_tls;
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;
} }
void* muentry_get_thread_local() { void* muentry_get_thread_local() {
printf("Thread%p: getting mu_tls as %p\n", (void*) pthread_self(), mu_tls); // printf("Thread%p: getting mu_tls as %p\n", (void*) pthread_self(), mu_tls);
return mu_tls; return mu_tls;
} }
void* resolve_symbol(const char* sym) { void* resolve_symbol(const char* sym) {
printf("%s\n", sym); // printf("%s\n", sym);
return dlsym(RTLD_DEFAULT, sym); return dlsym(RTLD_DEFAULT, sym);
} }
...@@ -165,7 +165,7 @@ impl MuStack { ...@@ -165,7 +165,7 @@ impl MuStack {
let mut cursor = self.upper_bound.sub(WORD_SIZE); let mut cursor = self.upper_bound.sub(WORD_SIZE);
let mut count = 0; let mut count = 0;
println!("0x{:x} | UPPER_BOUND", self.upper_bound); debug!("0x{:x} | UPPER_BOUND", self.upper_bound);
while cursor >= self.lower_bound { while cursor >= self.lower_bound {
let val = unsafe{cursor.load::<Word>()}; let val = unsafe{cursor.load::<Word>()};
print!("0x{:x} | 0x{:x} ({})", cursor, val, val); print!("0x{:x} | 0x{:x} ({})", cursor, val, val);
...@@ -174,18 +174,18 @@ impl MuStack { ...@@ -174,18 +174,18 @@ impl MuStack {
print!(" <- SP"); print!(" <- SP");
} }
println!(""); debug!("");
cursor = cursor.sub(WORD_SIZE); cursor = cursor.sub(WORD_SIZE);
count += 1; count += 1;
if n_entries.is_some() && count > n_entries.unwrap() { if n_entries.is_some() && count > n_entries.unwrap() {
println!("..."); debug!("...");
break; break;
} }
} }
println!("0x{:x} | LOWER_BOUND", self.lower_bound); debug!("0x{:x} | LOWER_BOUND", self.lower_bound);
} }
} }
......
use testutil::*; use testutil::*;
use ast::ir::MuName; use ast::ir::MuName;
use runtime; use runtime;
use vm::VM;
use compiler::backend; use compiler::backend;
use std::path::PathBuf; use std::path::PathBuf;
...@@ -68,22 +69,22 @@ fn link_dylib_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf { ...@@ -68,22 +69,22 @@ fn link_dylib_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
out out
} }
fn get_path_for_mu_func (f: MuName) -> PathBuf { fn get_path_for_mu_func (f: MuName, vm: &VM) -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR); let mut ret = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
ret.push(f); ret.push(f);
ret.set_extension("s"); ret.set_extension("s");
ret ret
} }
fn get_path_for_mu_context () -> PathBuf { fn get_path_for_mu_context (vm: &VM) -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR); let mut ret = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
ret.push(backend::AOT_EMIT_CONTEXT_FILE); ret.push(backend::AOT_EMIT_CONTEXT_FILE);
ret ret
} }
pub fn link_primordial (funcs: Vec<MuName>, out: &str) -> PathBuf { pub fn link_primordial (funcs: Vec<MuName>, out: &str, vm: &VM) -> PathBuf {
let emit_dir = PathBuf::from(backend::AOT_EMIT_DIR); let emit_dir = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
let files : Vec<PathBuf> = { let files : Vec<PathBuf> = {
use std::fs; use std::fs;
...@@ -92,15 +93,15 @@ pub fn link_primordial (funcs: Vec<MuName>, out: &str) -> PathBuf { ...@@ -92,15 +93,15 @@ pub fn link_primordial (funcs: Vec<MuName>, out: &str) -> PathBuf {
// all interested mu funcs // all interested mu funcs
for func in funcs { for func in funcs {
ret.push(get_path_for_mu_func(func)); ret.push(get_path_for_mu_func(func, vm));
} }
// mu context // mu context
ret.push(get_path_for_mu_context()); ret.push(get_path_for_mu_context(vm));
// copy primoridal entry // copy primoridal entry
let source = PathBuf::from(runtime::PRIMORDIAL_ENTRY); let source = PathBuf::from(runtime::PRIMORDIAL_ENTRY);
let mut dest = PathBuf::from(backend::AOT_EMIT_DIR); let mut dest = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
dest.push("main.c"); dest.push("main.c");
fs::copy(source.as_path(), dest.as_path()).unwrap(); fs::copy(source.as_path(), dest.as_path()).unwrap();
// include the primordial C main // include the primordial C main
...@@ -129,43 +130,43 @@ pub fn execute_nocheck(executable: PathBuf) -> Output { ...@@ -129,43 +130,43 @@ pub fn execute_nocheck(executable: PathBuf) -> Output {
exec_nocheck(run) exec_nocheck(run)
} }
pub fn link_dylib (funcs: Vec<MuName>, out: &str) -> PathBuf { pub fn link_dylib (funcs: Vec<MuName>, out: &str, vm: &VM) -> PathBuf {
let files = { let files = {
let mut ret = vec![]; let mut ret = vec![];
for func in funcs { for func in funcs {
ret.push(get_path_for_mu_func(func)); ret.push(get_path_for_mu_func(func, vm));
} }
ret.push(get_path_for_mu_context()); ret.push(get_path_for_mu_context(vm));
ret ret
}; };
let mut out_path = PathBuf::from(backend::AOT_EMIT_DIR); let mut out_path = PathBuf::from(&vm.vm_options.flag_aot_emit_dir);
out_path.push(out); out_path.push(out);
link_dylib_internal(files, out_path) link_dylib_internal(files, out_path)
} }
pub fn link_dylib_with_extra_srcs(funcs: Vec<MuName>, srcs: Vec<String>, out: &str) -> PathBuf{ pub fn link_dylib_with_extra_srcs(funcs: Vec<MuName>, srcs: Vec<String>, out: &str, vm: &VM) -> PathBuf{
let files = { let files = {
let mut ret = vec![]; let mut ret = vec![];
for func in funcs { for func in funcs {
ret.push(get_path_for_mu_func(func)); ret.push(get_path_for_mu_func(func, vm));
} }
for src in srcs { for src in srcs {
ret.push(PathBuf::from(src)); ret.push(PathBuf::from(src));
}