feat: 字节码VM基础设施 — 编译器、VM执行循环、Runtime trait

Phase 1-3: 基础VM架构
- 新增 Runtime trait: 抽象树遍历解释器和VM的共同接口
- NativeFn 改为接受 &mut dyn Runtime
- 重构所有内置函数使用新签名
- vm/opcode.rs: 33个字节码指令 + 编码/解码辅助函数
- vm/compiler.rs: AST→字节码编译器,支持变量解析、跳转回填、作用域
- vm/vm.rs: 栈式VM执行循环,支持全局变量、原生函数调用
- lib.rs: 新增 run_file_vm() + --vm CLI标志
- 修复: 跳转偏移计算、对象字面量编译

工作特性: 算术、变量、while/for循环、条件、数组、对象、字符串
待完成: 用户定义函数调用、闭包/upvalue捕获、完整require支持

Release模式: 1M算术循环 VM 0.44s vs 树遍历 0.89s (2.0x加速)
This commit is contained in:
2026-06-25 01:08:49 +08:00
parent 89952139c5
commit d854b22006
15 changed files with 2185 additions and 74 deletions
+27 -24
View File
@@ -8,15 +8,20 @@
use crate::error::RuntimeError;
use crate::lexer::Lexer;
use crate::parser::Parser;
use super::{Interpreter, Env, Value, Signal};
use super::{Interpreter, Env, Value, Signal, Runtime};
use std::cell::RefCell;
use std::collections::HashMap;
use std::path::Path;
use std::rc::Rc;
/// require() 的内置函数实现
pub fn require_fn(interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, RuntimeError> {
// 1. 参数验证
impl Runtime for Interpreter {
fn require(&mut self, path: &str) -> Result<Value, RuntimeError> {
require_impl(self, path)
}
}
/// require() 的内置函数实现 — 薄包装,委托给 Runtime::require
pub fn require_fn(runtime: &mut dyn Runtime, args: Vec<Value>) -> Result<Value, RuntimeError> {
let path_str = match args.first() {
Some(Value::String(s)) => s.clone(),
Some(other) => return Err(runtime_error(format!(
@@ -24,28 +29,32 @@ pub fn require_fn(interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, R
None => return Err(runtime_error(
"require() expects 1 argument (string path)")),
};
runtime.require(&path_str)
}
// 2. 路径解析
let resolved = resolve_path(&interp.current_dir, &path_str)?;
/// require() 的内部实现 (供 Interpreter::require 使用)
fn require_impl(interp: &mut Interpreter, path_str: &str) -> Result<Value, RuntimeError> {
// 1. 路径解析
let resolved = resolve_path(&interp.current_dir, path_str)?;
// 3. 缓存查找
// 2. 缓存查找
if let Some(cached) = interp.module_cache.borrow().get(&resolved) {
return Ok(cached.clone());
}
// 4. 读取文件
// 3. 读取文件
let src = std::fs::read_to_string(&resolved)
.map_err(|e| runtime_error(format!(
"Module '{}' not found: {}", path_str, e)))?;
// 5. 词法分析
// 4. 词法分析
let (tokens, lex_errors) = Lexer::new(&src).tokenize();
if !lex_errors.is_empty() {
return Err(runtime_error(format!(
"Lex error in module '{}': {}", path_str, lex_errors[0])));
}
// 6. 语法分析
// 5. 语法分析
let mut parser = Parser::new(tokens);
let (stmts, parse_errors) = parser.parse();
if !parse_errors.is_empty() {
@@ -53,27 +62,26 @@ pub fn require_fn(interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, R
"Parse error in module '{}': {}", path_str, parse_errors[0])));
}
// 7. 创建隔离的模块 env(父级 = builtins_env,看不到调用者的变量)
// 6. 创建隔离的模块 env(父级 = builtins_env,看不到调用者的变量)
let module_env = Rc::new(RefCell::new(Env::new(Some(Rc::clone(&interp.builtins_env)))));
// 8. 在缓存中插入占位符(支持循环 require)
// 7. 在缓存中插入占位符(支持循环 require)
let exports_map = Rc::new(RefCell::new(HashMap::new()));
let exports = Value::Object(Rc::clone(&exports_map));
interp.module_cache.borrow_mut().insert(resolved.clone(), exports.clone());
// 9. 保存调用者状态
// 8. 保存调用者状态
let previous_env = Rc::clone(&interp.env);
let previous_dir = interp.current_dir.clone();
// 10. 切换到模块上下文
// 9. 切换到模块上下文
interp.env = module_env.clone();
interp.current_dir = module_dir(&resolved);
// 11. 执行模块
// 10. 执行模块
for stmt in &stmts {
match interp.execute(stmt.clone()) {
Ok(Signal::Break) | Ok(Signal::Continue) => {
// 恢复状态后返回错误
interp.env = previous_env;
interp.current_dir = previous_dir;
interp.module_cache.borrow_mut().remove(&resolved);
@@ -81,23 +89,20 @@ pub fn require_fn(interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, R
"break/continue outside of loop in module"));
}
Err(e) => {
// 恢复状态后传播错误
interp.env = previous_env;
interp.current_dir = previous_dir;
interp.module_cache.borrow_mut().remove(&resolved);
return Err(e);
}
Ok(Signal::None) | Ok(Signal::Return(_)) => {
// 正常执行或顶层 return,继续
}
Ok(Signal::None) | Ok(Signal::Return(_)) => {}
}
}
// 12. 恢复调用者状态
// 11. 恢复调用者状态
interp.env = previous_env;
interp.current_dir = previous_dir;
// 13. 收集 exports(模块 env 中的所有直接绑定)
// 12. 收集 exports(模块 env 中的所有直接绑定)
for (name, (val, _mutable)) in module_env.borrow().values.clone() {
exports_map.borrow_mut().insert(name, val);
}
@@ -109,7 +114,6 @@ pub fn require_fn(interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, R
// Helpers
// ============================================================================
/// 解析模块路径:相对路径基于 current_dir,用 canonicalize 规范化
fn resolve_path(current_dir: &str, path_str: &str) -> Result<String, RuntimeError> {
let path = Path::new(path_str);
let resolved = if path.is_absolute() {
@@ -124,7 +128,6 @@ fn resolve_path(current_dir: &str, path_str: &str) -> Result<String, RuntimeErro
path_str, resolved.display())))
}
/// 提取模块文件所在目录
fn module_dir(resolved: &str) -> String {
Path::new(resolved)
.parent()