WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit c3ba71ac authored by John Zhang's avatar John Zhang
Browse files

Merge branch 'master' into ci-script

parents 00c57362 a241c754
**/target/*
**/__pycache__/*
**/.cache/*
emit/*
**/temp/*
Cargo.lock
......
......@@ -35,21 +35,21 @@ test:cargo:api:
dependencies:
- build_test
script:
- RUST_BACKTRACE=1 CC=clang cargo test test_api
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo test test_api
test:cargo:ir:
stage: test
dependencies:
- build_test
script:
- RUST_BACKTRACE=1 CC=clang cargo test test_ir
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo test test_ir
test:cargo:compiler:
stage: test
dependencies:
- build_test
script:
- RUST_BACKTRACE=1 CC=clang cargo test test_compiler
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo test test_compiler
test:cargo:runtime:
stage: test
......@@ -63,6 +63,7 @@ testjit:milestones:
dependencies:
- build_test
script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_milestones.py
testjit:binops:
......@@ -70,6 +71,7 @@ testjit:binops:
dependencies:
- build_test
script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_binops.py
testjit:cmpops:
......@@ -77,4 +79,11 @@ testjit:cmpops:
dependencies:
- build_test
script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_cmpops.py
testjit:cmpops:
stage: test
script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
- RUST_BACKTRACE=1 pytest tests/test_jit/test_convops.py
\ No newline at end of file
......@@ -64,6 +64,8 @@ echo "KERNEL: $KERNEL"
echo "ARCH: $MACH"
echo "---------"
rm emit/*
if [ "$OS" == "linux" ]; then
RUSTFLAGS=-Zincremental=target/incr-cache RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang-3.8 cargo test "$@"
elif [ "$OS" == "Darwin" ]; then
......
......@@ -91,6 +91,12 @@ pub enum Instruction_ {
BinOp(BinOp, OpIndex, OpIndex),
CmpOp(CmpOp, OpIndex, OpIndex),
ConvOp{
operation: ConvOp,
from_ty: P<MuType>,
to_ty: P<MuType>,
operand: OpIndex
},
// yields a tuple of results from the call
ExprCall{
......@@ -254,6 +260,9 @@ impl Instruction_ {
match self {
&Instruction_::BinOp(op, op1, op2) => format!("{:?} {} {}", op, ops[op1], ops[op2]),
&Instruction_::CmpOp(op, op1, op2) => format!("{:?} {} {}", op, ops[op1], ops[op2]),
&Instruction_::ConvOp{operation, ref from_ty, ref to_ty, operand} => {
format!("{:?} {} {} {}", operation, from_ty, to_ty, ops[operand])
}
&Instruction_::ExprCall{ref data, is_abort} => {
let abort = select_value!(is_abort, "ABORT_ON_EXN", "RETHROW");
format!("CALL {} {}", data.debug_str(ops), abort)
......
......@@ -4,6 +4,7 @@ use inst::*;
use op::*;
use utils::vec_utils;
use utils::Address;
use std::collections::HashMap;
use std::fmt;
......@@ -735,6 +736,8 @@ pub enum Constant {
FuncRef(MuID),
UFuncRef(MuID),
Vector(Vec<Constant>),
//Pointer(Address),
NullRef,
}
impl fmt::Display for Constant {
......@@ -756,6 +759,7 @@ impl fmt::Display for Constant {
}
write!(f, "]")
}
&Constant::NullRef => write!(f, "NullRef"),
}
}
}
......
......@@ -5,6 +5,7 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool {
match inst {
&BinOp(_, _, _)
| &CmpOp(_, _, _)
| &ConvOp{..}
| &ExprCall{..}
| &Load{..}
| &Store{..}
......@@ -49,6 +50,7 @@ pub fn has_side_effect(inst: &Instruction_) -> bool {
match inst {
&BinOp(_, _, _) => false,
&CmpOp(_, _, _) => false,
&ConvOp{..} => false,
&ExprCall{..} => true,
&Load{..} => true,
&Store{..} => true,
......
......@@ -35,6 +35,7 @@ pub enum OpCode {
// expression
Binary(BinOp),
Comparison(CmpOp),
Conversion(ConvOp),
AtomicRMW(AtomicRMWOp),
ExprCall,
......@@ -172,6 +173,22 @@ pub enum CmpOp {
FUNO
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum ConvOp {
TRUNC,
ZEXT,
SEXT,
FPTRUNC,
FPEXT,
FPTOUI,
FPTOSI,
UITOFP,
SITOFP,
BITCAST,
REFCAST,
PTRCAST
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum AtomicRMWOp {
XCHG,
......@@ -207,6 +224,7 @@ pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode {
match inst.v {
Instruction_::BinOp(op, _, _) => OpCode::Binary(op),
Instruction_::CmpOp(op, _, _) => OpCode::Comparison(op),
Instruction_::ConvOp{operation, ..} => OpCode::Conversion(operation),
Instruction_::AtomicRMW{op, ..} => OpCode::AtomicRMW(op),
Instruction_::ExprCall{..} => OpCode::ExprCall,
Instruction_::Load{..} => OpCode::Load,
......
......@@ -13,6 +13,14 @@ lazy_static! {
MuType::new(new_internal_id(), MuType_::int(POINTER_SIZE * 8))
);
pub static ref UINT8_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::int(8))
);
pub static ref UINT16_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::int(16))
);
pub static ref UINT32_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::int(32))
);
......@@ -27,6 +35,8 @@ lazy_static! {
pub static ref INTERNAL_TYPES : Vec<P<MuType>> = vec![
ADDRESS_TYPE.clone(),
UINT8_TYPE.clone(),
UINT16_TYPE.clone(),
UINT32_TYPE.clone(),
UINT64_TYPE.clone(),
DOUBLE_TYPE.clone()
......
......@@ -4,6 +4,9 @@ use runtime::ValueLocation;
use compiler::machine_code::MachineCode;
pub type Reg<'a> = &'a P<Value>;
pub type Mem<'a> = &'a P<Value>;
pub trait CodeGenerator {
fn start_code(&mut self, func_name: MuName) -> ValueLocation;
fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode + Sync + Send>, ValueLocation);
......@@ -22,47 +25,187 @@ pub trait CodeGenerator {
fn emit_nop(&mut self, bytes: usize);
fn emit_cmp_r64_r64(&mut self, op1: &P<Value>, op2: &P<Value>);
fn emit_cmp_r64_imm32(&mut self, op1: &P<Value>, op2: i32);
fn emit_cmp_r64_mem64(&mut self, op1: &P<Value>, op2: &P<Value>);
fn emit_mov_r64_imm32 (&mut self, dest: &P<Value>, src: i32);
fn emit_mov_r64_mem64 (&mut self, dest: &P<Value>, src: &P<Value>); // load
fn emit_mov_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_mov_mem64_r64 (&mut self, dest: &P<Value>, src: &P<Value>); // store
fn emit_mov_mem64_imm32(&mut self, dest: &P<Value>, src: i32);
fn emit_movsd_f64_f64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_movsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); // load
fn emit_movsd_mem64_f64(&mut self, dest: &P<Value>, src: &P<Value>); // store
fn emit_lea_r64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_and_r64_imm32(&mut self, dest: &P<Value>, src: i32);
fn emit_and_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_xor_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_xor_r64_mem64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_xor_r64_imm32(&mut self, dest: &P<Value>, src: i32);
fn emit_add_r64_r64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_add_r64_mem64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_add_r64_imm32(&mut self, dest: &P<Value>, src: i32);
fn emit_addsd_f64_f64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_addsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_sub_r64_r64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_sub_r64_mem64(&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_sub_r64_imm32(&mut self, dest: &P<Value>, src: i32);
fn emit_mul_r64 (&mut self, src: &P<Value>);
fn emit_mul_mem64(&mut self, src: &P<Value>);
fn emit_div_r64 (&mut self, src: &P<Value>);
fn emit_div_mem64 (&mut self, src: &P<Value>);
fn emit_idiv_r64 (&mut self, src: &P<Value>);
fn emit_idiv_mem64(&mut self, src: &P<Value>);
// comparison
fn emit_cmp_r64_r64 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_r64_imm32(&mut self, op1: Reg, op2: i32);
fn emit_cmp_r64_mem64(&mut self, op1: Reg, op2: Mem);
fn emit_cmp_r32_r32 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_r32_imm32(&mut self, op1: Reg, op2: i32);
fn emit_cmp_r32_mem32(&mut self, op1: Reg, op2: Mem);
fn emit_cmp_r16_r16 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_r16_imm16(&mut self, op1: Reg, op2: i16);
fn emit_cmp_r16_mem16(&mut self, op1: Reg, op2: Mem);
fn emit_cmp_r8_r8 (&mut self, op1: Reg, op2: Reg);
fn emit_cmp_r8_imm8 (&mut self, op1: Reg, op2: i8);
fn emit_cmp_r8_mem8 (&mut self, op1: Reg, op2: Mem);
// gpr move
fn emit_mov_r64_imm32 (&mut self, dest: Reg, src: i32);
fn emit_mov_r64_mem64 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem64_r64 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem64_imm32(&mut self, dest: Mem, src: i32);
fn emit_mov_r32_imm32 (&mut self, dest: Reg, src: i32);
fn emit_mov_r32_mem32 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem32_r32 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem32_imm32(&mut self, dest: Mem, src: i32);
fn emit_mov_r16_imm16 (&mut self, dest: Reg, src: i16);
fn emit_mov_r16_mem16 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_mov_mem16_r16 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem16_imm16(&mut self, dest: Mem, src: i16);
fn emit_mov_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_mov_r8_mem8 (&mut self, dest: Reg, src: Mem); // load
fn emit_mov_r8_r8 (&mut self, dest: Reg, src: Mem);
fn emit_mov_mem8_r8 (&mut self, dest: Mem, src: Reg); // store
fn emit_mov_mem8_imm8 (&mut self, dest: Mem, src: i8);
// lea
fn emit_lea_r64(&mut self, dest: Reg, src: Reg);
// and
fn emit_and_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_and_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_and_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_and_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_and_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_and_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_and_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_and_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_and_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_and_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_and_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_and_r8_mem8 (&mut self, dest: Reg, src: Mem);
// xor
fn emit_xor_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_xor_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_xor_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_xor_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_xor_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r16_mem16(&mut self, dest: Reg, src: Reg);
fn emit_xor_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_xor_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r8_mem8 (&mut self, dest: Reg, src: Reg);
fn emit_xor_r8_imm8 (&mut self, dest: Reg, src: i8);
// add
fn emit_add_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_add_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_add_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_add_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_add_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_add_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_add_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_add_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_add_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_add_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_add_r8_mem8(&mut self, dest: Reg, src: Mem);
fn emit_add_r8_imm8(&mut self, dest: Reg, src: i8);
// sub
fn emit_sub_r64_r64 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r64_mem64(&mut self, dest: Reg, src: Mem);
fn emit_sub_r64_imm32(&mut self, dest: Reg, src: i32);
fn emit_sub_r32_r32 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r32_mem32(&mut self, dest: Reg, src: Mem);
fn emit_sub_r32_imm32(&mut self, dest: Reg, src: i32);
fn emit_sub_r16_r16 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r16_mem16(&mut self, dest: Reg, src: Mem);
fn emit_sub_r16_imm16(&mut self, dest: Reg, src: i16);
fn emit_sub_r8_r8 (&mut self, dest: Reg, src: Reg);
fn emit_sub_r8_mem8(&mut self, dest: Reg, src: Mem);
fn emit_sub_r8_imm8(&mut self, dest: Reg, src: i8);
// floating point
fn emit_addsd_f64_f64 (&mut self, dest: Reg, src: Reg);
fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem);
// multiply
fn emit_mul_r64 (&mut self, src: Reg);
fn emit_mul_r32 (&mut self, src: Reg);
fn emit_mul_r16 (&mut self, src: Reg);
fn emit_mul_r8 (&mut self, src: Reg);
fn emit_mul_mem64(&mut self, src: Mem);
fn emit_mul_mem32(&mut self, src: Mem);
fn emit_mul_mem16(&mut self, src: Mem);
fn emit_mul_mem8 (&mut self, src: Mem);
// div
fn emit_div_r64 (&mut self, src: Reg);
fn emit_div_r32 (&mut self, src: Reg);
fn emit_div_r16 (&mut self, src: Reg);
fn emit_div_r8 (&mut self, src: Reg);
fn emit_div_mem64 (&mut self, src: Mem);
fn emit_div_mem32 (&mut self, src: Mem);
fn emit_div_mem16 (&mut self, src: Mem);
fn emit_div_mem8 (&mut self, src: Mem);
// idiv
fn emit_idiv_r64 (&mut self, src: Reg);
fn emit_idiv_r32 (&mut self, src: Reg);
fn emit_idiv_r16 (&mut self, src: Reg);
fn emit_idiv_r8 (&mut self, src: Reg);
fn emit_idiv_mem64(&mut self, src: Mem);
fn emit_idiv_mem32(&mut self, src: Mem);
fn emit_idiv_mem16(&mut self, src: Mem);
fn emit_idiv_mem8 (&mut self, src: Mem);
// shl
fn emit_shl_r64_cl (&mut self, dest: Reg);
// fn emit_shl_r32_cl (&mut self, dest: Reg);
// fn emit_shl_r16_cl (&mut self, dest: Reg);
// fn emit_shl_r8_cl (&mut self, dest: Reg);
fn emit_shl_mem64_cl (&mut self, dest: Mem);
// fn emit_shl_mem32_cl (&mut self, dest: Mem);
// fn emit_shl_mem16_cl (&mut self, dest: Mem);
// fn emit_shl_mem8_cl (&mut self, dest: Mem);
fn emit_shl_r64_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r32_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r16_imm8 (&mut self, dest: Reg, src: i8);
// fn emit_shl_r8_imm8 (&mut self, dest: Reg, src: i8);
fn emit_shl_mem64_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem32_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem16_imm8(&mut self, dest: Mem, src: i8);
// fn emit_shl_mem8_imm8 (&mut self, dest: Mem, src: i8);
fn emit_shr_r64_cl (&mut self, dest: &P<Value>);
fn emit_shr_mem64_cl (&mut self, dest: &P<Value>);
fn emit_shr_r64_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_shr_mem64_imm8(&mut self, dest: &P<Value>, src: i8);
fn emit_sar_r64_cl (&mut self, dest: &P<Value>);
fn emit_sar_mem64_cl (&mut self, dest: &P<Value>);
fn emit_sar_r64_imm8 (&mut self, dest: &P<Value>, src: i8);
fn emit_sar_mem64_imm8(&mut self, dest: &P<Value>, src: i8);
fn emit_cqo(&mut self);
......@@ -87,4 +230,10 @@ pub trait CodeGenerator {
fn emit_push_r64(&mut self, src: &P<Value>);
fn emit_push_imm32(&mut self, src: i32);
fn emit_pop_r64(&mut self, dest: &P<Value>);
// fpr move
fn emit_movsd_f64_f64 (&mut self, dest: &P<Value>, src: &P<Value>);
fn emit_movsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); // load
fn emit_movsd_mem64_f64(&mut self, dest: &P<Value>, src: &P<Value>); // store
}
\ No newline at end of file
......@@ -171,3 +171,30 @@ pub struct BackendTypeInfo {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum RegGroup {GPR, FPR}
impl RegGroup {
pub fn get(ty: &P<MuType>) -> RegGroup {
match ty.v {
// for now, only use 64bits registers
MuType_::Int(len) if len == 8 => RegGroup::GPR,
MuType_::Int(len) if len == 16 => RegGroup::GPR,
MuType_::Int(len) if len == 32 => RegGroup::GPR,
MuType_::Int(len) if len == 64 => RegGroup::GPR,
MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_)
| MuType_::UPtr(_)
| MuType_::ThreadRef
| MuType_::StackRef
| MuType_::Tagref64
| MuType_::FuncRef(_)
| MuType_::UFuncPtr(_) => RegGroup::GPR,
MuType_::Float => RegGroup::FPR,
MuType_::Double => RegGroup::FPR,
_ => unimplemented!()
}
}
}
\ No newline at end of file
......@@ -54,18 +54,7 @@ impl InterferenceGraph {
self.nodes.insert(reg_id, node.clone());
// add node property
let group = {
let ref ty = entry.ty();
if types::is_scalar(ty) {
if types::is_fp(ty) {
backend::RegGroup::FPR
} else {
backend::RegGroup::GPR
}
} else {
unimplemented!()
}
};
let group = backend::RegGroup::get(entry.ty());
let property = NodeProperty {
color: None,
group: group,
......
......@@ -140,3 +140,26 @@ pub fn link_dylib (funcs: Vec<MuName>, out: &str) -> PathBuf {
link_dylib_internal(files, out_path)
}
pub fn link_dylib_with_extra_srcs(funcs: Vec<MuName>, srcs: Vec<String>, out: &str) -> PathBuf{
let files = {
let mut ret = vec![];
for func in funcs {
ret.push(get_path_for_mu_func(func));
}
for src in srcs {
ret.push(PathBuf::from(src));
}
ret.push(get_path_for_mu_context());
ret
};
let mut out_path = PathBuf::from(backend::AOT_EMIT_DIR);
out_path.push(out);
link_dylib_internal(files, out_path)
}
\ No newline at end of file
......@@ -24,13 +24,18 @@ pub fn get_test_clang_path() -> String {
pub fn exec (mut cmd: Command) -> Output {
println!("executing: {:?}", cmd);
let output = cmd.output().expect("failed to execute");
let output = match cmd.output() {
Ok(res) => res,
Err(e) => panic!("failed to execute: {}", e)
};
println!("---out---");
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("---err---");
println!("{}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
output
}
......
......@@ -243,11 +243,13 @@ extern fn _forwarder__MuVM__set_trap_handler(mvm: *mut CMuVM, trap_handler: CMuT
};
}
extern fn _forwarder__MuVM__compile_to_sharedlib(mvm: *mut CMuVM, lib_name: CMuCString) {
extern fn _forwarder__MuVM__compile_to_sharedlib(mvm: *mut CMuVM, lib_name: CMuCString,
extra_srcs: *const CMuCString, n: usize) {
let mut _arg_mvm = from_MuVM_ptr(mvm);
let mut _arg_lib_name = from_MuCString(lib_name);
let _arg_extra_srcs = from_MuCString_array(extra_srcs, n);
unsafe {
(*_arg_mvm).compile_to_sharedlib(&_arg_lib_name)
(*_arg_mvm).compile_to_sharedlib(&_arg_lib_name, _arg_extra_srcs)
};
}
......
......@@ -110,7 +110,7 @@ pub struct CMuVM {
pub name_of: extern fn(*mut CMuVM, CMuID) -> CMuName,
pub set_trap_handler: extern fn(*mut CMuVM, CMuTrapHandler, CMuCPtr),
// this function is only used in testing jit
pub compile_to_sharedlib: extern fn(*mut CMuVM, CMuCString),
pub compile_to_sharedlib: extern fn(*mut CMuVM, CMuCString, *const CMuCString, CMuArraySize),
}
#[repr(C)]
......
......@@ -42,7 +42,10 @@ pub enum NodeType {
TypeStruct { id: MuID, fieldtys: Vec<MuTypeNode> },
TypeHybrid { id: MuID, fixedtys: Vec<MuTypeNode>, varty: MuTypeNode },
TypeArray { id: MuID, elemty: MuTypeNode, len: usize },