编译流程记录

use anyhow::{anyhow, Result};
use wasmtime::*;
use std::collections::HashMap;

// 1. 脚本解析器
#[derive(Debug, Clone)]
enum ASTNode {
    Print(String),
}

fn parse_script(script: &str) -> Result<Vec<ASTNode>> {
    let mut ast = Vec::new();
    
    for line in script.lines() {
        let line = line.trim();
        if line.is_empty() {
            continue;
        }
        
        if let Some(text) = line.strip_prefix("print ") {
            let text = text.trim();
            if let Some(text) = text.strip_prefix('"').and_then(|s| s.strip_suffix('"')) {
                ast.push(ASTNode::Print(text.to_string()));
            } else {
                return Err(anyhow!("Invalid print statement: {}", line));
            }
        } else {
            return Err(anyhow!("Unsupported command: {}", line));
        }
    }
    
    Ok(ast)
}

// 2. WASM编译器(简化版)
fn compile_to_wasm(ast: &[ASTNode]) -> Result<Vec<u8>> {
    use wasm_encoder::*;
    
    let mut module = Module::new();
    
    // 类型段 (print: (i32, i32) -> ())
    let mut types = TypeSection::new();
    types.function(vec![ValType::I32, ValType::I32], vec![]);
    module.section(&types);
    
    // 导入段 (从env导入print)
    let mut imports = ImportSection::new();
    imports.import("env", "print", TypeRef::Func(0));
    module.section(&imports);
    
    // 函数段 (主函数)
    let mut functions = FunctionSection::new();
    functions.function(0); // 使用类型0
    module.section(&functions);
    
    // 内存段 (1页)
    let mut memories = MemorySection::new();
    memories.memory(MemoryType {
        minimum: 1,
        maximum: None,
        memory64: false,
        shared: false,
    });
    module.section(&memories);
    
    // 导出段 (导出main函数)
    let mut exports = ExportSection::new();
    exports.export("main", ExportKind::Func, 0); // 导出函数0
    module.section(&exports);
    
    // 代码段
    let mut code = CodeSection::new();
    
    // 主函数体
    let mut func = Function::new(vec![]);
    
    for node in ast {
        match node {
            ASTNode::Print(text) => {
                // 在内存偏移0处写入字符串长度
                func.instruction(&Instruction::I32Const(0));
                func.instruction(&Instruction::I32Const(text.len() as i32));
                func.instruction(&Instruction::I32Store(MemArg::new(2, 0)));
                
                // 在内存偏移4处写入字符串内容
                for (i, byte) in text.as_bytes().iter().enumerate() {
                    func.instruction(&Instruction::I32Const(4 + i as i32));
                    func.instruction(&Instruction::I32Const(*byte as i32));
                    func.instruction(&Instruction::I32Store(MemArg::new(0, 0)));
                }
                
                // 调用print函数 (ptr=0, len=text.len())
                func.instruction(&Instruction::I32Const(0));
                func.instruction(&Instruction::I32Const(text.len() as i32));
                func.instruction(&Instruction::Call(0));
            }
        }
    }
    
    // 函数结束
    func.instruction(&Instruction::End);
    code.function(&func);
    module.section(&code);
    
    Ok(module.finish())
}

// 3. 引擎实现
struct GameEngine {
    print_history: Vec<String>,
}

impl GameEngine {
    fn new() -> Self {
        GameEngine {
            print_history: Vec::new(),
        }
    }
    
    fn engine_print(&mut self, memory: &Memory, ptr: i32, len: i32) {
        // 读取内存中的字符串
        let mut buffer = vec![0u8; len as usize];
        memory
            .read(&mut (), ptr as u64 as usize, &mut buffer)
            .expect("Failed to read memory");
        
        let text = String::from_utf8_lossy(&buffer).into_owned();
        
        // 记录打印历史
        self.print_history.push(text.clone());
        
        // 模拟执行打印
        println!("[ENGINE] PRINT: {}", text);
    }
}

// 4. 主执行流程
fn main() -> Result<()> {
    // 1. 用户脚本
    let script = r#"print "123""#;
    println!("[PARSER] Script: {}", script);
    
    // 2. 解析脚本为AST
    let ast = parse_script(script)?;
    println!("[PARSER] AST: {:?}", ast);
    
    // 3. 编译为WASM
    let wasm_bytes = compile_to_wasm(&ast)?;
    println!("[COMPILER] Generated WASM module ({} bytes)", wasm_bytes.len());
    
    // 4. 创建引擎状态
    let engine_state = GameEngine::new();
    
    // 5. 配置WASM引擎
    let engine = Engine::default();
    let mut store = Store::new(&engine, engine_state);
    
    // 6. 创建链接器并定义print函数
    let mut linker = Linker::new(&engine);
    linker.func_wrap("env", "print", |mut caller: Caller<'_, GameEngine>, ptr: i32, len: i32| {
        // 获取内存
        let memory = caller.get_export("memory")
            .expect("Memory export not found")
            .into_memory()
            .expect("Not a memory");
        
        // 调用引擎的print实现
        caller.data_mut().engine_print(&memory, ptr, len);
    })?;
    
    // 7. 加载WASM模块
    let module = Module::new(&engine, &wasm_bytes)?;
    
    // 8. 实例化并执行
    let instance = linker.instantiate(&mut store, &module)?;
    
    // 确保导出了内存
    instance.get_memory(&mut store, "memory")
        .expect("Memory not exported");
    
    // 获取并执行main函数
    let main = instance.get_typed_func::<(), ()>(&mut store, "main")?;
    println!("[ENGINE] Executing WASM module...");
    main.call(&mut store, ())?;
    
    // 9. 验证执行结果
    let state = store.data();
    println!("\n[RESULT] Print history: {:?}", state.print_history);
    assert_eq!(state.print_history, vec!["123"]);
    
    println!("✅ Successfully executed script!");
    Ok(())
}

// 测试
#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_parser() {
        let script = r#"print "hello world""#;
        let ast = parse_script(script).unwrap();
        assert!(matches!(ast[0], ASTNode::Print(ref s) if s == "hello world"));
    }
    
    #[test]
    fn test_wasm_generation() {
        let ast = vec![ASTNode::Print("test".to_string())];
        let wasm = compile_to_wasm(&ast).unwrap();
        assert!(!wasm.is_empty());
        assert!(wasm.starts_with(b"\0asm")); // WASM magic number
    }
}
posted @ 2025-06-02 06:10  Furau  阅读(5)  评论(0)    收藏  举报