Commit 52d4f54d authored by qinsoon's avatar qinsoon

compile/link generated code within rust tests

parent 09971f3a
build_targets=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<build_targets xmlns\="com.github.rustdt.ide.core">\n<target auto_enabled\="false" config\="build" n_enabled\="true" version2\="true"/>\n<target auto_enabled\="true" config\="check" n_enabled\="false" version2\="true">\n<command_invocation append_env\="true" command_arguments\="${CARGO_TOOL_PATH} build">\n<env_vars/>\n</command_invocation>\n</target>\n</build_targets>\n
build_targets=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<build_targets xmlns\="com.github.rustdt.ide.core">\n<target auto_enabled\="false" config\="build" n_enabled\="true" version2\="true"/>\n<target auto_enabled\="false" config\="check" n_enabled\="false" version2\="true">\n<command_invocation append_env\="true" command_arguments\="${CARGO_TOOL_PATH} build">\n<env_vars/>\n</command_invocation>\n</target>\n</build_targets>\n
eclipse.preferences.version=1
......@@ -7,8 +7,8 @@ build = "build.rs"
[lib]
crate-type = ["staticlib", "rlib"]
[build-dependencies.gcc]
git = "https://github.com/alexcrichton/gcc-rs"
[build-dependencies]
gcc = "0.3"
[dependencies]
lazy_static = "0.1.15"
......
#![allow(unused_variables)]
use compiler::backend;
use compiler::backend::AOT_EMIT_CONTEXT_FILE;
use compiler::backend::AOT_EMIT_DIR;
use utils::ByteSize;
use compiler::backend::x86_64;
use compiler::backend::x86_64::CodeGenerator;
......@@ -1074,11 +1076,9 @@ impl CodeGenerator for ASMCodeGen {
}
}
const EMIT_DIR : &'static str = "emit";
fn create_emit_directory() {
use std::fs;
match fs::create_dir(EMIT_DIR) {
match fs::create_dir(AOT_EMIT_DIR) {
Ok(_) => {},
Err(_) => {}
}
......@@ -1101,7 +1101,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
create_emit_directory();
let mut file_path = path::PathBuf::new();
file_path.push(EMIT_DIR);
file_path.push(AOT_EMIT_DIR);
file_path.push(func.name().unwrap().to_string() + ".s");
let mut file = match File::create(file_path.as_path()) {
Err(why) => panic!("couldn't create emission file {}: {}", file_path.to_str().unwrap(), why),
......@@ -1114,7 +1114,6 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
}
}
const CONTEXT_FILE : &'static str = "context.s";
pub fn emit_context(vm: &VM) {
use std::path;
use std::fs::File;
......@@ -1125,8 +1124,8 @@ pub fn emit_context(vm: &VM) {
create_emit_directory();
let mut file_path = path::PathBuf::new();
file_path.push(EMIT_DIR);
file_path.push(CONTEXT_FILE);
file_path.push(AOT_EMIT_DIR);
file_path.push(AOT_EMIT_CONTEXT_FILE);
let mut file = match File::create(file_path.as_path()) {
Err(why) => panic!("couldn't create context file {}: {}", file_path.to_str().unwrap(), why),
......
......@@ -8,6 +8,9 @@ use utils::ByteSize;
pub type Word = usize;
pub const WORD_SIZE : ByteSize = 8;
pub const AOT_EMIT_DIR : &'static str = "emit";
pub const AOT_EMIT_CONTEXT_FILE : &'static str = "context.s";
// X86_64
#[cfg(target_arch = "x86_64")]
......
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
void* malloc_zero(size_t size) {
void* ret = malloc(size);
......
......@@ -85,6 +85,8 @@ impl ValueLocation {
}
}
pub const PRIMORDIAL_ENTRY : &'static str = "src/runtime/main.c";
#[no_mangle]
pub extern fn mu_trace_level_log() {
simple_logger::init_with_level(log::LogLevel::Trace).ok();
......
......@@ -2,7 +2,6 @@
pub type ByteSize = usize;
pub mod mem;
mod linked_hashset;
pub use utils::linked_hashset::LinkedHashSet;
pub use utils::linked_hashset::LinkedHashMap;
......
......@@ -28,3 +28,87 @@ mod common {
assert_eq!(format!("{:?}", left), format!("{:?}", right))
}
}
mod aot {
use mu::ast::ir::MuName;
use mu::runtime;
use mu::compiler::backend;
use std::path::PathBuf;
use std::process::Command;
fn link (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
let mut gcc = Command::new("gcc");
for file in files {
println!("link with {:?}", file.as_path());
gcc.arg(file.as_path());
}
println!("output as {:?}", out.as_path());
gcc.arg("-o");
gcc.arg(out.as_os_str());
println!("executing: {:?}", gcc);
let status = gcc.status().expect("failed to link generated code");
assert!(status.success());
out
}
pub fn link_primordial (funcs: Vec<MuName>, out: &str) -> PathBuf {
let emit_dir = PathBuf::from(backend::AOT_EMIT_DIR);
let files : Vec<PathBuf> = {
use std::fs;
let mut ret = vec![];
// all interested mu funcs
for func in funcs {
let mut p = emit_dir.clone();
p.push(func);
p.set_extension("s");
ret.push(p);
}
// mu context
let mut p = emit_dir.clone();
p.push(backend::AOT_EMIT_CONTEXT_FILE);
ret.push(p);
// copy primoridal entry
let source = PathBuf::from(runtime::PRIMORDIAL_ENTRY);
let mut dest = PathBuf::from(backend::AOT_EMIT_DIR);
dest.push("main.c");
fs::copy(source.as_path(), dest.as_path()).unwrap();
// include the primordial C main
ret.push(dest);
// include mu static lib
let libmu = PathBuf::from("target/debug/libmu.a");
ret.push(libmu);
ret
};
let mut out_path = emit_dir.clone();
out_path.push(out);
link(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");
println!("---out---");
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("---err---");
println!("{}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::compiler::*;
use test_ir::test_ir::factorial;
use aot;
use std::sync::Arc;
use std::sync::RwLock;
......@@ -37,6 +37,9 @@ fn test_thread_create() {
vm.make_primordial_thread(func_id, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec!["primordial_main".to_string()], "primordial_main_test");
aot::execute(executable);
}
fn primordial_main() -> VM {
......
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