fix: 接通透传闭包值链路
This commit is contained in:
@@ -226,9 +226,11 @@ impl Vm {
|
||||
let upvals = obj.upvalues_slice_mut();
|
||||
if uv_idx < upvals.len() {
|
||||
if !upvals[uv_idx].is_null() {
|
||||
unsafe { (*upvals[uv_idx]).value = src_val; }
|
||||
unsafe {
|
||||
(*upvals[uv_idx]).value = src_val;
|
||||
}
|
||||
vm_debug!("STORE_UPVALUE len={} wrote existing", upvals.len());
|
||||
} else {
|
||||
// Lazy create: cell was null (CREATE_CLOSURE before MAKE_CELL)
|
||||
let cell = self.gc_state.session_epoch.alloc(Cell::new(src_val, true));
|
||||
upvals[uv_idx] = cell as *mut Cell;
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@ pub struct Vm {
|
||||
pub(crate) profiling: ProfilingState,
|
||||
pub(crate) sub_module_stack: Vec<Arc<Vec<CompiledModule>>>,
|
||||
pub(crate) cell_stack: Vec<Vec<*mut Cell>>,
|
||||
pub(crate) temp_immutables: Vec<Vec<JsValue>>,
|
||||
/// Reusable string buffer for concatenation to avoid allocation per `+` op.
|
||||
pub(crate) string_buf: String,
|
||||
}
|
||||
@@ -753,7 +754,9 @@ impl Vm {
|
||||
self.pc = 0;
|
||||
self.bytecode = sub_bytecode;
|
||||
let subs = Arc::clone(&self.sub_modules);
|
||||
self.activate_immutables(sub_idx + 1, &subs[sub_idx].constants);
|
||||
let converted = self.convert_immutables(&subs[sub_idx].constants);
|
||||
self.temp_immutables.push(converted);
|
||||
self.active_immutables = self.temp_immutables.last().unwrap().as_slice() as *const [JsValue];
|
||||
self.cell_stack.push(Vec::with_capacity(subs[sub_idx].cells_needed as usize));
|
||||
for (name, reg) in &self.sub_modules[sub_idx].builtin_reg_map.clone() {
|
||||
let si = self.kernel_core.perm_interner().intern(name.as_str()).0;
|
||||
|
||||
@@ -131,6 +131,7 @@ impl Vm {
|
||||
if let Some(saved_subs) = self.sub_module_stack.pop() {
|
||||
self.sub_modules = saved_subs;
|
||||
}
|
||||
self.temp_immutables.pop();
|
||||
let offset = frame.saved_reg_offset as usize;
|
||||
let len = frame.caller_reg_limit as usize;
|
||||
self.regs[..len].copy_from_slice(&self.save_stack[offset..offset + len]);
|
||||
|
||||
@@ -72,6 +72,7 @@ impl Vm {
|
||||
string_buf: String::new(),
|
||||
sub_module_stack: Vec::new(),
|
||||
cell_stack: Vec::new(),
|
||||
temp_immutables: Vec::new(),
|
||||
};
|
||||
vm_info!("Vm created");
|
||||
vm
|
||||
@@ -133,6 +134,7 @@ impl Vm {
|
||||
string_buf: String::new(),
|
||||
sub_module_stack: Vec::new(),
|
||||
cell_stack: Vec::new(),
|
||||
temp_immutables: Vec::new(),
|
||||
};
|
||||
vm_info!("Vm created (pool)");
|
||||
vm
|
||||
@@ -206,6 +208,7 @@ impl Vm {
|
||||
self.saved_immutables_stack.clear();
|
||||
self.save_stack.clear();
|
||||
self.cell_stack.clear();
|
||||
self.temp_immutables.clear();
|
||||
self.try_stack.clear();
|
||||
self.exception_value = None;
|
||||
self.pending_exception = None;
|
||||
@@ -482,7 +485,7 @@ mod tests {
|
||||
assert_eq!(vm.lookup_str(result).as_deref(), Some("done"));
|
||||
// Cache = top module + 1 sub-module (f); the sub-module slot was initialized by the calls.
|
||||
assert_eq!(vm.immutables_cache.len(), 2);
|
||||
assert!(vm.immutables_cache[1].get().is_some(), "f's immutables should be cached after its calls");
|
||||
// Sub-module constants now use temp_immutables (avoiding cache index collision)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user