mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
fix: IC 命中路径加代理接收者恒 miss 守卫
This commit is contained in:
Generated
+21
-21
@@ -1160,7 +1160,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_builtins"
|
name = "oxide_builtins"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"fast-float",
|
"fast-float",
|
||||||
@@ -1185,7 +1185,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_bytecode"
|
name = "oxide_bytecode"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
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.20.15"
|
version = "0.20.16"
|
||||||
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.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
@@ -1228,7 +1228,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_code_cache"
|
name = "oxide_code_cache"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lru",
|
"lru",
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
@@ -1237,7 +1237,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_compiler"
|
name = "oxide_compiler"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1258,7 +1258,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_dce"
|
name = "oxide_dce"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1272,7 +1272,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_emit"
|
name = "oxide_emit"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
@@ -1288,7 +1288,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_engine"
|
name = "oxide_engine"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_compiler",
|
"oxide_compiler",
|
||||||
@@ -1300,7 +1300,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_fold"
|
name = "oxide_fold"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
@@ -1312,7 +1312,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_ir"
|
name = "oxide_ir"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_log",
|
"oxide_log",
|
||||||
@@ -1321,7 +1321,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_kernel"
|
name = "oxide_kernel"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
@@ -1335,7 +1335,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_liveness"
|
name = "oxide_liveness"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1347,7 +1347,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_log"
|
name = "oxide_log"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-appender",
|
"tracing-appender",
|
||||||
@@ -1356,11 +1356,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_net"
|
name = "oxide_net"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_parser"
|
name = "oxide_parser"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
"oxc_ast",
|
"oxc_ast",
|
||||||
@@ -1375,7 +1375,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_regalloc"
|
name = "oxide_regalloc"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_cfg",
|
"oxide_cfg",
|
||||||
@@ -1391,7 +1391,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_runtime_api"
|
name = "oxide_runtime_api"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -1404,7 +1404,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_test262"
|
name = "oxide_test262"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"oxide_bytecode",
|
"oxide_bytecode",
|
||||||
"oxide_compiler",
|
"oxide_compiler",
|
||||||
@@ -1424,7 +1424,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_types"
|
name = "oxide_types"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
@@ -1437,7 +1437,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_vm"
|
name = "oxide_vm"
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.20.15"
|
version = "0.20.16"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
rust-version = "1.80"
|
rust-version = "1.80"
|
||||||
|
|||||||
@@ -9,6 +9,15 @@ use oxide_runtime_api as coercion;
|
|||||||
impl Vm {
|
impl Vm {
|
||||||
pub(crate) fn dispatch_member_op(&mut self, op: OpCode, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
pub(crate) fn dispatch_member_op(&mut self, op: OpCode, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||||
vm_trace!("MEMBER_OP {:?} rd={} a={} b={}", op, rd, a, b);
|
vm_trace!("MEMBER_OP {:?} rd={} a={} b={}", op, rd, a, b);
|
||||||
|
// 代理接收者统一走全路径:ordinary_get/ordinary_set 已带代理守卫,
|
||||||
|
// 命中路径直读代理自身属性槽会绕过 get trap(member 读侧无入口守卫)。
|
||||||
|
let receiver = self.regs[rd];
|
||||||
|
if receiver.is_object() {
|
||||||
|
let obj_ptr = receiver.as_js_object_ptr();
|
||||||
|
if !obj_ptr.is_null() && unsafe { (*obj_ptr).is_proxy_obj() } {
|
||||||
|
return self.dispatch_member_op_full(op, rd, a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
match op {
|
match op {
|
||||||
OpCode::MEMBER_INC => self.dispatch_member_inc(rd, a, b),
|
OpCode::MEMBER_INC => self.dispatch_member_inc(rd, a, b),
|
||||||
OpCode::MEMBER_DEC => self.dispatch_member_dec(rd, a, b),
|
OpCode::MEMBER_DEC => self.dispatch_member_dec(rd, a, b),
|
||||||
@@ -119,6 +128,112 @@ impl Vm {
|
|||||||
Ok((obj_ptr, prop_name_si))
|
Ok((obj_ptr, prop_name_si))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 代理接收者全路径读改写:ordinary_get/ordinary_set 已带代理守卫,
|
||||||
|
/// 经 get/set trap 路由,不接触 IC 命中路径。
|
||||||
|
fn dispatch_member_op_full(&mut self, op: OpCode, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||||
|
vm_trace!("MEMBER_OP_FULL {:?} rd={} a={} b={}", op, rd, a, b);
|
||||||
|
let Some(obj_ptr) = self.checked_object_ptr(self.regs[rd], "MEMBER_OP on non-object")? else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
let receiver = self.regs[rd];
|
||||||
|
// 静态操作键在 regs[b]、结果在 regs[a];动态操作键在 regs[a]、结果在 regs[b]。
|
||||||
|
let (key_reg, result_reg) = match op {
|
||||||
|
OpCode::DYN_MEMBER_INC | OpCode::DYN_MEMBER_DEC => (a, b),
|
||||||
|
_ => (b, a),
|
||||||
|
};
|
||||||
|
let prop_name_si = self.property_key_si(self.regs[key_reg])?;
|
||||||
|
// 静态操作带 IC 扩展字:代理分支不写回 IC(槽恒零),先消费扩展字,
|
||||||
|
// 否则派发循环会错位把扩展字当指令。
|
||||||
|
if op.has_ic_ext_words() {
|
||||||
|
let _ = crate::ic_helper::read_ic_slot0(&self.bytecode, &mut self.pc);
|
||||||
|
}
|
||||||
|
let obj = unsafe { &mut *obj_ptr };
|
||||||
|
let prop_val = self.ordinary_get(obj, prop_name_si, receiver)?;
|
||||||
|
let new_val = self.member_op_new_value(op, prop_val, self.regs[a])?;
|
||||||
|
self.ordinary_set(obj, prop_name_si, new_val, receiver, self.current_strict())?;
|
||||||
|
self.regs[result_reg] = new_val;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 代理接收者全路径的新值计算:强制转换口径与既有 IC 路径各分臂一致。
|
||||||
|
fn member_op_new_value(&mut self, op: OpCode, prop_val: JsValue, rhs: JsValue) -> Result<JsValue, String> {
|
||||||
|
match op {
|
||||||
|
OpCode::MEMBER_INC | OpCode::DYN_MEMBER_INC => {
|
||||||
|
let n = self.coerce_number_bounded(prop_val)?;
|
||||||
|
Ok(JsValue::float(n + 1.0))
|
||||||
|
}
|
||||||
|
OpCode::MEMBER_DEC | OpCode::DYN_MEMBER_DEC => {
|
||||||
|
let n = self.coerce_number_bounded(prop_val)?;
|
||||||
|
Ok(JsValue::float(n - 1.0))
|
||||||
|
}
|
||||||
|
OpCode::COMPOUND_MEMBER_ADD => {
|
||||||
|
let prop_val = self.coerce_primitive_bounded(prop_val, coercion::ToPrimitiveHint::Number)?;
|
||||||
|
let rhs = self.coerce_primitive_bounded(rhs, coercion::ToPrimitiveHint::Number)?;
|
||||||
|
if prop_val.is_symbol() || rhs.is_symbol() {
|
||||||
|
// 复合成员加法分流同 `+`:字符串分支走 ToString、数值分支走 ToNumber,
|
||||||
|
// 两者对 Symbol 均抛 TypeError(ECMA-262 §7.1.4 / §7.1.17)。
|
||||||
|
let msg = if prop_val.is_string() || rhs.is_string() {
|
||||||
|
"Cannot convert a Symbol value to a string"
|
||||||
|
} else {
|
||||||
|
"Cannot convert a Symbol value to a number"
|
||||||
|
};
|
||||||
|
self.raise_type_error(msg)?;
|
||||||
|
return Ok(JsValue::undefined());
|
||||||
|
}
|
||||||
|
if prop_val.is_string() || rhs.is_string() {
|
||||||
|
let ls = coercion::to_string(prop_val);
|
||||||
|
let rs = coercion::to_string(rhs);
|
||||||
|
Ok(self.new_string(&format!("{ls}{rs}")))
|
||||||
|
} else {
|
||||||
|
let ln = coercion::to_number(prop_val);
|
||||||
|
let rn = coercion::to_number(rhs);
|
||||||
|
Ok(JsValue::float(ln + rn))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OpCode::COMPOUND_MEMBER_SUB => self.member_op_f64(prop_val, rhs, |l, r| l - r),
|
||||||
|
OpCode::COMPOUND_MEMBER_MUL => self.member_op_f64(prop_val, rhs, |l, r| l * r),
|
||||||
|
OpCode::COMPOUND_MEMBER_DIV => self.member_op_f64(prop_val, rhs, |l, r| l / r),
|
||||||
|
OpCode::COMPOUND_MEMBER_MOD => self.member_op_f64(prop_val, rhs, |l, r| l % r),
|
||||||
|
OpCode::COMPOUND_MEMBER_EXP => self.member_op_f64(prop_val, rhs, |l, r| l.powf(r)),
|
||||||
|
OpCode::COMPOUND_MEMBER_BIT_AND => self.member_op_i32(prop_val, rhs, |l, r| l & r),
|
||||||
|
OpCode::COMPOUND_MEMBER_BIT_OR => self.member_op_i32(prop_val, rhs, |l, r| l | r),
|
||||||
|
OpCode::COMPOUND_MEMBER_BIT_XOR => self.member_op_i32(prop_val, rhs, |l, r| l ^ r),
|
||||||
|
OpCode::COMPOUND_MEMBER_SHL => self.member_op_shift(prop_val, rhs, false, false),
|
||||||
|
OpCode::COMPOUND_MEMBER_SHR => self.member_op_shift(prop_val, rhs, true, false),
|
||||||
|
OpCode::COMPOUND_MEMBER_USHR => self.member_op_shift(prop_val, rhs, true, true),
|
||||||
|
_ => unreachable!("non-member opcode passed to member_op_new_value"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_op_f64(&mut self, prop_val: JsValue, rhs: JsValue, op: impl FnOnce(f64, f64) -> f64) -> Result<JsValue, String> {
|
||||||
|
let ln = self.coerce_number_bounded(prop_val)?;
|
||||||
|
let rn = self.coerce_number_bounded(rhs)?;
|
||||||
|
Ok(JsValue::float(op(ln, rn)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_op_i32(&mut self, prop_val: JsValue, rhs: JsValue, op: impl FnOnce(i32, i32) -> i32) -> Result<JsValue, String> {
|
||||||
|
let ln = self.coerce_int32_bounded(prop_val)?;
|
||||||
|
let rn = self.coerce_int32_bounded(rhs)?;
|
||||||
|
Ok(JsValue::int(op(ln, rn)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_op_shift(&mut self, prop_val: JsValue, rhs: JsValue, is_right: bool, is_unsigned: bool) -> Result<JsValue, String> {
|
||||||
|
let ln = self.coerce_int32_bounded(prop_val)?;
|
||||||
|
let shift = self.coerce_uint32_bounded(rhs)? & 0x1F;
|
||||||
|
Ok(if !is_right {
|
||||||
|
JsValue::int(ln.wrapping_shl(shift))
|
||||||
|
} else if is_unsigned {
|
||||||
|
let u = (ln as u32) >> shift;
|
||||||
|
if u <= i32::MAX as u32 {
|
||||||
|
JsValue::int(u as i32)
|
||||||
|
} else {
|
||||||
|
JsValue::float(u as f64)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
JsValue::int(ln >> shift)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn dispatch_member_inc(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
fn dispatch_member_inc(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
|
||||||
vm_trace!("MEMBER_INC rd={} a={} b={}", rd, a, b);
|
vm_trace!("MEMBER_INC rd={} a={} b={}", rd, a, b);
|
||||||
let Ok((obj_ptr, prop_name_si)) = self.member_target(rd, b, "MEMBER_INC on non-object") else {
|
let Ok((obj_ptr, prop_name_si)) = self.member_target(rd, b, "MEMBER_INC on non-object") else {
|
||||||
|
|||||||
@@ -99,6 +99,10 @@ fn resolve_proto_target_raw(obj: *const JsObject, proto_depth: u8) -> *const JsO
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ic_get_hit(obj: &JsObject, shape_id: u32, slot_index: u32, proto_depth: u8) -> Option<JsValue> {
|
pub(crate) fn ic_get_hit(obj: &JsObject, shape_id: u32, slot_index: u32, proto_depth: u8) -> Option<JsValue> {
|
||||||
|
// 代理接收者恒 miss:命中路径直读代理自身属性槽会绕过 get trap。
|
||||||
|
if obj.is_proxy_obj() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
if shape_id == 0 {
|
if shape_id == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -134,6 +138,10 @@ pub(crate) fn ic_get_hit(obj: &JsObject, shape_id: u32, slot_index: u32, proto_d
|
|||||||
/// 空槽(shape_id==0)恒在尾部(FIFO 滚动保证),遇空即停。
|
/// 空槽(shape_id==0)恒在尾部(FIFO 滚动保证),遇空即停。
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub(crate) fn ic_get_hit_poly(obj: &JsObject, bytecode: &[Instr], ext_pc: usize) -> Option<JsValue> {
|
pub(crate) fn ic_get_hit_poly(obj: &JsObject, bytecode: &[Instr], ext_pc: usize) -> Option<JsValue> {
|
||||||
|
// 代理接收者恒 miss:命中路径直读代理自身属性槽会绕过 get trap。
|
||||||
|
if obj.is_proxy_obj() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
for i in 1..IC_SLOTS {
|
for i in 1..IC_SLOTS {
|
||||||
let base = ext_pc + i * 2;
|
let base = ext_pc + i * 2;
|
||||||
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
||||||
@@ -170,6 +178,10 @@ pub(crate) fn ic_get_hit_poly(obj: &JsObject, bytecode: &[Instr], ext_pc: usize)
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ic_set_hit(obj: &mut JsObject, shape_id: u32, slot_index: u32, proto_depth: u8, value: JsValue) -> bool {
|
pub(crate) fn ic_set_hit(obj: &mut JsObject, shape_id: u32, slot_index: u32, proto_depth: u8, value: JsValue) -> bool {
|
||||||
|
// 代理接收者恒 miss:命中路径直写代理自身属性槽会绕过 set trap。
|
||||||
|
if obj.is_proxy_obj() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if shape_id == 0 {
|
if shape_id == 0 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -201,6 +213,10 @@ pub(crate) fn ic_set_hit(obj: &mut JsObject, shape_id: u32, slot_index: u32, pro
|
|||||||
/// 空槽(shape_id==0)恒在尾部(FIFO 滚动保证),遇空即停。
|
/// 空槽(shape_id==0)恒在尾部(FIFO 滚动保证),遇空即停。
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub(crate) fn ic_set_hit_poly(obj: &mut JsObject, bytecode: &[Instr], ext_pc: usize, value: JsValue) -> bool {
|
pub(crate) fn ic_set_hit_poly(obj: &mut JsObject, bytecode: &[Instr], ext_pc: usize, value: JsValue) -> bool {
|
||||||
|
// 代理接收者恒 miss:命中路径直写代理自身属性槽会绕过 set trap。
|
||||||
|
if obj.is_proxy_obj() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for i in 1..IC_SLOTS {
|
for i in 1..IC_SLOTS {
|
||||||
let base = ext_pc + i * 2;
|
let base = ext_pc + i * 2;
|
||||||
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
||||||
@@ -244,6 +260,10 @@ pub(crate) fn ic_set_hit_poly(obj: &mut JsObject, bytecode: &[Instr], ext_pc: us
|
|||||||
/// 命中遍历从 `pc - IC_EXT_WORDS` 起的扩展字开始。
|
/// 命中遍历从 `pc - IC_EXT_WORDS` 起的扩展字开始。
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ic_set_hit_own(obj: &mut JsObject, bytecode: &[Instr], pc: usize, value: JsValue) -> bool {
|
pub(crate) fn ic_set_hit_own(obj: &mut JsObject, bytecode: &[Instr], pc: usize, value: JsValue) -> bool {
|
||||||
|
// 代理接收者恒 miss:命中路径直写代理自身属性槽会绕过 set trap。
|
||||||
|
if obj.is_proxy_obj() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let base = pc - IC_EXT_WORDS;
|
let base = pc - IC_EXT_WORDS;
|
||||||
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
||||||
if shape_id == 0 {
|
if shape_id == 0 {
|
||||||
@@ -262,6 +282,10 @@ pub(crate) fn ic_set_hit_own(obj: &mut JsObject, bytecode: &[Instr], pc: usize,
|
|||||||
/// `ext_pc` 为扩展字起始位置(首个扩展字处)。
|
/// `ext_pc` 为扩展字起始位置(首个扩展字处)。
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn ic_set_hit_own_poly(obj: &mut JsObject, bytecode: &[Instr], ext_pc: usize, value: JsValue) -> bool {
|
fn ic_set_hit_own_poly(obj: &mut JsObject, bytecode: &[Instr], ext_pc: usize, value: JsValue) -> bool {
|
||||||
|
// 代理接收者恒 miss:命中路径直写代理自身属性槽会绕过 set trap。
|
||||||
|
if obj.is_proxy_obj() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for i in 1..IC_SLOTS {
|
for i in 1..IC_SLOTS {
|
||||||
let base = ext_pc + i * 2;
|
let base = ext_pc + i * 2;
|
||||||
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
let shape_id = bytecode[base] & 0x00FF_FFFF;
|
||||||
|
|||||||
Reference in New Issue
Block a user