refactor: 动态编译改经 CompilerService 注入,oxide_vm 去编译器依赖

This commit is contained in:
2026-10-08 05:51:58 +00:00
parent 66735f802f
commit 4f9b6ab444
94 changed files with 459 additions and 67 deletions
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -27,6 +29,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse ok");
let module = Compiler::new().compile(&program).expect("compile ok");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let val = vm.run(&Arc::new(module)).expect("run ok");
if val.is_string() {
vm.lookup_str(val).unwrap_or_default()
+3
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -16,6 +17,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {}", e),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{}", result),
Err(e) => format!("vm error: {}", e),
@@ -33,6 +35,7 @@ fn eval_val(source: &str) -> (Vm, Result<JsValue, String>) {
Err(e) => return (Vm::new(), Err(format!("compile error: {}", e))),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module));
(vm, result)
}
+2
View File
@@ -4,6 +4,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::promise::promise_settled_value;
use oxide_vm::vm::Vm;
@@ -20,6 +21,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format_value(&vm, result),
Err(e) => format!("vm error: {e}"),
@@ -8,6 +8,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -16,6 +17,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -10,6 +10,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -19,6 +20,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -9,6 +9,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -17,6 +18,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -8,6 +8,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -16,6 +17,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -8,6 +8,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -22,6 +23,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -2,6 +2,7 @@ use std::sync::Arc;
use oxide_builtins::array::{array_constructor, array_push};
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -10,6 +11,7 @@ fn eval(source: &str) -> Result<(Vm, JsValue), String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module))?;
Ok((vm, result))
}
@@ -40,6 +42,7 @@ fn array_push_returns_length() {
#[test]
fn array_push_returns_true_length_beyond_31() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.set_reg(1, oxide_types::value::JsValue::int(31));
let array = array_constructor(&mut vm, &[0, 1]).unwrap();
vm.set_reg(0, array);
@@ -2,13 +2,16 @@ use std::sync::Arc;
use oxide_builtins::error;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::mem::P;
use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
fn make_vm() -> Vm {
Vm::new()
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm
}
fn eval(source: &str) -> Result<JsValue, String> {
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -249,6 +250,7 @@ fn function_apply_non_callable_this_throws_catchable_type_error() {
// 不可调用 this(实例原型链含函数)经 apply 转发:抛可捕获 TypeError,
// 不得绕过 try/catch 成为引擎级错误。
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let name = eval(
&mut vm,
"function FACTORY(){} FACTORY.prototype = Function(); var o = new FACTORY(); try { o.apply(); } catch (e) { e.name }",
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -10,6 +11,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -18,6 +20,7 @@ fn eval_with_vm(source: &str) -> (Vm, Result<JsValue, String>) {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module));
(vm, result)
}
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -9,6 +10,7 @@ fn eval(source: &str) -> Result<(Vm, JsValue), String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module))?;
Ok((vm, result))
}
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -18,6 +19,7 @@ fn to_str(vm: &Vm, val: JsValue) -> String {
#[test]
fn to_base64_rfc4648_vectors() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -43,6 +45,7 @@ fn to_base64_rfc4648_vectors() {
#[test]
fn to_base64_alphabet_and_omit_padding() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -65,6 +68,7 @@ fn to_base64_alphabet_and_omit_padding() {
#[test]
fn to_base64_option_coercion_and_receiver() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -90,6 +94,7 @@ fn to_base64_option_coercion_and_receiver() {
#[test]
fn to_hex_and_receiver_validation() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -110,6 +115,7 @@ fn to_hex_and_receiver_validation() {
#[test]
fn set_from_base64_results_and_target_size() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -151,6 +157,7 @@ fn set_from_base64_results_and_target_size() {
#[test]
fn set_from_base64_last_chunk_handling() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -190,6 +197,7 @@ fn set_from_base64_last_chunk_handling() {
#[test]
fn set_from_base64_subarray_and_option_order() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -234,6 +242,7 @@ fn set_from_base64_subarray_and_option_order() {
#[test]
fn set_from_base64_writes_up_to_error() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -251,6 +260,7 @@ fn set_from_base64_writes_up_to_error() {
#[test]
fn set_from_hex_results_and_odd_length() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -285,6 +295,7 @@ fn set_from_hex_results_and_odd_length() {
#[test]
fn from_base64_static() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -330,6 +341,7 @@ fn from_base64_static() {
#[test]
fn from_hex_static() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -353,6 +365,7 @@ fn from_hex_static() {
#[test]
fn typed_array_prototype_to_string_chain() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -378,6 +391,7 @@ fn typed_array_prototype_to_string_chain() {
#[test]
fn clamped_inherits_base64_methods_but_rejects() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -401,6 +415,7 @@ fn clamped_inherits_base64_methods_but_rejects() {
#[test]
fn base64_method_metadata() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(
&mut vm,
r#"(function() {
@@ -9,6 +9,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -23,6 +24,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
+5
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_runtime_api as coercion;
use oxide_types::value::JsValue;
@@ -17,6 +18,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -88,6 +90,7 @@ fn test_strict_equality_null_undefined() {
#[test]
fn test_to_int32_and_to_uint32() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let string_three = vm.new_string("3");
let string_bad = vm.new_string("x");
@@ -151,6 +154,7 @@ fn to_primitive_symbol_hint_invoked() {
#[test]
fn to_number_full_symbol_throws() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let sym = JsValue::symbol(0);
let result = coercion::to_number_full(sym, &mut vm);
assert!(result.is_err(), "to_number_full(Symbol) must error, got {result:?}");
@@ -323,6 +327,7 @@ fn eval_ty(source: &str) -> Result<(Vm, JsValue), String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module))?;
Ok((vm, result))
}
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -7,6 +7,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -12,6 +12,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -20,6 +21,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -9,6 +10,7 @@ fn eval(source: &str) -> Result<(Vm, JsValue), String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module))?;
Ok((vm, result))
}
@@ -10,6 +10,7 @@ use std::sync::Arc;
use oxide_bytecode::module::CompiledModule;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -25,6 +26,7 @@ fn eval_js(source: &str) -> Result<(Vm, JsValue), String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("parse: {e:?}"))?;
let module = Arc::new(Compiler::new().compile(&program).map_err(|e| format!("compile: {e}"))?);
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let val = vm.run(&module)?;
Ok((vm, val))
}
@@ -15,6 +15,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -23,6 +24,7 @@ fn eval_truthy(source: &str) {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
assert!(result.is_bool() && result.as_bool(), "expected true, got: {result:?}\nsource: {source}");
}
@@ -6,6 +6,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -14,6 +15,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -23,6 +25,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_else(|| format!("{result}"))
}
@@ -4,6 +4,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -12,6 +13,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -32,6 +34,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_else(|| format!("{result}"))
}
+26
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::object::JsObject;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -21,6 +22,7 @@ fn assert_num(result: JsValue, expected: f64) {
#[test]
fn eval_string_expression_completion_value() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 脚本模式完成值保留:`eval('1+2')` 返回 3(档 2 起,不再被函数模式 body wrap 吞掉)。
let result = eval(&mut vm, "eval('1+2')").unwrap();
assert_num(result, 3.0);
@@ -29,6 +31,7 @@ fn eval_string_expression_completion_value() {
#[test]
fn eval_string_number_completion_value() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 脚本模式完成值保留:`eval('42')` 返回 42。
let result = eval(&mut vm, "eval('42')").unwrap();
assert_num(result, 42.0);
@@ -37,6 +40,7 @@ fn eval_string_number_completion_value() {
#[test]
fn eval_string_var_declaration_inside() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 档 2:eval 内 var 声明落全局对象,完成值保留为末表达式值。
let result = eval(&mut vm, "eval('var y = 1; y')").unwrap();
assert_num(result, 1.0);
@@ -47,6 +51,7 @@ fn eval_string_var_declaration_inside() {
#[test]
fn eval_non_string_returns_as_is() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(&mut vm, "eval(123)").unwrap();
assert_num(result, 123.0);
}
@@ -54,6 +59,7 @@ fn eval_non_string_returns_as_is() {
#[test]
fn eval_object_identity() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 非字符串实参原样返回:同一对象引用。
let result = eval(&mut vm, "var o = {}; eval(o) === o").unwrap();
assert_eq!(result, JsValue::bool(true));
@@ -62,6 +68,7 @@ fn eval_object_identity() {
#[test]
fn eval_new_string_not_tostring() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// new String 是非字符串对象:不 ToString,原样返回同一对象(非原始值)。
let result = eval(&mut vm, "var s = new String('1+1'); eval(s) === s").unwrap();
assert_eq!(result, JsValue::bool(true));
@@ -70,6 +77,7 @@ fn eval_new_string_not_tostring() {
#[test]
fn eval_throw_primitive_rethrown() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// eval 内 throw 1 重抛原始值 1,可被外层 catch 捕获(非 Error 包装)。
let result = eval(&mut vm, "try { eval('throw 1') } catch(e) { e }").unwrap();
assert_num(result, 1.0);
@@ -78,6 +86,7 @@ fn eval_throw_primitive_rethrown() {
#[test]
fn eval_syntax_error_throws() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 换行分隔的 `x` 与 `++` 为非法语法,eval 抛 SyntaxError。
let result = eval(&mut vm, "try { eval('x\\u000A++') } catch(e) { e.name }").unwrap();
let rendered = vm.lookup_str(result).unwrap_or_default();
@@ -87,6 +96,7 @@ fn eval_syntax_error_throws() {
#[test]
fn eval_length_is_one() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(&mut vm, "eval.length").unwrap();
assert_num(result, 1.0);
}
@@ -94,6 +104,7 @@ fn eval_length_is_one() {
#[test]
fn eval_name_is_eval() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(&mut vm, "eval.name").unwrap();
let rendered = vm.lookup_str(result).unwrap_or_default();
assert_eq!(rendered, "eval");
@@ -102,6 +113,7 @@ fn eval_name_is_eval() {
#[test]
fn eval_global_descriptor() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 全局 eval 属性描述符:{writable:true, enumerable:false, configurable:true}。
let result = eval(
&mut vm,
@@ -115,6 +127,7 @@ fn eval_global_descriptor() {
#[test]
fn eval_new_throws_type_error() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// eval 不是构造器:new eval() 抛 TypeError。
let result = eval(&mut vm, "try { new eval() } catch(e) { e.name }").unwrap();
let rendered = vm.lookup_str(result).unwrap_or_default();
@@ -124,6 +137,7 @@ fn eval_new_throws_type_error() {
#[test]
fn eval_no_arg_and_undefined_are_undefined() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(&mut vm, "eval() === undefined && eval(undefined) === undefined").unwrap();
assert_eq!(result, JsValue::bool(true));
}
@@ -131,6 +145,7 @@ fn eval_no_arg_and_undefined_are_undefined() {
#[test]
fn eval_typeof_is_function() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval(&mut vm, "typeof eval").unwrap();
let rendered = vm.lookup_str(result).unwrap_or_default();
assert_eq!(rendered, "function");
@@ -139,6 +154,7 @@ fn eval_typeof_is_function() {
#[test]
fn eval_survives_full_reset_rebuild() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 仅 global 脏:full_reset 走 bind_global_functions 重建路径,eval 须保留。
let g_ptr = vm.session().global_object().as_ptr() as *mut JsObject;
unsafe { (&mut *g_ptr).bump_generation() };
@@ -157,6 +173,7 @@ fn eval_survives_full_reset_rebuild() {
#[test]
fn eval_script_var_lands_on_global() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 间接 eval 脚本模式:var 声明落全局对象,外层 this 可见。
let result = eval(&mut vm, "(0,eval)('var q = 9'); this.q === 9").unwrap();
assert_eq!(result, JsValue::bool(true));
@@ -165,6 +182,7 @@ fn eval_script_var_lands_on_global() {
#[test]
fn eval_script_function_decl_lands_on_global() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 脚本模式:顶层函数声明落全局对象。
let result = eval(&mut vm, "(0,eval)('function f(){}'); typeof f === 'function'").unwrap();
assert_eq!(result, JsValue::bool(true));
@@ -173,6 +191,7 @@ fn eval_script_function_decl_lands_on_global() {
#[test]
fn eval_script_let_is_isolated() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// let/const 词法隔离:不落全局,不泄漏到外层。
let result = eval(&mut vm, "(0,eval)('let z = 1'); typeof z === 'undefined'").unwrap();
assert_eq!(result, JsValue::bool(true));
@@ -184,6 +203,7 @@ fn eval_script_let_is_isolated() {
#[test]
fn eval_script_this_is_global() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 脚本模式:this 与 globalThis 恒等(inline 调用 receiver 传 global)。
let result = eval(&mut vm, "(0,eval)('this === globalThis')").unwrap();
assert_eq!(result, JsValue::bool(true));
@@ -192,6 +212,7 @@ fn eval_script_this_is_global() {
#[test]
fn eval_nested_eval() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 嵌套 eval:内层完成值透传为外层脚本值。
let result = eval(&mut vm, "eval(\"eval('1+1')\")").unwrap();
assert_num(result, 2.0);
@@ -200,6 +221,7 @@ fn eval_nested_eval() {
#[test]
fn eval_script_completion_value() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 间接 eval 脚本模式完成值:var 初始化 + 表达式。
let result = eval(&mut vm, "(0,eval)('var a = 1; a')").unwrap();
assert_num(result, 1.0);
@@ -210,6 +232,7 @@ fn eval_script_completion_value() {
#[test]
fn eval_script_empty_and_decl_only() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 空脚本 / 纯声明脚本:完成值为 undefined。
let result = eval(&mut vm, "eval('') === undefined").unwrap();
assert_eq!(result, JsValue::bool(true));
@@ -220,6 +243,7 @@ fn eval_script_empty_and_decl_only() {
#[test]
fn eval_script_throw_still_rethrows() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 脚本模式异常路径回归:eval 内 throw 原始值,外层 catch 捕获同一值。
let result = eval(&mut vm, "try { (0,eval)('throw 5') } catch(e) { e }").unwrap();
assert_num(result, 5.0);
@@ -228,6 +252,7 @@ fn eval_script_throw_still_rethrows() {
#[test]
fn compound_statement_completion_values() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// 混合形完成值:switch 命中 case 链最后非空值、无命中 undefined;空命中不沿用前值。
let result = eval(&mut vm, "7; switch(1){case 1: 9}").unwrap();
assert_num(result, 9.0);
@@ -321,6 +346,7 @@ fn compound_statement_completion_values() {
#[test]
fn iteration_labeled_completion_values() {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
// do-while 循环体完成值 = 末次体值。
let result = eval(&mut vm, "7; do { 8 } while (false)").unwrap();
assert_num(result, 8.0);
@@ -8,6 +8,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -22,6 +23,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -7,6 +7,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -7,6 +7,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -7,6 +7,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -10,6 +10,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -19,6 +20,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -5,6 +5,7 @@ use std::sync::Arc;
use oxide_bytecode::module::CompiledModule;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -18,6 +19,7 @@ fn eval(source: &str) -> JsValue {
fn run(module: &Arc<CompiledModule>) -> JsValue {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(module).expect("vm run failed")
}
@@ -26,6 +28,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse failed");
let module = Arc::new(Compiler::new().compile(&program).expect("compile failed"));
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let v = vm.run(&module).expect("vm run failed");
// 字符串结果须在同一 VM 上读:perm 串指向 VM 私有内核,VM drop 后指针悬垂。
if v.is_string() {
@@ -4,6 +4,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -18,6 +19,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => {
if result.is_string() {
@@ -8,6 +8,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -19,12 +20,14 @@ fn compile(source: &str) -> oxide_bytecode::module::CompiledModule {
fn run_truthy(source: &str) {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(compile(source))).expect("run");
assert!(result.is_bool() && result.as_bool(), "expected true, got: {result:?}\nsource: {source}");
}
fn run_string(source: &str) -> String {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(compile(source))).expect("run");
if result.is_undefined() {
return "undefined".to_string();
@@ -35,6 +38,7 @@ fn run_string(source: &str) -> String {
/// 求值并返回完成值字符串;运行期异常返回错误文本(供 TypeError 断言)。
fn eval(source: &str) -> String {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(compile(source))) {
Ok(result) => vm.lookup_str(result).unwrap_or_default(),
Err(e) => e,
@@ -9,6 +9,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -17,6 +18,7 @@ fn eval_truthy(source: &str) {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
assert!(result.is_bool() && result.as_bool(), "expected true, got: {result:?}\nsource: {source}");
}
@@ -8,6 +8,7 @@ use std::sync::Arc;
use oxide_bytecode::module::CompiledModule;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_emit::module::{ModuleSourceLoader, ResolvedModule};
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -17,6 +18,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -33,6 +35,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_else(|| format!("{result}"))
}
@@ -53,6 +56,7 @@ fn script_err_text(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Err(e) => e,
Ok(v) => panic!("expected uncaught error, got: {v:?}\nsource: {source}"),
@@ -68,6 +72,7 @@ fn err_then_script_str(decl: &str, probe: &str) -> String {
Arc::new(Compiler::new().compile(&program).expect("compile"))
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let err = vm.run(&compile(decl));
assert!(err.is_err(), "声明脚本应抛未捕获异常,实际: {err:?}\ndecl: {decl}");
let result = vm.run(&compile(probe)).expect("probe run");
@@ -181,6 +186,7 @@ fn module_fn_decl_undefined_keeps_global_constant() {
.compile_module(&program, "test.mjs", &mut NoopLoader)
.expect("compile module");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module)).expect("module run");
assert_eq!(
@@ -10,6 +10,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_emit::module::{ModuleSourceLoader, ResolvedModule};
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -19,6 +20,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -60,6 +62,7 @@ fn eval_module(source: &str) -> Result<JsValue, String> {
.compile_module(&program, "test.mjs", &mut Loader)
.map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -12,6 +12,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -29,6 +31,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_else(|| format!("{result}"))
}
@@ -3,6 +3,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -12,6 +13,7 @@ fn eval_truthy(source: &str) {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
assert!(result.is_bool() && result.as_bool(), "expected true, got: {result:?}\nsource: {source}");
}
@@ -21,6 +23,7 @@ fn eval_string(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_default()
}
@@ -34,6 +37,7 @@ fn compile(source: &str) -> oxide_bytecode::module::CompiledModule {
/// 两阶段执行:phase1 → `reset()`(轻量重置,epoch 清空、session 保留)→ phase2。
fn eval_two_phases(phase1: &str, phase2: &str) -> bool {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(compile(phase1))).expect("run1");
vm.reset();
let result = vm.run(&Arc::new(compile(phase2))).expect("run2");
@@ -43,6 +47,7 @@ fn eval_two_phases(phase1: &str, phase2: &str) -> bool {
/// 两阶段 run-Err 变体:phase2 返回运行结果,供未捕获异常(TypeError 等)断言。
fn run_two_phases(phase1: &str, phase2: &str) -> Result<JsValue, String> {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(compile(phase1))).expect("run1");
vm.reset();
vm.run(&Arc::new(compile(phase2)))
@@ -69,6 +74,7 @@ fn phase2_err_text(phase1: &str, phase2: &str) -> String {
/// "true"/"false")。
fn phase2_err_then_probe(phase1: &str, phase2: &str, probe: &str) -> String {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(compile(phase1))).expect("run1");
vm.reset();
assert!(vm.run(&Arc::new(compile(phase2))).is_err(), "phase2 应抛未捕获异常: {phase2}");
@@ -576,6 +582,7 @@ fn strict_eval_var_init_on_nonwritable_user_property_throws() {
fn nonextensible_global_strict_var_prologue_throws_before_body() {
// 序言期抛:体副作用不执行(touched 未写入)。
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(compile("Object.preventExtensions(globalThis)")))
.expect("run1");
vm.reset();
@@ -6,6 +6,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -14,6 +15,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -34,6 +36,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_else(|| format!("{result}"))
}
+2
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -4,6 +4,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -12,6 +13,7 @@ fn eval(source: &str) -> Result<(Vm, JsValue), String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module))?;
Ok((vm, result))
}
+4
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -28,6 +30,7 @@ fn object_create_and_read() {
let program = oxide_parser::parse(&allocator, source).expect("parse failed");
let module = Compiler::new().compile(&program).expect("compile failed");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let obj = vm.run(&Arc::new(module)).expect("vm run failed");
assert!(obj.is_object());
let obj_ref = unsafe { &*obj.as_js_object_ptr() };
@@ -273,6 +276,7 @@ fn object_literal_getter_setter_pair() {
fn eval_string(source: &str) -> String {
let allocator = Allocator::default();
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let program = oxide_parser::parse(&allocator, source).expect("parse failed");
let module = Compiler::new().compile(&program).expect("compile failed");
let result = vm.run(&Arc::new(module)).expect("vm run failed");
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -9,6 +10,7 @@ fn eval(source: &str) -> Result<(Vm, JsValue), String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module))?;
Ok((vm, result))
}
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -9,6 +10,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -8,6 +8,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -16,6 +17,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -36,6 +38,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_else(|| format!("{result}"))
}
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_kernel::kernel::{KernelConfig, KernelCore};
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -16,6 +17,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -33,6 +35,7 @@ fn eval_with_kernel(source: &str, kernel: Arc<KernelCore>) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::with_kernel_core(kernel);
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -52,6 +55,7 @@ fn regression_rerun_clears_ic_cache() {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
assert_eq!(format!("{}", vm.run(&Arc::new(module)).unwrap()), "1");
let source2 = "var o = {a: 2}; o.a";
@@ -188,6 +192,7 @@ fn eval_shallow(source: &str, depth: usize) -> String {
let mut cfg = KernelConfig::minimal();
cfg.max_call_depth = depth;
let mut vm = Vm::with_kernel_core(KernelCore::new(cfg));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(val) => {
if val.is_string() {
@@ -4,6 +4,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -13,6 +14,7 @@ fn eval(source: &str) -> JsValue {
let program = oxide_parser::parse(&allocator, source).expect("parse failed");
let module = Compiler::new().compile(&program).expect("compile failed");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module)).expect("vm run failed")
}
@@ -32,6 +34,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse failed");
let module = Compiler::new().compile(&program).expect("compile failed");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let v = vm.run(&Arc::new(module)).expect("vm run failed");
// 字符串结果须在同一 VM 上读:perm 串指向 VM 私有内核,VM drop 后指针悬垂。
if v.is_string() {
+2
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -9,6 +10,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -9,6 +9,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -24,6 +25,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => js_value_to_str(result),
Err(e) => format!("vm error: {e}"),
@@ -41,6 +43,7 @@ fn eval_json(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => js_value_to_str(result),
Err(e) => format!("vm error: {e}"),
@@ -6,6 +6,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -14,6 +15,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -34,6 +36,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run");
vm.lookup_str(result).unwrap_or_else(|| format!("{result}"))
}
@@ -9,6 +9,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -17,6 +18,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -7,6 +7,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -24,6 +26,7 @@ fn eval_str(source: &str) -> String {
let program = oxide_parser::parse(&allocator, source).expect("parse");
let module = Compiler::new().compile(&program).expect("compile");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let value = vm.run(&Arc::new(module)).expect("run");
assert!(value.is_string(), "expected string, got {value:?}");
// SAFETY: is_string 已确认值为字符串指针,内容在 VM 析构前拷贝为自有 String。
@@ -11,6 +11,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_vm::vm::Vm;
fn eval(source: &str) -> Result<oxide_types::value::JsValue, String> {
@@ -18,6 +19,7 @@ fn eval(source: &str) -> Result<oxide_types::value::JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("parse error: {}", e[0].message))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("compile error: {e}"))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
@@ -9,6 +9,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -23,6 +24,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
+4
View File
@@ -3,6 +3,7 @@ use std::sync::Arc;
use oxide_bytecode::module::Constant;
use oxide_bytecode::opcode::OpCode;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_ir::inst::Inst;
use oxide_ir::operand::Operand;
use oxide_ir::IRFunction;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {}", e),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{}", result),
Err(e) => format!("vm error: {}", e),
@@ -38,6 +40,7 @@ fn eval_val(source: &str) -> (Vm, Result<JsValue, String>) {
Err(e) => return (Vm::new(), Err(format!("compile error: {}", e))),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module));
(vm, result)
}
@@ -136,6 +139,7 @@ fn template_expression_reads_physical_register_above_127() {
let module = oxide_ir::lower::lower(&ir).expect("lower template IR");
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = vm.run(&Arc::new(module)).expect("run template IR");
assert_eq!(to_str(&vm, result), "value");
}
@@ -4,6 +4,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_kernel::kernel::{KernelConfig, KernelCore};
use oxide_parser::Allocator;
use oxide_types::value::JsValue;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => vm.lookup_str(result).unwrap_or_else(|| format!("{result}")),
Err(e) => format!("vm error: {e}"),
@@ -104,6 +106,7 @@ fn gc_keeps_reachable_session_objects_alive() {
let mut config = KernelConfig::minimal();
config.set_session_gc_threshold(4096);
let mut vm = Vm::with_kernel_core(KernelCore::new(config));
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let result = eval_on(
&mut vm,
"(function () { \
@@ -7,6 +7,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -21,6 +22,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -6,6 +6,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_types::value::JsValue;
use oxide_vm::vm::Vm;
@@ -14,12 +15,14 @@ fn eval(source: &str) -> Result<JsValue, String> {
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
vm.run(&Arc::new(module))
}
/// 求值并取字符串结果内容(字符串值走 lookup_str,非字符串走 Display)。
fn eval_str(source: &str) -> Result<String, String> {
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
let allocator = oxide_parser::Allocator::default();
let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?;
let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?;
+2
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),
+2
View File
@@ -1,6 +1,7 @@
use std::sync::Arc;
use oxide_compiler::compiler::Compiler;
use oxide_compiler::DefaultCompilerService;
use oxide_parser::Allocator;
use oxide_vm::vm::Vm;
@@ -15,6 +16,7 @@ fn eval(source: &str) -> String {
Err(e) => return format!("compile error: {e}"),
};
let mut vm = Vm::new();
vm.set_compiler_service(Arc::new(DefaultCompilerService));
match vm.run(&Arc::new(module)) {
Ok(result) => format!("{result}"),
Err(e) => format!("vm error: {e}"),