|
@@ -4,6 +4,8 @@ use std::io::{Write, Read};
|
|
|
use std::mem;
|
|
|
use super::ir::{MutVisitor, Instruction};
|
|
|
|
|
|
+use winapi::um::memoryapi::VirtualAlloc;
|
|
|
+use winapi::um::winnt::{MEM_COMMIT, PAGE_EXECUTE_READWRITE};
|
|
|
|
|
|
use dynasmrt::{DynasmApi, DynasmLabelApi};
|
|
|
|
|
@@ -36,14 +38,16 @@ pub fn compile(mut instrs: Vec<ir::Instruction>) -> Vec<u8> {
|
|
|
let entry = cg.buffer.offset();
|
|
|
|
|
|
cg.visit_instructions(&mut instrs);
|
|
|
+ cg.buffer.commit();
|
|
|
cg.finalize();
|
|
|
- let buf = cg.buffer.finalize().unwrap();
|
|
|
+ //let buf = cg.buffer.finalize().unwrap();
|
|
|
|
|
|
- let ret = buf.to_vec();
|
|
|
+ //let ret = buf.to_vec();
|
|
|
//println!("{:02x?}", ret);
|
|
|
|
|
|
let function: extern "C" fn(memory: *mut u8) -> bool = unsafe {
|
|
|
- mem::transmute(buf.ptr(entry))
|
|
|
+ //mem::transmute(cg.get_callable())
|
|
|
+ mem::transmute(cg.buffer.finalize().unwrap().ptr(entry))
|
|
|
};
|
|
|
|
|
|
let mut data: Vec<u8> = Vec::with_capacity(100000);
|
|
@@ -53,7 +57,8 @@ pub fn compile(mut instrs: Vec<ir::Instruction>) -> Vec<u8> {
|
|
|
}
|
|
|
|
|
|
//cg.into_vec()
|
|
|
- ret
|
|
|
+ //ret
|
|
|
+ vec![]
|
|
|
}
|
|
|
|
|
|
pub struct CodeGenerator {
|
|
@@ -78,6 +83,21 @@ impl CodeGenerator {
|
|
|
; ret
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ #[cfg(target_os = "windows")]
|
|
|
+ pub fn get_callable(self) -> *const u8 {
|
|
|
+ let data = self.buffer.finalize().unwrap().to_vec();
|
|
|
+ println!("asm buffer of size {}", data.len());
|
|
|
+ let ex = unsafe { VirtualAlloc(0 as _, data.len(), MEM_COMMIT, PAGE_EXECUTE_READWRITE) };
|
|
|
+ unsafe {
|
|
|
+ std::ptr::copy_nonoverlapping(data.as_ptr(), ex as _, data.len());
|
|
|
+ }
|
|
|
+ ex as _
|
|
|
+ }
|
|
|
+
|
|
|
+ #[cfg(not(target_os = "windows"))]
|
|
|
+ pub fn get_callable(self) {
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl ir::MutVisitor for CodeGenerator {
|
|
@@ -91,34 +111,6 @@ impl ir::MutVisitor for CodeGenerator {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_move_ptr(&mut self, mp: &'_ mut Instruction) {
|
|
|
- if let Instruction::MovePtr(offset) = mp {
|
|
|
- dynasm!(self.buffer
|
|
|
- ; add rsi, DWORD *offset as i32
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fn visit_loop(&mut self, l: &mut Instruction) {
|
|
|
- if let Instruction::Loop(insts) = l {
|
|
|
- let begin = self.buffer.new_dynamic_label();
|
|
|
- let end = self.buffer.new_dynamic_label();
|
|
|
- dynasm!(self.buffer
|
|
|
- ; mov al, BYTE [rdi + rsi]
|
|
|
- ; test al, al
|
|
|
- ; jz => end
|
|
|
- ; => begin
|
|
|
- );
|
|
|
- self.visit_instructions(insts);
|
|
|
- dynasm!(self.buffer
|
|
|
- ; mov al, BYTE [rdi + rsi]
|
|
|
- ; test al, al
|
|
|
- ; jnz => begin
|
|
|
- ; => end
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
fn visit_linear_loop(&mut self, l: &mut Instruction) {
|
|
|
if let Instruction::LinearLoop(factors) = l {
|
|
|
if factors.len() > 1 ||
|
|
@@ -172,34 +164,62 @@ impl ir::MutVisitor for CodeGenerator {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_write(&mut self, w: &mut Instruction) {
|
|
|
- if let Instruction::Write(offset) = w {
|
|
|
+ fn visit_move_ptr(&mut self, mp: &'_ mut Instruction) {
|
|
|
+ if let Instruction::MovePtr(offset) = mp {
|
|
|
+ dynasm!(self.buffer
|
|
|
+ ; add rsi, DWORD *offset as i32
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn visit_loop(&mut self, l: &mut Instruction) {
|
|
|
+ if let Instruction::Loop(insts) = l {
|
|
|
+ let begin = self.buffer.new_dynamic_label();
|
|
|
+ let end = self.buffer.new_dynamic_label();
|
|
|
+ dynasm!(self.buffer
|
|
|
+ ; mov al, BYTE [rdi + rsi]
|
|
|
+ ; test al, al
|
|
|
+ ; jz => end
|
|
|
+ ; => begin
|
|
|
+ );
|
|
|
+ self.visit_instructions(insts);
|
|
|
+ dynasm!(self.buffer
|
|
|
+ ; mov al, BYTE [rdi + rsi]
|
|
|
+ ; test al, al
|
|
|
+ ; jnz => begin
|
|
|
+ ; => end
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn visit_read(&mut self, r: &mut Instruction) {
|
|
|
+ if let Instruction::Read(offset) = r {
|
|
|
dynasm!(self.buffer
|
|
|
; push rdi
|
|
|
; push rsi
|
|
|
; sub rsp, 24
|
|
|
- ; mov dil, BYTE [rdi + rsi + *offset as i32]
|
|
|
- ; mov rax, QWORD putbyte as _
|
|
|
+ ; mov rax, QWORD readbyte as _
|
|
|
; call rax
|
|
|
; add rsp, 24
|
|
|
; pop rsi
|
|
|
; pop rdi
|
|
|
+ ; mov BYTE [rdi + rsi + *offset as i32], al
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn visit_read(&mut self, r: &mut Instruction) {
|
|
|
- if let Instruction::Read(offset) = r {
|
|
|
+ fn visit_write(&mut self, w: &mut Instruction) {
|
|
|
+ if let Instruction::Write(offset) = w {
|
|
|
dynasm!(self.buffer
|
|
|
; push rdi
|
|
|
; push rsi
|
|
|
; sub rsp, 24
|
|
|
- ; mov rax, QWORD readbyte as _
|
|
|
+ ; mov dil, BYTE [rdi + rsi + *offset as i32]
|
|
|
+ ; mov rax, QWORD putbyte as _
|
|
|
; call rax
|
|
|
; add rsp, 24
|
|
|
; pop rsi
|
|
|
; pop rdi
|
|
|
- ; mov BYTE [rdi + rsi + *offset as i32], al
|
|
|
);
|
|
|
}
|
|
|
}
|