feat: 函数 length 属性(字节码函数/bind 包装器)+ getter/setter name 前缀

This commit is contained in:
爱特每羊队
2026-08-09 15:38:45 +08:00
parent 8f8c9a39ff
commit c65d7e0373
10 changed files with 263 additions and 19 deletions
+7 -1
View File
@@ -112,7 +112,13 @@ impl Emitter {
)?;
ctx.in_instance_method = saved_instance;
ctx.in_static_method = saved_static;
method_module.function_name = Some(method_name.to_string());
// 访问器函数名带 "get "/"set " 前缀(SetFunctionName 语义),普通方法裸属性名。
let display_name = match method.kind {
MethodDefinitionKind::Get => format!("get {method_name}"),
MethodDefinitionKind::Set => format!("set {method_name}"),
_ => method_name.to_string(),
};
method_module.function_name = Some(display_name);
method_module.needs_home_object = true;
ctx.nested.push(method_module);
let method_reg = ctx.alloc_reg();
+15
View File
@@ -175,6 +175,9 @@ pub struct CompileCtx {
/// 捕获判断(MAKE_CELL / CELL_GET / CELL_SET)与子函数 upvalue cell_idx 统一查此映射,
/// 消除符号表时序依赖与 cell 索引错位。
pub(crate) captured_bindings: BTreeMap<String, u8>,
/// 函数 `length` 属性值:首个带默认值形参之前的形参数(rest 不计)。
/// emit_params_prologue 前由编译入口从 param_specs 计算。
pub(crate) function_length: u32,
pub(crate) const_overflow: bool,
/// with 语句作用域栈:元素为 (with 对象寄存器, 打开时的作用域深度)。
/// 非空时 with 体内的自由标识符需动态解析(先查对象属性,回退外层)。
@@ -266,6 +269,7 @@ impl CompileCtx {
current_upvalue_captures: Vec::new(),
own_bindings: HashSet::new(),
captured_bindings: BTreeMap::new(),
function_length: 0,
const_overflow: false,
with_stack: Vec::new(),
open_try_handlers: Vec::new(),
@@ -601,6 +605,7 @@ impl CompileCtx {
needs_home_object: false,
captured_this_const_idx: 0,
function_name: None,
function_length: self.function_length,
is_top_level: parent_ctx.is_none(),
const_overflow: self.const_overflow,
nested: std::mem::take(&mut self.nested),
@@ -748,6 +753,16 @@ impl Emitter {
{
let mut ctx = CompileCtx::new();
// length = 第一个带默认值形参之前的形参数(解构默认与标识符默认同规则);
// rest 参数不在 param_specs 中(独立字段),天然不计入。
ctx.function_length = param_specs
.iter()
.take_while(|spec| match spec {
ParamSpec::Identifier { initializer, .. } => initializer.is_none(),
ParamSpec::Pattern { initializer, .. } => initializer.is_none(),
})
.count() as u32;
// 继承父内置寄存器映射:子模块寄存器文件中,内置标识符(Math、Object 等)
// 解析到父预先分配的槽位。
ctx.scopes.builtin_reg_map = parent_ctx.scopes.builtin_reg_map.clone();
@@ -45,7 +45,13 @@ impl Emitter {
}
let accessor_reg = self.emit_expression(&p.value, ctx)?;
if let Some(sub_mod) = ctx.nested.last_mut() {
sub_mod.function_name = Some(prop_name.to_string());
// 访问器函数名带 "get "/"set " 前缀(SetFunctionName 语义)。
let fn_name = match p.kind {
PropertyKind::Get => format!("get {prop_name}"),
PropertyKind::Set => format!("set {prop_name}"),
_ => prop_name.clone(),
};
sub_mod.function_name = Some(fn_name);
}
let undef_reg = self.emit_undefined(ctx);
let (get_reg, set_reg) = if p.kind == PropertyKind::Get {