mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-21 15:04:33 -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);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct OneByteConst {
|
||||
vtable: *const OneByteConstNoOp,
|
||||
cached_data: *const char,
|
||||
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
|
||||
// of the included functions are thread-safe, the cached_data pointer
|
||||
// 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,
|
||||
};
|
||||
|
||||
/// 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)]
|
||||
#[derive(Debug, Default)]
|
||||
pub enum NewStringType {
|
||||
|
@ -456,15 +464,28 @@ impl String {
|
|||
Self::new_from_utf8(scope, value.as_ref(), NewStringType::Normal)
|
||||
}
|
||||
|
||||
// Compile-time function to create an external string resource.
|
||||
// The buffer is checked to contain only ASCII characters.
|
||||
/// Compile-time function to create an external string resource.
|
||||
/// The buffer is checked to contain only ASCII characters.
|
||||
#[inline(always)]
|
||||
pub const fn create_external_onebyte_const(
|
||||
buffer: &'static [u8],
|
||||
) -> OneByteConst {
|
||||
// Assert that the buffer contains only ASCII, and that the
|
||||
// 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 {
|
||||
vtable: &ONE_BYTE_CONST_VTABLE.delete1,
|
||||
cached_data: buffer.as_ptr() as *const char,
|
||||
|
|
|
@ -9000,6 +9000,7 @@ fn external_strings() {
|
|||
assert!(latin1.contains_only_onebyte());
|
||||
|
||||
// one-byte "const" test
|
||||
assert_eq!(EXAMPLE_STRING.as_bytes(), b"const static");
|
||||
let const_ref_string =
|
||||
v8::String::new_from_onebyte_const(scope, &EXAMPLE_STRING).unwrap();
|
||||
assert!(const_ref_string.is_external());
|
||||
|
|
Loading…
Reference in a new issue