mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
feat: 模块命名空间导出条目表与预注册
This commit is contained in:
@@ -28,6 +28,11 @@ pub fn bind_global(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
|
||||
),
|
||||
// 模块求值 / 命名空间内部辅助(import 实现;非 JS 标准全局,以下划线开头避免撞名)。
|
||||
("__moduleObject", oxide_builtins::module::module_object::<crate::vm::Vm> as *const (), 0),
|
||||
(
|
||||
"__modulePreRegister",
|
||||
oxide_builtins::module::module_pre_register::<crate::vm::Vm> as *const (),
|
||||
2,
|
||||
),
|
||||
("__moduleSet", oxide_builtins::module::module_set::<crate::vm::Vm> as *const (), 3),
|
||||
("__moduleGet", oxide_builtins::module::module_get::<crate::vm::Vm> as *const (), 2),
|
||||
(
|
||||
|
||||
@@ -6,7 +6,7 @@ use oxide_types::value::JsValue;
|
||||
use rustc_hash::FxBuildHasher;
|
||||
|
||||
use crate::vm::Vm;
|
||||
use oxide_builtins::{array_buffer, data_view, disposable_stack, map, regexp, set, typed_array};
|
||||
use oxide_builtins::{array_buffer, data_view, disposable_stack, map, module, regexp, set, typed_array};
|
||||
|
||||
impl Vm {
|
||||
pub(crate) fn is_session_escape_root_ptr(&self, target_ptr: *mut JsObject) -> bool {
|
||||
@@ -99,6 +99,12 @@ impl Vm {
|
||||
} else if src_ref.holds_compiled_regex() {
|
||||
// 已编译正则是 Box 深拷贝到新对象:源盒随 epoch 释放,互不共享。
|
||||
regexp::clone_regexp_native(src_ref, dst_ref);
|
||||
} else if src_ref.is_module_namespace() {
|
||||
// 条目表深拷贝到新对象并改写值边:`clone_for_session_epoch` 只浅拷贝
|
||||
// native_data 指针,共享同一表会在释放时双放。
|
||||
module::clone_module_ns_native_with_rewrite(src_ref, dst_ref, |value| {
|
||||
self.promote_value_if_epoch_object(value, forwarding)
|
||||
});
|
||||
}
|
||||
// 账目计入:对象头 + 堆数据(属性/元素/meta Vec + native 状态盒),用 clone 后的 dst 核算。
|
||||
self.gc_state.session_bytes_allocated +=
|
||||
@@ -205,6 +211,10 @@ impl Vm {
|
||||
crate::async_generator::rewrite_async_generator_native(obj, |value| {
|
||||
self.promote_value_if_epoch_object(value, forwarding)
|
||||
});
|
||||
} else if obj.is_module_namespace() {
|
||||
module::rewrite_module_ns_native(obj, |value| {
|
||||
self.promote_value_if_epoch_object(value, forwarding)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use oxide_types::value::JsValue;
|
||||
use rustc_hash::FxBuildHasher;
|
||||
|
||||
use crate::vm::Vm;
|
||||
use oxide_builtins::{array_buffer, data_view, disposable_stack, map, regexp, set, typed_array};
|
||||
use oxide_builtins::{array_buffer, data_view, disposable_stack, map, module, regexp, set, typed_array};
|
||||
|
||||
/// session 级 mark-sweep GC 的状态与统计。
|
||||
///
|
||||
@@ -113,6 +113,7 @@ impl SessionGc {
|
||||
|
||||
bytes += map::map_native_size(obj);
|
||||
bytes += set::set_native_size(obj);
|
||||
bytes += module::module_ns_native_size(obj);
|
||||
bytes += disposable_stack::disposable_stack_native_size(obj);
|
||||
bytes += array_buffer::array_buffer_native_size(obj);
|
||||
bytes += regexp::regexp_native_size(obj);
|
||||
@@ -186,6 +187,11 @@ impl SessionGc {
|
||||
Self::process_edge(value, vm, stack, live_strings, live_bigints);
|
||||
}
|
||||
}
|
||||
if obj.is_module_namespace() {
|
||||
for value in module::module_ns_native_edges(obj) {
|
||||
Self::process_edge(value, vm, stack, live_strings, live_bigints);
|
||||
}
|
||||
}
|
||||
if obj.is_generator_obj() {
|
||||
for value in crate::generator::generator_native_edges(obj) {
|
||||
Self::process_edge(value, vm, stack, live_strings, live_bigints);
|
||||
@@ -347,6 +353,13 @@ impl SessionGc {
|
||||
}
|
||||
}
|
||||
}
|
||||
if obj.is_module_namespace() {
|
||||
for value in module::module_ns_native_edges(obj) {
|
||||
if value.is_string() {
|
||||
Self::mark_string_live(live, value.as_string_ptr_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
if obj.is_disposable_stack_obj() || obj.is_async_disposable_stack_obj() {
|
||||
for value in disposable_stack::dispose_edges(obj) {
|
||||
if value.is_string() {
|
||||
@@ -503,6 +516,7 @@ impl SessionGc {
|
||||
|
||||
freed_bytes += map::drop_map_native(obj);
|
||||
freed_bytes += set::drop_set_native(obj);
|
||||
freed_bytes += module::drop_module_ns_native(obj);
|
||||
freed_bytes += disposable_stack::drop_dispose_native(obj);
|
||||
freed_bytes += array_buffer::drop_array_buffer_native(obj);
|
||||
freed_bytes += regexp::drop_regexp_native(obj);
|
||||
@@ -608,6 +622,9 @@ impl SessionGc {
|
||||
} else if old_ref.holds_compiled_regex() {
|
||||
// 已编译正则是 Box 深拷贝到新对象:源 Box 由 drop 释放,互不共享。
|
||||
regexp::clone_regexp_native(old_ref, new_ref);
|
||||
} else if old_ref.is_module_namespace() {
|
||||
// 条目表深拷贝:`clone_for_session_epoch` 只浅拷贝 native_data 指针。
|
||||
module::clone_module_ns_native_with_rewrite(old_ref, new_ref, |value| value);
|
||||
}
|
||||
forwarding.insert(old_ptr, new_ptr);
|
||||
freed_bytes += Self::drop_session_object_heap_data(old_ptr);
|
||||
@@ -654,6 +671,8 @@ impl SessionGc {
|
||||
crate::async_generator::rewrite_async_generator_native(obj, |value| {
|
||||
rewrite_forwarded_value(value, &forwarding)
|
||||
});
|
||||
} else if obj.is_module_namespace() {
|
||||
module::rewrite_module_ns_native(obj, |value| rewrite_forwarded_value(value, &forwarding));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,24 @@ impl Vm {
|
||||
let mut current = Some(obj);
|
||||
let mut depth = 0usize;
|
||||
while let Some(obj) = current {
|
||||
// 模块命名空间 exotic [[Get]]:条目表是权威状态,预注册但未初始化的
|
||||
// 导出读抛 ReferenceError;非 live ns(无表)落普通属性路径零行为变化。
|
||||
if obj.is_module_namespace() {
|
||||
if let Some(state) = oxide_builtins::module::module_ns_export(obj, prop_name_si) {
|
||||
return match state {
|
||||
oxide_builtins::module::ModuleNsQuery::Initialized(v) => Ok(v),
|
||||
oxide_builtins::module::ModuleNsQuery::Uninitialized => {
|
||||
let msg = "Cannot access module export before initialization";
|
||||
if self.native_call_depth == 0 {
|
||||
self.raise_error_kind("ReferenceError", msg)?;
|
||||
} else {
|
||||
return Err(self.error_message_text("ReferenceError", msg));
|
||||
}
|
||||
Ok(JsValue::undefined())
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
if obj.is_array() && prop_name_si == length_si {
|
||||
return Ok(obj.logical_len_value());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user