mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
fix: 装箱 Symbol 强转恒返 Symbol 并修正迭代器 name
This commit is contained in:
@@ -137,12 +137,14 @@ pub fn string_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let v = oxide_runtime_api::to_string_for_string_constructor(v, vm);
|
||||
match v {
|
||||
Ok(s) => vm.new_string_owned(s),
|
||||
Err(_) => {
|
||||
Err(msg) => {
|
||||
// ToString on an object may throw via toString/valueOf; propagate the original exception.
|
||||
if let Some(exc) = vm.take_uncaught_value() {
|
||||
return NativeResult::Err(exc);
|
||||
}
|
||||
return NativeResult::Err(crate::error::create_type_error(vm, "Cannot convert value to a string"));
|
||||
// 无在途异常时按格式化文本恢复 kind 与消息(装箱 Symbol 走 ToString
|
||||
// 抛 TypeError,消息须与原始异常一致)。
|
||||
return NativeResult::Err(crate::error::create_from_text(vm, &msg));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -95,41 +95,18 @@ pub fn symbol_to_string<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
NativeResult::Ok(vm.new_string_owned(result))
|
||||
}
|
||||
|
||||
/// `Symbol.prototype[Symbol.toPrimitive](hint)`:thisSymbolValue 校验后按
|
||||
/// hint 返回 Symbol 或其描述串。
|
||||
/// `Symbol.prototype[Symbol.toPrimitive](hint)`:thisSymbolValue 校验后忽略
|
||||
/// hint,恒返回 Symbol 本体(规范 ThisSymbolValue,不转描述串、不触发 hint 转换)。
|
||||
///
|
||||
/// # 步骤
|
||||
/// 1. this 非 Symbol 或 Symbol 包装对象 → TypeError。
|
||||
/// 2. hint 缺省 → 返回 Symbol。
|
||||
/// 3. hint 做完整 ToString(异常传播);结果串为 "string" → 返回
|
||||
/// `Symbol(description)` 描述串,其余值(含 "number")→ 返回 Symbol。
|
||||
/// 2. 返回 Symbol(hint 缺省与否均忽略)。
|
||||
pub fn symbol_to_primitive<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let this_val = vm.reg(args[0]);
|
||||
let sym = match this_symbol_value(vm, this_val) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return NativeResult::Err(e),
|
||||
};
|
||||
if args.len() <= 1 {
|
||||
return NativeResult::Ok(sym);
|
||||
}
|
||||
let hint = vm.reg(args[1]);
|
||||
if hint.is_undefined() {
|
||||
return NativeResult::Ok(sym);
|
||||
}
|
||||
let hint_str = match oxide_runtime_api::to_string_full(hint, vm) {
|
||||
Ok(s) => s,
|
||||
Err(_) => {
|
||||
if let Some(exc) = vm.take_uncaught_value() {
|
||||
return NativeResult::Err(exc);
|
||||
}
|
||||
return NativeResult::Err(crate::error::create_type_error(vm, "Cannot convert value to a string"));
|
||||
}
|
||||
};
|
||||
if hint_str == "string" {
|
||||
let idx = sym.as_symbol_index();
|
||||
let desc = vm.symbol_description(idx).unwrap_or("").to_string();
|
||||
return NativeResult::Ok(vm.new_string_owned(format!("Symbol({})", desc)));
|
||||
}
|
||||
NativeResult::Ok(sym)
|
||||
}
|
||||
|
||||
|
||||
@@ -977,8 +977,10 @@ fn string_to_bigint_full<H: VmHost>(host: &mut H, s: &str) -> Result<JsValue, St
|
||||
Ok(host.new_bigint(if neg { -m } else { m }))
|
||||
}
|
||||
|
||||
/// `String()` 构造器的字符串转换(§21.1.1.1):Symbol 值(及本引擎以空对象表示的
|
||||
/// well-known symbol)返回描述串 `Symbol(desc)`;其余走完整 ToString。
|
||||
/// `String()` 构造器的字符串转换(§21.1.1.1):原始 Symbol 值(及本引擎以空对象
|
||||
/// 表示的 well-known symbol)返回描述串 `Symbol(desc)`(步骤 2a);其余走完整
|
||||
/// ToString(步骤 3)——装箱 Symbol 的 ToPrimitive 返回 Symbol 本体,ToString 抛
|
||||
/// TypeError。
|
||||
pub fn to_string_for_string_constructor<H: VmHost>(val: JsValue, host: &mut H) -> Result<String, String> {
|
||||
if val.is_object() {
|
||||
if let Some(id) = well_known_symbol_id(host, val.as_js_object_ptr()) {
|
||||
@@ -987,10 +989,15 @@ pub fn to_string_for_string_constructor<H: VmHost>(val: JsValue, host: &mut H) -
|
||||
}
|
||||
}
|
||||
}
|
||||
// 原始 Symbol:步骤 2a,SymbolDescriptiveString(不经 ToString)。
|
||||
if val.is_symbol() {
|
||||
let desc = host.symbol_description(val.as_symbol_index()).unwrap_or("");
|
||||
return Ok(format!("Symbol({desc})"));
|
||||
}
|
||||
// 步骤 3:ToString。装箱 Symbol 经 ToPrimitive 得 Symbol 本体,ToString 抛 TypeError。
|
||||
let primitive = to_primitive(val, ToPrimitiveHint::String, host)?;
|
||||
if primitive.is_symbol() {
|
||||
let desc = host.symbol_description(primitive.as_symbol_index()).unwrap_or("");
|
||||
return Ok(format!("Symbol({desc})"));
|
||||
return Err(host.error_message_text("TypeError", "Cannot convert a Symbol value to a string"));
|
||||
}
|
||||
Ok(to_string(primitive))
|
||||
}
|
||||
|
||||
@@ -85,13 +85,14 @@ pub fn bind_string(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
|
||||
core,
|
||||
&[("toString", oxide_builtins::string::string_to_string::<crate::vm::Vm> as *const (), 0)],
|
||||
);
|
||||
// String.prototype[@@iterator]:逐 code point 迭代字符。
|
||||
// String.prototype[@@iterator]:逐 code point 迭代字符;name 属性按规范
|
||||
// 落 "[Symbol.iterator]"。
|
||||
super::bind_well_known_method(
|
||||
session.builtin_world(),
|
||||
core,
|
||||
proto,
|
||||
0,
|
||||
"iterator",
|
||||
"[Symbol.iterator]",
|
||||
oxide_builtins::string::string_symbol_iterator::<crate::vm::Vm> as *const (),
|
||||
0,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user