feat: 生成器基础支持(YIELD 帧快照挂起/恢复 + GeneratorPrototype next/return/throw)

- 新增 YIELD/SUSPEND_BODY opcode;function* 识别与 yield emit
- GeneratorState 全量快照 VM 执行上下文(regs/pc/bytecode/spill/save/try/cell 栈段/迭代器)
- 调用时参数初始化(默认值/解构副作用与异常在 g() 时刻生效)
- %GeneratorPrototype%/%GeneratorFunction.prototype% 内建对象与 next/return/throw
- session GC trace 生成器状态 JsValues;闭包捕获分析补 yield/赋值目标扫描
This commit is contained in:
爱特每羊队
2026-08-09 18:02:08 +08:00
parent 7c2e9ec1ff
commit 6f80c12ac9
26 changed files with 1265 additions and 107 deletions
+60 -16
View File
@@ -21,7 +21,7 @@ impl Vm {
let mut session = KernelSession::new(&core);
bindings::init_kernel_builtins(&core, &mut session);
let obj_proto = P::clone(&session.builtin_world().object_proto);
let vm = Self {
let mut vm = Self {
regs: [JsValue::undefined(); 256],
pc: 0,
bytecode: Vec::new(),
@@ -32,6 +32,8 @@ impl Vm {
session,
epoch: Epoch::new(),
object_prototype: obj_proto,
generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
generator_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
math_rng_state: 0,
sub_modules: Arc::new(Vec::new()),
saved_bytecode_stack: Vec::new(),
@@ -51,6 +53,10 @@ impl Vm {
inline_args_count: 0,
accessor_frame_target_reg: None,
inline_callee: None,
generator_suspended: None,
generator_dispatch: false,
generator_init_step: false,
generator_body_started: false,
gc_state: GcState {
session_epoch: bumpalo::Bump::new(),
session_gc: crate::session_gc::SessionGc::new(),
@@ -78,6 +84,7 @@ impl Vm {
string_buf: String::new(),
cell_stack: Vec::new(),
};
vm.init_generator_intrinsics();
vm_info!("Vm created");
vm
}
@@ -87,7 +94,7 @@ impl Vm {
let mut session = KernelSession::new(&core);
bindings::init_kernel_builtins(&core, &mut session);
let obj_proto = P::clone(&session.builtin_world().object_proto);
let vm = Self {
let mut vm = Self {
regs: [JsValue::undefined(); 256],
pc: 0,
bytecode: Vec::new(),
@@ -98,6 +105,8 @@ impl Vm {
session,
epoch: Epoch::new(),
object_prototype: obj_proto,
generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
generator_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
math_rng_state: 0,
sub_modules: Arc::new(Vec::new()),
saved_bytecode_stack: Vec::new(),
@@ -117,6 +126,10 @@ impl Vm {
inline_args_count: 0,
accessor_frame_target_reg: None,
inline_callee: None,
generator_suspended: None,
generator_dispatch: false,
generator_init_step: false,
generator_body_started: false,
gc_state: GcState {
session_epoch: bumpalo::Bump::new(),
session_gc: crate::session_gc::SessionGc::new(),
@@ -144,10 +157,19 @@ impl Vm {
string_buf: String::new(),
cell_stack: Vec::new(),
};
vm.init_generator_intrinsics();
vm_info!("Vm created (pool)");
vm
}
/// 初始化/重建生成器内建对象(`%GeneratorPrototype%` 与 `%GeneratorFunction.prototype%`)。
///
/// 在 VM 创建与 `full_reset`(session 重建)后调用——原型继承自 session 的
/// Object/Function 原型,session 重建后须重挂。
pub(crate) fn init_generator_intrinsics(&mut self) {
crate::generator::init_generator_intrinsics(self);
}
/// 全量隔离重置:仅重建被污染的内置对象与 global,并清空所有执行状态与内存。
///
/// 用于在多次 JS 执行之间达到完全隔离:session 内未被污染的 builtin 保留原指针。
@@ -163,6 +185,7 @@ impl Vm {
}
self.session.record_snapshot();
self.object_prototype = P::clone(&self.session.builtin_world().object_proto);
self.init_generator_intrinsics();
self.clear_full_reset_state();
vm_info!("full_reset completed");
}
@@ -173,6 +196,7 @@ impl Vm {
self.session = KernelSession::new(&self.kernel_core);
bindings::init_kernel_builtins(&self.kernel_core, &mut self.session);
self.object_prototype = P::clone(&self.session.builtin_world().object_proto);
self.init_generator_intrinsics();
self.clear_full_reset_state();
}
@@ -226,6 +250,10 @@ impl Vm {
self.pending_exception = None;
self.pending_error_kind = None;
self.pending_completion = None;
self.generator_suspended = None;
self.generator_dispatch = false;
self.generator_init_step = false;
self.generator_body_started = false;
self.native_call_depth = 0;
}
@@ -290,8 +318,14 @@ impl Vm {
&mut self, sub_idx: u32, is_arrow: bool, is_class_constructor: bool, is_derived_constructor: bool,
needs_home_object: bool,
) -> JsValue {
let func_proto_ptr = self.session.builtin_world().function_proto.as_ptr() as *mut JsObject;
let proto_val = JsValue::from_js_object(func_proto_ptr);
// 生成器函数对象:原型为 %GeneratorFunction.prototype%(constructor 链解析到
// "GeneratorFunction"),且不像普通函数那样拥有 `prototype` 属性。
let is_generator = self.sub_modules.get(sub_idx as usize).map(|m| m.is_generator).unwrap_or(false);
let proto_val = if is_generator {
JsValue::from_js_object(self.generator_function_proto.as_ptr() as *mut JsObject)
} else {
JsValue::from_js_object(self.session.builtin_world().function_proto.as_ptr() as *mut JsObject)
};
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto_val);
obj.set_function(true);
obj.set_sub_module_index(sub_idx);
@@ -306,26 +340,36 @@ impl Vm {
let func_val = JsValue::object(obj_ptr as *mut u8);
if !is_arrow {
let object_proto_ptr = self.session.builtin_world().object_proto.as_ptr() as *mut JsObject;
let prototype_obj = self
.epoch
.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto_ptr)));
// 原型对象自身的 [[Prototype]]:生成器为 %GeneratorPrototype%,普通函数为 Object.prototype。
let proto_of_proto = if is_generator {
JsValue::from_js_object(self.generator_proto.as_ptr() as *mut JsObject)
} else {
JsValue::from_js_object(self.session.builtin_world().object_proto.as_ptr() as *mut JsObject)
};
let prototype_obj = self.epoch.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, proto_of_proto));
self.gc_state.track_epoch_object(prototype_obj);
let prototype_val = JsValue::from_js_object(prototype_obj);
let constructor_si = self.kernel_core.perm_interner().intern("constructor").0;
let constructor_shape = self.kernel_core.shape_forge().make_shape(EMPTY_SHAPE_ID, constructor_si);
let prototype = unsafe { &mut *prototype_obj };
prototype.set_shape_id(constructor_shape);
let constructor_pos = prototype.push_prop(func_val);
prototype.set_data_meta(constructor_pos, PropAttributes::new(true, false, true));
prototype.bump_generation();
if !is_generator {
// 普通函数:prototype 对象带 constructor 指回函数。
let constructor_si = self.kernel_core.perm_interner().intern("constructor").0;
let constructor_shape = self.kernel_core.shape_forge().make_shape(EMPTY_SHAPE_ID, constructor_si);
let prototype = unsafe { &mut *prototype_obj };
prototype.set_shape_id(constructor_shape);
let constructor_pos = prototype.push_prop(func_val);
prototype.set_data_meta(constructor_pos, PropAttributes::new(true, false, true));
prototype.bump_generation();
}
// 函数自身 `prototype` 属性:生成器 writable:true / enumerable:false / configurable:false。
let prototype_si = self.kernel_core.perm_interner().intern("prototype").0;
let func = unsafe { &mut *obj_ptr };
let prototype_shape = self.kernel_core.shape_forge().make_shape(func.shape_id(), prototype_si);
func.set_shape_id(prototype_shape);
func.ensure_hash_props().push(prototype_val);
let prototype_pos = func.push_prop(prototype_val);
if is_generator {
func.set_data_meta(prototype_pos, PropAttributes::new(true, false, false));
}
func.bump_generation();
}