feat: async-generator 语义(async function*),yield/await 共存 + next 返回 Promise

- emit 识别 generator+async 组合,模块同时标记 is_generator/is_async
- 新增 AsyncGeneratorState:帧快照 + 请求队列 + 当前请求
- next/return/throw 返回 Promise,请求入队逐条处理
- YIELD 让出经 promise unwrap 后交付(yield rejected promise 关闭生成器)
- AWAIT 挂起保留当前请求,微任务恢复后继续执行
- %AsyncGeneratorPrototype% / %AsyncGeneratorFunction.prototype% 内建
- session GC / promote 支持异步生成器状态盒
- 普通 async 函数嵌套调用隔离外层异步生成器上下文
This commit is contained in:
2026-08-10 01:52:03 +08:00
parent 85c192a747
commit 5ced83e8c0
15 changed files with 1285 additions and 40 deletions
+21 -8
View File
@@ -686,9 +686,7 @@ impl Emitter {
) -> Result<(), String> {
match argument {
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
out.push(ParamSpec::Rest {
name: bi.name.to_string(),
});
out.push(ParamSpec::Rest { name: bi.name.to_string() });
}
_ => return Err("rest parameters with destructuring patterns not yet supported".into()),
}
@@ -733,7 +731,15 @@ impl Emitter {
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
is_expression_body: bool, is_arrow: bool,
) -> Result<IRFunction, String> {
self.compile_function_body_with_flags(param_specs, body_stmts, parent_ctx, is_expression_body, is_arrow, false, false)
self.compile_function_body_with_flags(
param_specs,
body_stmts,
parent_ctx,
is_expression_body,
is_arrow,
false,
false,
)
}
/// 编译函数体并显式指定生成器标志(`function*` 走此入口)。
@@ -743,6 +749,15 @@ impl Emitter {
self.compile_function_body_with_flags(param_specs, body_stmts, parent_ctx, false, false, true, false)
}
/// 编译异步生成器函数体(`async function*` / async 生成器表达式走此入口):
/// 同时标记 `is_generator` 与 `is_async`,VM 调用时按异步生成器协议执行
/// (next 返回 Promise,yield 挂起与 await 挂起共存)。
pub(crate) fn compile_async_generator_body<'a>(
&self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx,
) -> Result<IRFunction, String> {
self.compile_function_body_with_flags(param_specs, body_stmts, parent_ctx, false, false, true, true)
}
/// 编译异步函数体(`async function` / async 箭头走此入口):`is_async` 使
/// `assemble_ir` 标记模块,VM 调用时按异步函数协议执行。
pub(crate) fn compile_async_body<'a>(
@@ -1110,10 +1125,8 @@ impl Emitter {
ParamSpec::Rest { name } => {
// rest 数组:从实参区收集固定形参之后的实参,绑定为普通变量。
let reg = ctx.lookup(name)?;
let fixed_count = param_specs
.iter()
.filter(|s| !matches!(s, ParamSpec::Rest { .. }))
.count() as u32;
let fixed_count =
param_specs.iter().filter(|s| !matches!(s, ParamSpec::Rest { .. })).count() as u32;
ctx.inst(Inst::create_rest_array(Operand::Reg(reg), fixed_count));
}
}
+3 -1
View File
@@ -81,7 +81,9 @@ impl Emitter {
let body_stmts: &[Statement] = if let Some(body) = &fe.body { &body.statements } else { &[] };
let mut sub_module = if fe.generator {
let mut sub_module = if fe.generator && fe.r#async {
self.compile_async_generator_body(&param_names, body_stmts, ctx)?
} else if fe.generator {
self.compile_generator_body(&param_names, body_stmts, ctx)?
} else if fe.r#async {
self.compile_async_body(&param_names, body_stmts, ctx, false, false)?
@@ -36,7 +36,9 @@ impl Emitter {
self.push_rest_param(&rest.rest.argument, &mut param_names)?;
}
let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] };
let mut sub_module = if fd.generator {
let mut sub_module = if fd.generator && fd.r#async {
self.compile_async_generator_body(&param_names, body_stmts, ctx)?
} else if fd.generator {
self.compile_generator_body(&param_names, body_stmts, ctx)?
} else if fd.r#async {
self.compile_async_body(&param_names, body_stmts, ctx, false, false)?
+8
View File
@@ -404,6 +404,9 @@ impl JsObject {
pub const OBJ_TYPE_PROMISE: u8 = 11;
/// 异步函数执行上下文(隐藏对象):`AsyncState` 快照存于 `native_data`。
pub const OBJ_TYPE_ASYNC: u8 = 12;
/// 异步生成器迭代器对象(`async function*` 调用返回):`AsyncGeneratorState`
/// 快照存于 `native_data`。
pub const OBJ_TYPE_ASYNC_GENERATOR: u8 = 13;
/// `is_session_epoch` 字段中的 session 标记位。
pub const SESSION_EPOCH_BIT: u8 = 0x01;
/// `is_session_epoch` 字段中的 GC 标记位。
@@ -464,6 +467,11 @@ impl JsObject {
pub fn is_async_obj(&self) -> bool {
self.type_tag == Self::OBJ_TYPE_ASYNC
}
/// 是否异步生成器迭代器对象。
#[inline]
pub fn is_async_generator_obj(&self) -> bool {
self.type_tag == Self::OBJ_TYPE_ASYNC_GENERATOR
}
/// 构造无属性、可扩展的空对象(`new Object()` 的基础对象)。
pub fn new_empty(shape_id: ShapeId, proto: JsValue) -> Self {
+37 -22
View File
@@ -87,7 +87,7 @@ pub(crate) enum AsyncResumeMode {
}
/// 异步上下文对象上存 capability 闭包的属性名(await 恢复闭包定位上下文用)。
const ASYNC_CTX_PROP: &str = "__oxide_async_ctx__";
pub(crate) const ASYNC_CTX_PROP: &str = "__oxide_async_ctx__";
/// 恢复闭包上区分 reject 角色的属性名。
const ASYNC_REJECT_PROP: &str = "__oxide_async_reject__";
@@ -167,7 +167,11 @@ impl Vm {
self.async_suspended = false;
let prev_ctx = self.async_context.take();
let prev_dispatch = self.async_dispatch;
let prev_gen_ctx = self.async_gen_context.take();
let prev_gen_dispatch = self.async_gen_dispatch;
self.async_dispatch = true;
// 普通异步函数执行期间 AWAIT 走普通异步恢复路径:屏蔽外层异步生成器上下文。
self.async_gen_dispatch = false;
self.async_context = Some(ctx_val);
self.native_call_depth += 1;
@@ -200,8 +204,7 @@ impl Vm {
);
unsafe { (*state_ptr).args = args };
if let Err(e) = push_res {
self.async_dispatch = prev_dispatch;
self.async_context = prev_ctx;
self.restore_async_flags(prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch);
self.native_call_depth -= 1;
self.restore_inline_state(saved);
return Err(e);
@@ -209,8 +212,7 @@ impl Vm {
unsafe { (*state_ptr).phase = AsyncPhase::Running };
let result = self.dispatch();
self.async_dispatch = prev_dispatch;
self.async_context = prev_ctx;
self.restore_async_flags(prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch);
self.native_call_depth -= 1;
if std::mem::take(&mut self.async_suspended) {
@@ -251,7 +253,11 @@ impl Vm {
self.async_suspended = false;
let prev_ctx = self.async_context.take();
let prev_dispatch = self.async_dispatch;
let prev_gen_ctx = self.async_gen_context.take();
let prev_gen_dispatch = self.async_gen_dispatch;
self.async_dispatch = true;
// 普通异步函数执行期间 AWAIT 走普通异步恢复路径:屏蔽外层异步生成器上下文。
self.async_gen_dispatch = false;
self.async_context = Some(ctx_val);
self.native_call_depth += 1;
@@ -265,8 +271,7 @@ impl Vm {
self.activate_immutables(state.sub_idx as usize, &subs[state.sub_idx as usize].constants);
} else {
// 挂起状态跨 run:sub_modules 已重建,无法恢复(与生成器同限制)。
self.async_dispatch = prev_dispatch;
self.async_context = prev_ctx;
self.restore_async_flags(prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch);
self.native_call_depth -= 1;
self.restore_inline_state(saved);
return Err("async function suspended across runs is no longer valid".into());
@@ -300,8 +305,7 @@ impl Vm {
self.pending_error_kind = Some(self.thrown_error_kind(exc));
if self.unwind().is_err() {
// 异常逃逸出异步帧(无 catch/finally):结算为 reject。
self.async_dispatch = prev_dispatch;
self.async_context = prev_ctx;
self.restore_async_flags(prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch);
self.native_call_depth -= 1;
let thrown = self.last_uncaught_value.take().unwrap_or(exc);
self.finish_async(state_ptr, Err(thrown))?;
@@ -313,8 +317,7 @@ impl Vm {
}
let result = self.dispatch();
self.async_dispatch = prev_dispatch;
self.async_context = prev_ctx;
self.restore_async_flags(prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch);
self.native_call_depth -= 1;
if std::mem::take(&mut self.async_suspended) {
@@ -342,6 +345,17 @@ impl Vm {
}
}
/// 恢复嵌套 dispatch 覆盖的 async 上下文标志(含外层异步生成器上下文)。
fn restore_async_flags(
&mut self, prev_ctx: Option<JsValue>, prev_dispatch: bool, prev_gen_ctx: Option<JsValue>,
prev_gen_dispatch: bool,
) {
self.async_dispatch = prev_dispatch;
self.async_context = prev_ctx;
self.async_gen_dispatch = prev_gen_dispatch;
self.async_gen_context = prev_gen_ctx;
}
/// 结算异步函数:正常结束 resolve capability,异常结束 reject capability。
fn finish_async(&mut self, state_ptr: *mut AsyncState, outcome: Result<JsValue, JsValue>) -> Result<(), String> {
let (promise, value) = {
@@ -374,6 +388,8 @@ impl Vm {
/// # 副作用
/// - 被等待值为原生 Promise 时直接复用,否则建新 promise 并 PromiseResolve。
/// - 经 `perform_promise_then` 登记 fulfill/reject 恢复反应(微任务入队)。
/// - 异步生成器内(`async_gen_dispatch`)登记异步生成器恢复闭包并置
/// `async_gen_suspended`;普通异步函数走 `async_suspended`。
pub(crate) fn dispatch_await(&mut self, rd: usize) -> Result<(), String> {
let ctx = match self.async_context {
Some(c) => c,
@@ -387,6 +403,13 @@ impl Vm {
let _ = self.resolve_promise(p, value);
p
};
if self.async_gen_dispatch {
let fulfill_fn = self.make_async_gen_await_resume_fn(ctx, false);
let reject_fn = self.make_async_gen_await_resume_fn(ctx, true);
let _ = self.perform_promise_then(promise, fulfill_fn, reject_fn);
self.async_gen_suspended = true;
return Ok(());
}
let fulfill_fn = self.make_async_await_resume_fn(ctx, false);
let reject_fn = self.make_async_await_resume_fn(ctx, true);
let _ = self.perform_promise_then(promise, fulfill_fn, reject_fn);
@@ -416,10 +439,7 @@ impl Vm {
///
/// 异步帧弹出存 `frame`,其余栈段整段搬入(嵌套循环期间这些栈只含异步数据)。
fn snapshot_async(&mut self, state: &mut AsyncState) -> Result<(), String> {
let frame = self
.frames
.pop()
.ok_or_else(|| "async frame missing on await".to_string())?;
let frame = self.frames.pop().ok_or_else(|| "async frame missing on await".to_string())?;
state.frame = Some(frame);
state.regs = Box::new(self.regs);
state.pc = self.pc;
@@ -459,9 +479,7 @@ fn async_await_resume_closure(vm: &mut Vm, args: &[u8]) -> NativeResult {
let ctx_si = vm.kernel_core.perm_interner().intern(ASYNC_CTX_PROP).0;
let ctx = vm.resolve_property(callee_obj, ctx_si).unwrap_or(JsValue::undefined());
let role_si = vm.kernel_core.perm_interner().intern(ASYNC_REJECT_PROP).0;
let is_reject = vm
.resolve_property(callee_obj, role_si)
.map_or(false, to_boolean);
let is_reject = vm.resolve_property(callee_obj, role_si).map_or(false, to_boolean);
let value = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
let mode = if is_reject {
AsyncResumeMode::Throw(value)
@@ -520,10 +538,7 @@ pub(crate) fn init_async_intrinsics(vm: &mut Vm) {
/// `%AsyncFunction%` 占位:动态异步函数创建未实现,调用抛错。
fn async_function_stub(vm: &mut Vm, _args: &[u8]) -> NativeResult {
NativeResult::Err(oxide_builtins::error::create_type_error(
vm,
"AsyncFunction constructor is not supported",
))
NativeResult::Err(oxide_builtins::error::create_type_error(vm, "AsyncFunction constructor is not supported"))
}
// ── session GC 支撑:状态快照中的 JsValues 作为异步上下文对象边追踪 ──
File diff suppressed because it is too large Load Diff
+9
View File
@@ -742,6 +742,15 @@ impl Vm {
}
} else if obj.sub_module_index() > 0 {
let sub_idx = obj.sub_module_index() as usize;
// 异步生成器函数调用返回异步生成器迭代器对象。
if sub_idx < self.sub_modules.len()
&& self.sub_modules[sub_idx].is_generator
&& self.sub_modules[sub_idx].is_async
{
let gen = self.create_async_generator_object(callee, this_value, &args)?;
self.regs[0] = gen;
return Ok(false);
}
// 生成器函数调用返回迭代器对象,不执行函数体。
if sub_idx < self.sub_modules.len() && self.sub_modules[sub_idx].is_generator {
let gen = self.create_generator_object(callee, this_value, &args)?;
+3 -4
View File
@@ -108,7 +108,7 @@ pub(crate) enum YieldStarOutcome {
}
/// `yield*` 委托转发(生成器恢复时)的结局。
enum DelegateOutcome {
pub(crate) enum DelegateOutcome {
/// 内层未 done:保持委托挂起,让出 value。
Suspend { value: JsValue },
/// 内层消化 next/throw 后 done:委托结束,外层继续,value 为委托值。
@@ -605,7 +605,7 @@ impl Vm {
/// # 副作用
/// - 内层调用抛错时经 unwind 展开(可被外层 catch/finally 捕获,返回 Unwind)。
/// - 委托结束时清空 `self.delegated_iterator`,挂起透传时保留。
fn delegate_forward(&mut self, mode: GeneratorResumeMode) -> Result<DelegateOutcome, String> {
pub(crate) fn delegate_forward(&mut self, mode: GeneratorResumeMode) -> Result<DelegateOutcome, String> {
let iterator = match self.delegated_iterator {
Some(it) => it,
None => return Ok(DelegateOutcome::Unwind),
@@ -787,8 +787,7 @@ impl Vm {
/// # 返回值
/// - `Ok(Some(value))`:直接完成,无需再 dispatch(`value` 为返回值);
/// - `Ok(None)`:进入 finally 穿越,调用方须继续 `dispatch()`。
fn complete_generator_return(&mut self, value: JsValue) -> Result<Option<JsValue>, String> {
// return 逃出当前帧:弹出纯 catch handler,穿越 finally。
pub(crate) fn complete_generator_return(&mut self, value: JsValue) -> Result<Option<JsValue>, String> {
self.pop_frame_catch_handlers();
let crossed = self
.try_stack
+2 -1
View File
@@ -7,9 +7,10 @@
//! 核心入口为 [`vm::Vm`];`VmPool` 负责 VM 实例的复用;`session_gc` 提供
//! session 内存回收;`bindings` 把内置对象绑定到每个 session 的 global 上。
mod async_func;
mod async_generator;
/// 内置对象绑定模块:向 session 的 global 对象安装 Object/Array/... 及各原型。
pub mod bindings;
mod async_func;
mod dispatch;
mod generator;
mod ic_helper;
+5
View File
@@ -80,6 +80,11 @@ impl Vm {
crate::async_func::clone_async_native_with_rewrite(src_ref, dst_ref, |value| {
self.promote_value_if_epoch_object(value, forwarding)
});
} else if src_ref.is_async_generator_obj() {
// 异步生成器状态盒深拷贝到新对象:源盒随 epoch 释放,互不共享。
crate::async_generator::clone_async_generator_native_with_rewrite(src_ref, dst_ref, |value| {
self.promote_value_if_epoch_object(value, forwarding)
});
}
dst
}
+17
View File
@@ -98,6 +98,9 @@ impl SessionGc {
if obj.is_async_obj() {
edges.extend(crate::async_func::async_native_edges(obj));
}
if obj.is_async_generator_obj() {
edges.extend(crate::async_generator::async_generator_native_edges(obj));
}
// 遍历 upvalue cell 中的对象引用。
for cell_ptr in obj.upvalues_slice() {
if cell_ptr.is_null() {
@@ -174,6 +177,13 @@ impl SessionGc {
}
}
}
if obj.is_async_generator_obj() {
for value in crate::async_generator::async_generator_native_edges(obj) {
if value.is_string() {
live.insert(value.as_string_ptr_mut());
}
}
}
}
pub(crate) fn mark(&mut self, vm: &Vm) {
@@ -286,6 +296,7 @@ impl SessionGc {
freed_bytes += crate::generator::drop_generator_native(obj);
freed_bytes += crate::promise::drop_promise_native(obj);
freed_bytes += crate::async_func::drop_async_native(obj);
freed_bytes += crate::async_generator::drop_async_generator_native(obj);
freed_bytes
}
@@ -346,6 +357,8 @@ impl SessionGc {
crate::promise::clone_promise_native_with_rewrite(old_ref, new_ref, |value| value);
} else if old_ref.is_async_obj() {
crate::async_func::clone_async_native_with_rewrite(old_ref, new_ref, |value| value);
} else if old_ref.is_async_generator_obj() {
crate::async_generator::clone_async_generator_native_with_rewrite(old_ref, new_ref, |value| value);
}
forwarding.insert(old_ptr, new_ptr);
freed_bytes += Self::drop_session_object_heap_data(old_ptr);
@@ -381,6 +394,10 @@ impl SessionGc {
crate::promise::rewrite_promise_native(obj, |value| rewrite_forwarded_value(value, &forwarding));
} else if obj.is_async_obj() {
crate::async_func::rewrite_async_native(obj, |value| rewrite_forwarded_value(value, &forwarding));
} else if obj.is_async_generator_obj() {
crate::async_generator::rewrite_async_generator_native(obj, |value| {
rewrite_forwarded_value(value, &forwarding)
});
}
}
+14
View File
@@ -256,6 +256,10 @@ pub struct Vm {
pub aggregate_error_proto: P<JsObject>,
/// `%AsyncFunction.prototype%`:异步函数对象的原型(`constructor` 指向 `%AsyncFunction%`)。
pub async_function_proto: P<JsObject>,
/// `%AsyncGeneratorPrototype%`:异步生成器实例的原型(next/return/throw/@@asyncIterator)。
pub async_generator_proto: P<JsObject>,
/// `%AsyncGeneratorFunction.prototype%`:异步生成器函数对象的原型。
pub async_generator_function_proto: P<JsObject>,
/// 微任务队列(Promise reactions / thenable 委托),`run()` 末尾 FIFO drain。
pub(crate) job_queue: VecDeque<crate::promise::Microtask>,
pub math_rng_state: u64,
@@ -318,6 +322,16 @@ pub struct Vm {
/// 当前是否处于异步函数内嵌 dispatch 循环:异步帧弹出且 frames 清空时,
/// `do_return` 据此把结果交付给恢复方(与 generator_dispatch 同语义)。
pub(crate) async_dispatch: bool,
/// 当前正在执行的异步生成器上下文对象(`OBJ_TYPE_ASYNC_GENERATOR`,持有
/// `AsyncGeneratorState` 快照)。AWAIT dispatch 据此登记异步生成器恢复反应;
/// 跨嵌套 async 调用保存/恢复(与 `async_context` 同生命周期,二者互斥占用)。
pub(crate) async_gen_context: Option<JsValue>,
/// 当前是否处于异步生成器内嵌 dispatch 循环:AWAIT 据此走异步生成器恢复
/// 闭包;yield 让出复用 `generator_suspended` 信号。
pub(crate) async_gen_dispatch: bool,
/// 异步生成器 body `dispatch()` 的 AWAIT 让出信号:置 true 表示挂起在 await,
/// 恢复方(异步生成器内嵌 dispatch 循环)据此快照挂起状态。
pub(crate) async_gen_suspended: bool,
/// 分组保存 session arena / GC 簿记状态。
pub(crate) gc_state: GcState,
/// 分组保存 `Symbol` intern 状态。
+10
View File
@@ -35,6 +35,16 @@ impl Vm {
let args: Vec<JsValue> = (0..arg_count)
.map(|i| self.regs[first_arg_reg.wrapping_add(i as u8) as usize])
.collect();
// 异步生成器函数调用返回异步生成器迭代器对象。
if sub_idx < self.sub_modules.len()
&& self.sub_modules[sub_idx].is_generator
&& self.sub_modules[sub_idx].is_async
{
let gen =
self.create_async_generator_object(callee, self.regs[this_reg as usize], &args)?;
self.regs[0] = gen;
return Ok(false);
}
// 生成器函数调用返回迭代器对象,不执行函数体。
if sub_idx < self.sub_modules.len() && self.sub_modules[sub_idx].is_generator {
let gen = self.create_generator_object(callee, self.regs[this_reg as usize], &args)?;
+4
View File
@@ -112,6 +112,10 @@ impl Vm {
self.raise_error_kind("RangeError", "Maximum call stack size exceeded")?;
return Ok(JsValue::undefined());
}
// 异步生成器函数调用返回异步生成器迭代器对象,next/return/throw 返回 Promise。
if self.sub_modules[sub_idx].is_generator && self.sub_modules[sub_idx].is_async {
return self.create_async_generator_object(callee, receiver, args);
}
// 生成器函数调用返回迭代器对象,不执行函数体。
if self.sub_modules[sub_idx].is_generator {
return self.create_generator_object(callee, receiver, args);
+34 -3
View File
@@ -40,6 +40,8 @@ impl Vm {
aggregate_error_constructor: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
aggregate_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
async_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
async_generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
async_generator_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
job_queue: VecDeque::new(),
math_rng_state: 0,
sub_modules: Arc::new(Vec::new()),
@@ -68,6 +70,9 @@ impl Vm {
async_context: None,
async_suspended: false,
async_dispatch: false,
async_gen_context: None,
async_gen_dispatch: false,
async_gen_suspended: false,
gc_state: GcState {
session_epoch: bumpalo::Bump::new(),
session_gc: crate::session_gc::SessionGc::new(),
@@ -98,6 +103,7 @@ impl Vm {
vm.init_generator_intrinsics();
vm.init_promise_intrinsics();
vm.init_async_intrinsics();
vm.init_async_generator_intrinsics();
// Promise 全局绑定发生在快照采集之后,重录快照避免首次 full_reset 误判脏。
vm.session.record_snapshot();
vm_info!("Vm created");
@@ -127,6 +133,8 @@ impl Vm {
aggregate_error_constructor: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
aggregate_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
async_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
async_generator_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
async_generator_function_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
job_queue: VecDeque::new(),
math_rng_state: 0,
sub_modules: Arc::new(Vec::new()),
@@ -155,6 +163,9 @@ impl Vm {
async_context: None,
async_suspended: false,
async_dispatch: false,
async_gen_context: None,
async_gen_dispatch: false,
async_gen_suspended: false,
gc_state: GcState {
session_epoch: bumpalo::Bump::new(),
session_gc: crate::session_gc::SessionGc::new(),
@@ -185,6 +196,7 @@ impl Vm {
vm.init_generator_intrinsics();
vm.init_promise_intrinsics();
vm.init_async_intrinsics();
vm.init_async_generator_intrinsics();
// Promise 全局绑定发生在快照采集之后,重录快照避免首次 full_reset 误判脏。
vm.session.record_snapshot();
vm_info!("Vm created (pool)");
@@ -206,6 +218,14 @@ impl Vm {
crate::async_func::init_async_intrinsics(self);
}
/// 初始化/重建异步生成器内建对象(`%AsyncGeneratorPrototype%` 与
/// `%AsyncGeneratorFunction.prototype%`)。
///
/// 在 VM 创建与 `full_reset`(session 重建)后调用。
pub(crate) fn init_async_generator_intrinsics(&mut self) {
crate::async_generator::init_async_generator_intrinsics(self);
}
/// 全量隔离重置:仅重建被污染的内置对象与 global,并清空所有执行状态与内存。
///
/// 用于在多次 JS 执行之间达到完全隔离:session 内未被污染的 builtin 保留原指针。
@@ -223,6 +243,7 @@ impl Vm {
self.init_generator_intrinsics();
self.init_promise_intrinsics();
self.init_async_intrinsics();
self.init_async_generator_intrinsics();
// 快照须在 Promise 全局绑定之后采集:绑定会修改 global 世代。
self.session.record_snapshot();
self.clear_full_reset_state();
@@ -238,6 +259,7 @@ impl Vm {
self.init_generator_intrinsics();
self.init_promise_intrinsics();
self.init_async_intrinsics();
self.init_async_generator_intrinsics();
self.session.record_snapshot();
self.clear_full_reset_state();
}
@@ -300,6 +322,9 @@ impl Vm {
self.async_context = None;
self.async_suspended = false;
self.async_dispatch = false;
self.async_gen_context = None;
self.async_gen_dispatch = false;
self.async_gen_suspended = false;
self.native_call_depth = 0;
// 微任务队列是执行期状态:跨 run 不保留。
self.job_queue.clear();
@@ -370,7 +395,11 @@ impl Vm {
// "GeneratorFunction"),且不像普通函数那样拥有 `prototype` 属性。
let is_generator = self.sub_modules.get(sub_idx as usize).map(|m| m.is_generator).unwrap_or(false);
let is_async = self.sub_modules.get(sub_idx as usize).map(|m| m.is_async).unwrap_or(false);
let proto_val = if is_generator {
// 异步生成器(`async function*`)函数对象:原型为 %AsyncGeneratorFunction.prototype%。
let is_async_generator = is_generator && is_async;
let proto_val = if is_async_generator {
JsValue::from_js_object(self.async_generator_function_proto.as_ptr() as *mut JsObject)
} else if is_generator {
JsValue::from_js_object(self.generator_function_proto.as_ptr() as *mut JsObject)
} else if is_async {
JsValue::from_js_object(self.async_function_proto.as_ptr() as *mut JsObject)
@@ -392,7 +421,9 @@ impl Vm {
if !is_arrow {
// 原型对象自身的 [[Prototype]]:生成器为 %GeneratorPrototype%,普通函数为 Object.prototype。
let proto_of_proto = if is_generator {
let proto_of_proto = if is_async_generator {
JsValue::from_js_object(self.async_generator_proto.as_ptr() as *mut JsObject)
} else 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)
@@ -418,7 +449,7 @@ impl Vm {
let prototype_shape = self.kernel_core.shape_forge().make_shape(func.shape_id(), prototype_si);
func.set_shape_id(prototype_shape);
let prototype_pos = func.push_prop(prototype_val);
if is_generator {
if is_generator || is_async_generator {
func.set_data_meta(prototype_pos, PropAttributes::new(true, false, false));
}
func.bump_generation();