Skip to content

Commit 3b4ed23

Browse files
committed
Implement VM await suspension and async regression fixes
- add a dedicated Await opcode and default chunk initialization - lower await and for-await through bytecode suspension points - track async function state and resume execution with restored try frames - route promise callbacks through shared callable dispatch and assimilate thenables - preserve top-level block aliases during compilation in strict contexts - await explicit completion promises in async regression scripts and Rust tests
1 parent d158049 commit 3b4ed23

6 files changed

Lines changed: 561 additions & 349 deletions

File tree

js-scripts/async_n_throw_async_tests_regression.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,6 @@ async function runRegressionTest() {
276276

277277
}
278278

279-
(async function () {
279+
globalThis.__async_regression_done = (async function () {
280280
await runRegressionTest();
281281
})();

js-scripts/var_scope_await_regression.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ async function run() {
99
globalThis.__var_scope_result = typeof a;
1010
}
1111

12-
(async function () { await run(); return true; })();
12+
globalThis.__var_scope_done = (async function () { await run(); return true; })();

src/core/compiler.rs

Lines changed: 169 additions & 46 deletions
Large diffs are not rendered by default.

src/core/opcode.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ pub enum Opcode {
9292
ValidateProtoValue = 86, // validate TOS is object or null (for class extends prototype check); throws TypeError if not
9393
GetSuperPropertyComputed = 87, // computed super property: pop key from stack, look up on super prototype
9494
ThrowTypeError = 88, // pop message string from stack, construct TypeError, handle_throw
95+
Await = 89, // async suspension point: pop awaited value and resume in a microtask
9596
}
9697

9798
impl TryFrom<u8> for Opcode {
@@ -188,14 +189,15 @@ impl TryFrom<u8> for Opcode {
188189
86 => Opcode::ValidateProtoValue,
189190
87 => Opcode::GetSuperPropertyComputed,
190191
88 => Opcode::ThrowTypeError,
192+
89 => Opcode::Await,
191193
_ => return Err(crate::raise_syntax_error!(format!("Unknown opcode: {byte}"))),
192194
};
193195
Ok(v)
194196
}
195197
}
196198

197199
/// Bytecode chunk (stores instruction array and constant pool)
198-
#[derive(Debug, Clone)]
200+
#[derive(Debug, Clone, Default)]
199201
pub struct Chunk<'gc> {
200202
pub code: Vec<u8>,
201203
pub constants: Vec<Value<'gc>>,
@@ -227,22 +229,7 @@ pub struct Chunk<'gc> {
227229

228230
impl<'gc> Chunk<'gc> {
229231
pub fn new() -> Self {
230-
Self {
231-
code: Vec::new(),
232-
constants: Vec::new(),
233-
fn_names: std::collections::HashMap::new(),
234-
fn_lengths: std::collections::HashMap::new(),
235-
class_constructor_ips: std::collections::HashSet::new(),
236-
derived_constructor_ips: std::collections::HashSet::new(),
237-
fn_strictness: std::collections::HashMap::new(),
238-
async_function_ips: std::collections::HashSet::new(),
239-
arrow_function_ips: std::collections::HashSet::new(),
240-
fn_local_names: std::collections::HashMap::new(),
241-
call_callee_names: std::collections::HashMap::new(),
242-
generator_function_ips: std::collections::HashSet::new(),
243-
method_function_ips: std::collections::HashSet::new(),
244-
line_map: Vec::new(),
245-
}
232+
Self::default()
246233
}
247234

248235
pub fn write_byte(&mut self, byte: u8) {

0 commit comments

Comments
 (0)