|
|
|
@ -167,8 +167,9 @@ fn main()
|
|
|
|
|
{
|
|
|
|
|
if let Some(index) = file_content.find(":END:")
|
|
|
|
|
{
|
|
|
|
|
let expected = &format!("//invalid,{}:END:", msg.replace("\n", "\n//"));
|
|
|
|
|
let expected_output = file_content[10..index].replace("\n//", "\n");
|
|
|
|
|
println!("\n\n===FAILED===\nExpected the output to be {}", expected_output);
|
|
|
|
|
println!("\n===FAILED===\nExpected the output to be\n'{}'\n({})", expected_output, expected);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -269,8 +270,12 @@ fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec
|
|
|
|
|
{
|
|
|
|
|
Ok(stderr) =>
|
|
|
|
|
{
|
|
|
|
|
println!("{:?}", stdout.as_bytes());
|
|
|
|
|
Ok(Some(format!("{}{}", stdout, stderr)))
|
|
|
|
|
let text = format!("{}{}", stdout, stderr);
|
|
|
|
|
match output.status.code()
|
|
|
|
|
{
|
|
|
|
|
Some(0) => Ok(Some(text)),
|
|
|
|
|
_ => Err(text),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Err(err) => Err(err.to_string()),
|
|
|
|
|
}
|
|
|
|
@ -362,10 +367,38 @@ fn generate_assembly_linux_x64(operations: &Vec<Operation>, functions: &Vec<Func
|
|
|
|
|
data.code += "\tlea rax, [dynamic+rsi]\n";
|
|
|
|
|
data.code += "\tret\n";
|
|
|
|
|
}
|
|
|
|
|
if data.code.contains("exception_array_read_out_of_bounds")
|
|
|
|
|
{
|
|
|
|
|
data.strings += "\texception_array_oob_msg db \"Attempted array out-of-bounds access\", 10\n";
|
|
|
|
|
data.code += "exception_array_read_out_of_bounds:\n";
|
|
|
|
|
//TODO: report the passed sizes
|
|
|
|
|
data.code += "\tmov rax, 1\n";
|
|
|
|
|
data.code += "\tmov rdi, 1\n";
|
|
|
|
|
// size
|
|
|
|
|
data.code += "\tmov rdx, 37\n";
|
|
|
|
|
// data
|
|
|
|
|
data.code += "\tmov rsi, exception_array_oob_msg\n";
|
|
|
|
|
data.code += "\tsyscall\n";
|
|
|
|
|
data.code += "\tmov rax, 60\n";
|
|
|
|
|
data.code += "\tmov rdi, -1\n";
|
|
|
|
|
data.code += "\tsyscall\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fs::write("out.asm", format!("{}{}{}{}", ASSEMBLY_LINUX_X64_HEADER, data.code, data.arrays, data.strings));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn generate_assembly_linux_x64_array_oob_check(length: i64) -> String
|
|
|
|
|
{
|
|
|
|
|
let mut data = String::new();
|
|
|
|
|
data += "\t\t;;Array bounds check\n";
|
|
|
|
|
data += format!("\tcmp qword rax, {}\n", length).as_str();
|
|
|
|
|
data += "\tjge exception_array_read_out_of_bounds\n";
|
|
|
|
|
data += "\tcmp qword rax, 0\n";
|
|
|
|
|
data += "\tjl exception_array_read_out_of_bounds\n";
|
|
|
|
|
data += "\t\t;;Array bounds check over\n";
|
|
|
|
|
return data.clone();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, arrays: &Vec<Arr>, debug: bool) -> AssemblyData
|
|
|
|
|
{
|
|
|
|
|
let mut data = AssemblyData
|
|
|
|
@ -640,12 +673,14 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|
|
|
|
}
|
|
|
|
|
Operation::Apply(name, word, line, col) =>
|
|
|
|
|
{
|
|
|
|
|
let array = arrays.iter().find(|x| &x.name == name).unwrap();
|
|
|
|
|
data.code += format!("\t;;apply {}.{} {}:{}\n", name, word, line, col).as_str();
|
|
|
|
|
match word.as_str()
|
|
|
|
|
{
|
|
|
|
|
"read" =>
|
|
|
|
|
{
|
|
|
|
|
data.code += "\tmov rax, [queue+8*r12]\n";
|
|
|
|
|
data.code += generate_assembly_linux_x64_array_oob_check(array.length).as_str();
|
|
|
|
|
data.code += "\tinc r12\n";
|
|
|
|
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
|
|
|
|
data.code += format!("\tmov qword rbx, [arr_{}+8*rax]\n", name).as_str();
|
|
|
|
@ -655,6 +690,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|
|
|
|
"write" =>
|
|
|
|
|
{
|
|
|
|
|
data.code += "\tmov rax, [queue+8*r12]\n";
|
|
|
|
|
data.code += generate_assembly_linux_x64_array_oob_check(array.length).as_str();
|
|
|
|
|
data.code += "\tinc r12\n";
|
|
|
|
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
|
|
|
|
data.code += "\tmov qword rbx, [queue+8*r12]\n";
|
|
|
|
@ -664,7 +700,6 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|
|
|
|
}
|
|
|
|
|
"length" =>
|
|
|
|
|
{
|
|
|
|
|
let array = arrays.iter().find(|x| &x.name == name).unwrap();
|
|
|
|
|
data.code += format!("\tmov qword [queue+8*r13], {}\n", array.length).as_str();
|
|
|
|
|
data.code += "\tinc r13\n";
|
|
|
|
|
}
|
|
|
|
@ -896,11 +931,13 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
|
|
|
|
let position: i64 = queue.remove(0).parse::<i64>().unwrap();
|
|
|
|
|
if position >= arr.length
|
|
|
|
|
{
|
|
|
|
|
return Err(format!("Attempted an out of bounds write for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
|
|
|
|
//return Err(format!("Attempted an out of bounds write for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
|
|
|
|
return Err(String::from("Attempted array out-of-bounds access"));
|
|
|
|
|
}
|
|
|
|
|
if position < 0
|
|
|
|
|
{
|
|
|
|
|
return Err(format!("Attempted an out of bounds write for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
|
|
|
|
//return Err(format!("Attempted an out of bounds write for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
|
|
|
|
return Err(String::from("Attempted array out-of-bounds access"));
|
|
|
|
|
}
|
|
|
|
|
let data = queue.remove(0);
|
|
|
|
|
if debug
|
|
|
|
@ -918,11 +955,13 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
|
|
|
|
let position: i64 = queue.remove(0).parse::<i64>().unwrap();
|
|
|
|
|
if position >= arr.length
|
|
|
|
|
{
|
|
|
|
|
return Err(format!("Attempted an out of bounds read for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
|
|
|
|
//return Err(format!("Attempted an out of bounds read for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
|
|
|
|
return Err(String::from("Attempted array out-of-bounds access"));
|
|
|
|
|
}
|
|
|
|
|
if position < 0
|
|
|
|
|
{
|
|
|
|
|
return Err(format!("Attempted an out of bounds read for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
|
|
|
|
//return Err(format!("Attempted an out of bounds read for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
|
|
|
|
return Err(String::from("Attempted array out-of-bounds access"));
|
|
|
|
|
}
|
|
|
|
|
queue.push(arr.data[position as usize].clone());
|
|
|
|
|
}
|
|
|
|
|