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

Commit 56967872 authored by qinsoon's avatar qinsoon
Browse files

run generated func from dylib in tests

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