GitLab will be upgraded on June 2nd 2020 at 2.00 pm (AEDT) to 3.00 pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to local Gitlab admin team.

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));
} }
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);