mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
feat: with 语句、成员位/移位复合赋值、CALL_NATIVE 无目标修复
with 语句:新增 emit 支持,with 体内自由标识符动态解析(对象属性优先, 回退外层),支持读/写/复合赋值/自增自减/delete/var 初始化动态化, TO_OBJECT opcode 处理原始值对象,顶层 this 绑定全局对象。 复合赋值:新增 6 个 COMPOUND_MEMBER_BIT_* opcode 支持成员位/移位复合赋值, 修复 computed member 复合赋值覆盖 bug,with 内标识符复合赋值动态化。 CALL_NATIVE:实现全局 isNaN/isFinite 并绑定,用户覆盖 builtin 名时 回退通用调用路径而非报错,局部遮蔽 builtin 名走普通 CALL。 test262: with 34 pass(基线 0),compound-assignment 320 pass(基线 223)
This commit is contained in:
@@ -175,6 +175,9 @@ pub struct CompileCtx {
|
||||
/// 消除符号表时序依赖与 cell 索引错位。
|
||||
pub(crate) captured_bindings: BTreeMap<String, u8>,
|
||||
pub(crate) const_overflow: bool,
|
||||
/// with 语句作用域栈:元素为 (with 对象寄存器, 打开时的作用域深度)。
|
||||
/// 非空时 with 体内的自由标识符需动态解析(先查对象属性,回退外层)。
|
||||
pub(crate) with_stack: Vec<(u32, usize)>,
|
||||
}
|
||||
|
||||
/// 函数体编译上下文:决定 `this`/`super` 绑定与参数前导(prologue)形态。
|
||||
@@ -255,6 +258,7 @@ impl CompileCtx {
|
||||
own_bindings: HashSet::new(),
|
||||
captured_bindings: BTreeMap::new(),
|
||||
const_overflow: false,
|
||||
with_stack: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,10 +479,45 @@ impl CompileCtx {
|
||||
self.scopes.builtin_reg_map.iter().any(|(n, _)| n == name)
|
||||
}
|
||||
|
||||
/// 内置名是否被局部声明遮蔽(`var parseInt = ...` 等)。
|
||||
/// builtin_reg_map 记录的是全局内置槽;若该名在静态作用域另有绑定,则调用应解析局部。
|
||||
pub(crate) fn is_local_shadowing_builtin(&self, name: &str) -> bool {
|
||||
if let Some(reg) = self.scopes.symbols.lookup_any(name) {
|
||||
let is_builtin_slot = self.scopes.builtin_reg_map.iter().any(|(n, r)| n == name && *r == reg);
|
||||
return !is_builtin_slot;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn is_known_builtin(name: &str) -> bool {
|
||||
BUILTIN_GLOBALS.contains(&name)
|
||||
}
|
||||
|
||||
/// 进入 with 语句体:记录对象寄存器与当前作用域深度,供动态标识符解析。
|
||||
pub(crate) fn push_with(&mut self, obj_reg: u32) {
|
||||
let depth = self.scopes.symbols.scopes.len();
|
||||
self.with_stack.push((obj_reg, depth));
|
||||
}
|
||||
|
||||
/// 离开 with 语句体。
|
||||
pub(crate) fn pop_with(&mut self) {
|
||||
self.with_stack.pop();
|
||||
}
|
||||
|
||||
/// 最内层 with 对象寄存器;无 with 时为 None。
|
||||
pub(crate) fn innermost_with_obj(&self) -> Option<u32> {
|
||||
self.with_stack.last().map(|&(reg, _)| reg)
|
||||
}
|
||||
|
||||
/// 指定名字是否在 with 语句体**内**(with 打开之后的块作用域)声明。
|
||||
/// with 内声明优先于对象属性;with 之前的外层声明被对象遮蔽。
|
||||
pub(crate) fn is_with_internal_binding(&self, name: &str) -> bool {
|
||||
let Some(&(_, depth)) = self.with_stack.last() else {
|
||||
return false;
|
||||
};
|
||||
matches!(self.scopes.symbols.lookup_any_binding(name), Some((_, idx)) if idx >= depth)
|
||||
}
|
||||
|
||||
fn builtin_reg_floor(&self) -> u32 {
|
||||
self.scopes
|
||||
.builtin_reg_map
|
||||
@@ -945,6 +984,7 @@ impl Emitter {
|
||||
Statement::BreakStatement(b) => self.emit_break_statement(b, ctx),
|
||||
Statement::ContinueStatement(c) => self.emit_continue_statement(c, ctx),
|
||||
Statement::LabeledStatement(ls) => self.emit_labeled_statement(ls, ctx),
|
||||
Statement::WithStatement(_) => self.emit_with_domain(stmt, ctx),
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user