mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 19:51:11 +08:00
fix: DefineOwnProperty 臂写参数寄存器补顶帧守卫
This commit is contained in:
Generated
+19
-19
@@ -1160,7 +1160,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_builtins"
|
name = "oxide_builtins"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"fast-float",
|
"fast-float",
|
||||||
@@ -1185,7 +1185,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_bytecode"
|
name = "oxide_bytecode"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"oxide_log",
|
"oxide_log",
|
||||||
@@ -1193,7 +1193,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_cfg"
|
name = "oxide_cfg"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_emit",
|
"oxide_emit",
|
||||||
@@ -1204,7 +1204,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_cli"
|
name = "oxide_cli"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
@@ -1226,7 +1226,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_code_cache"
|
name = "oxide_code_cache"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lru",
|
"lru",
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
@@ -1235,7 +1235,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_compiler"
|
name = "oxide_compiler"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1255,7 +1255,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_dce"
|
name = "oxide_dce"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1269,7 +1269,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_emit"
|
name = "oxide_emit"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
@@ -1284,7 +1284,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_engine"
|
name = "oxide_engine"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_compiler",
|
"oxide_compiler",
|
||||||
@@ -1296,7 +1296,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_ir"
|
name = "oxide_ir"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_log",
|
"oxide_log",
|
||||||
@@ -1305,7 +1305,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_kernel"
|
name = "oxide_kernel"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
@@ -1319,7 +1319,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_liveness"
|
name = "oxide_liveness"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1331,7 +1331,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_log"
|
name = "oxide_log"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-appender",
|
"tracing-appender",
|
||||||
@@ -1340,7 +1340,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_parser"
|
name = "oxide_parser"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
"oxc_ast",
|
"oxc_ast",
|
||||||
@@ -1355,7 +1355,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_regalloc"
|
name = "oxide_regalloc"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1371,7 +1371,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_runtime_api"
|
name = "oxide_runtime_api"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -1384,7 +1384,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_test262"
|
name = "oxide_test262"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_compiler",
|
"oxide_compiler",
|
||||||
@@ -1402,7 +1402,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_types"
|
name = "oxide_types"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
@@ -1415,7 +1415,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_vm"
|
name = "oxide_vm"
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.13.23"
|
version = "0.13.24"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
rust-version = "1.80"
|
rust-version = "1.80"
|
||||||
|
|||||||
@@ -984,8 +984,9 @@ pub(crate) fn define_from_descriptor<H: VmHost>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mapped arguments exotic [[DefineOwnProperty]]:整数索引且映射存活时,旧描述符
|
// mapped arguments exotic [[DefineOwnProperty]]:整数索引且映射存活时,旧描述符
|
||||||
// 可写且新描述符不可写则移除映射,新描述符含 value 则写参数寄存器;随后落穿
|
// 可写且新描述符不可写则移除映射,新描述符含 value 且创建帧为顶帧时写参数
|
||||||
// 普通 define 路径(描述符收窄校验由 define_data_property 承担)。
|
// 寄存器;随后落穿普通 define 路径(描述符收窄校验由 define_data_property
|
||||||
|
// 承担)。
|
||||||
if unsafe { &*obj_ptr }.is_arguments_obj() {
|
if unsafe { &*obj_ptr }.is_arguments_obj() {
|
||||||
let state_ptr = unsafe { &*obj_ptr }.native_data() as *mut ArgumentsMapState;
|
let state_ptr = unsafe { &*obj_ptr }.native_data() as *mut ArgumentsMapState;
|
||||||
if !state_ptr.is_null() {
|
if !state_ptr.is_null() {
|
||||||
@@ -1006,8 +1007,13 @@ pub(crate) fn define_from_descriptor<H: VmHost>(
|
|||||||
state.unmap(index as u16);
|
state.unmap(index as u16);
|
||||||
}
|
}
|
||||||
if let Some(v) = value_field {
|
if let Some(v) = value_field {
|
||||||
let reg = (state.param_base as u16 + index as u16) as u8;
|
// 参数寄存器仅创建帧为顶帧时写——嵌套调用期寄存器被被调方
|
||||||
vm.set_reg(reg, v);
|
// 占用,写之串值,参数值在 save_stack,存储值仍为权威
|
||||||
|
// 读源(与 [[Set]] 臂同口径)。
|
||||||
|
if vm.is_top_frame(state.frame_depth) {
|
||||||
|
let reg = (state.param_base as u16 + index as u16) as u8;
|
||||||
|
vm.set_reg(reg, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,6 +259,11 @@ pub trait VmHost {
|
|||||||
/// - `state` 为 arguments 对象 `native_data` 中的同步状态盒;`frame_depth`
|
/// - `state` 为 arguments 对象 `native_data` 中的同步状态盒;`frame_depth`
|
||||||
/// 为创建帧下标,帧弹出后映射失效。
|
/// 为创建帧下标,帧弹出后映射失效。
|
||||||
fn arguments_mapping_alive(&self, state: &oxide_types::arguments_map::ArgumentsMapState) -> bool;
|
fn arguments_mapping_alive(&self, state: &oxide_types::arguments_map::ArgumentsMapState) -> bool;
|
||||||
|
/// 判定帧栈下标 `frame_depth` 处的帧是否为顶帧(当前帧)。
|
||||||
|
///
|
||||||
|
/// # 边界与前提
|
||||||
|
/// - `frame_depth` 为创建帧在帧栈中的下标;帧弹出后下标越界返回 `false`。
|
||||||
|
fn is_top_frame(&self, frame_depth: u32) -> bool;
|
||||||
|
|
||||||
// 属性访问
|
// 属性访问
|
||||||
fn ordinary_get(&mut self, obj: &JsObject, prop_name_si: u32, receiver: JsValue) -> Result<JsValue, String>;
|
fn ordinary_get(&mut self, obj: &JsObject, prop_name_si: u32, receiver: JsValue) -> Result<JsValue, String>;
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ impl oxide_runtime_api::VmHost for Vm {
|
|||||||
fn arguments_mapping_alive(&self, state: &oxide_types::arguments_map::ArgumentsMapState) -> bool {
|
fn arguments_mapping_alive(&self, state: &oxide_types::arguments_map::ArgumentsMapState) -> bool {
|
||||||
self.arguments_mapping_alive(state)
|
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> {
|
fn ordinary_get(&mut self, obj: &JsObject, prop_name_si: u32, receiver: JsValue) -> Result<JsValue, String> {
|
||||||
self.ordinary_get(obj, prop_name_si, receiver)
|
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
|
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 虚拟属性、
|
/// 属性读入口:解析 `obj[prop_name_si]`,依次尝试数组 length 虚拟属性、
|
||||||
/// 数组元素区、TypedArray 整数索引、命名属性槽,最后沿原型链查找。
|
/// 数组元素区、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();
|
let result = eval(&mut vm, "var c=1; function f(a){c--; return arguments.length} f(1)").unwrap();
|
||||||
assert_eq!(result.as_int(), 1);
|
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