From c7a9b273fab82cb9cf9625dde4958d11d7a64435 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sun, 13 Sep 2026 12:26:24 +0000 Subject: [PATCH] =?UTF-8?q?types/vm/runner:=20JsString=20=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E8=A1=A5=20size=5Fof/offset=5Fof=20=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=9C=9F=E9=94=9A=EF=BC=88=E5=AE=9E=E6=B5=8B=2032B=E3=80=81utf?= =?UTF-8?q?16=5Flen@24=EF=BC=8Ctag=20=E5=B9=B6=E5=85=A5=E8=BD=BD=E8=8D=B7?= =?UTF-8?q?=E9=A6=96=E5=AD=97=E6=97=A0=E7=8B=AC=E7=AB=8B=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E5=AD=97=EF=BC=89=EF=BC=8Ceval=20fn-decl=20=E6=8A=9B=E5=90=8E?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E7=AC=A6=E6=94=B9=E6=98=BE=E5=BC=8F=E5=80=BC?= =?UTF-8?q?=E8=AF=BB=E9=92=89=E4=BD=8F=EF=BC=8Cnon-definable-global-var=20?= =?UTF-8?q?=E5=A4=8D=E6=B5=8B=E5=85=A8=E7=BB=BF=E6=92=A4=20skip=20?= =?UTF-8?q?=E6=9D=A1=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_test262/src/main.rs | 9 ++++----- crates/oxide_types/src/object.rs | 12 +++++++++++- .../oxide_vm/tests/global_fn_decl_builtin_tests.rs | 7 ++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/crates/oxide_test262/src/main.rs b/crates/oxide_test262/src/main.rs index 3d6febf1..e4a61d73 100644 --- a/crates/oxide_test262/src/main.rs +++ b/crates/oxide_test262/src/main.rs @@ -489,11 +489,10 @@ fn eval_family_excluded(path: &str) -> Option<&'static str> { } let is_direct = path.contains("eval-code/direct/"); let common = [ - "declare-arguments", // 直接 eval 的 arguments 语义族(档 3) - "non-definable-global-var", // CanDeclareGlobalVar(var 面)c:false 语义与全局描述符面裁决绑定 - "this-value-func", // 调用者 this 传递(档 3) - "new.target", // new.target 语义(档 3) - "strict-caller", // 严格调用者传播(档 3) + "declare-arguments", // 直接 eval 的 arguments 语义族(档 3) + "this-value-func", // 调用者 this 传递(档 3) + "new.target", // new.target 语义(档 3) + "strict-caller", // 严格调用者传播(档 3) "strict-source", "strictness-override", // 直接 eval 严格性覆盖 "onlystrict", // onlyStrict 块声明族 diff --git a/crates/oxide_types/src/object.rs b/crates/oxide_types/src/object.rs index aa9f2d02..a5e51306 100644 --- a/crates/oxide_types/src/object.rs +++ b/crates/oxide_types/src/object.rs @@ -25,6 +25,7 @@ use std::sync::OnceLock; /// `Cons` 首字为 tag(0xffff_ffff_ffff_ffff)@0、子节点指针@8;`utf16_len` /// 两形态统一 @24(4B),尾部 4B 填充。`String` 原样存储(零 realloc 收缩); /// Cons 专属状态(子节点/产物缓存)独立分配在 [`ConsNode`],仅大链持有。 +/// 尺寸锚见下方 size_of/offset_of 断言。 /// /// 生命周期约定: /// - `Cons` 子节点各自独立登记 session 字符串表(或为 perm 串),由 GC 的 @@ -42,6 +43,14 @@ pub struct JsString { utf16_len: AtomicU32, } +// 布局锚:32B = 载荷 24B(Flat 内联 String / Cons tag+子指针)+ utf16_len 4B +// + 尾部填充 4B。tag 并入载荷首字(Cons 以 0xffff.. marker 占位),无独立索引字—— +// 换变体形状/字段类型可能改变该折叠,布局变更先同步结构体头注释再改本断言。 +const _: () = assert!( + std::mem::size_of::() == 32 && std::mem::offset_of!(JsString, utf16_len) == 24, + "JsString 布局漂移:锚定布局见结构体头注释(32B,utf16_len@24)" +); + /// 字符串内容变体。 #[derive(Debug)] enum StringKind { @@ -52,7 +61,8 @@ enum StringKind { /// Cons(rope)节点的载荷:左右子节点指针 + O(1) 拼接字节长 + 扁平化产物缓存。 /// /// 独立于 `JsString` 分配,使 Flat 路径的 `JsString` 保持与 rope 前相同的 32B -/// 结构;仅超过字节阈值的拼接(`Vm::new_cons_string`)才创建本节点。 +/// 结构(tag 并入载荷首字,见其尺寸断言);仅超过字节阈值的拼接 +/// (`Vm::new_cons_string`)才创建本节点。 /// /// 生命周期约定:节点由 `Box::into_raw` 分配,只经 [`JsString::drop_cons_node`] /// 释放(连带扁平化产物);`left`/`right` 由 GC 传播闭包保证随父存活。 diff --git a/crates/oxide_vm/tests/global_fn_decl_builtin_tests.rs b/crates/oxide_vm/tests/global_fn_decl_builtin_tests.rs index 1dc137fa..1748e979 100644 --- a/crates/oxide_vm/tests/global_fn_decl_builtin_tests.rs +++ b/crates/oxide_vm/tests/global_fn_decl_builtin_tests.rs @@ -205,11 +205,12 @@ fn eval_fn_decl_with_function_no_partial_binding_creation() { #[test] fn eval_fn_decl_a_side_value_and_descriptor_preserved() { - // 抛后 A 侧保留:Infinity 仍为原常量(自相等),描述符不可写位不变。 + // 抛后 A 侧保留:Infinity 属性值仍为原常量(显式值读),描述符不可写位不变。 let s = eval_str( "try { eval('function Infinity(){}'); } catch (e) {} \ - (Infinity === Infinity) + ':' + \ - (Object.getOwnPropertyDescriptor(globalThis, 'Infinity').writable === false ? 'w-false' : 'w-true')", + var d = Object.getOwnPropertyDescriptor(globalThis, 'Infinity'); \ + (d.value === Infinity) + ':' + \ + (d.writable === false ? 'w-false' : 'w-true')", ); assert_eq!(s, "true:w-false"); }