WebKit Bugzilla
Attachment 369379 Details for
Bug 197535
: [GLib] Expose typed arrays in the public API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP Patch v2
bug-197535-20190508154702.patch (text/plain), 13.60 KB, created by
Adrian Perez
on 2019-05-08 05:47:05 PDT
(
hide
)
Description:
WIP Patch v2
Filename:
MIME Type:
Creator:
Adrian Perez
Created:
2019-05-08 05:47:05 PDT
Size:
13.60 KB
patch
obsolete
>Subversion Revision: 245051 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index b876d10893dd2c3b1db9cfda5e917f30a26519ad..bba60097b16b5a61a49a8ddfc60bc6660704bf00 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,27 @@ >+2019-05-07 Adrian Perez de Castro <aperez@igalia.com> >+ >+ [GLib] Expose typed arrays in the API >+ https://bugs.webkit.org/show_bug.cgi?id=197535 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This adds a set of new functions to operate on JSCValue objects which refer to typed >+ arrays in the JS side of the world. This allows sharing memory buffers efficiently >+ with native code, without needing to copy nor encode data back and forth. It is >+ possible to both let JSC allocate the memory buffers, or to provide an existing chunk >+ of memory to JSC and be notified when JSC will not be using it anymore. >+ >+ * API/glib/JSCValue.cpp: >+ (jscTypedArrayTypeToJSType): >+ (jsc_value_new_typed_array): >+ (jscTypedArrayDeallocate): >+ (jsc_value_new_typed_array_from_data): >+ (jsc_value_is_typed_array): >+ (jsc_value_typed_array_get_length): >+ (jsc_value_typed_array_get_contents): >+ * API/glib/JSCValue.h: >+ * API/glib/docs/jsc-glib-4.0-sections.txt: >+ > 2019-05-07 Yusuke Suzuki <ysuzuki@apple.com> > > [JSC] DFG_ASSERT failed in lowInt52 >diff --git a/Source/JavaScriptCore/API/glib/JSCValue.cpp b/Source/JavaScriptCore/API/glib/JSCValue.cpp >index 76b892fea30fdfc0d8e29144db28bf66afe375d2..1f8e4477344168dc4f3ea546ff59164b135a1cb2 100644 >--- a/Source/JavaScriptCore/API/glib/JSCValue.cpp >+++ b/Source/JavaScriptCore/API/glib/JSCValue.cpp >@@ -28,6 +28,7 @@ > #include "JSCInlines.h" > #include "JSCValuePrivate.h" > #include "JSRetainPtr.h" >+#include "JSTypedArray.h" > #include "OpaqueJSString.h" > #include <gobject/gvaluecollector.h> > #include <wtf/glib/GRefPtr.h> >@@ -1441,3 +1442,232 @@ JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount, > > return jscContextGetOrCreateValue(priv->context.get(), result).leakRef(); > } >+ >+static inline JSTypedArrayType jscTypedArrayTypeToJSType(JSCTypedArrayType type) >+{ >+ switch (type) { >+ case JSC_TYPED_ARRAY_INT8: return kJSTypedArrayTypeInt8Array; >+ case JSC_TYPED_ARRAY_INT16: return kJSTypedArrayTypeInt16Array; >+ case JSC_TYPED_ARRAY_INT32: return kJSTypedArrayTypeInt32Array; >+ case JSC_TYPED_ARRAY_UINT8: return kJSTypedArrayTypeUint8Array; >+ case JSC_TYPED_ARRAY_UINT16: return kJSTypedArrayTypeUint16Array; >+ case JSC_TYPED_ARRAY_UINT32: return kJSTypedArrayTypeUint32Array; >+ case JSC_TYPED_ARRAY_FLOAT32: return kJSTypedArrayTypeFloat32Array; >+ case JSC_TYPED_ARRAY_FLOAT64: return kJSTypedArrayTypeFloat64Array; >+ default: ASSERT_NOT_REACHED(); >+ } >+ return kJSTypedArrayTypeNone; >+} >+ >+/** >+ * JSCTypedArrayType: >+ * @JSC_TYPED_ARRAY_INT8: Array elements are 8-bit signed integers (int8_t). >+ * @JSC_TYPED_ARRAY_INT16: Array elements are 16-bit signed integers (int16_t). >+ * @JSC_TYPED_ARRAY_INT32: Array elements are 32-bit signed integers (int32_t). >+ * @JSC_TYPED_ARRAY_UINT8: Array elements are 8-bit unsigned integers (uint8_t). >+ * @JSC_TYPED_ARRAY_UINT16: Array elements are 16-bit unsigned integers (uint16_t). >+ * @JSC_TYPED_ARRAY_UINT32: Array elements are 32-bit unsigned integers (uint32_t). >+ * @JSC_TYPED_ARRAY_FLOAT32: Array elements are 32-bit floating point numbers (float). >+ * @JSC_TYPED_ARRAY_FLOAT64: Array elements are 64-bit floating point numbers (double). >+ * >+ * Possible types of the elements contained in a typed array. See >+ * jsc_value_new_typed_array(), jsc_value_new_typed_array_from_data(), and >+ * jsc_value_typed_array_get_type(). >+ * >+ * Since: 2.26 >+ */ >+ >+/** >+ * jsc_value_new_typed_array: >+ * @context: a @JSCContext >+ * @type: the type of array elements >+ * @len: number of elements in the array >+ * >+ * Create a new typed array which holds @len elements of a given @type. >+ * The elements of the typed array will be initialized to zero. >+ * >+ * Returns: (transfer full): a #JSCValue >+ * >+ * Since: 2.26 >+ */ >+JSCValue* jsc_value_new_typed_array(JSCContext* context, JSCTypedArrayType type, size_t len) >+{ >+ g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr); >+ >+ JSValueRef exception = nullptr; >+ auto* jsContext = jscContextGetJSContext(context); >+ auto* jsTypedArray = JSObjectMakeTypedArray(jsContext, jscTypedArrayTypeToJSType(type), len, &exception); >+ if (jscContextHandleExceptionIfNeeded(context, exception)) >+ return nullptr; >+ >+ return jscContextGetOrCreateValue(context, jsTypedArray).leakRef(); >+} >+ >+struct TypedArrayDeallocatorContext { >+ gpointer userData; >+ GDestroyNotify destroyNotify; >+}; >+ >+static void jscTypedArrayDeallocate(void*, void* deallocatorContext) >+{ >+ auto* context = static_cast<TypedArrayDeallocatorContext*>(deallocatorContext); >+ context->destroyNotify(context->userData); >+ fastFree(context); >+} >+ >+/** >+ * jsc_value_new_typed_array_from_data: >+ * @context: a @JSCContext >+ * @type: the type of array elements >+ * @data: pointer to a memory region >+ * @data_bytes: size in bytes of the memory region >+ * @user_data: (closure): user data >+ * @destroy_notify: (nullable): destroy notifier for @user_data >+ * >+ * Creates a new typed array from existing @data in memory, whose contents >+ * will be interpreted to be elements of @type. >+ * >+ * Optionally, a @destroy_notify callback can be provided, which will be >+ * invoked with @user_data as parameter when the typed array is released. >+ * This is intended to be used for freeing resources related to the memory >+ * region which contains the data: >+ * >+ * |[<!-- language="C" --> >+ * GMappedFile *f = g_mapped_file_new (file_path, TRUE, NULL); >+ * JSCValue *value = jsc_value_new_typed_array_from_data (context, JSC_TYPED_ARRAY_UINT8, >+ * g_mapped_file_get_contents (f), g_mapped_file_get_length (f), >+ * f, (GDestroyNotify) g_mapped_file_unref); >+ * ]| >+ * >+ * Note that the @user_data can be the same value as @data: >+ * >+ * |[<!-- language="C" --> >+ * guchar *data = g_malloc (guchar, size); >+ * JSCValue *value = jsc_value_new_typed_array_from_data (context, >+ * JSC_TYPED_ARRAY_UINT8, data, size, data, g_free); >+ * ]| >+ * >+ * Returns: (transfer full): a #JSCValue >+ * >+ * Since: 2.26 >+ */ >+JSCValue* jsc_value_new_typed_array_from_data(JSCContext* context, JSCTypedArrayType type, gpointer data, gsize dataBytes, gpointer userData, GDestroyNotify destroyNotify) >+{ >+ g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr); >+ >+ TypedArrayDeallocatorContext* deallocatorContext = nullptr; >+ if (destroyNotify) { >+ deallocatorContext = static_cast<TypedArrayDeallocatorContext*>(fastMalloc(sizeof(TypedArrayDeallocatorContext))); >+ deallocatorContext->userData = userData; >+ deallocatorContext->destroyNotify = destroyNotify; >+ } >+ >+ JSValueRef exception = nullptr; >+ auto* jsContext = jscContextGetJSContext(context); >+ auto* jsTypedArray = JSObjectMakeTypedArrayWithBytesNoCopy(jsContext, jscTypedArrayTypeToJSType(type), data, dataBytes, deallocatorContext ? jscTypedArrayDeallocate : nullptr, deallocatorContext, &exception); >+ if (jscContextHandleExceptionIfNeeded(context, exception)) >+ return nullptr; >+ >+ return jscContextGetOrCreateValue(context, jsTypedArray).leakRef(); >+} >+ >+/** >+ * jsc_value_is_typed_array: >+ * @value: a #JSCValue >+ * >+ * Check whether the @value is a typed array. >+ * >+ * Returns: whether the value is a typed array >+ * >+ * Since: 2.26 >+ */ >+gboolean jsc_value_is_typed_array(JSCValue* value) >+{ >+ g_return_val_if_fail(JSC_IS_VALUE(value), FALSE); >+ >+ auto* jsContext = jscContextGetJSContext(value->priv->context.get()); >+ >+ JSValueRef exception = nullptr; >+ auto jsTypedArrayType = JSValueGetTypedArrayType(jsContext, value->priv->jsValue, &exception); >+ if (jscContextHandleExceptionIfNeeded(value->priv->context.get(), exception)) >+ return FALSE; >+ >+ return jsTypedArrayType != kJSTypedArrayTypeNone && jsTypedArrayType != kJSTypedArrayTypeArrayBuffer; >+} >+ >+/** >+ * jsc_value_typed_array_get_length: >+ * @value: a #JSCValue >+ * >+ * Obtains the size in bytes of the memory region which holds the contents of a typed array. >+ * >+ * Returns: size in bytes or zero if @value is not a typed array >+ * >+ * Since: 2.26 >+ */ >+gsize jsc_value_typed_array_get_length(JSCValue* value) >+{ >+ g_return_val_if_fail(JSC_IS_VALUE(value), 0); >+ >+ auto* jsContext = jscContextGetJSContext(value->priv->context.get()); >+ >+ JSValueRef exception = nullptr; >+ auto* jsObject = JSValueToObject(jsContext, value->priv->jsValue, &exception); >+ if (jscContextHandleExceptionIfNeeded(value->priv->context.get(), exception)) >+ return 0; >+ >+ size_t len = JSObjectGetTypedArrayLength(jsContext, jsObject, &exception); >+ if (jscContextHandleExceptionIfNeeded(value->priv->context.get(), exception)) >+ return 0; >+ >+ return len; >+} >+ >+/** >+ * jsc_value_typed_array_get_contents: >+ * @value: a @JSCValue >+ * @len: (nullable): if not `NULL`, location of a variable where to store the length in bytes >+ * of the memory area which holds the array contents. >+ * >+ * Obtains a pointer to the memory area which stores the elements of a typed array, which >+ * needs to be casted to the appropriate C type corresponding to the type of the elements >+ * (see #JSCTypedArrayType): >+ * >+ * |[<!-- language="C" --> >+ * if (jsc_value_typed_array_get_type (value) == JSC_TYPED_ARRAY_UINT32) >+ * calculate ((uint32_t*) jsc_value_typed_array_get_contents (value, NULL)); >+ * else >+ * g_error ("Only arrays of uint32_t are supported!"); >+ * ]| >+ * >+ * Note that the pointer returned by this function is not guaranteed to remain the same after >+ * calls to other JSC API functions. >+ * >+ * Returns: pointer to the typed array elements, or `NULL` if @value is not a typed array >+ * >+ * Since: 2.26 >+ */ >+gpointer jsc_value_typed_array_get_contents(JSCValue* value, gsize* len) >+{ >+ g_return_val_if_fail(JSC_IS_VALUE(value), nullptr); >+ >+ auto* jsContext = jscContextGetJSContext(value->priv->context.get()); >+ >+ JSValueRef exception = nullptr; >+ auto* jsObject = JSValueToObject(jsContext, value->priv->jsValue, &exception); >+ if (jscContextHandleExceptionIfNeeded(value->priv->context.get(), exception)) >+ return nullptr; >+ >+ auto* ptr = JSObjectGetTypedArrayBytesPtr(jsContext, jsObject, &exception); >+ if (jscContextHandleExceptionIfNeeded(value->priv->context.get(), exception)) >+ return nullptr; >+ >+ if (len) { >+ auto byteLength = JSObjectGetTypedArrayByteLength(jsContext, jsObject, &exception); >+ if (jscContextHandleExceptionIfNeeded(value->priv->context.get(), exception)) >+ return nullptr; >+ *len = byteLength; >+ } >+ >+ return static_cast<char*>(ptr); >+} >diff --git a/Source/JavaScriptCore/API/glib/JSCValue.h b/Source/JavaScriptCore/API/glib/JSCValue.h >index fae6267a6ee46960124b8c398be7c4fe803c9ba4..e6ff363bd5002e4cc706133f67e31873cdc29ed1 100644 >--- a/Source/JavaScriptCore/API/glib/JSCValue.h >+++ b/Source/JavaScriptCore/API/glib/JSCValue.h >@@ -260,6 +260,44 @@ jsc_value_constructor_callv (JSCValue *value, > guint n_parameters, > JSCValue **parameters); > >+typedef enum { >+ JSC_TYPED_ARRAY_INT8, >+ JSC_TYPED_ARRAY_INT16, >+ JSC_TYPED_ARRAY_INT32, >+ JSC_TYPED_ARRAY_UINT8, >+ JSC_TYPED_ARRAY_UINT16, >+ JSC_TYPED_ARRAY_UINT32, >+ JSC_TYPED_ARRAY_FLOAT32, >+ JSC_TYPED_ARRAY_FLOAT64, >+} JSCTypedArrayType; >+ >+JSC_API JSCValue * >+jsc_value_new_typed_array (JSCContext *context, >+ JSCTypedArrayType type, >+ gsize len); >+ >+JSC_API JSCValue * >+jsc_value_new_typed_array_from_data (JSCContext *context, >+ JSCTypedArrayType type, >+ gpointer data, >+ gsize data_bytes, >+ gpointer user_data, >+ GDestroyNotify destroy_notify); >+ >+JSC_API gboolean >+jsc_value_is_typed_array (JSCValue *value); >+ >+JSC_API JSCTypedArrayType >+jsc_value_typed_array_get_type (JSCValue *value); >+ >+JSC_API gsize >+jsc_value_typed_array_get_length (JSCValue *value); >+ >+JSC_API gpointer >+jsc_value_typed_array_get_contents (JSCValue *value, >+ gsize *len); >+ >+ > G_END_DECLS > > #endif /* JSCValue_h */ >diff --git a/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt b/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt >index 3ae2225e1b611a975e1d68f5ecbc0a638fbc249f..49dd6d8225376916d5d9c20bd84ce1fca07700f0 100644 >--- a/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt >+++ b/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt >@@ -69,6 +69,7 @@ jsc_context_get_type > <TITLE>JSCValue</TITLE> > JSCValue > JSCValuePropertyFlags >+JSCTypedArrayType > jsc_value_get_context > jsc_value_new_undefined > jsc_value_is_undefined >@@ -113,6 +114,12 @@ jsc_value_function_callv > jsc_value_is_constructor > jsc_value_constructor_call > jsc_value_constructor_callv >+jsc_value_new_typed_array >+jsc_value_new_typed_array_from_data >+jsc_value_is_typed_array >+jsc_value_typed_array_get_contents >+jsc_value_typed_array_get_length >+jsc_value_typed_array_get_type > > <SUBSECTION Standard> > JSCValueClass
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197535
:
368836
|
368852
|
369379
|
369480
|
454040
|
454112
|
454538
|
454578