mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
feat: 循环 let/const 每迭代绑定(MAKE_CELL_FRESH + 解构捕获修复)
This commit is contained in:
@@ -18,6 +18,14 @@ impl Emitter {
|
||||
fn emit_compound_identifier_static(
|
||||
&self, name: &str, op: OpCode, rhs: u32, ctx: &mut CompileCtx,
|
||||
) -> Result<u32, String> {
|
||||
// 循环 update 段:被捕获绑定走寄存器 RMW(C 风格 for 每迭代 fresh,
|
||||
// update 写寄存器供下一迭代 fresh 拷贝,不污染本迭代闭包捕获的 cell)。
|
||||
if ctx.register_update_names.iter().any(|n| n == name) {
|
||||
if let Some(reg) = ctx.scopes.symbols.lookup_any(name) {
|
||||
ctx.inst(Inst::new(op, Operand::Reg(reg), Operand::Reg(rhs), Operand::None));
|
||||
return Ok(reg);
|
||||
}
|
||||
}
|
||||
let uv_idx = ctx.current_upvalue_captures.iter().position(|u| u.name == name);
|
||||
let captured_cell = ctx.captured_bindings.get(name).copied();
|
||||
if let Some(uv) = uv_idx {
|
||||
|
||||
@@ -112,6 +112,19 @@ impl Emitter {
|
||||
/// - `const_flag` 为 1 时走 STORE_VAR 运行时 const guard(对 const 再赋值报错)。
|
||||
/// - upvalue 与 cell 写穿共享单元,不设 guard。
|
||||
pub(crate) fn emit_identifier_store(&self, name: &str, val_reg: u32, const_flag: u16, ctx: &mut CompileCtx) {
|
||||
// 循环 update 段:被捕获绑定走寄存器而非 cell(C 风格 for 每迭代 fresh,
|
||||
// update 写寄存器供下一迭代 fresh 拷贝,不污染本迭代闭包捕获的 cell)。
|
||||
if ctx.register_update_names.iter().any(|n| n == name) {
|
||||
if let Some(reg) = ctx.scopes.symbols.lookup_any(name) {
|
||||
ctx.inst(Inst::new(
|
||||
OpCode::STORE_VAR,
|
||||
Operand::Reg(reg),
|
||||
Operand::Reg(val_reg),
|
||||
Operand::Imm(const_flag),
|
||||
));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 目标若是 upvalue 引用,走 STORE_UPVALUE
|
||||
if let Some(uv_idx) = ctx.current_upvalue_captures.iter().position(|u| u.name == name) {
|
||||
ctx.inst(Inst::new(
|
||||
|
||||
@@ -418,6 +418,21 @@ impl Emitter {
|
||||
) -> Result<u32, String> {
|
||||
let uv_idx = ctx.current_upvalue_captures.iter().position(|u| u.name == name);
|
||||
let captured_cell = ctx.captured_bindings.get(name).copied();
|
||||
// 循环 update 段:被捕获绑定走寄存器 INC/DEC(C 风格 for 每迭代 fresh,
|
||||
// update 写寄存器供下一迭代 fresh 拷贝,不污染本迭代闭包捕获的 cell)。
|
||||
if ctx.register_update_names.iter().any(|n| n == name) {
|
||||
if let Some(reg) = ctx.scopes.symbols.lookup_any(name) {
|
||||
let result_reg = ctx.alloc_reg();
|
||||
let op = match (update.operator, update.prefix) {
|
||||
(UpdateOperator::Increment, true) => OpCode::INC_PRE,
|
||||
(UpdateOperator::Increment, false) => OpCode::INC_POST,
|
||||
(UpdateOperator::Decrement, true) => OpCode::DEC_PRE,
|
||||
(UpdateOperator::Decrement, false) => OpCode::DEC_POST,
|
||||
};
|
||||
ctx.inst(Inst::new(op, Operand::Reg(reg), Operand::Reg(result_reg), Operand::Reg(result_reg)));
|
||||
return Ok(result_reg);
|
||||
}
|
||||
}
|
||||
if let Some(uv) = uv_idx {
|
||||
// upvalue:LOAD_UPVALUE + 常量 1 + ADD/SUB + STORE_UPVALUE;
|
||||
// 后缀形式返回旧值(前缀返回新值)。
|
||||
|
||||
Reference in New Issue
Block a user