mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 11:11:11 +08:00
vm/kernel/emit/builtins: 动态源编码重设计 + 数值键 2^32 边界 + 单元域解码/Source 面——14 头独占 test262 回归 13 修 0 新增
全量 A/B 差分撞出 14 个头独占回归,本提交闭合 13(text-self.js 双树同败归 pre-existing):
数值键 u32 回绕(release 态,debug 为 panic 故单测未现):canonical_index_str/
units 的 v.checked_mul(10)? + d as u32 在乘积合法而和溢出 2^32 时静默回绕
(10 位数字串 "4294967296".."4294967299" 误判整数键 0..3,属性查找回
退、Object.keys 串键),改 checked_mul+checked_add 双段防溢出;str/units 各
钉一枚 2^30-1/2^30/2^32-1/2^32 边界(Group B 5 文件:defineProperty/
defineProperties 2^32 键族 + Array property-cast-number)。
decodeURI/decodeURIComponent 单元域重写(Group A 2 文件):decode_uri_units
按单元扫描(非 % 单元原样透传——孤立 surrogate 往返不再被 lossy 串值面
打碎),%XX 解单元入缓冲;string_arg_units 经 to_units_full 取单元。
动态源编码(eval/Function/$262.evalScript)重设计(Group A 6 文件 + value-u):
source_escape 旧设计把源码域反斜杠恒双写(与 marker 起始区分),但源码即
JS 程序、反斜杠恒为字面量内转义序列起始,双写改变程序语义——
/\u{1d306}/u 变 /\\u{1d306}/u,u 模式撞裸 { 直接 SyntaxError(value-u 回归
根因)。现反斜杠原样透传;孤立 surrogate/FFFD 单元仍以 \\uXXXX 转义文本
注入(Rust str 无法承载裸孤立 surrogate,转义文本是唯一注入形态);
source_escape_to_key 逆路径仅还原注入 marker(\\ud800..\\udfff/\\ufffd
小写转义文本 → FFFD+hex4 池键形态,物化 decode_key 还原原始单元,正则
.source 按原始源返回;用户转义文本 \\u0041/\\u{1d306} 等逐字透传),
\\+marker 拼接形态(数据反斜杠紧邻注入,S7.8.5_A1.4 族 cu=d800 断言)按
前瞻还原 [数据反斜杠, 单元]。source_encoded 标志经 Compiler→Emitter→CompileCtx
(嵌套继承)贯通,仅动态编译入口置位;静态源切片维持 pool_key_plain 不变。
RegExp [[Source]]/[[Flags]] 单元域(regexp 构造器):to_units_full →
new_string_units_owned 入键(旧 lossy to_string 把孤立 surrogate 单元打成
FFFD,src_match 探针 false);regress 编译仍 lossy(既有缺口,另行报告)。
三并钉:source_escape marker 形态 / 反斜杠透传 / decode_key∘to_key∘escape
闭环(含 \\+marker 相邻与 astral 对)。实测:Group A 8/8、Group B 5/5、
value-u 1/1;8178 文件回归子集(13 目录)双树 A/B 差分 HEAD-only=∅、
13 文件转双树同 pass;text-self.js 双树同 compile 败
(requested module export is not exported: default)归 pre-existing;
七 crate 单测 2879/1(唯一失败 compile_class_declaration_emits_constructor
为 HEAD~0 既有,本提交未引入)。
This commit is contained in:
@@ -77,16 +77,28 @@ fn set_prop_at(obj: *mut JsObject, idx: usize, val: JsValue) {
|
||||
/// 支持 backreference/lookaround/命名组/v-flag);非法模式抛 SyntaxError。
|
||||
/// 编译结果存于对象的 native_fn 槽。
|
||||
pub fn regexp_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let (pattern, flags) = if args.len() < 2 {
|
||||
(String::new(), String::new())
|
||||
} else if args.len() < 3 {
|
||||
let pat = oxide_runtime_api::to_string(vm.reg(args[1]));
|
||||
(pat, String::new())
|
||||
// [[Source]]/[[Flags]] 是 ToString 结果的**单元序列**:`to_units_full` 直取
|
||||
// (lossy `to_string` 会把孤立 surrogate 单元折成 FFFD,破坏 source 往返)。
|
||||
// regress 编译用 lossy 文本(其匹配语义对孤立 surrogate 本即既有缺口,
|
||||
// 不因本处改变)。
|
||||
let pattern_units = if args.len() < 2 {
|
||||
Vec::<u16>::new()
|
||||
} else {
|
||||
let pat = oxide_runtime_api::to_string(vm.reg(args[1]));
|
||||
let fl = oxide_runtime_api::to_string(vm.reg(args[2]));
|
||||
(pat, fl)
|
||||
match oxide_runtime_api::to_units_full(vm.reg(args[1]), vm) {
|
||||
Ok(u) => u,
|
||||
Err(e) => return NativeResult::Err(crate::error::create_from_text(vm, &e)),
|
||||
}
|
||||
};
|
||||
let flags_units = if args.len() < 3 {
|
||||
Vec::<u16>::new()
|
||||
} else {
|
||||
match oxide_runtime_api::to_units_full(vm.reg(args[2]), vm) {
|
||||
Ok(u) => u,
|
||||
Err(e) => return NativeResult::Err(crate::error::create_from_text(vm, &e)),
|
||||
}
|
||||
};
|
||||
let pattern = String::from_utf16_lossy(&pattern_units);
|
||||
let flags = String::from_utf16_lossy(&flags_units);
|
||||
|
||||
let (global, ignore_case, multi_line, dot_all, sticky, unicode, has_indices) = parse_flags(&flags);
|
||||
|
||||
@@ -116,8 +128,9 @@ pub fn regexp_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
|
||||
set_prop(&mut obj, "lastIndex", JsValue::int(0), vm);
|
||||
set_prop(&mut obj, "source", vm.new_string(&pattern), vm);
|
||||
set_prop(&mut obj, "flags", vm.new_string(&flags), vm);
|
||||
// 单元口径物化 source/flags(孤立 surrogate 单元保持往返)。
|
||||
set_prop(&mut obj, "source", vm.new_string_units_owned(pattern_units), vm);
|
||||
set_prop(&mut obj, "flags", vm.new_string_units_owned(flags_units), vm);
|
||||
set_prop(&mut obj, "global", JsValue::bool(global), vm);
|
||||
set_prop(&mut obj, "ignoreCase", JsValue::bool(ignore_case), vm);
|
||||
set_prop(&mut obj, "multiline", JsValue::bool(multi_line), vm);
|
||||
|
||||
Reference in New Issue
Block a user