refactor: 拆分 Kernel 中可变 Session 与不可变 Core

This commit is contained in:
爱特每羊队
2026-06-14 12:58:09 +08:00
parent ec537cb8b3
commit d242d08e6d
63 changed files with 666 additions and 615 deletions
+4 -4
View File
@@ -8,13 +8,13 @@ impl Vm {
let lhs = self.regs[a];
let rhs = self.regs[b];
if lhs.is_string() || rhs.is_string() {
let ls = coercion::to_string(self.kernel.string_forge().as_ref(), lhs);
let rs = coercion::to_string(self.kernel.string_forge().as_ref(), rhs);
let ls = coercion::to_string(self.kernel_core.string_forge().as_ref(), lhs);
let rs = coercion::to_string(self.kernel_core.string_forge().as_ref(), rhs);
let concat = format!("{ls}{rs}");
self.regs[rd] = self.intern(&concat);
} else {
let ln = coercion::to_number(lhs, self.kernel.string_forge().as_ref());
let rn = coercion::to_number(rhs, self.kernel.string_forge().as_ref());
let ln = coercion::to_number(lhs, self.kernel_core.string_forge().as_ref());
let rn = coercion::to_number(rhs, self.kernel_core.string_forge().as_ref());
self.regs[rd] = JsValue::float(ln + rn);
}
}
+13 -13
View File
@@ -14,25 +14,25 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_bit_and(&mut self, rd: usize, a: usize, b: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[a], sf) & coercion::to_int32(self.regs[b], sf));
}
#[inline(always)]
pub(crate) fn dispatch_bit_or(&mut self, rd: usize, a: usize, b: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[a], sf) | coercion::to_int32(self.regs[b], sf));
}
#[inline(always)]
pub(crate) fn dispatch_bit_xor(&mut self, rd: usize, a: usize, b: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[a], sf) ^ coercion::to_int32(self.regs[b], sf));
}
#[inline(always)]
pub(crate) fn dispatch_shl(&mut self, rd: usize, a: usize, b: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
let lhs = coercion::to_int32(self.regs[a], sf);
let shift = coercion::to_uint32(self.regs[b], sf) & 0x1F;
self.regs[rd] = JsValue::int(lhs.wrapping_shl(shift));
@@ -40,7 +40,7 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_shr(&mut self, rd: usize, a: usize, b: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
let lhs = coercion::to_int32(self.regs[a], sf);
let shift = coercion::to_uint32(self.regs[b], sf) & 0x1F;
self.regs[rd] = JsValue::int(lhs >> shift);
@@ -48,7 +48,7 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_ushr(&mut self, rd: usize, a: usize, b: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
let lhs = coercion::to_uint32(self.regs[a], sf);
let shift = coercion::to_uint32(self.regs[b], sf) & 0x1F;
self.write_ushr_result(rd, lhs >> shift);
@@ -56,31 +56,31 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_bit_not(&mut self, rd: usize, a: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
self.regs[rd] = JsValue::int(!coercion::to_int32(self.regs[a], sf));
}
#[inline(always)]
pub(crate) fn dispatch_compound_bit_and(&mut self, rd: usize, a: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[rd], sf) & coercion::to_int32(self.regs[a], sf));
}
#[inline(always)]
pub(crate) fn dispatch_compound_bit_or(&mut self, rd: usize, a: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[rd], sf) | coercion::to_int32(self.regs[a], sf));
}
#[inline(always)]
pub(crate) fn dispatch_compound_bit_xor(&mut self, rd: usize, a: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
self.regs[rd] = JsValue::int(coercion::to_int32(self.regs[rd], sf) ^ coercion::to_int32(self.regs[a], sf));
}
#[inline(always)]
pub(crate) fn dispatch_compound_shl(&mut self, rd: usize, a: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
let lhs = coercion::to_int32(self.regs[rd], sf);
let shift = coercion::to_uint32(self.regs[a], sf) & 0x1F;
self.regs[rd] = JsValue::int(lhs.wrapping_shl(shift));
@@ -88,7 +88,7 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_compound_shr(&mut self, rd: usize, a: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
let lhs = coercion::to_int32(self.regs[rd], sf);
let shift = coercion::to_uint32(self.regs[a], sf) & 0x1F;
self.regs[rd] = JsValue::int(lhs >> shift);
@@ -96,7 +96,7 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_compound_ushr(&mut self, rd: usize, a: usize) {
let sf = self.kernel.string_forge().as_ref();
let sf = self.kernel_core.string_forge().as_ref();
let lhs = coercion::to_uint32(self.regs[rd], sf);
let shift = coercion::to_uint32(self.regs[a], sf) & 0x1F;
self.write_ushr_result(rd, lhs >> shift);
+2 -2
View File
@@ -20,7 +20,7 @@ impl Vm {
pub(crate) fn dispatch_native_call(
&mut self, obj: &JsObject, callee: JsValue, this_reg: u8, first_arg_reg: u8, arg_count: usize,
) -> Result<(), String> {
if self.native_call_depth >= self.kernel.config.max_call_depth {
if self.native_call_depth >= self.kernel_core.config.max_call_depth {
return Err("RangeError: Maximum call stack size exceeded".into());
}
let (args_buf, len) = Self::build_native_args(first_arg_reg, arg_count, this_reg);
@@ -45,7 +45,7 @@ impl Vm {
(err_val, self.thrown_error_kind(err_val))
} else {
let msg = if err_val.is_string() {
self.kernel()
self.kernel_core
.string_forge()
.lookup(err_val.as_string_index())
.unwrap_or_else(|| format!("{err_val}"))
+6 -6
View File
@@ -5,37 +5,37 @@ use oxide_types::value::JsValue;
impl Vm {
#[inline(always)]
pub(crate) fn dispatch_eq(&mut self, rd: usize, a: usize, b: usize) {
let eq = coercion::abstract_eq(self.regs[a], self.regs[b], self.kernel.string_forge().as_ref());
let eq = coercion::abstract_eq(self.regs[a], self.regs[b], self.kernel_core.string_forge().as_ref());
self.regs[rd] = JsValue::bool(eq);
}
#[inline(always)]
pub(crate) fn dispatch_neq(&mut self, rd: usize, a: usize, b: usize) {
let ne = !coercion::abstract_eq(self.regs[a], self.regs[b], self.kernel.string_forge().as_ref());
let ne = !coercion::abstract_eq(self.regs[a], self.regs[b], self.kernel_core.string_forge().as_ref());
self.regs[rd] = JsValue::bool(ne);
}
#[inline(always)]
pub(crate) fn dispatch_lt(&mut self, rd: usize, a: usize, b: usize) {
let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[a], self.regs[b]);
let rel = coercion::relational_compare(self.kernel_core.string_forge().as_ref(), self.regs[a], self.regs[b]);
self.regs[rd] = JsValue::bool(rel.unwrap_or(false));
}
#[inline(always)]
pub(crate) fn dispatch_gt(&mut self, rd: usize, a: usize, b: usize) {
let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[b], self.regs[a]);
let rel = coercion::relational_compare(self.kernel_core.string_forge().as_ref(), self.regs[b], self.regs[a]);
self.regs[rd] = JsValue::bool(rel.unwrap_or(false));
}
#[inline(always)]
pub(crate) fn dispatch_lte(&mut self, rd: usize, a: usize, b: usize) {
let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[b], self.regs[a]);
let rel = coercion::relational_compare(self.kernel_core.string_forge().as_ref(), self.regs[b], self.regs[a]);
self.regs[rd] = JsValue::bool(!rel.unwrap_or(true));
}
#[inline(always)]
pub(crate) fn dispatch_gte(&mut self, rd: usize, a: usize, b: usize) {
let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[a], self.regs[b]);
let rel = coercion::relational_compare(self.kernel_core.string_forge().as_ref(), self.regs[a], self.regs[b]);
self.regs[rd] = JsValue::bool(!rel.unwrap_or(true));
}
+3 -3
View File
@@ -6,7 +6,7 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_and(&mut self, rd: usize, a: usize, b: usize) {
let val = self.regs[a];
if coercion::to_boolean(val, self.kernel.string_forge().as_ref()) {
if coercion::to_boolean(val, self.kernel_core.string_forge().as_ref()) {
self.regs[rd] = self.regs[b];
} else {
self.regs[rd] = val;
@@ -16,7 +16,7 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_or(&mut self, rd: usize, a: usize, b: usize) {
let val = self.regs[a];
if coercion::to_boolean(val, self.kernel.string_forge().as_ref()) {
if coercion::to_boolean(val, self.kernel_core.string_forge().as_ref()) {
self.regs[rd] = val;
} else {
self.regs[rd] = self.regs[b];
@@ -25,7 +25,7 @@ impl Vm {
#[inline(always)]
pub(crate) fn dispatch_not(&mut self, rd: usize, a: usize) {
let b = !coercion::to_boolean(self.regs[a], self.kernel.string_forge().as_ref());
let b = !coercion::to_boolean(self.regs[a], self.kernel_core.string_forge().as_ref());
self.regs[rd] = JsValue::bool(b);
}
}
+10 -10
View File
@@ -47,7 +47,7 @@ impl Vm {
let receiver = self.regs[rd];
let obj = unsafe { &mut *obj_ptr };
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
let n = coercion::to_number(prop_val, self.kernel.string_forge().as_ref());
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
let new_val = JsValue::float(n + 1.0);
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
self.regs[a] = new_val;
@@ -61,7 +61,7 @@ impl Vm {
let receiver = self.regs[rd];
let obj = unsafe { &mut *obj_ptr };
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
let n = coercion::to_number(prop_val, self.kernel.string_forge().as_ref());
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
let new_val = JsValue::float(n - 1.0);
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
self.regs[a] = new_val;
@@ -76,7 +76,7 @@ impl Vm {
let obj = unsafe { &mut *obj_ptr };
let prop_name_si = self.property_key_si(self.regs[a]);
let prop_val = self.ordinary_get(obj, prop_name_si, receiver)?;
let n = coercion::to_number(prop_val, self.kernel.string_forge().as_ref());
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
let new_val = JsValue::float(n + 1.0);
self.ordinary_set(obj, prop_name_si, new_val, receiver)?;
self.regs[b] = new_val;
@@ -91,7 +91,7 @@ impl Vm {
let obj = unsafe { &mut *obj_ptr };
let prop_name_si = self.property_key_si(self.regs[a]);
let prop_val = self.ordinary_get(obj, prop_name_si, receiver)?;
let n = coercion::to_number(prop_val, self.kernel.string_forge().as_ref());
let n = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
let new_val = JsValue::float(n - 1.0);
self.ordinary_set(obj, prop_name_si, new_val, receiver)?;
self.regs[b] = new_val;
@@ -107,12 +107,12 @@ impl Vm {
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
let rhs = self.regs[a];
let new_val = if prop_val.is_string() || rhs.is_string() {
let ls = coercion::to_string(self.kernel.string_forge().as_ref(), prop_val);
let rs = coercion::to_string(self.kernel.string_forge().as_ref(), rhs);
let ls = coercion::to_string(self.kernel_core.string_forge().as_ref(), prop_val);
let rs = coercion::to_string(self.kernel_core.string_forge().as_ref(), rhs);
self.intern(&format!("{ls}{rs}"))
} else {
let ln = coercion::to_number(prop_val, self.kernel.string_forge().as_ref());
let rn = coercion::to_number(rhs, self.kernel.string_forge().as_ref());
let ln = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
let rn = coercion::to_number(rhs, self.kernel_core.string_forge().as_ref());
JsValue::float(ln + rn)
};
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
@@ -132,8 +132,8 @@ impl Vm {
let receiver = self.regs[rd];
let obj = unsafe { &mut *obj_ptr };
let prop_val = self.read_member_prop(obj, prop_name_si, receiver)?;
let ln = coercion::to_number(prop_val, self.kernel.string_forge().as_ref());
let rn = coercion::to_number(self.regs[a], self.kernel.string_forge().as_ref());
let ln = coercion::to_number(prop_val, self.kernel_core.string_forge().as_ref());
let rn = coercion::to_number(self.regs[a], self.kernel_core.string_forge().as_ref());
let new_val = JsValue::float(op(ln, rn));
self.regs[a] = new_val;
self.set_member_prop(obj, prop_name_si, new_val, receiver)?;
+10 -10
View File
@@ -47,7 +47,7 @@ impl Vm {
let obj_ptr = val.as_object_ptr() as *mut JsObject;
if obj_ptr.is_null() {
if val.is_string() {
let proto_ptr = self.kernel.builtin_world().string_proto.as_ptr() as *mut JsObject;
let proto_ptr = self.session.builtin_world().string_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &*proto_ptr };
let prop_name_si = self.property_key_si(self.regs[b]);
let resolved = self.ordinary_get(proto, prop_name_si, val)?;
@@ -58,7 +58,7 @@ impl Vm {
}
}
if val.is_int() || val.is_double() {
let proto_ptr = self.kernel.builtin_world().number_proto.as_ptr() as *mut JsObject;
let proto_ptr = self.session.builtin_world().number_proto.as_ptr() as *mut JsObject;
let proto = unsafe { &*proto_ptr };
let prop_name_si = self.property_key_si(self.regs[b]);
let resolved = self.ordinary_get(proto, prop_name_si, val)?;
@@ -96,7 +96,7 @@ impl Vm {
if let Some(value) = ic_get_hit(obj, cached_shape_id, cached_slot) {
self.regs[a] = value;
ic_trace!("IC_GET hit shape={} slot={}", cached_shape_id, cached_slot);
} else if let Some(template) = self.kernel.prop_forge().get_template(obj.shape_id()) {
} else if let Some(template) = self.kernel_core.prop_forge().get_template(obj.shape_id()) {
prop_cache_miss();
if template.prop_name == prop_name_si {
if template.position < obj.prop_vec_len() as u32 {
@@ -120,7 +120,7 @@ impl Vm {
prop_cache_miss();
ic_debug!("IC_GET miss shape={} prop={}", obj.shape_id(), prop_name_si);
let resolved = self.ordinary_get(obj, prop_name_si, val)?;
if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
self.write_ic_back(obj.shape_id(), pos);
}
self.regs[a] = resolved;
@@ -135,7 +135,7 @@ impl Vm {
};
let prop_name_si = self.property_key_si(self.regs[b]);
if self.kernel.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") {
if self.kernel_core.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") {
let obj = unsafe { &mut *obj_ptr };
if self.is_object_prototype(obj_ptr) && !self.regs[a].is_null() {
self.raise_type_error("Object.prototype.__proto__ is immutable")?;
@@ -163,7 +163,7 @@ impl Vm {
if ic_set_hit(obj, cached_shape_id, cached_slot, value) {
ic_trace!("IC_SET hit shape={} slot={}", cached_shape_id, cached_slot);
} else if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
} else if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
prop_cache_miss();
obj.set_prop_at(pos, value);
self.write_ic_back(obj.shape_id(), pos);
@@ -173,10 +173,10 @@ impl Vm {
let old_shape = obj.shape_id();
self.ordinary_set_dispatch(obj, prop_name_si, value, receiver)?;
if old_shape != obj.shape_id() {
if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
if let Some(pos) = self.kernel_core.shape_forge().lookup_position(obj.shape_id(), prop_name_si) {
self.write_ic_back(obj.shape_id(), pos);
ic_debug!("IC_SET write-back shape={} slot={}", obj.shape_id(), pos);
self.kernel.prop_forge().upsert(
self.kernel_core.prop_forge().upsert(
obj.shape_id(),
PropTemplate {
shape_id: obj.shape_id(),
@@ -211,7 +211,7 @@ impl Vm {
};
let obj = unsafe { &mut *obj_ptr };
let prop_name_si = self.property_key_si(self.regs[b]);
if self.kernel.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") {
if self.kernel_core.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") {
if self.is_object_prototype(obj_ptr) && !self.regs[a].is_null() {
self.raise_type_error("Object.prototype.__proto__ is immutable")?;
return Ok(());
@@ -242,7 +242,7 @@ impl Vm {
};
let obj = unsafe { &mut *obj_ptr };
let prop_name_si = self.property_key_si(self.regs[a]);
if self.kernel.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") {
if self.kernel_core.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") {
if self.is_object_prototype(obj_ptr) && !self.regs[b].is_null() {
self.raise_type_error("Object.prototype.__proto__ is immutable")?;
return Ok(());