mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 10:41:11 +08:00
refactor: 提取 Realm 组合类型,session 与 GC 及原型槽归 realm
This commit is contained in:
@@ -230,7 +230,7 @@ impl Vm {
|
||||
if current_cells[cell_idx].is_null() {
|
||||
// 占位 Cell 保持未初始化(TDZ)直到 MAKE_CELL 置位;
|
||||
// 若绑定为 var 则其初始化 MAKE_CELL 在函数序言先于任何读取执行。
|
||||
current_cells[cell_idx] = self.gc_state.alloc_cell(JsValue::undefined(), false);
|
||||
current_cells[cell_idx] = self.realm.gc.alloc_cell(JsValue::undefined(), false);
|
||||
}
|
||||
current_cells[cell_idx]
|
||||
};
|
||||
@@ -275,14 +275,14 @@ impl Vm {
|
||||
}
|
||||
if current[cell_idx].is_null() {
|
||||
// 无占位 cell:新建。
|
||||
current[cell_idx] = self.gc_state.alloc_cell(value, initialized);
|
||||
current[cell_idx] = self.realm.gc.alloc_cell(value, initialized);
|
||||
} else {
|
||||
let existing_initialized = unsafe { &*current[cell_idx] }.is_initialized();
|
||||
if !initialized && existing_initialized {
|
||||
// TDZ 占位而槽内是已初始化 cell:新建替换。循环体每迭代重执行
|
||||
// 的 TDZ 占位不得原位翻新迭代 cell(已被本迭代前闭包捕获);
|
||||
// 已初始化 cell 保持身份,闭包 upvalue 保值。
|
||||
current[cell_idx] = self.gc_state.alloc_cell(value, initialized);
|
||||
current[cell_idx] = self.realm.gc.alloc_cell(value, initialized);
|
||||
} else {
|
||||
// 更新占位 cell(CREATE_CLOSURE 已建),使闭包 upvalue 指向的
|
||||
// cell 值跟随初始化;初始化标志随指令 b 槽。
|
||||
@@ -309,7 +309,7 @@ impl Vm {
|
||||
while current.len() <= cell_idx {
|
||||
current.push(std::ptr::null_mut());
|
||||
}
|
||||
current[cell_idx] = self.gc_state.alloc_cell(value, true);
|
||||
current[cell_idx] = self.realm.gc.alloc_cell(value, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ impl Vm {
|
||||
}
|
||||
if current[cell_idx].is_null() {
|
||||
let val = self.regs[a];
|
||||
current[cell_idx] = self.gc_state.alloc_cell(val, true);
|
||||
current[cell_idx] = self.realm.gc.alloc_cell(val, true);
|
||||
}
|
||||
let c = unsafe { &*current[cell_idx] };
|
||||
if !c.is_initialized() {
|
||||
@@ -478,7 +478,7 @@ impl Vm {
|
||||
} else {
|
||||
self.regs[rd]
|
||||
};
|
||||
upvals[uv_idx] = self.gc_state.alloc_cell(val, true);
|
||||
upvals[uv_idx] = self.realm.gc.alloc_cell(val, true);
|
||||
self.regs[rd] = unsafe { (*upvals[uv_idx]).value };
|
||||
return Ok(());
|
||||
}
|
||||
@@ -532,7 +532,7 @@ impl Vm {
|
||||
}
|
||||
vm_debug!("STORE_UPVALUE len={} wrote existing", upvals.len());
|
||||
} else {
|
||||
upvals[uv_idx] = self.gc_state.alloc_cell(src_val, true);
|
||||
upvals[uv_idx] = self.realm.gc.alloc_cell(src_val, true);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -544,7 +544,7 @@ impl Vm {
|
||||
vm_trace!("CREATE_REGEXP rd={}", rd);
|
||||
let pat_val = self.regs[a];
|
||||
let flags_val = self.regs[b];
|
||||
let ctor_ptr = self.session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject;
|
||||
let ctor_ptr = self.realm.session.builtin_world().regexp_constructor.as_ptr() as *mut JsObject;
|
||||
let ctor = unsafe { &*ctor_ptr };
|
||||
let Some(native_fn) = ctor.native_fn() else {
|
||||
self.raise_error_kind("TypeError", "RegExp constructor unavailable")?;
|
||||
@@ -1004,7 +1004,7 @@ impl Vm {
|
||||
|
||||
// bound 包装:解包链后转发到最内层 target([[Construct]] 语义)。
|
||||
if ctor_obj.type_tag == oxide_types::object::JsObject::OBJ_TYPE_BOUND {
|
||||
let proto_ptr = &*self.object_prototype as *const JsObject as *mut JsObject;
|
||||
let proto_ptr = &*self.realm.object_prototype as *const JsObject as *mut JsObject;
|
||||
let new_obj = self.alloc_object(JsObject::new_empty(
|
||||
oxide_kernel::shape_forge::EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(proto_ptr),
|
||||
@@ -1012,7 +1012,7 @@ impl Vm {
|
||||
return self.dispatch_new_bound(rd, constructor, new_obj, args, 0);
|
||||
}
|
||||
|
||||
let proto_ptr = &*self.object_prototype as *const JsObject as *mut JsObject;
|
||||
let proto_ptr = &*self.realm.object_prototype as *const JsObject as *mut JsObject;
|
||||
let new_obj = self.alloc_object(JsObject::new_empty(
|
||||
oxide_kernel::shape_forge::EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(proto_ptr),
|
||||
|
||||
@@ -39,7 +39,7 @@ impl Vm {
|
||||
return Err(format!("LOAD_GLOBAL constant index {idx} is not a string key"));
|
||||
}
|
||||
let si = self.property_key_si(key_val)?;
|
||||
let global = self.session.global_object();
|
||||
let global = self.realm.session.global_object();
|
||||
if let Some(val) = self.resolve_property(global, si) {
|
||||
self.regs[rd] = val;
|
||||
Ok(false)
|
||||
@@ -67,7 +67,7 @@ impl Vm {
|
||||
return Err(format!("LOAD_GLOBAL_TYPEOF constant index {idx} is not a string key"));
|
||||
}
|
||||
let si = self.property_key_si(key_val)?;
|
||||
let global = self.session.global_object();
|
||||
let global = self.realm.session.global_object();
|
||||
self.regs[rd] = self.resolve_property(global, si).unwrap_or(JsValue::undefined());
|
||||
Ok(())
|
||||
}
|
||||
@@ -215,7 +215,7 @@ impl Vm {
|
||||
pub(crate) fn dispatch_new_object(&mut self, rd: usize, instr: u32) -> Result<(), String> {
|
||||
let nprops = opcode::a(instr) as usize;
|
||||
vm_trace!("NEW_OBJECT rd={} nprops={}", rd, nprops);
|
||||
let proto_ptr = &*self.object_prototype as *const JsObject as *mut JsObject;
|
||||
let proto_ptr = &*self.realm.object_prototype as *const JsObject as *mut JsObject;
|
||||
let mut shape_id = EMPTY_SHAPE_ID;
|
||||
if nprops > 0 {
|
||||
let key_idxs: Vec<u32> = self.bytecode[self.pc..self.pc + nprops].to_vec();
|
||||
@@ -258,7 +258,7 @@ impl Vm {
|
||||
/// - 登记 session 对象表并计入堆账目;回收由 session GC mark/sweep 承担。
|
||||
pub(crate) fn dispatch_new_session_object(&mut self, rd: usize) -> Result<(), String> {
|
||||
vm_trace!("NEW_SESSION_OBJECT rd={}", rd);
|
||||
let proto_ptr = &*self.object_prototype as *const JsObject as *mut JsObject;
|
||||
let proto_ptr = &*self.realm.object_prototype as *const JsObject as *mut JsObject;
|
||||
let obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr));
|
||||
let obj_ptr = self.alloc_session_object(obj);
|
||||
self.regs[rd] = JsValue::object(obj_ptr as *mut u8);
|
||||
@@ -278,7 +278,7 @@ impl Vm {
|
||||
Some(frame) => (frame.arguments_base, frame.arguments_count),
|
||||
None => (self.inline_args_base, self.inline_args_count),
|
||||
};
|
||||
let proto_ptr = &*self.object_prototype as *const JsObject as *mut JsObject;
|
||||
let proto_ptr = &*self.realm.object_prototype as *const JsObject as *mut JsObject;
|
||||
let obj_ptr = self.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr)));
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
obj.type_tag = JsObject::OBJ_TYPE_ARGUMENTS;
|
||||
@@ -312,7 +312,7 @@ impl Vm {
|
||||
let simple = self.active_module().is_some_and(|m| m.has_simple_params);
|
||||
if strict || !simple {
|
||||
// SAFETY: 指针由绑定层在 session 构造期写入,session 存活期内有效。
|
||||
let thrower_ptr = self.session.builtin_world().throw_type_error.get();
|
||||
let thrower_ptr = self.realm.session.builtin_world().throw_type_error.get();
|
||||
if thrower_ptr.is_null() {
|
||||
// 绑定层尚未写入共享对象(正常路径不出现):退化为数据属性保调用可用。
|
||||
if let Err(msg) =
|
||||
@@ -367,7 +367,7 @@ impl Vm {
|
||||
let sym_iter_si = make_well_known_symbol_key(0);
|
||||
// SAFETY: array_proto 是 perm 层内置对象(BuiltinWorld 持有),地址稳定且
|
||||
// 跨 epoch/session 存活,本调用期间无 GC 搬移。
|
||||
let array_proto = self.session.builtin_world().array_proto.as_ptr();
|
||||
let array_proto = self.realm.session.builtin_world().array_proto.as_ptr();
|
||||
let iter_val = match self.ordinary_get(unsafe { &*array_proto }, sym_iter_si, JsValue::undefined()) {
|
||||
Ok(v) => v,
|
||||
Err(msg) => return self.raise_error_kind("TypeError", &msg),
|
||||
@@ -397,7 +397,7 @@ impl Vm {
|
||||
};
|
||||
let n = count as usize;
|
||||
let rest_len = n.saturating_sub(fixed_count);
|
||||
let proto_ptr = self.session.builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
let proto_ptr = self.realm.session.builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
let obj_ptr =
|
||||
self.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr), rest_len));
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
@@ -417,7 +417,7 @@ impl Vm {
|
||||
pub(crate) fn dispatch_new_array(&mut self, rd: usize, instr: u32) {
|
||||
let n = opcode::imm16(instr) as usize;
|
||||
vm_trace!("NEW_ARRAY rd={} n={}", rd, n);
|
||||
let proto_ptr = self.session.builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
let proto_ptr = self.realm.session.builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
let obj = self.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr), n));
|
||||
self.regs[rd] = JsValue::object(obj as *mut u8);
|
||||
}
|
||||
|
||||
@@ -88,27 +88,27 @@ impl Vm {
|
||||
}
|
||||
return Ok(Some(JsValue::undefined()));
|
||||
}
|
||||
let proto_ptr = self.session.builtin_world().string_proto.as_ptr() as *mut JsObject;
|
||||
let proto_ptr = self.realm.session.builtin_world().string_proto.as_ptr() as *mut JsObject;
|
||||
let proto = unsafe { &*proto_ptr };
|
||||
return self.ordinary_get(proto, prop_name_si, val).map(Some);
|
||||
}
|
||||
if val.is_int() || val.is_double() {
|
||||
let proto_ptr = self.session.builtin_world().number_proto.as_ptr() as *mut JsObject;
|
||||
let proto_ptr = self.realm.session.builtin_world().number_proto.as_ptr() as *mut JsObject;
|
||||
let proto = unsafe { &*proto_ptr };
|
||||
return self.ordinary_get(proto, prop_name_si, val).map(Some);
|
||||
}
|
||||
if val.is_bool() {
|
||||
let proto_ptr = self.session.builtin_world().boolean_proto.as_ptr() as *mut JsObject;
|
||||
let proto_ptr = self.realm.session.builtin_world().boolean_proto.as_ptr() as *mut JsObject;
|
||||
let proto = unsafe { &*proto_ptr };
|
||||
return self.ordinary_get(proto, prop_name_si, val).map(Some);
|
||||
}
|
||||
if val.is_bigint() {
|
||||
let proto_ptr = self.session.builtin_world().bigint_proto.as_ptr() as *mut JsObject;
|
||||
let proto_ptr = self.realm.session.builtin_world().bigint_proto.as_ptr() as *mut JsObject;
|
||||
let proto = unsafe { &*proto_ptr };
|
||||
return self.ordinary_get(proto, prop_name_si, val).map(Some);
|
||||
}
|
||||
if val.is_symbol() {
|
||||
let proto_ptr = self.session.builtin_world().symbol_proto.as_ptr() as *mut JsObject;
|
||||
let proto_ptr = self.realm.session.builtin_world().symbol_proto.as_ptr() as *mut JsObject;
|
||||
let proto = unsafe { &*proto_ptr };
|
||||
return self.ordinary_get(proto, prop_name_si, val).map(Some);
|
||||
}
|
||||
@@ -790,7 +790,7 @@ impl Vm {
|
||||
return Err(format!("DELETE_GLOBAL_PROP_C constant index {idx} is not a string key"));
|
||||
}
|
||||
let si = self.property_key_si(key_val)?;
|
||||
let global_ptr = self.session.global_object().as_ptr() as *mut JsObject;
|
||||
let global_ptr = self.realm.session.global_object().as_ptr() as *mut JsObject;
|
||||
// SAFETY: 全局对象钉在 session 永久区,指针在 VM 生命周期内有效。
|
||||
let obj = unsafe { &mut *global_ptr };
|
||||
// 统一走共享删除逻辑(与 Reflect.deleteProperty 同源);不可配置返回
|
||||
|
||||
Reference in New Issue
Block a user