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 7e069cf8 authored by Eduardo Souza's avatar Eduardo Souza
Browse files

Adding arrays support in Mu backend.

parent 642770c8
var int[] x = {12, 232, 33} in
x[0]
\ No newline at end of file
x[2]
\ No newline at end of file
def int foo(int[] x)
x[0]
x[1]
var int[] x = {13, 25, 32} in
foo(x)
\ No newline at end of file
This diff is collapsed.
......@@ -66,12 +66,6 @@ impl Mu_VM {
let vm = Arc::new(VM::new_with_opts(opts.as_str()));
// set current thread as mu thread
unsafe {
let tl_address = Address::zero();
MuThread::current_thread_as_mu_thread(tl_address, vm.clone());
}
let curr_function = 0;
let mut types_mu_types_map = HashMap::new();
......@@ -106,8 +100,9 @@ impl Mu_VM {
match t {
RefType::Ref(t) => {
let mu_type = self.get_mu_type(t);
let name = self.generate_name(String::from("ref_type"));
let mu_type_ref = self.vm.declare_type(
MuEntityHeader::named(self.vm.next_id(), Mu(stringify!(double))),
MuEntityHeader::named(self.vm.next_id(), Arc::new(name)),
MuType_::muref(mu_type),
);
self.vm.set_name(mu_type_ref.as_entity());
......@@ -118,9 +113,10 @@ impl Mu_VM {
}
RefType::IRef(t) => {
let mu_type = self.get_mu_type(t);
let name = self.generate_name(String::from("i_ref_type"));
let mu_type_i_ref = self.vm.declare_type(
MuEntityHeader::named(self.vm.next_id(), Mu(stringify!(double))),
MuType_::Ref(mu_type),
MuEntityHeader::named(self.vm.next_id(), Arc::new(name)),
MuType_::IRef(mu_type),
);
self.vm.set_name(mu_type_i_ref.as_entity());
......@@ -303,7 +299,7 @@ fn make_boot_image(mu_vm: &Mu_VM, f: &MuEntityHeader, use_llvm_aot: bool) {
Vec::new(),
Vec::new(),
Vec::new(),
String::from("boot-image.bin"),
String::from("boot-image.so"),
);
} else {
mu_vm.vm.make_boot_image(
......@@ -315,7 +311,7 @@ fn make_boot_image(mu_vm: &Mu_VM, f: &MuEntityHeader, use_llvm_aot: bool) {
Vec::new(),
Vec::new(),
Vec::new(),
String::from("boot-image.bin"),
String::from("boot-image.so"),
);
}
}
......@@ -334,14 +330,10 @@ unsafe fn run_code(
dylib_args.push(Arc::new(dep.clone()));
}
// using boot image from vm.make_boot_image(
// let dylib =
// PathBuf::from("./emit/boot-image.bin");
// linking new dylib manually
// using boot image from vm.make_boot_image
let dylib =
linkutils::aot::link_dylib(dylib_args, libname.as_str(), &mu_vm.vm);
PathBuf::from("emit/boot-image.so");
let lib: ll::Library = unsafe {
std::mem::transmute(
......@@ -353,16 +345,14 @@ unsafe fn run_code(
)
};
let resume_function: ll::Symbol<unsafe extern "C" fn() -> *mut mu::vm::api::api_c::CMuVM> =
lib.get((b"resume_mu")).unwrap();
let vm = mu::vm::api::from_CMuVM(resume_function());
unsafe {
let tl_address = Address::zero();
MuThread::current_thread_as_mu_thread(tl_address, vm.clone());
MuThread::current_thread_as_mu_thread(tl_address, mu_vm.vm.clone());
}
lib.get::<unsafe extern "C" fn(Address)>("set_thread_local".as_bytes()).unwrap()(mu::runtime::thread::muentry_get_thread_local());
unsafe {
match f_type {
Type::Double => {
......@@ -423,7 +413,20 @@ impl Mu_code_gen for Function {
.proto()
.args()
.iter()
.map(|(type_par, name_par)| -> P<MuType> { mu_vm.get_mu_type(type_par) })
.map(|(type_par, name_par)| -> P<MuType> {
match type_par {
Type::IntArray(_) => {
mu_vm.get_mu_ref_type(&RefType::IRef(Type::Int))
},
Type::BoolArray(_) => {
mu_vm.get_mu_ref_type(&RefType::IRef(Type::Bool))
},
Type::DoubleArray(_) => {
mu_vm.get_mu_ref_type(&RefType::IRef(Type::Double))
},
t => mu_vm.get_mu_type(t)
}
})
.collect();
let return_type = mu_vm.get_mu_type(self.proto().return_type());
......@@ -442,10 +445,26 @@ impl Mu_code_gen for Function {
let mut alloca_instr = vec![];
for (arg_type, arg_name) in self.proto().args() {
let form_arg = function_version.new_ssa(
MuEntityHeader::named(mu_vm.vm.next_id(), Arc::new(arg_name.clone())),
mu_vm.get_mu_type(arg_type),
);
let form_arg = match arg_type {
Type::IntArray(_) => function_version.new_ssa(
MuEntityHeader::named(mu_vm.vm.next_id(), Arc::new(arg_name.clone())),
mu_vm.get_mu_ref_type(&RefType::IRef(Type::Int)),
),
Type::DoubleArray(_) => function_version.new_ssa(
MuEntityHeader::named(mu_vm.vm.next_id(), Arc::new(arg_name.clone())),
mu_vm.get_mu_ref_type(&RefType::IRef(Type::Double)),
),
Type::BoolArray(_) => function_version.new_ssa(
MuEntityHeader::named(mu_vm.vm.next_id(), Arc::new(arg_name.clone())),
mu_vm.get_mu_ref_type(&RefType::IRef(Type::Bool)),
),
t => function_version.new_ssa(
MuEntityHeader::named(mu_vm.vm.next_id(), Arc::new(arg_name.clone())),
mu_vm.get_mu_type(arg_type),
)
};
mu_vm.vm.set_name(form_arg.as_entity());
form_args.insert(arg_name.clone(), form_arg.clone());
var_type_map.insert(arg_name.clone(), arg_type.clone());
......
......@@ -671,3 +671,73 @@ fn test_int_mutable_fibonacci_iter() {
assert_eq!(mu_values, expected);
assert_eq!(mu_llvm_values, expected);
}
#[test]
fn test_array_access_variable() {
let input = "var int[] x = {12, 232, 33} in x[2]";
let tokens = lexer::tokenize(String::from(input));
let nodes = parser::parse_program(tokens);
let llvm_values;
let mu_values;
// let mu_llvm_values;
unsafe {
llvm_values = generator::code_gen(
String::from("test_array_access_variable\0"),
nodes.clone(),
);
mu_values = mu_generator::code_gen(
String::from("test_array_access_variable"),
nodes.clone(),
false,
false,
);
// mu_llvm_values = mu_generator::code_gen(
// String::from("test_int_mutable_fibonacci_iter"),
// nodes.clone(),
// true,
// false,
// );
}
let expected: Vec<Result<RunResult, String>> = vec![Ok(RunResult::Int(33))];
assert_eq!(llvm_values, expected);
assert_eq!(mu_values, expected);
// assert_eq!(mu_llvm_values, expected);
}
#[test]
fn test_array_access_variable_function() {
let input = "def int foo(int[] x)
x[1]
var int[] x = {13, 25, 32} in
foo(x)";
let tokens = lexer::tokenize(String::from(input));
let nodes = parser::parse_program(tokens);
let llvm_values;
let mu_values;
// let mu_llvm_values;
unsafe {
llvm_values = generator::code_gen(
String::from("test_array_access_variable_function\0"),
nodes.clone(),
);
mu_values = mu_generator::code_gen(
String::from("test_array_access_variable_function"),
nodes.clone(),
false,
false,
);
// mu_llvm_values = mu_generator::code_gen(
// String::from("test_array_access_variable_function"),
// nodes.clone(),
// true,
// false,
// );
}
let expected: Vec<Result<RunResult, String>> = vec![Ok(RunResult::Int(25))];
assert_eq!(llvm_values, expected);
assert_eq!(mu_values, expected);
// assert_eq!(mu_llvm_values, expected);
}
extern int exit()
var int[] x = {12, 232, 33} in
exit()
# comment the var line and `cargo run` should show Int(42)
# running `./emit/boot-image.bin` currently segfaults because of the return instruction
# change 42 to exit() and running `./emit/boot-image.bin` does not segfault
\ No newline at end of file
x[1]
\ No newline at end of file
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