mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
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:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(¶m_names, body_stmts, ctx)?
|
||||
} else if fe.generator {
|
||||
self.compile_generator_body(¶m_names, body_stmts, ctx)?
|
||||
} else if fe.r#async {
|
||||
self.compile_async_body(¶m_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(¶m_names, body_stmts, ctx)?
|
||||
} else if fd.generator {
|
||||
self.compile_generator_body(¶m_names, body_stmts, ctx)?
|
||||
} else if fd.r#async {
|
||||
self.compile_async_body(¶m_names, body_stmts, ctx, false, false)?
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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)?;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 状态。
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user