mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
style: 修 rustfmt 格式化差异
This commit is contained in:
@@ -22,9 +22,7 @@ use std::sync::Arc;
|
|||||||
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
|
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
|
||||||
use oxide_types::mem::P;
|
use oxide_types::mem::P;
|
||||||
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
|
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
|
||||||
use oxide_types::private_key::{
|
use oxide_types::private_key::{decode_symbol_key, int_key_value, is_int_key, WELL_KNOWN_SYMBOL_COUNT};
|
||||||
decode_symbol_key, int_key_value, is_int_key, WELL_KNOWN_SYMBOL_COUNT,
|
|
||||||
};
|
|
||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use oxide_runtime_api::{to_string_full, VmHost};
|
use oxide_runtime_api::{to_string_full, VmHost};
|
||||||
@@ -58,7 +56,10 @@ pub enum MessageValue {
|
|||||||
Map(Vec<(MessageValue, MessageValue)>),
|
Map(Vec<(MessageValue, MessageValue)>),
|
||||||
Set(Vec<MessageValue>),
|
Set(Vec<MessageValue>),
|
||||||
Date(f64),
|
Date(f64),
|
||||||
RegExp { source: String, flags: String },
|
RegExp {
|
||||||
|
source: String,
|
||||||
|
flags: String,
|
||||||
|
},
|
||||||
Error {
|
Error {
|
||||||
name: String,
|
name: String,
|
||||||
message: Option<String>,
|
message: Option<String>,
|
||||||
@@ -66,7 +67,10 @@ pub enum MessageValue {
|
|||||||
},
|
},
|
||||||
/// 跨 realm 符号:`well_known` 为 well-known 局部下标(0..14),
|
/// 跨 realm 符号:`well_known` 为 well-known 局部下标(0..14),
|
||||||
/// `description` 为用户符号描述。
|
/// `description` 为用户符号描述。
|
||||||
Symbol { well_known: Option<u32>, description: Option<String> },
|
Symbol {
|
||||||
|
well_known: Option<u32>,
|
||||||
|
description: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// detach 状态:`on_stack` 记录正在 detach 中的源对象指针(递归栈),用于
|
/// detach 状态:`on_stack` 记录正在 detach 中的源对象指针(递归栈),用于
|
||||||
@@ -98,9 +102,7 @@ impl DetachState {
|
|||||||
/// # 返回值
|
/// # 返回值
|
||||||
/// 成功 `Ok(MessageValue)`,失败 `Err(DataCloneError)`。
|
/// 成功 `Ok(MessageValue)`,失败 `Err(DataCloneError)`。
|
||||||
pub fn detach_message<H: VmHost>(
|
pub fn detach_message<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, value: JsValue, transfer: &HashSet<*const JsObject>,
|
||||||
value: JsValue,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let mut state = DetachState::new();
|
let mut state = DetachState::new();
|
||||||
detach_value(vm, &mut state, value, transfer)
|
detach_value(vm, &mut state, value, transfer)
|
||||||
@@ -108,10 +110,7 @@ pub fn detach_message<H: VmHost>(
|
|||||||
|
|
||||||
/// 递归 detach 一个值:非对象走原始值分派,对象先查循环再按类型分派。
|
/// 递归 detach 一个值:非对象走原始值分派,对象先查循环再按类型分派。
|
||||||
fn detach_value<H: VmHost>(
|
fn detach_value<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, state: &mut DetachState, value: JsValue, transfer: &HashSet<*const JsObject>,
|
||||||
state: &mut DetachState,
|
|
||||||
value: JsValue,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
if !value.is_object() {
|
if !value.is_object() {
|
||||||
return detach_primitive(vm, value);
|
return detach_primitive(vm, value);
|
||||||
@@ -162,7 +161,10 @@ fn detach_primitive<H: VmHost>(vm: &mut H, value: JsValue) -> Result<MessageValu
|
|||||||
fn detach_symbol<H: VmHost>(vm: &mut H, value: JsValue) -> MessageValue {
|
fn detach_symbol<H: VmHost>(vm: &mut H, value: JsValue) -> MessageValue {
|
||||||
let local_index = value.as_symbol_local_index();
|
let local_index = value.as_symbol_local_index();
|
||||||
if local_index < WELL_KNOWN_SYMBOL_COUNT {
|
if local_index < WELL_KNOWN_SYMBOL_COUNT {
|
||||||
MessageValue::Symbol { well_known: Some(local_index), description: None }
|
MessageValue::Symbol {
|
||||||
|
well_known: Some(local_index),
|
||||||
|
description: None,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let description = vm.symbol_description(local_index);
|
let description = vm.symbol_description(local_index);
|
||||||
MessageValue::Symbol { well_known: None, description }
|
MessageValue::Symbol { well_known: None, description }
|
||||||
@@ -171,10 +173,7 @@ fn detach_symbol<H: VmHost>(vm: &mut H, value: JsValue) -> MessageValue {
|
|||||||
|
|
||||||
/// 对象值按类型分派:装箱解箱、缓冲区、容器递归、Date/RegExp/Error 专用。
|
/// 对象值按类型分派:装箱解箱、缓冲区、容器递归、Date/RegExp/Error 专用。
|
||||||
fn detach_object<H: VmHost>(
|
fn detach_object<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, state: &mut DetachState, value: JsValue, transfer: &HashSet<*const JsObject>,
|
||||||
state: &mut DetachState,
|
|
||||||
value: JsValue,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let src_ptr = value.as_js_object_ptr();
|
let src_ptr = value.as_js_object_ptr();
|
||||||
// SAFETY: is_object 保证非空指针;对象在 native 执行期间被根保持、不被回收。
|
// SAFETY: is_object 保证非空指针;对象在 native 执行期间被根保持、不被回收。
|
||||||
@@ -260,9 +259,7 @@ fn detach_boxed<H: VmHost>(vm: &mut H, src: &JsObject) -> MessageValue {
|
|||||||
/// ArrayBuffer:transfer 命中移动载荷(源 detach),未命中克隆字节;detached
|
/// ArrayBuffer:transfer 命中移动载荷(源 detach),未命中克隆字节;detached
|
||||||
/// 源报 DataCloneError。
|
/// 源报 DataCloneError。
|
||||||
fn detach_array_buffer<H: VmHost>(
|
fn detach_array_buffer<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, src: &JsObject, transfer: &HashSet<*const JsObject>,
|
||||||
src: &JsObject,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let Some(payload_ptr) = crate::array_buffer::array_buffer_payload_ptr(src) else {
|
let Some(payload_ptr) = crate::array_buffer::array_buffer_payload_ptr(src) else {
|
||||||
return Err(data_clone_error(vm, "ArrayBuffer internal state invalid"));
|
return Err(data_clone_error(vm, "ArrayBuffer internal state invalid"));
|
||||||
@@ -290,10 +287,7 @@ fn detach_array_buffer<H: VmHost>(
|
|||||||
|
|
||||||
/// Map:逐条 detach 键值后组装 `MessageValue::Map`。
|
/// Map:逐条 detach 键值后组装 `MessageValue::Map`。
|
||||||
fn detach_map<H: VmHost>(
|
fn detach_map<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, state: &mut DetachState, src: &JsObject, transfer: &HashSet<*const JsObject>,
|
||||||
state: &mut DetachState,
|
|
||||||
src: &JsObject,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let src_inner = src.native_data() as *const MapInner;
|
let src_inner = src.native_data() as *const MapInner;
|
||||||
if src_inner.is_null() {
|
if src_inner.is_null() {
|
||||||
@@ -313,10 +307,7 @@ fn detach_map<H: VmHost>(
|
|||||||
|
|
||||||
/// Set:逐个 detach 元素后组装 `MessageValue::Set`。
|
/// Set:逐个 detach 元素后组装 `MessageValue::Set`。
|
||||||
fn detach_set<H: VmHost>(
|
fn detach_set<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, state: &mut DetachState, src: &JsObject, transfer: &HashSet<*const JsObject>,
|
||||||
state: &mut DetachState,
|
|
||||||
src: &JsObject,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let src_inner = src.native_data() as *const SetInner;
|
let src_inner = src.native_data() as *const SetInner;
|
||||||
if src_inner.is_null() {
|
if src_inner.is_null() {
|
||||||
@@ -336,10 +327,7 @@ fn detach_set<H: VmHost>(
|
|||||||
/// Error:name 经原型链 Get 归一、message 仅取自有数据描述符槽值并 ToString、
|
/// Error:name 经原型链 Get 归一、message 仅取自有数据描述符槽值并 ToString、
|
||||||
/// cause 在场时递归 detach。
|
/// cause 在场时递归 detach。
|
||||||
fn detach_error<H: VmHost>(
|
fn detach_error<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, state: &mut DetachState, src: &JsObject, transfer: &HashSet<*const JsObject>,
|
||||||
state: &mut DetachState,
|
|
||||||
src: &JsObject,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let src_val = JsValue::from_js_object(src as *const JsObject as *mut JsObject);
|
let src_val = JsValue::from_js_object(src as *const JsObject as *mut JsObject);
|
||||||
let si_name = vm.kernel_core().perm_interner().intern("name").0;
|
let si_name = vm.kernel_core().perm_interner().intern("name").0;
|
||||||
@@ -377,11 +365,7 @@ fn detach_error<H: VmHost>(
|
|||||||
|
|
||||||
/// 读源对象自有属性的值:数据属性直读槽值,访问器属性经 getter 取值。
|
/// 读源对象自有属性的值:数据属性直读槽值,访问器属性经 getter 取值。
|
||||||
fn read_own_value<H: VmHost>(
|
fn read_own_value<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, src: &JsObject, src_val: JsValue, si: u32, store: u32,
|
||||||
src: &JsObject,
|
|
||||||
src_val: JsValue,
|
|
||||||
si: u32,
|
|
||||||
store: u32,
|
|
||||||
) -> Result<JsValue, JsValue> {
|
) -> Result<JsValue, JsValue> {
|
||||||
let is_accessor = src.prop_meta_at(store).is_some_and(|m| m.is_accessor);
|
let is_accessor = src.prop_meta_at(store).is_some_and(|m| m.is_accessor);
|
||||||
if !is_accessor {
|
if !is_accessor {
|
||||||
@@ -400,10 +384,7 @@ fn read_own_value<H: VmHost>(
|
|||||||
|
|
||||||
/// 数组:逐元素 detach(元素区 0..length)。
|
/// 数组:逐元素 detach(元素区 0..length)。
|
||||||
fn detach_array<H: VmHost>(
|
fn detach_array<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, state: &mut DetachState, src: &JsObject, transfer: &HashSet<*const JsObject>,
|
||||||
state: &mut DetachState,
|
|
||||||
src: &JsObject,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let len = src.logical_len() as usize;
|
let len = src.logical_len() as usize;
|
||||||
let mut result = Vec::with_capacity(len);
|
let mut result = Vec::with_capacity(len);
|
||||||
@@ -417,10 +398,7 @@ fn detach_array<H: VmHost>(
|
|||||||
|
|
||||||
/// plain 对象:复制可枚举自有属性(字符串键加 Symbol 键),键值均 detach。
|
/// plain 对象:复制可枚举自有属性(字符串键加 Symbol 键),键值均 detach。
|
||||||
fn detach_plain_object<H: VmHost>(
|
fn detach_plain_object<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, state: &mut DetachState, src: &JsObject, transfer: &HashSet<*const JsObject>,
|
||||||
state: &mut DetachState,
|
|
||||||
src: &JsObject,
|
|
||||||
transfer: &HashSet<*const JsObject>,
|
|
||||||
) -> Result<MessageValue, JsValue> {
|
) -> Result<MessageValue, JsValue> {
|
||||||
let src_val = JsValue::from_js_object(src as *const JsObject as *mut JsObject);
|
let src_val = JsValue::from_js_object(src as *const JsObject as *mut JsObject);
|
||||||
let str_keys = walk_own_keys(vm, src);
|
let str_keys = walk_own_keys(vm, src);
|
||||||
@@ -463,7 +441,10 @@ fn key_si_to_message_value<H: VmHost>(vm: &mut H, si: u32) -> Result<MessageValu
|
|||||||
fn symbol_key_to_message_value<H: VmHost>(vm: &mut H, si: u32) -> MessageValue {
|
fn symbol_key_to_message_value<H: VmHost>(vm: &mut H, si: u32) -> MessageValue {
|
||||||
let (_realm_id, local_index) = decode_symbol_key(si);
|
let (_realm_id, local_index) = decode_symbol_key(si);
|
||||||
if local_index < WELL_KNOWN_SYMBOL_COUNT {
|
if local_index < WELL_KNOWN_SYMBOL_COUNT {
|
||||||
MessageValue::Symbol { well_known: Some(local_index), description: None }
|
MessageValue::Symbol {
|
||||||
|
well_known: Some(local_index),
|
||||||
|
description: None,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let description = vm.symbol_description(local_index);
|
let description = vm.symbol_description(local_index);
|
||||||
MessageValue::Symbol { well_known: None, description }
|
MessageValue::Symbol { well_known: None, description }
|
||||||
@@ -472,9 +453,7 @@ fn symbol_key_to_message_value<H: VmHost>(vm: &mut H, si: u32) -> MessageValue {
|
|||||||
|
|
||||||
/// 判定 store 槽的自有属性是否可枚举(无元数据槽时按默认数据属性,可枚举)。
|
/// 判定 store 槽的自有属性是否可枚举(无元数据槽时按默认数据属性,可枚举)。
|
||||||
fn is_enumerable_own(src: &JsObject, store: u32) -> bool {
|
fn is_enumerable_own(src: &JsObject, store: u32) -> bool {
|
||||||
src.prop_meta_at(store)
|
src.prop_meta_at(store).map(|m| m.attributes.enumerable()).unwrap_or(true)
|
||||||
.map(|m| m.attributes.enumerable())
|
|
||||||
.unwrap_or(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 目标 realm 侧:遍历 `MessageValue` 产出目标 realm 的 `JsValue`。
|
/// 目标 realm 侧:遍历 `MessageValue` 产出目标 realm 的 `JsValue`。
|
||||||
@@ -519,8 +498,7 @@ fn rehydrate_value<H: VmHost>(vm: &mut H, value: &MessageValue) -> JsValue {
|
|||||||
}
|
}
|
||||||
MessageValue::Object(props) => {
|
MessageValue::Object(props) => {
|
||||||
let proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject;
|
let proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject;
|
||||||
let ptr =
|
let ptr = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto)));
|
||||||
vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto)));
|
|
||||||
// SAFETY: ptr 是本函数新分配的对象,存活且本段无别名。
|
// SAFETY: ptr 是本函数新分配的对象,存活且本段无别名。
|
||||||
let obj = unsafe { &mut *ptr };
|
let obj = unsafe { &mut *ptr };
|
||||||
for (key, val) in props {
|
for (key, val) in props {
|
||||||
@@ -620,10 +598,7 @@ fn rehydrate_regexp<H: VmHost>(vm: &mut H, source: &str, flags: &str) -> JsValue
|
|||||||
/// Error 臂 rehydrate:按归一化 name 选标准原型,定义 message(非枚举)与
|
/// Error 臂 rehydrate:按归一化 name 选标准原型,定义 message(非枚举)与
|
||||||
/// cause(在场时全真数据属性)。
|
/// cause(在场时全真数据属性)。
|
||||||
fn rehydrate_error<H: VmHost>(
|
fn rehydrate_error<H: VmHost>(
|
||||||
vm: &mut H,
|
vm: &mut H, name: &str, message: &Option<String>, cause: &Option<Box<MessageValue>>,
|
||||||
name: &str,
|
|
||||||
message: &Option<String>,
|
|
||||||
cause: &Option<Box<MessageValue>>,
|
|
||||||
) -> JsValue {
|
) -> JsValue {
|
||||||
let proto = match name {
|
let proto = match name {
|
||||||
"EvalError" => P::as_ptr(&vm.session().builtin_world().eval_error_proto) as *mut JsObject,
|
"EvalError" => P::as_ptr(&vm.session().builtin_world().eval_error_proto) as *mut JsObject,
|
||||||
@@ -654,11 +629,7 @@ fn rehydrate_error<H: VmHost>(
|
|||||||
|
|
||||||
/// Symbol 臂 rehydrate:well-known 映目标 realm 同 local_index,用户符号经
|
/// Symbol 臂 rehydrate:well-known 映目标 realm 同 local_index,用户符号经
|
||||||
/// 描述重新 intern 得目标 realm 新局部下标。
|
/// 描述重新 intern 得目标 realm 新局部下标。
|
||||||
fn rehydrate_symbol<H: VmHost>(
|
fn rehydrate_symbol<H: VmHost>(vm: &mut H, well_known: &Option<u32>, description: &Option<String>) -> JsValue {
|
||||||
vm: &mut H,
|
|
||||||
well_known: &Option<u32>,
|
|
||||||
description: &Option<String>,
|
|
||||||
) -> JsValue {
|
|
||||||
let realm_id = vm.realm_id();
|
let realm_id = vm.realm_id();
|
||||||
match well_known {
|
match well_known {
|
||||||
Some(idx) => JsValue::symbol_realm(realm_id, *idx),
|
Some(idx) => JsValue::symbol_realm(realm_id, *idx),
|
||||||
|
|||||||
@@ -376,9 +376,7 @@ fn read_own_value<H: VmHost>(
|
|||||||
|
|
||||||
/// 判定 store 槽的自有属性是否可枚举(无元数据槽时按默认数据属性,可枚举)。
|
/// 判定 store 槽的自有属性是否可枚举(无元数据槽时按默认数据属性,可枚举)。
|
||||||
fn is_enumerable_own(src: &JsObject, store: u32) -> bool {
|
fn is_enumerable_own(src: &JsObject, store: u32) -> bool {
|
||||||
src.prop_meta_at(store)
|
src.prop_meta_at(store).map(|m| m.attributes.enumerable()).unwrap_or(true)
|
||||||
.map(|m| m.attributes.enumerable())
|
|
||||||
.unwrap_or(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 把克隆值按描述符定义到克隆对象。
|
/// 把克隆值按描述符定义到克隆对象。
|
||||||
@@ -590,7 +588,11 @@ fn alloc_buffer_object<H: VmHost>(
|
|||||||
) -> *mut JsObject {
|
) -> *mut JsObject {
|
||||||
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
|
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
|
||||||
obj.type_tag = JsObject::OBJ_TYPE_ARRAY_BUFFER;
|
obj.type_tag = JsObject::OBJ_TYPE_ARRAY_BUFFER;
|
||||||
let payload = crate::array_buffer::ArrayBufferPayload { data, max_byte_length, immutable };
|
let payload = crate::array_buffer::ArrayBufferPayload {
|
||||||
|
data,
|
||||||
|
max_byte_length,
|
||||||
|
immutable,
|
||||||
|
};
|
||||||
let payload_ptr = Arc::into_raw(Arc::new(payload));
|
let payload_ptr = Arc::into_raw(Arc::new(payload));
|
||||||
// SAFETY: ArrayBuffer 对象不可调用,native_fn 槽复用为不透明载荷盒指针,
|
// SAFETY: ArrayBuffer 对象不可调用,native_fn 槽复用为不透明载荷盒指针,
|
||||||
// 与 new_array_buffer 的存储形态一致。
|
// 与 new_array_buffer 的存储形态一致。
|
||||||
@@ -630,8 +632,15 @@ fn alloc_typed_array_clone<H: VmHost>(
|
|||||||
let data = unsafe { *data_ptr };
|
let data = unsafe { *data_ptr };
|
||||||
let cloned_buffer = clone_value(vm, state, data.buffer)?;
|
let cloned_buffer = clone_value(vm, state, data.buffer)?;
|
||||||
let proto = JsValue::from_js_object(crate::typed_array::typed_array_proto_ptr(vm, data.kind));
|
let proto = JsValue::from_js_object(crate::typed_array::typed_array_proto_ptr(vm, data.kind));
|
||||||
let clone_ptr =
|
let clone_ptr = crate::typed_array::create_typed_array(
|
||||||
crate::typed_array::create_typed_array(vm, data.kind, cloned_buffer, data.byte_offset, data.length, data.auto_length, proto);
|
vm,
|
||||||
|
data.kind,
|
||||||
|
cloned_buffer,
|
||||||
|
data.byte_offset,
|
||||||
|
data.length,
|
||||||
|
data.auto_length,
|
||||||
|
proto,
|
||||||
|
);
|
||||||
Ok(clone_ptr)
|
Ok(clone_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,7 +909,10 @@ mod tests {
|
|||||||
|
|
||||||
/// 读 TypedArray 视图状态盒(Copy)。
|
/// 读 TypedArray 视图状态盒(Copy)。
|
||||||
fn ta_data(ta: &JsObject) -> crate::typed_array::TypedArrayData {
|
fn ta_data(ta: &JsObject) -> crate::typed_array::TypedArrayData {
|
||||||
let ptr = ta.native_fn().map(|p| p.as_ptr() as *const crate::typed_array::TypedArrayData).unwrap();
|
let ptr = ta
|
||||||
|
.native_fn()
|
||||||
|
.map(|p| p.as_ptr() as *const crate::typed_array::TypedArrayData)
|
||||||
|
.unwrap();
|
||||||
// SAFETY: ptr 经对象类型标签校验为存活状态盒。
|
// SAFETY: ptr 经对象类型标签校验为存活状态盒。
|
||||||
unsafe { *ptr }
|
unsafe { *ptr }
|
||||||
}
|
}
|
||||||
@@ -920,7 +932,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn clone_arraybuffer_transfer() {
|
fn clone_arraybuffer_transfer() {
|
||||||
let (mut vm, v) =
|
let (mut vm, v) =
|
||||||
eval("var ab = new Uint8Array([9, 8, 7]).buffer; var opts = {transfer: [ab]}; ({ab: ab, opts: opts})").unwrap();
|
eval("var ab = new Uint8Array([9, 8, 7]).buffer; var opts = {transfer: [ab]}; ({ab: ab, opts: opts})")
|
||||||
|
.unwrap();
|
||||||
let holder = unsafe { &*v.as_js_object_ptr() };
|
let holder = unsafe { &*v.as_js_object_ptr() };
|
||||||
let si_ab = vm.kernel_core().perm_interner().intern("ab").0;
|
let si_ab = vm.kernel_core().perm_interner().intern("ab").0;
|
||||||
let si_opts = vm.kernel_core().perm_interner().intern("opts").0;
|
let si_opts = vm.kernel_core().perm_interner().intern("opts").0;
|
||||||
@@ -942,7 +955,10 @@ mod tests {
|
|||||||
assert!(cl.is_typed_array_obj());
|
assert!(cl.is_typed_array_obj());
|
||||||
let data = ta_data(cl);
|
let data = ta_data(cl);
|
||||||
let src_data = ta_data(unsafe { &*v.as_js_object_ptr() });
|
let src_data = ta_data(unsafe { &*v.as_js_object_ptr() });
|
||||||
assert!(!std::ptr::eq(data.buffer.as_js_object_ptr(), src_data.buffer.as_js_object_ptr()), "克隆缓冲应为新对象");
|
assert!(
|
||||||
|
!std::ptr::eq(data.buffer.as_js_object_ptr(), src_data.buffer.as_js_object_ptr()),
|
||||||
|
"克隆缓冲应为新对象"
|
||||||
|
);
|
||||||
assert_eq!(data.length, 3);
|
assert_eq!(data.length, 3);
|
||||||
assert_eq!(data.byte_offset, 0);
|
assert_eq!(data.byte_offset, 0);
|
||||||
let buf = unsafe { &*data.buffer.as_js_object_ptr() };
|
let buf = unsafe { &*data.buffer.as_js_object_ptr() };
|
||||||
@@ -952,7 +968,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn clone_typed_array_with_transfer() {
|
fn clone_typed_array_with_transfer() {
|
||||||
let (mut vm, v) =
|
let (mut vm, v) =
|
||||||
eval("var ta = new Uint8Array([1, 2, 3]); var opts = {transfer: [ta.buffer]}; ({ta: ta, opts: opts})").unwrap();
|
eval("var ta = new Uint8Array([1, 2, 3]); var opts = {transfer: [ta.buffer]}; ({ta: ta, opts: opts})")
|
||||||
|
.unwrap();
|
||||||
let holder = unsafe { &*v.as_js_object_ptr() };
|
let holder = unsafe { &*v.as_js_object_ptr() };
|
||||||
let si_ta = vm.kernel_core().perm_interner().intern("ta").0;
|
let si_ta = vm.kernel_core().perm_interner().intern("ta").0;
|
||||||
let si_opts = vm.kernel_core().perm_interner().intern("opts").0;
|
let si_opts = vm.kernel_core().perm_interner().intern("opts").0;
|
||||||
@@ -976,7 +993,10 @@ mod tests {
|
|||||||
let c = clone(&mut vm, v).unwrap();
|
let c = clone(&mut vm, v).unwrap();
|
||||||
let cl = unsafe { &*c.as_js_object_ptr() };
|
let cl = unsafe { &*c.as_js_object_ptr() };
|
||||||
assert!(cl.is_data_view_obj());
|
assert!(cl.is_data_view_obj());
|
||||||
let data_ptr = cl.native_fn().map(|p| p.as_ptr() as *const crate::data_view::DataViewData).unwrap();
|
let data_ptr = cl
|
||||||
|
.native_fn()
|
||||||
|
.map(|p| p.as_ptr() as *const crate::data_view::DataViewData)
|
||||||
|
.unwrap();
|
||||||
// SAFETY: data_ptr 经对象类型标签校验为存活状态盒。
|
// SAFETY: data_ptr 经对象类型标签校验为存活状态盒。
|
||||||
let data = unsafe { *data_ptr };
|
let data = unsafe { *data_ptr };
|
||||||
assert_eq!(data.byte_length, 4);
|
assert_eq!(data.byte_length, 4);
|
||||||
@@ -992,7 +1012,8 @@ mod tests {
|
|||||||
let cl = unsafe { &*c.as_js_object_ptr() };
|
let cl = unsafe { &*c.as_js_object_ptr() };
|
||||||
assert!(cl.is_shared_array_buffer_obj());
|
assert!(cl.is_shared_array_buffer_obj());
|
||||||
// 两对象共享同一载荷盒(克隆侧写入对源侧可见)。
|
// 两对象共享同一载荷盒(克隆侧写入对源侧可见)。
|
||||||
let src_payload = crate::array_buffer::shared_array_buffer_payload_ptr(unsafe { &*v.as_js_object_ptr() }).unwrap();
|
let src_payload =
|
||||||
|
crate::array_buffer::shared_array_buffer_payload_ptr(unsafe { &*v.as_js_object_ptr() }).unwrap();
|
||||||
let cl_payload = crate::array_buffer::shared_array_buffer_payload_ptr(cl).unwrap();
|
let cl_payload = crate::array_buffer::shared_array_buffer_payload_ptr(cl).unwrap();
|
||||||
assert!(std::ptr::eq(src_payload, cl_payload), "克隆应共享同一载荷");
|
assert!(std::ptr::eq(src_payload, cl_payload), "克隆应共享同一载荷");
|
||||||
// SAFETY: 载荷盒存活。
|
// SAFETY: 载荷盒存活。
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ use oxide_bytecode::opcode::OpCode;
|
|||||||
use oxide_ir::inst::Inst;
|
use oxide_ir::inst::Inst;
|
||||||
use oxide_ir::operand::Operand;
|
use oxide_ir::operand::Operand;
|
||||||
use oxide_ir::{IRFunction, ParamLayout};
|
use oxide_ir::{IRFunction, ParamLayout};
|
||||||
use oxide_types::MODULE_NAMESPACE_BINDING;
|
|
||||||
use oxide_parser::{
|
use oxide_parser::{
|
||||||
BindingPattern, Declaration, ExportDefaultDeclarationKind, Expression, ImportAttributeKey,
|
BindingPattern, Declaration, ExportDefaultDeclarationKind, Expression, ImportAttributeKey,
|
||||||
ImportDeclarationSpecifier, ModuleExportName, Statement, VariableDeclarationKind, WithClause,
|
ImportDeclarationSpecifier, ModuleExportName, Statement, VariableDeclarationKind, WithClause,
|
||||||
};
|
};
|
||||||
|
use oxide_types::MODULE_NAMESPACE_BINDING;
|
||||||
|
|
||||||
/// 数据模块种类(非 JS 源码模块)。
|
/// 数据模块种类(非 JS 源码模块)。
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
use oxide_types::object::JsString;
|
||||||
use oxide_types::string_forge::{
|
use oxide_types::string_forge::{
|
||||||
decode_key, encode_key, single_char_ptr, small_int_ptr, source_escape, source_escape_to_key, typeof_string_ptr,
|
decode_key, encode_key, single_char_ptr, small_int_ptr, source_escape, source_escape_to_key, typeof_string_ptr,
|
||||||
PermInterner,
|
PermInterner,
|
||||||
};
|
};
|
||||||
use oxide_types::object::JsString;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn intern_dedup() {
|
fn intern_dedup() {
|
||||||
|
|||||||
@@ -56,7 +56,11 @@ pub fn bind_global(core: &Arc<KernelCore>, session: &KernelSession, global: &mut
|
|||||||
("__moduleEval", oxide_builtins::module::module_eval::<crate::vm::Vm> as *const (), 1),
|
("__moduleEval", oxide_builtins::module::module_eval::<crate::vm::Vm> as *const (), 1),
|
||||||
("__moduleData", oxide_builtins::module::module_data::<crate::vm::Vm> as *const (), 2),
|
("__moduleData", oxide_builtins::module::module_data::<crate::vm::Vm> as *const (), 2),
|
||||||
("eval", oxide_builtins::eval::eval::<crate::vm::Vm> as *const (), 1),
|
("eval", oxide_builtins::eval::eval::<crate::vm::Vm> as *const (), 1),
|
||||||
("structuredClone", oxide_builtins::structured_clone::structured_clone_entry::<crate::vm::Vm> as *const (), 1),
|
(
|
||||||
|
"structuredClone",
|
||||||
|
oxide_builtins::structured_clone::structured_clone_entry::<crate::vm::Vm> as *const (),
|
||||||
|
1,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -857,7 +857,11 @@ fn bind_global_functions(core: &Arc<KernelCore>, session: &KernelSession, global
|
|||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
("eval", oxide_builtins::eval::eval::<crate::vm::Vm> as *const (), 1),
|
("eval", oxide_builtins::eval::eval::<crate::vm::Vm> as *const (), 1),
|
||||||
("structuredClone", oxide_builtins::structured_clone::structured_clone_entry::<crate::vm::Vm> as *const (), 1),
|
(
|
||||||
|
"structuredClone",
|
||||||
|
oxide_builtins::structured_clone::structured_clone_entry::<crate::vm::Vm> as *const (),
|
||||||
|
1,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user