From 9b2ac86dbe0a41b3e5f82f822be506a9667d16ed Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Wed, 7 Oct 2026 02:53:42 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20realm=20=E7=BC=96=E5=8F=B7=E5=8A=A0=2051?= =?UTF-8?q?2=20=E4=B8=8A=E7=95=8C=E6=96=AD=E8=A8=80=E5=B9=B6=E9=99=8D=20ke?= =?UTF-8?q?rnel=20=E9=87=8D=E5=BB=BA=E7=BC=BA=E7=9C=81=E9=98=B2=E7=AC=A6?= =?UTF-8?q?=E5=8F=B7=E9=94=AE=E7=A2=B0=E6=92=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 36 ++++++++--------- Cargo.toml | 2 +- crates/oxide_kernel/src/kernel/core.rs | 15 +++++-- crates/oxide_test262/src/config.rs | 2 +- crates/oxide_test262/src/main.rs | 4 +- crates/oxide_types/src/private_key/tests.rs | 44 +++++++++++++++++++++ 6 files changed, 78 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa97eb34..be94d91a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "oxide_builtins" -version = "0.8.51" +version = "0.8.52" dependencies = [ "chrono", "fast-float", @@ -1185,7 +1185,7 @@ dependencies = [ [[package]] name = "oxide_bytecode" -version = "0.8.51" +version = "0.8.52" dependencies = [ "num-bigint", "oxide_log", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "oxide_cfg" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxide_bytecode", "oxide_emit", @@ -1204,7 +1204,7 @@ dependencies = [ [[package]] name = "oxide_cli" -version = "0.8.51" +version = "0.8.52" dependencies = [ "ansi_term", "bumpalo", @@ -1225,7 +1225,7 @@ dependencies = [ [[package]] name = "oxide_code_cache" -version = "0.8.51" +version = "0.8.52" dependencies = [ "lru", "oxide_bytecode", @@ -1234,7 +1234,7 @@ dependencies = [ [[package]] name = "oxide_compiler" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1253,7 +1253,7 @@ dependencies = [ [[package]] name = "oxide_dce" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1267,7 +1267,7 @@ dependencies = [ [[package]] name = "oxide_emit" -version = "0.8.51" +version = "0.8.52" dependencies = [ "num-bigint", "oxc_allocator", @@ -1282,7 +1282,7 @@ dependencies = [ [[package]] name = "oxide_ir" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxide_bytecode", "oxide_log", @@ -1291,7 +1291,7 @@ dependencies = [ [[package]] name = "oxide_kernel" -version = "0.8.51" +version = "0.8.52" dependencies = [ "bumpalo", "dashmap", @@ -1306,7 +1306,7 @@ dependencies = [ [[package]] name = "oxide_liveness" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1318,7 +1318,7 @@ dependencies = [ [[package]] name = "oxide_log" -version = "0.8.51" +version = "0.8.52" dependencies = [ "tracing", "tracing-appender", @@ -1327,7 +1327,7 @@ dependencies = [ [[package]] name = "oxide_parser" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1342,7 +1342,7 @@ dependencies = [ [[package]] name = "oxide_regalloc" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1358,7 +1358,7 @@ dependencies = [ [[package]] name = "oxide_runtime_api" -version = "0.8.51" +version = "0.8.52" dependencies = [ "num-bigint", "num-traits", @@ -1370,7 +1370,7 @@ dependencies = [ [[package]] name = "oxide_test262" -version = "0.8.51" +version = "0.8.52" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1387,7 +1387,7 @@ dependencies = [ [[package]] name = "oxide_types" -version = "0.8.51" +version = "0.8.52" dependencies = [ "bumpalo", "hashbrown 0.14.5", @@ -1399,7 +1399,7 @@ dependencies = [ [[package]] name = "oxide_vm" -version = "0.8.51" +version = "0.8.52" dependencies = [ "bumpalo", "chrono", diff --git a/Cargo.toml b/Cargo.toml index eefe26c8..6239e9a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ members = [ ] [workspace.package] -version = "0.8.51" +version = "0.8.52" edition = "2021" license = "MIT" rust-version = "1.80" diff --git a/crates/oxide_kernel/src/kernel/core.rs b/crates/oxide_kernel/src/kernel/core.rs index 0bf2ccf1..e685bd1d 100644 --- a/crates/oxide_kernel/src/kernel/core.rs +++ b/crates/oxide_kernel/src/kernel/core.rs @@ -32,7 +32,9 @@ pub struct KernelCore { active_vms: AtomicUsize, /// realm 编号计数器:进程内单调递增,`alloc_realm_id` 取当前值后自增。 /// 首个 realm 编号为 0(与旧符号编码一致),至多 2^9 = 512 个 realm - /// (属性键符号空间 29 位减局部下标 20 位)。 + /// (属性键符号空间 29 位减局部下标 20 位)。宿主须在单 kernel 生命周期 + /// 内创建满 512 个 Vm 前重建 kernel(重建即计数器归零);test262 runner + /// 经 kernel_batch 缺省值(不超 512)满足该约束。 realm_counter: AtomicU32, } @@ -197,10 +199,15 @@ impl KernelCore { /// 分配一个 realm 编号:取计数器当前值后自增,进程内单调递增。 /// /// 首个 realm 编号为 0(与旧符号编码一致),供 `Realm` 构造时固化。 - /// 编号空间至多 2^9 = 512(属性键符号空间约束),超出后回绕(debug 断言不触发, - /// 实际单进程 realm 数远小于该上界)。 + /// 编号空间至多 2^9 = 512(属性键符号空间 29 位减局部下标 20 位):宿主 + /// 须在单 kernel 生命周期内创建满 512 个 Vm 前重建 kernel(重建即计数器 + /// 归零),否则超界编号编码的符号属性键与 realm 0 碰撞(属性别名、 + /// `Symbol.for` 注册表污染)。debug 构建对超界 fail-fast,release 构建 + /// 静默回绕(与引擎其余边界守卫同型)。 pub fn alloc_realm_id(&self) -> u32 { - self.realm_counter.fetch_add(1, Ordering::Relaxed) + let id = self.realm_counter.fetch_add(1, Ordering::Relaxed); + debug_assert!(id < 512, "realm 编号超出 512 上界:宿主须在创建满 512 个 Vm 前重建 kernel"); + id } } diff --git a/crates/oxide_test262/src/config.rs b/crates/oxide_test262/src/config.rs index 9ab5a4f6..3eda7b19 100644 --- a/crates/oxide_test262/src/config.rs +++ b/crates/oxide_test262/src/config.rs @@ -95,7 +95,7 @@ impl RunConfig { \x20 OXIDE_TEST262_CHUNK_SIZE tests per child in chunked mode\n\ \x20 OXIDE_TEST262_CHILD_CHUNK marks a spawned child as chunk worker (any value)\n\ \x20 OXIDE_TEST262_ALLOW_FAIL_EXIT child may exit 1 on fail (any value)\n\ - \x20 OXIDE_TEST262_KERNEL_BATCH kernel rebuilds every N tests (default 5000, 1000 under --no-skip)\n\ + \x20 OXIDE_TEST262_KERNEL_BATCH kernel rebuilds every N tests (default 256, kept under the 512 realm bound)\n\ \x20 OXIDE_TEST262_LOG_LEVEL runner log level (default info)\n\ \x20 OXIDE_SKIP_UNTIL skip test indexes below N (chunking/supervise resume)\n\ \x20 OXIDE_MAX_TESTS run at most N tests after skip point" diff --git a/crates/oxide_test262/src/main.rs b/crates/oxide_test262/src/main.rs index e51ec9bc..a4759798 100644 --- a/crates/oxide_test262/src/main.rs +++ b/crates/oxide_test262/src/main.rs @@ -173,11 +173,13 @@ fn run_tests() -> bool { .and_then(|n| skip_until.checked_add(n)) .map(|n| n.min(total)) .unwrap_or(total); + // 缺省 256:每 kernel 生命周期 realm 计数不超 512 上界(属性键符号空间约束), + // 留一倍余量防重建边界 off-by-one 触发 debug 断言。 let kernel_batch = std::env::var("OXIDE_TEST262_KERNEL_BATCH") .ok() .and_then(|s| s.parse::().ok()) .filter(|&n| n > 0) - .unwrap_or(if config.no_skip { 1000 } else { 5000 }); + .unwrap_or(256); let chunk_size = std::env::var("OXIDE_TEST262_CHUNK_SIZE") .ok() .and_then(|s| s.parse::().ok()) diff --git a/crates/oxide_types/src/private_key/tests.rs b/crates/oxide_types/src/private_key/tests.rs index 305b79bd..5a93402d 100644 --- a/crates/oxide_types/src/private_key/tests.rs +++ b/crates/oxide_types/src/private_key/tests.rs @@ -107,3 +107,47 @@ fn symbol_key_realm_dimensions_distinct() { // 跨 realm 同名 well-known 符号也产生不同键。 assert_ne!(encode_symbol_key(0, WELL_KNOWN_SYMBOL_ITERATOR), encode_symbol_key(2, WELL_KNOWN_SYMBOL_ITERATOR)); } + +#[test] +fn symbol_key_realm_511_in_range() { + // 511 是 512 上界内的最后一个 realm 编号:realm 位落 bit 20 至 28,与基址 + // 不重叠,编码落 29 位符号空间内,往返自洽且与相邻 realm 不碰撞。 + for idx in [0u32, 14, 15, 16] { + let key = encode_symbol_key(511, idx); + assert!(is_symbol_key(key)); + assert_eq!(decode_symbol_key(key), (511, idx)); + assert_ne!(key, encode_symbol_key(0, idx)); + assert_ne!(key, encode_symbol_key(510, idx)); + } +} + +#[test] +fn symbol_key_realm_512_collides_with_realm_zero() { + // 512 是第一个出界 realm 编号:realm 位 bit 9 左移 20 位落 bit 29,与 + // SYMBOL_KEY_BASE 的 bit 29 重叠,编码结果与 realm 0 逐字节一致(碰撞)。 + for idx in [0u32, 14, 15, 16] { + assert_eq!(encode_symbol_key(512, idx), encode_symbol_key(0, idx)); + } +} + +#[test] +fn symbol_key_realm_1024_out_of_range_still_injective() { + // 1024 出界但 realm 位 bit 10 左移 20 位落 bit 30,与基址不重叠:键仍单射 + // (解码自洽回 1024),仅出文档声明的 29 位符号空间,不与 realm 0 碰撞。 + for idx in [0u32, 15, 16] { + let key = encode_symbol_key(1024, idx); + assert!(is_symbol_key(key)); + assert_ne!(key, encode_symbol_key(0, idx)); + assert_eq!(symbol_realm_id_from_key(key), 1024); + assert_eq!(symbol_local_index_from_key(key), idx); + } +} + +#[test] +fn symbol_key_realm_2048_collides_with_realm_zero() { + // 2048 是第二个碰撞环:realm 位 bit 11 左移 20 位落 bit 31,与 + // SYMBOL_KEY_BASE 的 bit 31 重叠,编码结果与 realm 0 逐字节一致。 + for idx in [0u32, 15, 16] { + assert_eq!(encode_symbol_key(2048, idx), encode_symbol_key(0, idx)); + } +}