mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
fix: DefineOwnProperty 臂写参数寄存器补顶帧守卫
This commit is contained in:
@@ -218,6 +218,9 @@ impl oxide_runtime_api::VmHost for Vm {
|
||||
fn arguments_mapping_alive(&self, state: &oxide_types::arguments_map::ArgumentsMapState) -> bool {
|
||||
self.arguments_mapping_alive(state)
|
||||
}
|
||||
fn is_top_frame(&self, frame_depth: u32) -> bool {
|
||||
self.is_top_frame(frame_depth)
|
||||
}
|
||||
fn ordinary_get(&mut self, obj: &JsObject, prop_name_si: u32, receiver: JsValue) -> Result<JsValue, String> {
|
||||
self.ordinary_get(obj, prop_name_si, receiver)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,14 @@ impl Vm {
|
||||
self.frames.len() > depth && self.frames[depth].frame_id == state.frame_id
|
||||
}
|
||||
|
||||
/// 判定帧栈下标 `frame_depth` 处的帧是否为顶帧(当前帧)。
|
||||
///
|
||||
/// # 边界与前提
|
||||
/// - `frame_depth` 为创建帧在帧栈中的下标;帧弹出后下标越界返回 `false`。
|
||||
pub(crate) fn is_top_frame(&self, frame_depth: u32) -> bool {
|
||||
self.frames.len() == frame_depth as usize + 1
|
||||
}
|
||||
|
||||
/// 属性读入口:解析 `obj[prop_name_si]`,依次尝试数组 length 虚拟属性、
|
||||
/// 数组元素区、TypedArray 整数索引、命名属性槽,最后沿原型链查找。
|
||||
///
|
||||
|
||||
@@ -204,3 +204,28 @@ fn global_self_decrement_preserves_arguments() {
|
||||
let result = eval(&mut vm, "var c=1; function f(a){c--; return arguments.length} f(1)").unwrap();
|
||||
assert_eq!(result.as_int(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn define_property_nested_call_does_not_clobber_callee_param() {
|
||||
// 嵌套调用期对外层函数 arguments 索引属性 defineProperty 不写被调方帧的
|
||||
// 参数寄存器(顶帧守卫):被调方形参值不被串改。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"function a(x){function b(y){Object.defineProperty(a.arguments,0,{value:5}); return y} return b(7)} a(1)",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result.as_int(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn define_property_nested_call_updates_stored_value() {
|
||||
// 嵌套调用期 defineProperty 更新存储值(读路径权威源):回到顶帧后读为新值。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"function a(x){function b(){Object.defineProperty(a.arguments,0,{value:5})} b(); return a.arguments[0]} a(1)",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result.as_int(), 5);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user