fix: preserve high template expression registers
This commit is contained in:
@@ -199,8 +199,8 @@ impl Vm {
|
||||
let seg = self.bytecode[self.pc];
|
||||
self.pc += 1;
|
||||
if (seg >> 31) == 1 {
|
||||
let reg = (seg & 0x7F) as u8;
|
||||
let val = self.regs[reg as usize];
|
||||
let reg = (seg & 0x7FFF_FFFF) as usize;
|
||||
let val = self.regs[reg];
|
||||
let s = if val.is_string() {
|
||||
// SAFETY: val 是字符串值。
|
||||
unsafe { (*val.as_string_ptr()).data.clone() }
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
use oxide_bytecode::module::Constant;
|
||||
use oxide_bytecode::opcode::OpCode;
|
||||
use oxide_compiler::compiler::Compiler;
|
||||
use oxide_ir::inst::Inst;
|
||||
use oxide_ir::operand::Operand;
|
||||
use oxide_ir::IRFunction;
|
||||
use oxide_parser::Allocator;
|
||||
use oxide_types::value::JsValue;
|
||||
use oxide_vm::vm::Vm;
|
||||
@@ -87,6 +92,36 @@ fn template_numeric_expression() {
|
||||
assert_eq!(to_str(&vm, result.unwrap()), "2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_expression_reads_physical_register_above_127() {
|
||||
let mut ir = IRFunction::new();
|
||||
ir.constants = vec![Constant::String("value".to_string()), Constant::String(String::new())];
|
||||
ir.n_registers = 202;
|
||||
ir.insts = vec![
|
||||
Inst::load_const(Operand::Reg(200), 0),
|
||||
Inst::template_str(Operand::Reg(201), 3, 0, &[1, 0x8000_0000 | 200, 1]),
|
||||
Inst::inst_mov(Operand::Reg(0), Operand::Reg(201)),
|
||||
Inst::new(OpCode::HALT, Operand::None, Operand::None, Operand::None),
|
||||
];
|
||||
|
||||
let module = oxide_ir::lower::lower(&ir).expect("lower template IR");
|
||||
let mut vm = Vm::new();
|
||||
let result = vm.run(&module).expect("run template IR");
|
||||
assert_eq!(to_str(&vm, result), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_expression_survives_high_vreg_regalloc() {
|
||||
let mut source = String::from("function f() {");
|
||||
for i in 0..180 {
|
||||
source.push_str(&format!("let v{i}={i};"));
|
||||
}
|
||||
source.push_str("let value='unit'; return `${value}s`; } f();");
|
||||
|
||||
let (vm, result) = eval_val(&source);
|
||||
assert_eq!(to_str(&vm, result.unwrap()), "units");
|
||||
}
|
||||
|
||||
// ── 模板标签调用测试(基础)──
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user