0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-02-12 16:59:03 -05:00

feat: Bring back deprecated v8::String API (#1694)

Brings back String APIs removed in #1692
and renamed the new APIs to have _v2 suffix.
This commit is contained in:
Bartek Iwańczuk 2025-02-07 02:42:17 +01:00 committed by GitHub
parent 45edd18001
commit 79c94a9a69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 207 additions and 23 deletions

View file

@ -34,6 +34,9 @@
using namespace support;
// TODO(bartlomieju): ideally we could ignore only some of the deprecated APIs
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
template <typename T>
constexpr size_t align_to(size_t size) {
return (size + sizeof(T) - 1) & ~(sizeof(T) - 1);
@ -1082,20 +1085,37 @@ int v8__String__Utf8Length(const v8::String& self, v8::Isolate* isolate) {
return self.Utf8LengthV2(isolate);
}
void v8__String__Write(const v8::String& self, v8::Isolate* isolate,
uint32_t offset, uint32_t length, uint16_t* buffer,
int flags) {
int v8__String__Write(const v8::String& self, v8::Isolate* isolate,
uint16_t* buffer, int start, int length, int options) {
return self.Write(isolate, buffer, start, length, options);
}
void v8__String__Write_v2(const v8::String& self, v8::Isolate* isolate,
uint32_t offset, uint32_t length, uint16_t* buffer,
int flags) {
return self.WriteV2(isolate, offset, length, buffer, flags);
}
void v8__String__WriteOneByte(const v8::String& self, v8::Isolate* isolate,
uint32_t offset, uint32_t length, uint8_t* buffer,
int flags) {
int v8__String__WriteOneByte(const v8::String& self, v8::Isolate* isolate,
uint8_t* buffer, int start, int length,
int options) {
return self.WriteOneByte(isolate, buffer, start, length, options);
}
void v8__String__WriteOneByte_v2(const v8::String& self, v8::Isolate* isolate,
uint32_t offset, uint32_t length,
uint8_t* buffer, int flags) {
return self.WriteOneByteV2(isolate, offset, length, buffer, flags);
}
size_t v8__String__WriteUtf8(const v8::String& self, v8::Isolate* isolate,
char* buffer, size_t capacity, int flags) {
int v8__String__WriteUtf8(const v8::String& self, v8::Isolate* isolate,
char* buffer, int length, int* nchars_ref,
int options) {
return self.WriteUtf8(isolate, buffer, length, nchars_ref, options);
}
size_t v8__String__WriteUtf8_v2(const v8::String& self, v8::Isolate* isolate,
char* buffer, size_t capacity, int flags) {
return self.WriteUtf8V2(isolate, buffer, capacity, flags);
}

View file

@ -45,6 +45,15 @@ extern "C" {
fn v8__String__Utf8Length(this: *const String, isolate: *mut Isolate) -> int;
fn v8__String__Write(
this: *const String,
isolate: *mut Isolate,
buffer: *mut u16,
start: int,
length: int,
options: WriteOptions,
) -> int;
fn v8__String__Write_v2(
this: *const String,
isolate: *mut Isolate,
offset: u32,
@ -54,6 +63,15 @@ extern "C" {
);
fn v8__String__WriteOneByte(
this: *const String,
isolate: *mut Isolate,
buffer: *mut u8,
start: int,
length: int,
options: WriteOptions,
) -> int;
fn v8__String__WriteOneByte_v2(
this: *const String,
isolate: *mut Isolate,
offset: u32,
@ -63,6 +81,15 @@ extern "C" {
);
fn v8__String__WriteUtf8(
this: *const String,
isolate: *mut Isolate,
buffer: *mut char,
length: int,
nchars_ref: *mut int,
options: WriteOptions,
) -> int;
fn v8__String__WriteUtf8_v2(
this: *const String,
isolate: *mut Isolate,
buffer: *mut char,
@ -325,6 +352,21 @@ pub enum NewStringType {
Internalized,
}
bitflags! {
#[derive(Clone, Copy, Default)]
#[repr(transparent)]
pub struct WriteOptions: int {
const NO_OPTIONS = 0;
const HINT_MANY_WRITES_EXPECTED = 1;
const NO_NULL_TERMINATION = 2;
const PRESERVE_ONE_BYTE_NULL = 4;
// Used by WriteUtf8 to replace orphan surrogate code units with the
// unicode replacement character. Needs to be set to guarantee valid UTF-8
// output.
const REPLACE_INVALID_UTF8 = 8;
}
}
bitflags! {
#[derive(Clone, Copy, Default)]
#[repr(transparent)]
@ -430,7 +472,30 @@ impl String {
/// Writes the contents of the string to an external buffer, as 16-bit
/// (UTF-16) character codes.
#[inline(always)]
#[deprecated = "Use `v8::String::write_v2` instead"]
pub fn write(
&self,
scope: &mut Isolate,
buffer: &mut [u16],
start: usize,
options: WriteOptions,
) -> usize {
unsafe {
v8__String__Write(
self,
scope,
buffer.as_mut_ptr(),
start.try_into().unwrap_or(int::MAX),
buffer.len().try_into().unwrap_or(int::MAX),
options,
) as usize
}
}
/// Writes the contents of the string to an external buffer, as 16-bit
/// (UTF-16) character codes.
#[inline(always)]
pub fn write_v2(
&self,
scope: &mut Isolate,
offset: u32,
@ -438,7 +503,7 @@ impl String {
flags: WriteFlags,
) {
unsafe {
v8__String__Write(
v8__String__Write_v2(
self,
scope,
offset,
@ -452,7 +517,30 @@ impl String {
/// Writes the contents of the string to an external buffer, as one-byte
/// (Latin-1) characters.
#[inline(always)]
#[deprecated = "Use `v8::String::write_one_byte_v2` instead."]
pub fn write_one_byte(
&self,
scope: &mut Isolate,
buffer: &mut [u8],
start: usize,
options: WriteOptions,
) -> usize {
unsafe {
v8__String__WriteOneByte(
self,
scope,
buffer.as_mut_ptr(),
start.try_into().unwrap_or(int::MAX),
buffer.len().try_into().unwrap_or(int::MAX),
options,
) as usize
}
}
/// Writes the contents of the string to an external buffer, as one-byte
/// (Latin-1) characters.
#[inline(always)]
pub fn write_one_byte_v2(
&self,
scope: &mut Isolate,
offset: u32,
@ -460,7 +548,7 @@ impl String {
flags: WriteFlags,
) {
unsafe {
v8__String__WriteOneByte(
v8__String__WriteOneByte_v2(
self,
scope,
offset,
@ -474,7 +562,30 @@ impl String {
/// Writes the contents of the string to an external [`MaybeUninit`] buffer, as one-byte
/// (Latin-1) characters.
#[inline(always)]
#[deprecated = "Use `v8::String::write_one_byte_uninit_v2` instead."]
pub fn write_one_byte_uninit(
&self,
scope: &mut Isolate,
buffer: &mut [MaybeUninit<u8>],
start: usize,
options: WriteOptions,
) -> usize {
unsafe {
v8__String__WriteOneByte(
self,
scope,
buffer.as_mut_ptr() as *mut u8,
start.try_into().unwrap_or(int::MAX),
buffer.len().try_into().unwrap_or(int::MAX),
options,
) as usize
}
}
/// Writes the contents of the string to an external [`MaybeUninit`] buffer, as one-byte
/// (Latin-1) characters.
#[inline(always)]
pub fn write_one_byte_uninit_v2(
&self,
scope: &mut Isolate,
offset: u32,
@ -482,7 +593,7 @@ impl String {
flags: WriteFlags,
) {
unsafe {
v8__String__WriteOneByte(
v8__String__WriteOneByte_v2(
self,
scope,
offset,
@ -495,7 +606,31 @@ impl String {
/// Writes the contents of the string to an external buffer, as UTF-8.
#[inline(always)]
#[deprecated = "Use `v8::String::write_utf8_v2` instead."]
pub fn write_utf8(
&self,
scope: &mut Isolate,
buffer: &mut [u8],
nchars_ref: Option<&mut usize>,
options: WriteOptions,
) -> usize {
unsafe {
// SAFETY:
// We assume that v8 will overwrite the buffer without de-initializing any byte in it.
// So the type casting of the buffer is safe.
let buffer = {
let len = buffer.len();
let data = buffer.as_mut_ptr().cast();
slice::from_raw_parts_mut(data, len)
};
#[allow(deprecated)]
self.write_utf8_uninit(scope, buffer, nchars_ref, options)
}
}
/// Writes the contents of the string to an external buffer, as UTF-8.
#[inline(always)]
pub fn write_utf8_v2(
&self,
scope: &mut Isolate,
buffer: &mut [u8],
@ -511,19 +646,45 @@ impl String {
let data = buffer.as_mut_ptr().cast();
slice::from_raw_parts_mut(data, len)
};
self.write_utf8_uninit(scope, buffer, flags)
self.write_utf8_uninit_v2(scope, buffer, flags)
}
}
/// Writes the contents of the string to an external [`MaybeUninit`] buffer, as UTF-8.
#[deprecated = "Use `v8::String::write_utf8_uninit_v2` instead."]
pub fn write_utf8_uninit(
&self,
scope: &mut Isolate,
buffer: &mut [MaybeUninit<u8>],
nchars_ref: Option<&mut usize>,
options: WriteOptions,
) -> usize {
let mut nchars_ref_int: int = 0;
let bytes = unsafe {
v8__String__WriteUtf8(
self,
scope,
buffer.as_mut_ptr() as *mut char,
buffer.len().try_into().unwrap_or(int::MAX),
&mut nchars_ref_int,
options,
)
};
if let Some(r) = nchars_ref {
*r = nchars_ref_int as usize;
}
bytes as usize
}
/// Writes the contents of the string to an external [`MaybeUninit`] buffer, as UTF-8.
pub fn write_utf8_uninit_v2(
&self,
scope: &mut Isolate,
buffer: &mut [MaybeUninit<u8>],
flags: WriteFlags,
) -> usize {
let bytes = unsafe {
v8__String__WriteUtf8(
v8__String__WriteUtf8_v2(
self,
scope,
buffer.as_mut_ptr() as _,
@ -791,7 +952,7 @@ impl String {
let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf16);
// Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer
self.write_one_byte_uninit(
self.write_one_byte_uninit_v2(
scope,
0,
&mut *buffer,
@ -816,7 +977,7 @@ impl String {
let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf8);
// Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer
let length = self.write_utf8_uninit(
let length = self.write_utf8_uninit_v2(
scope,
&mut *buffer,
WriteFlags::kReplaceInvalidUtf8,
@ -850,7 +1011,7 @@ impl String {
// string is 100% 7-bit ASCII.
if self.is_onebyte() && len_utf8 == len_utf16 {
if len_utf16 <= N {
self.write_one_byte_uninit(scope, 0, buffer, WriteFlags::empty());
self.write_one_byte_uninit_v2(scope, 0, buffer, WriteFlags::empty());
unsafe {
// Get a slice of &[u8] of what we know is initialized now
let buffer = &mut buffer[..len_utf16];
@ -869,7 +1030,7 @@ impl String {
let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf16);
// Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer
self.write_one_byte_uninit(
self.write_one_byte_uninit_v2(
scope,
0,
&mut *buffer,
@ -886,8 +1047,11 @@ impl String {
if len_utf8 <= N {
// No malloc path
let length =
self.write_utf8_uninit(scope, buffer, WriteFlags::kReplaceInvalidUtf8);
let length = self.write_utf8_uninit_v2(
scope,
buffer,
WriteFlags::kReplaceInvalidUtf8,
);
debug_assert!(length == len_utf8);
// SAFETY: We know that we wrote `length` UTF-8 bytes. See `slice_assume_init_mut` for additional guarantee information.
@ -911,7 +1075,7 @@ impl String {
let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf8);
// Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer
let length = self.write_utf8_uninit(
let length = self.write_utf8_uninit_v2(
scope,
&mut *buffer,
WriteFlags::kReplaceInvalidUtf8,

View file

@ -265,10 +265,10 @@ fn test_string() {
let mut vec = vec![0; 17];
assert_eq!(
17,
local.write_utf8(scope, &mut vec, v8::WriteFlags::empty())
local.write_utf8_v2(scope, &mut vec, v8::WriteFlags::empty())
);
let mut u16_buffer = [0u16; 16];
local.write(scope, 0, &mut u16_buffer, v8::WriteFlags::empty());
local.write_v2(scope, 0, &mut u16_buffer, v8::WriteFlags::empty());
assert_eq!(
String::from(reference),
String::from_utf16(&u16_buffer[..15]).unwrap()
@ -297,7 +297,7 @@ fn test_string() {
assert_eq!(3, local.length());
assert_eq!(3, local.utf8_length(scope));
let mut buffer = [0u8; 3];
local.write_one_byte(scope, 0, &mut buffer, v8::WriteFlags::empty());
local.write_one_byte_v2(scope, 0, &mut buffer, v8::WriteFlags::empty());
assert_eq!(b"foo", &buffer);
assert_eq!("foo", local.to_rust_string_lossy(scope));
}