perf: 收紧字符串借用语义消除跨分配点 UB

This commit is contained in:
2026-08-13 16:24:00 +08:00
parent 352f3359cd
commit e62bc54f08
7 changed files with 30 additions and 12 deletions
+1 -1
View File
@@ -250,7 +250,7 @@ fn to_bigint<H: VmHost>(vm: &mut H, val: JsValue) -> Result<JsValue, JsValue> {
return Err(crate::error::create_type_error(vm, "Cannot convert a Number value to a BigInt"));
}
if val.is_string() {
let s = unsafe { oxide_runtime_api::string_data(val) }.to_string();
let s = oxide_runtime_api::to_string(val);
return match string_to_bigint(vm, &s) {
Ok(v) => Ok(v),
Err(e) => Err(e),
+4 -3
View File
@@ -308,9 +308,10 @@ fn next_array_like<H: VmHost>(
let index = current_index(vm, wrapper, index_si);
let byteoff_si = vm.kernel_core().perm_interner().intern(BYTEOFF_PROP).0;
let byteoff = current_index(vm, wrapper, byteoff_si);
let source = unsafe { &*inner.as_string_ptr() }.as_str();
let rest = &source[byteoff..];
if let Some(ch) = rest.chars().next() {
// 源串裸指针借用压缩到单个表达式:ch 是 Copy 的 char,不携带借用,
// 之后对 VM 状态的可变访问不再与源串借用共存。
let ch = unsafe { &*inner.as_string_ptr() }.as_str()[byteoff..].chars().next();
if let Some(ch) = ch {
vm.set_or_create_prop_value(wrapper, byteoff_si, JsValue::int((byteoff + ch.len_utf8()) as i32));
vm.set_or_create_prop_value(wrapper, index_si, JsValue::int((index + 1) as i32));
let value = vm.new_string(&ch.to_string());
+4 -3
View File
@@ -192,7 +192,7 @@ pub fn module_data<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
if !kind_val.is_string() || !content_val.is_string() {
return type_error(vm, "__moduleData: kind/content must be strings");
}
let kind = unsafe { oxide_runtime_api::string_data(kind_val) }.to_string();
let kind = oxide_runtime_api::to_string(kind_val);
let default_val = match kind.as_str() {
"json" => {
// 复用 JSON.parse 的 serde 管线:args[1] 即内容字符串。
@@ -204,8 +204,9 @@ pub fn module_data<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
}
}
"text" => {
let text = unsafe { oxide_runtime_api::string_data(content_val) };
vm.new_string(text)
// 经借用路径拷贝出 owned String 后再入堆,避免借用跨过 new_string 分配点。
let text = vm.string_ref(content_val).to_string();
vm.new_string_owned(text)
}
_ => return type_error(vm, "__moduleData: unsupported data kind"),
};