mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
feat: eval 代码块函数早期错误跳过不建绑定
This commit is contained in:
Generated
+21
-21
@@ -1160,7 +1160,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_builtins"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"fast-float",
|
||||
@@ -1185,7 +1185,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_bytecode"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxide_log",
|
||||
@@ -1193,7 +1193,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_cfg"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_emit",
|
||||
@@ -1204,7 +1204,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_cli"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"bumpalo",
|
||||
@@ -1228,7 +1228,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_code_cache"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"lru",
|
||||
"oxide_bytecode",
|
||||
@@ -1237,7 +1237,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_compiler"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1258,7 +1258,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_dce"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1272,7 +1272,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_emit"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxc_allocator",
|
||||
@@ -1288,7 +1288,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_engine"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_compiler",
|
||||
@@ -1300,7 +1300,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_fold"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"oxide_bytecode",
|
||||
@@ -1312,7 +1312,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_ir"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_log",
|
||||
@@ -1321,7 +1321,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_kernel"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"dashmap",
|
||||
@@ -1335,7 +1335,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_liveness"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1347,7 +1347,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_log"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
@@ -1356,11 +1356,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_net"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
|
||||
[[package]]
|
||||
name = "oxide_parser"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxc_allocator",
|
||||
"oxc_ast",
|
||||
@@ -1375,7 +1375,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_regalloc"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_cfg",
|
||||
@@ -1391,7 +1391,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_runtime_api"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
@@ -1404,7 +1404,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_test262"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"oxide_bytecode",
|
||||
"oxide_compiler",
|
||||
@@ -1424,7 +1424,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_types"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"dashmap",
|
||||
@@ -1437,7 +1437,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxide_vm"
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"chrono",
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.19.37"
|
||||
version = "0.19.38"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
rust-version = "1.80"
|
||||
|
||||
@@ -954,6 +954,14 @@ impl CompileCtx {
|
||||
NON_WRITABLE_GLOBAL_BUILTINS.contains(&name)
|
||||
}
|
||||
|
||||
/// 早期错误跳过谓词(Annex B.3.3.3 对 EvalDeclarationInstantiation 的增补):
|
||||
/// sloppy eval 代码内块函数声明的名若与同树词法声明/形参同名,替换为变量
|
||||
/// 语句即产生早期错误,规范不为其建任何绑定——函数体只求值副作用,不写块
|
||||
/// Let、不写外层 var、不写全局对象属性。预声明门与存储臂共用本谓词。
|
||||
pub(crate) fn is_eval_early_error_suppressed(&self, name: &str) -> bool {
|
||||
self.is_eval_script && !self.is_strict && self.block_fn_suppressed.contains(name)
|
||||
}
|
||||
|
||||
/// 进入 with 语句体:记录对象寄存器与当前作用域深度,供动态标识符解析。
|
||||
pub(crate) fn push_with(&mut self, obj_reg: u32) {
|
||||
let depth = self.scopes.symbols.scopes.len();
|
||||
|
||||
@@ -230,7 +230,13 @@ impl Emitter {
|
||||
let Some(identifier) = &f.id else {
|
||||
continue;
|
||||
};
|
||||
if if_arm && Self::if_arm_has_outer_var_carrier(ctx, identifier.name.as_str()) {
|
||||
// 早期错误跳过(Annex B.3.3.3):sloppy eval 代码内支臂函数名撞
|
||||
// 同树词法声明时不建块 Let 绑定,使词法预声明不撞名报重复声明
|
||||
// 错(函数体只求值副作用,不写任何绑定)。
|
||||
if if_arm
|
||||
&& (Self::if_arm_has_outer_var_carrier(ctx, identifier.name.as_str())
|
||||
|| ctx.is_eval_early_error_suppressed(identifier.name.as_str()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let reg = ctx.alloc_reg();
|
||||
|
||||
@@ -40,10 +40,16 @@ impl Emitter {
|
||||
// 其余 sub-pass 发的函数声明皆为块级(if/while/for/switch/try 支臂与块直接子)。
|
||||
let is_block_function = !ctx.in_hoisting_subpass;
|
||||
let var_reg = if is_block_function {
|
||||
match ctx.block_fn_entry_mats.last().and_then(|m| m.get(&name)) {
|
||||
Some(&m) if m == node => ctx.lookup(&name)?,
|
||||
Some(_) => self.materialize_function_declaration_var_only(fd, &name, ctx, true)?,
|
||||
None => self.materialize_function_declaration(fd, &name, ctx, true)?,
|
||||
if ctx.is_eval_early_error_suppressed(&name) {
|
||||
// 早期错误跳过(Annex B.3.3.3):不写入任何绑定,函数体只求值
|
||||
// 副作用(CREATE_CLOSURE 照发,结果寄存器丢弃,不发 STORE_VAR)。
|
||||
self.materialize_function_declaration_var_only(fd, &name, ctx, true)?
|
||||
} else {
|
||||
match ctx.block_fn_entry_mats.last().and_then(|m| m.get(&name)) {
|
||||
Some(&m) if m == node => ctx.lookup(&name)?,
|
||||
Some(_) => self.materialize_function_declaration_var_only(fd, &name, ctx, true)?,
|
||||
None => self.materialize_function_declaration(fd, &name, ctx, true)?,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.materialize_function_declaration(fd, &name, ctx, false)?
|
||||
|
||||
@@ -411,6 +411,31 @@ fn block_fn_suppressed_by_destructured_param_leaf() {
|
||||
);
|
||||
}
|
||||
|
||||
/// 面 22:Annex B.3.3.3 早期错误跳过——sloppy eval 代码内块函数名撞同树词法
|
||||
/// 声明时编译不报重复声明错,且函数声明不覆写词法绑定(STORE_VAR 少一条写回)。
|
||||
#[test]
|
||||
fn eval_early_error_skip_no_binding() {
|
||||
// base 形:碰撞在 eval 顶层 let。编译成功且函数不覆写词法绑定。
|
||||
let alloc = oxide_parser::Allocator::default();
|
||||
let program = oxide_parser::parse(&alloc, "let f = 123; if (true) function f() {}").unwrap();
|
||||
let ir = Emitter::new()
|
||||
.emit_program(&program, false, true)
|
||||
.unwrap_or_else(|e| panic!("base 形应编译成功:{e}"));
|
||||
// `let f = 123` 初始化写(1)+ 函数声明不覆写词法绑定(0)= 1。
|
||||
assert_eq!(
|
||||
count_op(&ir.insts, OpCode::STORE_VAR),
|
||||
1,
|
||||
"早期错误跳过:函数声明不覆写词法绑定"
|
||||
);
|
||||
|
||||
// -block 形:碰撞在同块 let。编译不报「Identifier has already been declared」。
|
||||
let alloc = oxide_parser::Allocator::default();
|
||||
let program = oxide_parser::parse(&alloc, "{ let f = 123; if (true) function f() {} }").unwrap();
|
||||
let _ir = Emitter::new()
|
||||
.emit_program(&program, false, true)
|
||||
.unwrap_or_else(|e| panic!("-block 形应编译成功:{e}"));
|
||||
}
|
||||
|
||||
/// 面 14:双常量折叠入口结构回归——双字面量算术编译后目标操作码计数为 0、
|
||||
/// 常量池含折值,锁死折叠入口不随后续重构丢失。
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user