[Webkit-unassigned] [Bug 120112] Typed Arrays have no public facing API

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Oct 13 11:55:27 PDT 2015


https://bugs.webkit.org/show_bug.cgi?id=120112

--- Comment #25 from Filip Pizlo <fpizlo at apple.com> ---
(In reply to comment #23)
> (In reply to comment #22)
> 
> > > Can you clarify what the caller must do to ensure that the returned pointer continues to point to valid memory? 
> > My assumption was that a call to JSValueProtect() on the Typed Array would
> > also ensure the pointer remains valid, but I'm not really sure if that's
> > actually the case. Maybe Filip Pizlo can chime in: when/how exactly is the
> > underlying buffer "pinned"?
> > 
> > If JSValueProtect() indeed already ensures the pointer remains valid, I
> > don't think we need another set of functions to retain/release the data
> > pointer. Imho it's obvious that if the JSObject is GC'ed, the pointer will
> > become invalid. If you want to hold on to the pointer, hold on to the
> > JSObject.
> > 
> 
> I'm not sure about this - Fil, do we guarantee we won't move a typed array's
> backing buffer if the referencing object is pinned?

Let's not get confused about the issues here.  Nobody is pinning anything, since we don't have a pinning API.  There is no way to say "please don't move this object or things that this object points to".  Incidentally it just so happens that the JSCell backing a JSObjectRef will not move, but that's not because it's pinned; it's because we don't move JSCells.

> 
> > 
> > > Why does getting the data pointer require a byte length?
> > I found that if you want to obtain the data pointer of a Typed Array, you
> > almost always also need to get the byte length of that data. Note that the
> > pointer to the size_t you pass in, is only used for output! Having two
> > separate API calls for this seemed wasteful. If you don't need the byte
> > length, simply pass NULL instead of a pointer to a size_t:
> > void * ptr = JSObjectGetTypedArrayDataPtr(ctx, object, NULL);
> 
> I don't believe we have any other api that behaves in this way.
> API consistency is important.
> 
> > > Why do we use byte length for access but element count for creation?
> > JSObjectGetTypedArrayDataPtr() returns a pointer to raw data. If we were to
> > return the element count instead of the byte length, you would always need
> > to call JSObjectGetTypedArrayType() as well, to figure out how many bytes
> > you could access. Using the byte length here greatly simplifies stuff like
> > memcpy() to/from own buffers for API users.
> 
> r- just based on this API decision.

I think this is a little extreme.  I understand and appreciate the justification for using byte size, and in fact, the JS typed array API emphasizes byte sizes a lot.

> 
> You're optimizing for a single case (memcpy), over the common case: casting
> the array of X into an X*.
> 
> Mixing and matching what unit the length you're using is a recipe for
> mistakes.

Let's not use this kind of logic.  The typed array API is intended to give expert users who are mixing JS and C to exchange raw memory buffers between the two worlds.  This API must allow the user to shoot himself in the foot; if it doesn't then surely it is a useless API.

> 
> > Likewise, we use an element count for JSObjectMakeTypedArray() because 
> > 1) you know the type of the Typed Array you want to create anyway
> > 2) usually you know the number of elements you want to store when creating a
> > Typed Array through the API (this is different from being passed a Typed
> > Array from JS Land!)
> > 3) using a byte length here would be error prone: what if I try to create a
> > Uint32Array with a byte length of 5?
> 
> Which is why we should always be using the item count. If absolutely
> necessary you could have a GetByteLength function just as the js api has.

By that logic, the C API should be using a mix of byte sizes and element counts in its functions, just like the JS API already does.

> 
> > 
> > 
> > > How do you create a typed array with a data pointer? Is the input a void*?
> > I don't think we need an API for this. Just let JSC handle the data
> > allocation and then obtain a pointer to it.
> > 
> > JSObjectRef array = JSObjectMakeTypedArray(ctx, kJSTypedArrayTypeUint8Array,
> > 1024);
> > void *dataPtr = JSObjectGetTypedArrayDataPtr(ctx, array, NULL);
> > memcpy(dataPtr, myOwnData, 1024);
> > 
> > Imho it's not worth to complicate the API to avoid a short memcpy() for
> > handing over data to JS Land.
> Again, optimizing for memcpy is not the right trade off here.
> 
> Also this API fails to allow sharing of data allocated elsewhere, that can
> lead to unnecessary memory copying. Most other data related APIs on OS X
> allow specifying the external buffer to use -- in fact most APIs take the
> buffer pointer, and only allocate if that pointer is null.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-unassigned/attachments/20151013/b61e679e/attachment.html>


More information about the webkit-unassigned mailing list