docs
Loading...
Searching...
No Matches
CAPI_JSBuffer.h

Overview

Functions for sharing raw binary memory with JavaScript through ArrayBuffers and typed arrays.

#include <Ultralight/CAPI/CAPI_JSBuffer.h>

Note
This API is a preview and may still change after 2.0.

These functions allow native code and page script to share raw binary memory without copying. You can pass native memory directly to JavaScript as an ArrayBuffer or typed array, and read binary buffers created by the page.

For conventions governing handle ownership, NULL handles, threading, and error reporting across the JavaScript C API, see CAPI_JSValue.h.

Share native memory with the page by wrapping a ULBuffer in an ArrayBuffer:

#include <stdlib.h>
static void FreePixels(void* user_data, void* data) {
free(data);
}
ULJSValue SharePixels(ULJSContext ctx, void* pixels, size_t size) {
ULBuffer buffer = ulCreateBuffer(pixels, size, NULL, FreePixels);
ULJSValue array_buffer = ulCreateJSArrayBufferFromBuffer(ctx, buffer);
ulDestroyBuffer(buffer); /* the ArrayBuffer keeps its own reference */
return array_buffer;
}
void ulDestroyBuffer(ULBuffer buffer)
Destroy a buffer previously created with ulCreateBuffer() or ulCreateBufferFromCopy().
ULBuffer ulCreateBuffer(void *data, size_t size, void *user_data, ulDestroyBufferCallback destruction_callback)
Create a Buffer from existing, user-owned data without any copies.
struct C_JSValue * ULJSValue
Opaque handle to a JavaScript value (see <Ultralight/CAPI/CAPI_JSValue.h>).
Definition CAPI_DOMDocument.h:763
struct C_JSContext * ULJSContext
Opaque handle to a JavaScript context (see <Ultralight/CAPI/CAPI_JSValue.h>).
Definition CAPI_DOMDocument.h:758
ULJSValue ulCreateJSArrayBufferFromBuffer(ULJSContext ctx, ULBuffer buffer)
Create an ArrayBuffer that shares a Buffer's bytes with JavaScript without copying.
struct C_Buffer * ULBuffer
Opaque handle to a Buffer object.
Definition CAPI_Defines.h:99

Sharing Native Bytes

Native memory passes to JavaScript as an ArrayBuffer or typed array using a ULBuffer or an explicit copy:

Reading Bytes from the Page

Native code accesses bytes from an ArrayBuffer or typed array without copying:

Inspect a typed array and read its elements through ULJSTypedArrayInfo:

float SumWeights(ULJSValue weights) {
float total = 0;
if (ulJSTypedArrayGetInfo(weights, &info) &&
const float* data = (const float*)info.data;
for (size_t i = 0; i < info.length; i++)
total += data[i];
}
return total;
}
@ kULJSTypedArrayType_Float32
Definition CAPI_JSBuffer.h:126
bool ulJSTypedArrayGetInfo(ULJSValue typed_array, ULJSTypedArrayInfo *info)
Describe a typed array: its element type, a pointer to its first element, and its lengths.
Description of a typed array, filled by ulJSTypedArrayGetInfo().
Definition CAPI_JSBuffer.h:135
void * data
Pointer to the first element (NULL if the array is detached).
Definition CAPI_JSBuffer.h:138
ULJSTypedArrayType type
The element type (kULJSTypedArrayType_None if the value is not a typed array).
Definition CAPI_JSBuffer.h:136
size_t length
Number of elements.
Definition CAPI_JSBuffer.h:139

Detaching an ArrayBuffer

Call ulJSArrayBufferDetach() to take shared bytes back from the page early so JavaScript can no longer reach the memory.

Once native code reads the bytes (by calling ulJSArrayBufferGetBuffer(), ulJSArrayBufferGetBytes(), or ulJSTypedArrayGetInfo()), the ArrayBuffer can no longer be detached by native code or by the page. This restriction applies even to an ArrayBuffer created from your own ULBuffer. Calling ulJSArrayBufferDetach() then returns false.

Byte Lifetimes

A ULBuffer shared with the page releases its memory according to who holds it:

  • Shared buffers stay referenced until collection or detachment. The library releases its reference during a later ulUpdate() after the ArrayBuffer is garbage-collected or detached.
  • The destruction callback runs when the last reference is released. That happens during a later ulUpdate() if the ArrayBuffer held the last reference, or wherever native code calls ulDestroyBuffer().
Warning
Bytes owned by the page are freed when the page goes away, even while native code holds a ULBuffer over them. Call ulCreateBufferFromCopy() if the bytes must outlive the page.
See also
ulCreateBuffer(), ulCreateBufferFromCopy(), CAPI_JSValue.h, <Ultralight/js/Buffer.h>

Classes

struct  ULJSTypedArrayInfo
 Description of a typed array, filled by ulJSTypedArrayGetInfo(). More...

Functions

bool ulJSValueIsArrayBuffer (ULJSValue value)
 Whether or not a value is an ArrayBuffer (detached ones included).
ULJSValue ulCreateJSArrayBuffer (ULJSContext ctx, const void *bytes, size_t length)
 Create an ArrayBuffer holding a copy of the given bytes.
ULJSValue ulCreateJSArrayBufferFromBuffer (ULJSContext ctx, ULBuffer buffer)
 Create an ArrayBuffer that shares a Buffer's bytes with JavaScript without copying.
ULBuffer ulJSArrayBufferGetBuffer (ULJSValue array_buffer)
 Get a Buffer that views an ArrayBuffer's bytes without copying.
void * ulJSArrayBufferGetBytes (ULJSValue array_buffer, size_t *length)
 Get a pointer to an ArrayBuffer's bytes without copying.
bool ulJSArrayBufferDetach (ULJSValue array_buffer)
 Detach an ArrayBuffer so JavaScript can no longer reach its bytes.
ULJSTypedArrayType ulJSValueGetTypedArrayType (ULJSValue value)
 Get the element type of a typed array.
ULJSValue ulCreateJSTypedArray (ULJSContext ctx, ULJSTypedArrayType type, size_t length)
 Create a typed array of zero-filled elements.
ULJSValue ulCreateJSTypedArrayFromBuffer (ULJSContext ctx, ULJSTypedArrayType type, ULBuffer buffer)
 Create a typed array that shares a Buffer's bytes with JavaScript without copying.
ULJSValue ulCreateJSTypedArrayFromArrayBuffer (ULJSContext ctx, ULJSTypedArrayType type, ULJSValue array_buffer, size_t byte_offset, size_t length)
 Create a typed array over part of an existing ArrayBuffer without copying.
bool ulJSTypedArrayGetInfo (ULJSValue typed_array, ULJSTypedArrayInfo *info)
 Describe a typed array: its element type, a pointer to its first element, and its lengths.
ULJSValue ulJSTypedArrayGetBuffer (ULJSValue typed_array)
 Get the ArrayBuffer a typed array views.

Enumerations

enum  ULJSTypedArrayType {
  kULJSTypedArrayType_None = 0 , kULJSTypedArrayType_Int8 , kULJSTypedArrayType_Uint8 , kULJSTypedArrayType_Uint8Clamped ,
  kULJSTypedArrayType_Int16 , kULJSTypedArrayType_Uint16 , kULJSTypedArrayType_Int32 , kULJSTypedArrayType_Uint32 ,
  kULJSTypedArrayType_Float32 , kULJSTypedArrayType_Float64 , kULJSTypedArrayType_BigInt64 , kULJSTypedArrayType_BigUint64
}
 Element types for JavaScript typed arrays. More...

Function Documentation

◆ ulCreateJSArrayBuffer()

ULJSValue ulCreateJSArrayBuffer ( ULJSContext ctx,
const void * bytes,
size_t length )

Create an ArrayBuffer holding a copy of the given bytes.

Parameters
ctxThe context to create the value in.
bytesThe bytes to copy (may be NULL only when length is 0).
lengthThe number of bytes to copy (0 creates an empty ArrayBuffer).
Returns
Returns a new ULJSValue handle (NULL if the context is gone, or if bytes is NULL and length isn't 0). You must call ulDestroyJSValue() when finished.

◆ ulCreateJSArrayBufferFromBuffer()

ULJSValue ulCreateJSArrayBufferFromBuffer ( ULJSContext ctx,
ULBuffer buffer )

Create an ArrayBuffer that shares a Buffer's bytes with JavaScript without copying.

The ArrayBuffer keeps a reference to buffer until it's garbage collected or detached (see "Byte Lifetimes" above). You still own your buffer handle and must destroy it as usual.

Parameters
ctxThe context to create the value in.
bufferThe Buffer to share. An empty Buffer gives an ordinary empty ArrayBuffer that keeps no reference.
Returns
Returns a new ULJSValue handle (NULL if the context is gone or buffer is NULL). You must call ulDestroyJSValue() when finished.

◆ ulCreateJSTypedArray()

ULJSValue ulCreateJSTypedArray ( ULJSContext ctx,
ULJSTypedArrayType type,
size_t length )

Create a typed array of zero-filled elements.

Parameters
ctxThe context to create the value in.
typeThe element type.
lengthThe number of elements (not bytes).
Returns
Returns a new ULJSValue handle (NULL if the context is gone or type is kULJSTypedArrayType_None). You must call ulDestroyJSValue() when finished.

◆ ulCreateJSTypedArrayFromArrayBuffer()

ULJSValue ulCreateJSTypedArrayFromArrayBuffer ( ULJSContext ctx,
ULJSTypedArrayType type,
ULJSValue array_buffer,
size_t byte_offset,
size_t length )

Create a typed array over part of an existing ArrayBuffer without copying.

The ArrayBuffer can still be detached.

Parameters
ctxThe context to create the value in.
typeThe element type.
array_bufferThe ArrayBuffer to view.
byte_offsetThe byte offset of the first element (must be a multiple of the element size).
lengthThe number of elements (not bytes).
Returns
Returns a new ULJSValue handle (NULL if the context is gone, type is kULJSTypedArrayType_None, array_buffer isn't an ArrayBuffer, byte_offset isn't a multiple of the element size, or the range doesn't fit in array_buffer). You must call ulDestroyJSValue() when finished.
Note
An array_buffer whose page is gone, or one from another page (unless both pages are frames of the same top-level page with exactly the same origin), gives NULL, and the second case logs a diagnostic.

◆ ulCreateJSTypedArrayFromBuffer()

ULJSValue ulCreateJSTypedArrayFromBuffer ( ULJSContext ctx,
ULJSTypedArrayType type,
ULBuffer buffer )

Create a typed array that shares a Buffer's bytes with JavaScript without copying.

Lifetime works as for ulCreateJSArrayBufferFromBuffer().

Parameters
ctxThe context to create the value in.
typeThe element type.
bufferThe Buffer to share (its size must be a multiple of the element size). An empty Buffer gives an ordinary empty typed array that keeps no reference.
Returns
Returns a new ULJSValue handle (NULL if the context is gone, type is kULJSTypedArrayType_None, buffer is NULL, or its size isn't a multiple of the element size). You must call ulDestroyJSValue() when finished.

◆ ulJSArrayBufferDetach()

bool ulJSArrayBufferDetach ( ULJSValue array_buffer)

Detach an ArrayBuffer so JavaScript can no longer reach its bytes.

Afterwards its byteLength is 0, typed arrays over it have length 0 (element reads return undefined), and creating a new typed array over it throws a TypeError. If it was created from a Buffer, its reference to that Buffer is released during a later ulUpdate().

Parameters
array_bufferThe ArrayBuffer to detach.
Returns
Returns true if the ArrayBuffer is detached on return (including one that was already detached). Returns false if it can no longer be detached or array_buffer isn't an ArrayBuffer.

◆ ulJSArrayBufferGetBuffer()

ULBuffer ulJSArrayBufferGetBuffer ( ULJSValue array_buffer)

Get a Buffer that views an ArrayBuffer's bytes without copying.

The Buffer is always a new one, even for an ArrayBuffer created from your own Buffer. Holding it keeps the ArrayBuffer alive while the page lives.

Parameters
array_bufferThe ArrayBuffer.
Returns
Returns a new ULBuffer (NULL if array_buffer isn't an ArrayBuffer or is detached). An empty ArrayBuffer gives a zero-size Buffer. You must call ulDestroyBuffer() when finished (from any thread).
Note
The ArrayBuffer can no longer be detached afterwards.
Warning
The bytes can be freed when the page goes away, even while you hold the Buffer (see "Byte Lifetimes" above).

◆ ulJSArrayBufferGetBytes()

void * ulJSArrayBufferGetBytes ( ULJSValue array_buffer,
size_t * length )

Get a pointer to an ArrayBuffer's bytes without copying.

Parameters
array_bufferThe ArrayBuffer.
lengthWhere to store the byte length (may be NULL; written only on success).
Returns
Returns the bytes (NULL if array_buffer isn't an ArrayBuffer or is detached). An empty ArrayBuffer gives a non-NULL pointer and a zero length. The pointer stays valid while array_buffer lives and the page lives (see "Byte Lifetimes" above).
Note
The ArrayBuffer can no longer be detached afterwards.

◆ ulJSTypedArrayGetBuffer()

ULJSValue ulJSTypedArrayGetBuffer ( ULJSValue typed_array)

Get the ArrayBuffer a typed array views.

The ArrayBuffer can still be detached.

Parameters
typed_arrayThe typed array.
Returns
Returns a new ULJSValue handle (NULL if typed_array isn't a typed array). You must call ulDestroyJSValue() when finished.

◆ ulJSTypedArrayGetInfo()

bool ulJSTypedArrayGetInfo ( ULJSValue typed_array,
ULJSTypedArrayInfo * info )

Describe a typed array: its element type, a pointer to its first element, and its lengths.

Parameters
typed_arrayThe typed array.
infoThe struct to fill (if NULL, the function returns false).
Returns
Returns true if typed_array is a typed array and info was filled. A detached typed array counts: it reports its type with NULL data and zero lengths. Returns false for anything else, with info->type set to kULJSTypedArrayType_None.
Note
The ArrayBuffer can no longer be detached afterwards. The data pointer stays valid while typed_array lives and the page lives (see "Byte Lifetimes" above).

◆ ulJSValueGetTypedArrayType()

ULJSTypedArrayType ulJSValueGetTypedArrayType ( ULJSValue value)

Get the element type of a typed array.

The ArrayBuffer can still be detached, so you can use it to check a value before ulJSTypedArrayGetInfo().

Parameters
valueThe value to check.
Returns
Returns the element type (kULJSTypedArrayType_None if value isn't a typed array; an ArrayBuffer or a DataView isn't one).

◆ ulJSValueIsArrayBuffer()

bool ulJSValueIsArrayBuffer ( ULJSValue value)

Whether or not a value is an ArrayBuffer (detached ones included).

The ArrayBuffer can still be detached.

Parameters
valueThe value to check.
Returns
Returns true if value is an ArrayBuffer.

Enumeration Type Documentation

◆ ULJSTypedArrayType

Element types for JavaScript typed arrays.

Enumerator
kULJSTypedArrayType_None 

The value is not a typed array.

kULJSTypedArrayType_Int8 
kULJSTypedArrayType_Uint8 
kULJSTypedArrayType_Uint8Clamped 
kULJSTypedArrayType_Int16 
kULJSTypedArrayType_Uint16 
kULJSTypedArrayType_Int32 
kULJSTypedArrayType_Uint32 
kULJSTypedArrayType_Float32 
kULJSTypedArrayType_Float64 
kULJSTypedArrayType_BigInt64 
kULJSTypedArrayType_BigUint64 

Go to the source code of this file.