Skip to main content

JsStringLatin1

Struct JsStringLatin1 

Source
pub struct JsStringLatin1<'env> { /* private fields */ }

Implementations§

Source§

impl<'env> JsStringLatin1<'env>

Source

pub fn from_data(env: &'env Env, data: Vec<u8>) -> Result<JsStringLatin1<'env>>

Try to create a new JavaScript latin1 string from a Rust Vec<u8> without copying the data.

§Behavior

The copied parameter in the underlying node_api_create_external_string_latin1 call indicates whether the string data was copied into V8’s heap rather than being used as an external reference.

§When copied is true:
  • String data is copied to V8’s heap
  • Finalizer is called synchronously to release the source buffer
  • Performance benefit of external strings is not achieved
§When copied is false:
  • V8 creates an external string that references the original buffer without copying
  • Original buffer must remain valid for the lifetime of the JS string
  • Finalizer called when string is garbage collected
  • Memory usage and copying overhead is reduced
§Common scenarios where copied is true:
  • String is too short (typically < 10-15 characters)
  • V8 heap is under memory pressure
  • V8 is running with pointer compression or sandbox features
  • Invalid Latin-1 encoding that requires sanitization
  • Platform doesn’t support external strings (e.g. wasm32-* / emnapi)
  • Memory alignment issues with the provided buffer
§Platform notes

On wasm32-* (WASI / emnapi) the external-string API always falls back to napi_create_string_latin1, which copies into the JS heap. To avoid the double work and the use-after-free that would otherwise come with the synchronous finalizer, this function uses napi_create_string_latin1 directly on WASM and keeps the source Vec alive in the wrapper so as_slice() / len() / is_empty() keep returning the original bytes.

On native, when V8 chooses to copy (copied = true), the source buffer has been freed by the finalizer before this returns. as_slice() then returns &[]; recover the bytes via JsString::into_latin1 on Self::into_value if needed.

Source

pub unsafe fn from_external<T: 'env, F: FnOnce(Env, T) + 'env>( env: &'env Env, data: *const u8, len: usize, finalize_hint: T, finalize_callback: F, ) -> Result<JsStringLatin1<'env>>

Creates an external Latin-1 string from raw data with a custom finalize callback.

§Safety

The caller must ensure that:

  • The data pointer is valid for the lifetime of the string and points to a memory region of at least len bytes
  • The finalize callback properly cleans up the data
§finalize_callback invocation contract

finalize_callback is invoked exactly once for any call that reaches the N-API layer:

  • On success, V8 invokes it (synchronously when copied = true, on GC when copied = false) on native; on WASM this function invokes it inline after the N-API call.
  • On N-API failure (e.g. OOM, status != napi_ok), this function invokes it inline before returning the error so the caller’s buffer is released.

It is not invoked when this function returns InvalidArg from its own pre-validation (null data or len > isize::MAX). Those are caller bugs: we cannot safely reach the buffer at data + len, and many real callbacks (e.g. Vec::from_raw_parts(ptr, len, len)) would trigger UB if invoked with the bogus arguments. Validate inputs and retain ownership of the source buffer until this returns Ok if you rely on the callback as your only cleanup path.

§Behavior

The copied parameter in the underlying node_api_create_external_string_latin1 call indicates whether the string data was copied into V8’s heap rather than being used as an external reference.

§When copied is true:
  • String data is copied to V8’s heap
  • Finalizer is invoked during string creation if provided
  • Original buffer can be freed after the call
  • Performance benefit of external strings is not achieved
§When copied is false:
  • V8 creates an external string that references the original buffer without copying
  • Original buffer must remain valid for the lifetime of the JS string
  • Finalizer called when string is garbage collected
  • Memory usage and copying overhead is reduced
§Platform notes

On wasm32-* (WASI / emnapi) the external-string API always copies and runs the finalizer synchronously, so this function makes its own copy of the bytes into the wrapper before invoking the caller’s finalize callback. The caller’s buffer ownership semantics are unchanged (finalize_callback is called exactly once); on WASM, as_slice() etc. observe the copy stored inside the wrapper.

On native, when V8 chooses to copy (copied = true), the caller’s finalize callback has already run synchronously by the time this returns, so the source bytes may be freed; as_slice() returns &[] in that case. When V8 keeps the buffer external (copied = false), as_slice() borrows the caller-provided bytes for free.

Source

pub fn from_static( env: &'env Env, string: &'static str, ) -> Result<JsStringLatin1<'env>>

Source

pub fn as_slice(&self) -> &[u8] ⓘ

Source

pub fn len(&self) -> usize

Source

pub fn is_empty(&self) -> bool

Source

pub fn take(self) -> Vec<u8> ⓘ

Source

pub fn into_value(self) -> JsString<'env>

Source

pub fn into_latin1_string(self) -> Result<String>

Trait Implementations§

Source§

impl From<JsStringLatin1<'_>> for Vec<u8>

Source§

fn from(value: JsStringLatin1<'_>) -> Self

Converts to this type from the input type.
Source§

impl ToNapiValue for JsStringLatin1<'_>

Source§

unsafe fn to_napi_value( _: napi_env, val: JsStringLatin1<'_>, ) -> Result<napi_value>

This function called to convert rust values to napi values Read more
Source§

fn into_unknown(self, env: &Env) -> Result<Unknown<'_>>

Auto Trait Implementations§

§

impl<'env> !Send for JsStringLatin1<'env>

§

impl<'env> !Sync for JsStringLatin1<'env>

§

impl<'env> Freeze for JsStringLatin1<'env>

§

impl<'env> RefUnwindSafe for JsStringLatin1<'env>

§

impl<'env> Unpin for JsStringLatin1<'env>

§

impl<'env> UnsafeUnpin for JsStringLatin1<'env>

§

impl<'env> UnwindSafe for JsStringLatin1<'env>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> JsValuesTupleIntoVec for T
where T: ToNapiValue,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more