<html>
<head>
<base href="https://bugs.webkit.org/" />
</head>
<body>
<p>
<div>
<b><a class="bz_bug_link
bz_status_NEW "
title="NEW - Typed Arrays have no public facing API"
href="https://bugs.webkit.org/show_bug.cgi?id=120112#c25">Comment # 25</a>
on <a class="bz_bug_link
bz_status_NEW "
title="NEW - Typed Arrays have no public facing API"
href="https://bugs.webkit.org/show_bug.cgi?id=120112">bug 120112</a>
from <span class="vcard"><a class="email" href="mailto:fpizlo@apple.com" title="Filip Pizlo <fpizlo@apple.com>"> <span class="fn">Filip Pizlo</span></a>
</span></b>
<pre>(In reply to <a href="show_bug.cgi?id=120112#c23">comment #23</a>)
<span class="quote">> (In reply to <a href="show_bug.cgi?id=120112#c22">comment #22</a>)
>
> > > 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?</span >
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.
<span class="quote">>
> >
> > > 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.</span >
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.
<span class="quote">>
> 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.</span >
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.
<span class="quote">>
> > 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.</span >
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.
<span class="quote">>
> >
> >
> > > 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.</span ></pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are the assignee for the bug.</li>
</ul>
</body>
</html>