Commit 56967872 authored by qinsoon's avatar qinsoon

run generated func from dylib in tests

parent 52d4f54d
......@@ -11,6 +11,7 @@ crate-type = ["staticlib", "rlib"]
gcc = "0.3"
[dependencies]
libloading = "0.3"
lazy_static = "0.1.15"
log = "0.3.5"
simple_logger = "0.4.0"
......
......@@ -16,6 +16,9 @@ pub type MuID = usize;
pub type MuName = String;
pub type CName = MuName;
#[allow(non_snake_case)]
pub fn Mu(str: &'static str) -> MuName {str.to_string()}
pub type OpIndex = usize;
lazy_static! {
......
......@@ -34,9 +34,22 @@ mod aot {
use mu::runtime;
use mu::compiler::backend;
use std::path::PathBuf;
use std::process::Command;
use std::process::Command;
use std::process::Output;
fn link (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
fn exec (mut cmd: Command) -> Output {
println!("executing: {:?}", cmd);
let output = cmd.output().expect("failed to execute");
println!("---out---");
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("---err---");
println!("{}", String::from_utf8_lossy(&output.stderr));
output
}
fn link_executable_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
let mut gcc = Command::new("gcc");
for file in files {
......@@ -48,16 +61,60 @@ mod aot {
gcc.arg("-o");
gcc.arg(out.as_os_str());
println!("executing: {:?}", gcc);
assert!(exec(gcc).status.success());
out
}
fn link_dylib_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
let mut object_files : Vec<PathBuf> = vec![];
for file in files {
let mut gcc = Command::new("gcc");
gcc.arg("-c");
gcc.arg("-fpic");
let mut out = file.clone();
out.set_extension("o");
gcc.arg(file.as_os_str());
gcc.arg("-o");
gcc.arg(out.as_os_str());
object_files.push(out);
exec(gcc);
}
let mut gcc = Command::new("gcc");
gcc.arg("-shared");
for obj in object_files {
gcc.arg(obj.as_os_str());
}
gcc.arg("-o");
gcc.arg(out.as_os_str());
let status = gcc.status().expect("failed to link generated code");
assert!(status.success());
exec(gcc);
out
}
fn get_path_for_mu_func (f: MuName) -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR);
ret.push(f);
ret.set_extension("s");
ret
}
fn get_path_for_mu_context () -> PathBuf {
let mut ret = PathBuf::from(backend::AOT_EMIT_DIR);
ret.push(backend::AOT_EMIT_CONTEXT_FILE);
ret
}
pub fn link_primordial (funcs: Vec<MuName>, out: &str) -> PathBuf {
let emit_dir = PathBuf::from(backend::AOT_EMIT_DIR);
let emit_dir = PathBuf::from(backend::AOT_EMIT_DIR);
let files : Vec<PathBuf> = {
use std::fs;
......@@ -66,17 +123,11 @@ mod aot {
// all interested mu funcs
for func in funcs {
let mut p = emit_dir.clone();
p.push(func);
p.set_extension("s");
ret.push(p);
ret.push(get_path_for_mu_func(func));
}
// mu context
let mut p = emit_dir.clone();
p.push(backend::AOT_EMIT_CONTEXT_FILE);
ret.push(p);
ret.push(get_path_for_mu_context());
// copy primoridal entry
let source = PathBuf::from(runtime::PRIMORDIAL_ENTRY);
......@@ -96,19 +147,30 @@ mod aot {
let mut out_path = emit_dir.clone();
out_path.push(out);
link(files, out_path)
link_executable_internal(files, out_path)
}
pub fn execute(exec: PathBuf) {
let mut run = Command::new(exec.as_os_str());
let output = run.output().expect("failed to execute");
pub fn execute(executable: PathBuf) {
let run = Command::new(executable.as_os_str());
assert!(exec(run).status.success());
}
pub fn link_dylib (funcs: Vec<MuName>, out: &str) -> PathBuf {
let files = {
let mut ret = vec![];
for func in funcs {
ret.push(get_path_for_mu_func(func));
}
ret.push(get_path_for_mu_context());
ret
};
println!("---out---");
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("---err---");
println!("{}", String::from_utf8_lossy(&output.stderr));
let mut out_path = PathBuf::from(backend::AOT_EMIT_DIR);
out_path.push(out);
assert!(output.status.success());
link_dylib_internal(files, out_path)
}
}
\ No newline at end of file
extern crate mu;
extern crate log;
extern crate simple_logger;
extern crate libloading;
use test_ir::test_ir::factorial;
use self::mu::compiler::*;
......@@ -8,6 +9,7 @@ use self::mu::utils::vec_utils;
use self::mu::ast::ir::*;
use std::sync::Arc;
use aot;
#[test]
fn test_ir_liveness_fac() {
......@@ -73,10 +75,26 @@ fn test_regalloc_fac() {
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let func_id = vm.id_of("fac");
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);
{
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);
}
backend::emit_context(&vm);
let dylib = aot::link_dylib(vec!["fac".to_string()], "libfac.dylib");
let lib = libloading::Library::new(dylib.as_os_str()).unwrap();
unsafe {
let fac : libloading::Symbol<unsafe extern fn(u64) -> u64> = lib.get(b"fac").unwrap();
let fac5 = fac(5);
println!("fac(5) = {}", fac5);
assert!(fac5 == 120);
}
}
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