mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 11:41:13 +08:00
deps/vm: vendor regress 0.11.1 补 Script/Script_Extensions 的 Unknown(Zzzz) 取值——上游表缺未分配码点集取值,规范合法模式 \p{Script=Unknown} 编译期 SyntaxError;fork 纯增量(0 行改动上游行,仅补区间表与解析臂),回归钉四则(未分配匹配/已分配不匹配/sc·scx·Zzzz 别名/既有取值不扰动)
This commit is contained in:
Vendored
+185
@@ -0,0 +1,185 @@
|
||||
use core::cmp::Eq;
|
||||
use core::fmt;
|
||||
use core::marker::PhantomData;
|
||||
use core::ops;
|
||||
|
||||
/// A trait which references a position in an input string.
|
||||
/// The intent is that this may be satisfied via indexes or pointers.
|
||||
/// Positions must be subtractable, producing usize; they also obey other "pointer arithmetic" ideas.
|
||||
pub trait PositionType:
|
||||
core::fmt::Debug + Copy + Clone + PartialEq + Eq + PartialOrd + Ord
|
||||
where
|
||||
Self: ops::Add<usize, Output = Self>,
|
||||
Self: ops::Sub<usize, Output = Self>,
|
||||
Self: ops::Sub<Self, Output = usize>,
|
||||
Self: ops::AddAssign<usize>,
|
||||
Self: ops::SubAssign<usize>,
|
||||
{
|
||||
}
|
||||
|
||||
/// Choose the preferred position type with this alias.
|
||||
#[cfg(feature = "index-positions")]
|
||||
pub type DefPosition<'a> = IndexPosition<'a>;
|
||||
|
||||
#[cfg(not(feature = "index-positions"))]
|
||||
pub type DefPosition<'a> = RefPosition<'a>;
|
||||
|
||||
/// A simple index-based position.
|
||||
/// It remembers the lifetime of the slice it is tied to.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct IndexPosition<'a>(usize, PhantomData<&'a ()>);
|
||||
|
||||
impl<'a> fmt::Debug for IndexPosition<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_tuple("IndexPosition").field(&self.0).finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl IndexPosition<'_> {
|
||||
/// IndexPosition does not enforce its size.
|
||||
#[inline(always)]
|
||||
pub fn check_size() {}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn new(pos: usize) -> Self {
|
||||
Self(pos, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Add<usize> for IndexPosition<'_> {
|
||||
type Output = Self;
|
||||
|
||||
#[inline(always)]
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
debug_assert!(self.0 + rhs >= self.0, "Overflow");
|
||||
IndexPosition(self.0 + rhs, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::AddAssign<usize> for IndexPosition<'_> {
|
||||
#[inline(always)]
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
*self = *self + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::SubAssign<usize> for IndexPosition<'_> {
|
||||
#[inline(always)]
|
||||
fn sub_assign(&mut self, rhs: usize) {
|
||||
*self = *self - rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ops::Sub<IndexPosition<'a>> for IndexPosition<'a> {
|
||||
type Output = usize;
|
||||
|
||||
#[inline(always)]
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
debug_assert!(self.0 >= rhs.0, "Underflow");
|
||||
self.0 - rhs.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Sub<usize> for IndexPosition<'_> {
|
||||
type Output = Self;
|
||||
|
||||
#[inline(always)]
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
debug_assert!(self.0 >= rhs, "Underflow");
|
||||
IndexPosition(self.0 - rhs, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl PositionType for IndexPosition<'_> {}
|
||||
|
||||
/// A reference position holds a reference to a byte and uses pointer arithmetic.
|
||||
/// This must use raw pointers because it must be capable of representing the one-past-the-end value.
|
||||
/// TODO: thread lifetimes through this.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct RefPosition<'a>(core::ptr::NonNull<u8>, PhantomData<&'a ()>);
|
||||
|
||||
impl<'a> fmt::Debug for RefPosition<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let addr = self.0.as_ptr() as usize;
|
||||
f.debug_tuple("RefPosition").field(&addr).finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl RefPosition<'_> {
|
||||
/// The big idea of RefPosition is that `Option<RefPosition>` becomes pointer-sized, by using nullptr as the None value.
|
||||
/// Good candidate for const-panics when stabilized.
|
||||
#[inline(always)]
|
||||
pub fn check_size() {
|
||||
if core::mem::size_of::<Option<Self>>() > core::mem::size_of::<*const u8>() {
|
||||
panic!("Option<RefPosition> should be pointer sized")
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the underlying pointer.
|
||||
#[inline(always)]
|
||||
pub fn ptr(self) -> *const u8 {
|
||||
self.0.as_ptr()
|
||||
}
|
||||
|
||||
/// Construct from a pointer, which must never be null.
|
||||
#[inline(always)]
|
||||
pub fn new(ptr: *const u8) -> Self {
|
||||
debug_assert!(!ptr.is_null(), "Pointer cannot be null");
|
||||
// Annoyingly there's no *const NonNull.
|
||||
let mutp = ptr as *mut u8;
|
||||
let nonnullp = if cfg!(feature = "prohibit-unsafe") {
|
||||
core::ptr::NonNull::new(mutp).expect("Pointer was null")
|
||||
} else {
|
||||
unsafe { core::ptr::NonNull::new_unchecked(mutp) }
|
||||
};
|
||||
Self(nonnullp, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl PositionType for RefPosition<'_> {}
|
||||
|
||||
impl ops::Add<usize> for RefPosition<'_> {
|
||||
type Output = Self;
|
||||
|
||||
#[inline(always)]
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
Self::new(unsafe { self.ptr().add(rhs) })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ops::Sub<RefPosition<'a>> for RefPosition<'a> {
|
||||
type Output = usize;
|
||||
|
||||
#[inline(always)]
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
debug_assert!(self.0 >= rhs.0, "Underflow");
|
||||
// Note Rust has backwards naming here. The "origin" is self, not the param; the rhs is the offset value.
|
||||
unsafe { self.ptr().offset_from(rhs.ptr()) as usize }
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Sub<usize> for RefPosition<'_> {
|
||||
type Output = Self;
|
||||
|
||||
#[inline(always)]
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
debug_assert!(self.ptr() as usize >= rhs, "Underflow");
|
||||
Self::new(unsafe { self.ptr().sub(rhs) })
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::AddAssign<usize> for RefPosition<'_> {
|
||||
#[inline(always)]
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
*self = *self + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::SubAssign<usize> for RefPosition<'_> {
|
||||
#[inline(always)]
|
||||
fn sub_assign(&mut self, rhs: usize) {
|
||||
*self = *self - rhs;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user