mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
feat: try 语句压边界帧,空体内 break/continue 完成值物化 undefined
This commit is contained in:
@@ -19,6 +19,10 @@ impl Emitter {
|
||||
let has_catch = ts.handler.is_some();
|
||||
let has_finally = ts.finalizer.is_some();
|
||||
let result_reg = ctx.alloc_reg();
|
||||
// try 语句整体是 `UpdateEmpty(_, undefined)` 站点:压边界帧,位于
|
||||
// try/catch/finally 三个体列表帧之外,非空内层列表值穿透、空内层体
|
||||
// 携值物化 undefined。
|
||||
ctx.push_completion_boundary();
|
||||
if has_finally {
|
||||
// finally 域跨整个语句(try 体 + catch 体 + finally 体):期间 break/continue
|
||||
// 逃出语句时须穿越本 finally,词法上记录域深度供跨越计数。
|
||||
@@ -144,6 +148,7 @@ impl Emitter {
|
||||
ctx.pop_finally_domain();
|
||||
}
|
||||
ctx.labels.set_label_pos(try_end_label, ctx.insts.len());
|
||||
ctx.pop_completion_boundary();
|
||||
Ok(Some(result_reg))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,6 +328,50 @@ fn compound_statement_completion_values() {
|
||||
assert_num(result, 5.0);
|
||||
let result = eval(&mut vm, "a: { try { throw 1; } catch (e) { 5; break a; } }").unwrap();
|
||||
assert_num(result, 5.0);
|
||||
// try 边界帧:空 catch/finally 体 break/continue 携值物化 undefined(无 if
|
||||
// 守卫独立验收形),非空 finally 体值穿透。
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"for (var i = 0; i < 2; ++i) { try { throw null; } catch (e) { break; } 'bad completion'; }",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result, JsValue::undefined());
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"for (var i = 0; i < 2; ++i) { try { throw null; } catch (e) { continue; } 'bad completion'; }",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result, JsValue::undefined());
|
||||
let result = eval(&mut vm, "for (var i = 0; i < 2; ++i) { try {} finally { break; } 'bad completion'; }").unwrap();
|
||||
assert_eq!(result, JsValue::undefined());
|
||||
let result =
|
||||
eval(&mut vm, "for (var i = 0; i < 2; ++i) { try {} finally { continue; } 'bad completion'; }").unwrap();
|
||||
assert_eq!(result, JsValue::undefined());
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"for (var i = 0; i < 2; ++i) { try { throw null; } catch (e) {} finally { break; } 'bad completion'; }",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result, JsValue::undefined());
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"for (var i = 0; i < 2; ++i) { try { throw null; } catch (e) {} finally { continue; } 'bad completion'; }",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result, JsValue::undefined());
|
||||
// 跨 finally 值通道守卫:非空 finally 体值穿透,空 finally 体物化 undefined。
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"99; do { -99; try { 39 } catch (e) { -1 } finally { 42; break; -2 }; } while (false);",
|
||||
)
|
||||
.unwrap();
|
||||
assert_num(result, 42.0);
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"99; do { -99; try { 39 } catch (e) { -1 } finally { break; -2 }; } while (false);",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result, JsValue::undefined());
|
||||
// for 泄漏形完成值:体不读循环变量加常量尾,取末次迭代体值,前值不沿用。
|
||||
let result = eval(&mut vm, "for (var i = 0; i < 2; ++i) { 42 }").unwrap();
|
||||
assert_num(result, 42.0);
|
||||
|
||||
Reference in New Issue
Block a user