mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-21 20:28:58 +00:00
feat: add String::ValueView (#1543)
This commit is contained in:
parent
1e4b691905
commit
39631b31d6
@ -1197,6 +1197,33 @@ bool v8__String__ContainsOnlyOneByte(const v8::String& self) {
|
||||
return self.ContainsOnlyOneByte();
|
||||
}
|
||||
|
||||
void v8__String__ValueView__CONSTRUCT(uninit_t<v8::String::ValueView>* buf,
|
||||
v8::Isolate* isolate,
|
||||
const v8::String& string) {
|
||||
construct_in_place<v8::String::ValueView>(buf, isolate,
|
||||
ptr_to_local(&string));
|
||||
}
|
||||
|
||||
void v8__String__ValueView__DESTRUCT(v8::String::ValueView* self) {
|
||||
self->~ValueView();
|
||||
}
|
||||
|
||||
bool v8__String__ValueView__is_one_byte(const v8::String::ValueView& self) {
|
||||
return self.is_one_byte();
|
||||
}
|
||||
|
||||
const void* v8__String__ValueView__data(const v8::String::ValueView& self) {
|
||||
if (self.is_one_byte()) {
|
||||
return reinterpret_cast<const void*>(self.data8());
|
||||
} else {
|
||||
return reinterpret_cast<const void*>(self.data16());
|
||||
}
|
||||
}
|
||||
|
||||
int v8__String__ValueView__length(const v8::String::ValueView& self) {
|
||||
return self.length();
|
||||
}
|
||||
|
||||
const v8::Symbol* v8__Symbol__New(v8::Isolate* isolate,
|
||||
const v8::String* description) {
|
||||
return local_to_ptr(v8::Symbol::New(isolate, ptr_to_local(description)));
|
||||
|
@ -19,3 +19,5 @@ static size_t RUST_cppgc__WeakMember_SIZE = sizeof(cppgc::WeakMember<RustObj>);
|
||||
|
||||
static size_t RUST_v8__TracedReference_SIZE =
|
||||
sizeof(v8::TracedReference<v8::Data>);
|
||||
|
||||
static size_t RUST_v8__String__ValueView_SIZE = sizeof(v8::String::ValueView);
|
||||
|
@ -149,6 +149,8 @@ pub use snapshot::StartupData;
|
||||
pub use string::Encoding;
|
||||
pub use string::NewStringType;
|
||||
pub use string::OneByteConst;
|
||||
pub use string::ValueView;
|
||||
pub use string::ValueViewData;
|
||||
pub use string::WriteOptions;
|
||||
pub use support::SharedPtr;
|
||||
pub use support::SharedRef;
|
||||
|
@ -1,10 +1,3 @@
|
||||
use std::borrow::Cow;
|
||||
use std::convert::TryInto;
|
||||
use std::default::Default;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::NonNull;
|
||||
use std::slice;
|
||||
|
||||
use crate::support::char;
|
||||
use crate::support::int;
|
||||
use crate::support::size_t;
|
||||
@ -13,6 +6,14 @@ use crate::HandleScope;
|
||||
use crate::Isolate;
|
||||
use crate::Local;
|
||||
use crate::String;
|
||||
use std::borrow::Cow;
|
||||
use std::convert::TryInto;
|
||||
use std::default::Default;
|
||||
use std::ffi::c_void;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::NonNull;
|
||||
use std::slice;
|
||||
|
||||
extern "C" {
|
||||
fn v8__String__kMaxLength() -> size_t;
|
||||
@ -116,6 +117,16 @@ extern "C" {
|
||||
fn v8__ExternalOneByteStringResource__length(
|
||||
this: *const ExternalOneByteStringResource,
|
||||
) -> size_t;
|
||||
|
||||
fn v8__String__ValueView__CONSTRUCT(
|
||||
buf: *mut ValueView,
|
||||
isolate: *mut Isolate,
|
||||
string: *const String,
|
||||
);
|
||||
fn v8__String__ValueView__DESTRUCT(this: *mut ValueView);
|
||||
fn v8__String__ValueView__is_one_byte(this: *const ValueView) -> bool;
|
||||
fn v8__String__ValueView__data(this: *const ValueView) -> *const c_void;
|
||||
fn v8__String__ValueView__length(this: *const ValueView) -> int;
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
@ -939,3 +950,53 @@ pub extern "C" fn free_rust_external_onebyte(s: *mut char, len: usize) {
|
||||
drop(Box::from_raw(slice));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ValueViewData<'s> {
|
||||
OneByte(&'s [u8]),
|
||||
TwoByte(&'s [u16]),
|
||||
}
|
||||
|
||||
/// Returns a view onto a string's contents.
|
||||
///
|
||||
/// WARNING: This does not copy the string's contents, and will therefore be
|
||||
/// invalidated if the GC can move the string while the ValueView is alive. It
|
||||
/// is therefore required that no GC or allocation can happen while there is an
|
||||
/// active ValueView. This requirement may be relaxed in the future.
|
||||
///
|
||||
/// V8 strings are either encoded as one-byte or two-bytes per character.
|
||||
#[repr(C)]
|
||||
pub struct ValueView<'s>(
|
||||
[u8; crate::binding::RUST_v8__String__ValueView_SIZE],
|
||||
PhantomData<&'s ()>,
|
||||
);
|
||||
|
||||
impl<'s> ValueView<'s> {
|
||||
#[inline(always)]
|
||||
pub fn new(isolate: &mut Isolate, string: Local<'s, String>) -> Self {
|
||||
let mut v = std::mem::MaybeUninit::uninit();
|
||||
unsafe {
|
||||
v8__String__ValueView__CONSTRUCT(v.as_mut_ptr(), isolate, &*string);
|
||||
v.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn data(&self) -> ValueViewData<'_> {
|
||||
unsafe {
|
||||
let data = v8__String__ValueView__data(self);
|
||||
let length = v8__String__ValueView__length(self) as usize;
|
||||
if v8__String__ValueView__is_one_byte(self) {
|
||||
ValueViewData::OneByte(std::slice::from_raw_parts(data as _, length))
|
||||
} else {
|
||||
ValueViewData::TwoByte(std::slice::from_raw_parts(data as _, length))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Drop for ValueView<'s> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { v8__String__ValueView__DESTRUCT(self) }
|
||||
}
|
||||
}
|
||||
|
@ -11779,3 +11779,34 @@ fn clear_slots_annex_uninitialized() {
|
||||
// initialized.
|
||||
context.clear_all_slots(&mut scope);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string_valueview() {
|
||||
let _setup_guard = setup::parallel_test();
|
||||
let mut isolate = v8::Isolate::new(Default::default());
|
||||
let mut scope = v8::HandleScope::new(&mut isolate);
|
||||
let context = v8::Context::new(&mut scope);
|
||||
let scope = &mut v8::ContextScope::new(&mut scope, context);
|
||||
|
||||
{
|
||||
let one_byte = v8::String::new_from_one_byte(
|
||||
scope,
|
||||
&[1, 2, 3],
|
||||
v8::NewStringType::Normal,
|
||||
)
|
||||
.unwrap();
|
||||
let view = v8::ValueView::new(scope, one_byte);
|
||||
assert_eq!(view.data(), v8::ValueViewData::OneByte(&[1, 2, 3]));
|
||||
}
|
||||
|
||||
{
|
||||
let two_byte = v8::String::new_from_two_byte(
|
||||
scope,
|
||||
&[1, 0x1FF, 3],
|
||||
v8::NewStringType::Normal,
|
||||
)
|
||||
.unwrap();
|
||||
let view = v8::ValueView::new(scope, two_byte);
|
||||
assert_eq!(view.data(), v8::ValueViewData::TwoByte(&[1, 0x1FF, 3]));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user