Jelajahi Sumber

trying out on windows

Nicolas Winkler 6 tahun lalu
induk
melakukan
38e78611d7
4 mengubah file dengan 66 tambahan dan 41 penghapusan
  1. 1 0
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 60 40
      src/compile.rs
  4. 4 1
      src/main.rs

+ 1 - 0
Cargo.lock

@@ -91,6 +91,7 @@ version = "0.1.0"
 dependencies = [
  "dynasm 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "dynasmrt 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [metadata]

+ 1 - 0
Cargo.toml

@@ -11,3 +11,4 @@ edition = "2018"
 [dependencies]
 dynasm = "*"
 dynasmrt = "*"
+winapi = "*"

+ 60 - 40
src/compile.rs

@@ -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
             );
         }
     }

+ 4 - 1
src/main.rs

@@ -4,6 +4,8 @@
 //#[macro_use]
 //extern crate dynasm;
 
+extern crate winapi;
+
 use std::io::{self, Read};
 use std::fs::File;
 use std::env;
@@ -36,7 +38,8 @@ fn main() -> io::Result<()> {
 
         //interpret::run(&insts);
         let code = compile::compile(insts);
-        
+
+
         //println!("{:?}", code.into_iter().map(|x| format!("{:x}", x)).collect::<Vec<String>>());
     }
     else if let Err(msg) = insts {