mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-25 15:29:43 -05:00
feat: Add string access methods to OneByteConst (#1409)
This commit is contained in:
parent
63eea06a9a
commit
be545b7d3d
2 changed files with 39 additions and 17 deletions
|
@ -119,13 +119,34 @@ pub struct ExternalStringResource(Opaque);
|
||||||
pub struct ExternalOneByteStringResourceBase(Opaque);
|
pub struct ExternalOneByteStringResourceBase(Opaque);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct OneByteConst {
|
pub struct OneByteConst {
|
||||||
vtable: *const OneByteConstNoOp,
|
vtable: *const OneByteConstNoOp,
|
||||||
cached_data: *const char,
|
cached_data: *const char,
|
||||||
length: usize,
|
length: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<str> for OneByteConst {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
// SAFETY: We know this is ASCII
|
||||||
|
unsafe { std::str::from_utf8_unchecked(AsRef::<[u8]>::as_ref(self)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for OneByteConst {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
// SAFETY: Returning to the slice from which this came
|
||||||
|
unsafe { std::slice::from_raw_parts(self.cached_data as _, self.length) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for OneByteConst {
|
||||||
|
type Target = str;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SAFETY: The vtable for OneByteConst is an immutable static and all
|
// SAFETY: The vtable for OneByteConst is an immutable static and all
|
||||||
// of the included functions are thread-safe, the cached_data pointer
|
// of the included functions are thread-safe, the cached_data pointer
|
||||||
// is never changed and points to a static ASCII string, and the
|
// is never changed and points to a static ASCII string, and the
|
||||||
|
@ -201,19 +222,6 @@ const ONE_BYTE_CONST_VTABLE: OneByteConstVtable = OneByteConstVtable {
|
||||||
length: one_byte_const_length,
|
length: one_byte_const_length,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Compile-time function to determine if a string is ASCII. Note that UTF-8 chars
|
|
||||||
/// longer than one byte have the high-bit set and thus, are not ASCII.
|
|
||||||
const fn is_ascii(s: &'static [u8]) -> bool {
|
|
||||||
let mut i = 0;
|
|
||||||
while i < s.len() {
|
|
||||||
if !s[i].is_ascii() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub enum NewStringType {
|
pub enum NewStringType {
|
||||||
|
@ -456,15 +464,28 @@ impl String {
|
||||||
Self::new_from_utf8(scope, value.as_ref(), NewStringType::Normal)
|
Self::new_from_utf8(scope, value.as_ref(), NewStringType::Normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile-time function to create an external string resource.
|
/// Compile-time function to create an external string resource.
|
||||||
// The buffer is checked to contain only ASCII characters.
|
/// The buffer is checked to contain only ASCII characters.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn create_external_onebyte_const(
|
pub const fn create_external_onebyte_const(
|
||||||
buffer: &'static [u8],
|
buffer: &'static [u8],
|
||||||
) -> OneByteConst {
|
) -> OneByteConst {
|
||||||
// Assert that the buffer contains only ASCII, and that the
|
// Assert that the buffer contains only ASCII, and that the
|
||||||
// length is less or equal to (64-bit) v8::String::kMaxLength.
|
// length is less or equal to (64-bit) v8::String::kMaxLength.
|
||||||
assert!(is_ascii(buffer) && buffer.len() <= ((1 << 29) - 24));
|
assert!(buffer.is_ascii() && buffer.len() <= ((1 << 29) - 24));
|
||||||
|
OneByteConst {
|
||||||
|
vtable: &ONE_BYTE_CONST_VTABLE.delete1,
|
||||||
|
cached_data: buffer.as_ptr() as *const char,
|
||||||
|
length: buffer.len(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compile-time function to create an external string resource which
|
||||||
|
/// skips the ASCII and length checks.
|
||||||
|
#[inline(always)]
|
||||||
|
pub const unsafe fn create_external_onebyte_const_unchecked(
|
||||||
|
buffer: &'static [u8],
|
||||||
|
) -> OneByteConst {
|
||||||
OneByteConst {
|
OneByteConst {
|
||||||
vtable: &ONE_BYTE_CONST_VTABLE.delete1,
|
vtable: &ONE_BYTE_CONST_VTABLE.delete1,
|
||||||
cached_data: buffer.as_ptr() as *const char,
|
cached_data: buffer.as_ptr() as *const char,
|
||||||
|
|
|
@ -9000,6 +9000,7 @@ fn external_strings() {
|
||||||
assert!(latin1.contains_only_onebyte());
|
assert!(latin1.contains_only_onebyte());
|
||||||
|
|
||||||
// one-byte "const" test
|
// one-byte "const" test
|
||||||
|
assert_eq!(EXAMPLE_STRING.as_bytes(), b"const static");
|
||||||
let const_ref_string =
|
let const_ref_string =
|
||||||
v8::String::new_from_onebyte_const(scope, &EXAMPLE_STRING).unwrap();
|
v8::String::new_from_onebyte_const(scope, &EXAMPLE_STRING).unwrap();
|
||||||
assert!(const_ref_string.is_external());
|
assert!(const_ref_string.is_external());
|
||||||
|
|
Loading…
Reference in a new issue