Bug 123058

Summary: JSC should have an API for typed arrays
Product: WebKit Reporter: Alexey Proskuryakov <ap>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: RESOLVED DUPLICATE    
Severity: Normal CC: fpizlo, ggaren, mhahnenberg
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   

Alexey Proskuryakov
Reported 2013-10-19 00:47:18 PDT
It seems that JavaScript API clients can't do anything with typed arrays passed to them as arguments. I'm facing this in bug 86914, implementing testRunner.setAudioData(ArrayBufferView). In DumpRenderTree, I can grudgingly use private JSC functions just like in WebCore, but API clients can't do that.
Attachments
Geoffrey Garen
Comment 1 2013-10-19 13:01:31 PDT
What would you like to be able to do with them? Surely you can do some things, like read their lengths and access individual elements.
Alexey Proskuryakov
Comment 2 2013-10-19 13:22:06 PDT
> access individual elements That's probably not the most reasonable thing to do in cases that warrant TypedArray use :) Personally, I only needed to get bytes from the buffer efficiently. Not sure if there is anything else that can't be done already, but perhaps some syntactic sugar would help? Also, not sure how efficiently one can create a typed array from C code.
Filip Pizlo
Comment 3 2013-10-19 13:26:53 PDT
(In reply to comment #2) > > access individual elements > > That's probably not the most reasonable thing to do in cases that warrant TypedArray use :) > > Personally, I only needed to get bytes from the buffer efficiently. Not sure if there is anything else that can't be done already, but perhaps some syntactic sugar would help? Also, not sure how efficiently one can create a typed array from C code. I agree we should have such an API. I think we even have some dup's for this bug - you're not the first to ask for this. Maybe just the following C API function would be enough: JSGetTypedArrayBase(JSValueRef) -> returns void* of the first element in the view or the base of the buffer JSGetTypedArrayByteLength(JSValueRef) -> returns size_t of the number of bytes that the view sees or the byteLength of the buffer. These will work for any view or buffer and return null/0 for things that aren't typed arrays. Sound sensible?
Geoffrey Garen
Comment 4 2013-10-19 13:35:31 PDT
I think Alexey is also asking for a way to create typed arrays. > JSGetTypedArrayBase(JSValueRef) -> returns void* of the first element in the view or the base of the buffer > JSGetTypedArrayByteLength(JSValueRef) -> returns size_t of the number of bytes that the view sees or the byteLength of the buffer. This would be JSObjectGetTypedArrayBase(JSContextRef, JSValueRef) JSObjectGetTypedArrayByteLength(JSContextRef, JSValueRef) Maybe "BytesPtr" is a better name than "Base", to match our string and data APIs. How would I know the data type in the typed array? How long would the returned pointer remain valid? What happens after neutering?
Geoffrey Garen
Comment 5 2013-10-19 13:36:09 PDT
> JSObjectGetTypedArrayBase(JSContextRef, JSValueRef) > JSObjectGetTypedArrayByteLength(JSContextRef, JSValueRef) Sorry: JSObjectGetTypedArrayBase(JSContextRef, JSObjectRef) JSObjectGetTypedArrayByteLength(JSContextRef, JSObjectRef)
Filip Pizlo
Comment 6 2013-10-19 13:44:50 PDT
(In reply to comment #4) > I think Alexey is also asking for a way to create typed arrays. > > > JSGetTypedArrayBase(JSValueRef) -> returns void* of the first element in the view or the base of the buffer > > JSGetTypedArrayByteLength(JSValueRef) -> returns size_t of the number of bytes that the view sees or the byteLength of the buffer. > > This would be > > JSObjectGetTypedArrayBase(JSContextRef, JSValueRef) > JSObjectGetTypedArrayByteLength(JSContextRef, JSValueRef) OK, but out of curiosity, does it have to be? You can get a JSGenericTypedArrayView's base and length without an ExecState*. > > Maybe "BytesPtr" is a better name than "Base", to match our string and data APIs. Yeah. > > How would I know the data type in the typed array? Why would a client care? If they did, they can already get the element type using JS constructs. > How long would the returned pointer remain valid? Only so long as the JSValueRef of the buffer or view was live and so long as it wasn't neutered. > What happens after neutering? It's interesting to note that neutering is purely a DOM construct - it will only happen if you use the JS API in conjunction with a WebView. Neutering will free the buffer so your pointer will become invalid.
Filip Pizlo
Comment 7 2013-10-19 13:51:21 PDT
(In reply to comment #6) > (In reply to comment #4) > > I think Alexey is also asking for a way to create typed arrays. > > > > > JSGetTypedArrayBase(JSValueRef) -> returns void* of the first element in the view or the base of the buffer > > > JSGetTypedArrayByteLength(JSValueRef) -> returns size_t of the number of bytes that the view sees or the byteLength of the buffer. > > > > This would be > > > > JSObjectGetTypedArrayBase(JSContextRef, JSValueRef) > > JSObjectGetTypedArrayByteLength(JSContextRef, JSValueRef) > > OK, but out of curiosity, does it have to be? You can get a JSGenericTypedArrayView's base and length without an ExecState*. > > > > > Maybe "BytesPtr" is a better name than "Base", to match our string and data APIs. > > Yeah. > > > > > How would I know the data type in the typed array? > > Why would a client care? If they did, they can already get the element type using JS constructs. > > > How long would the returned pointer remain valid? > > Only so long as the JSValueRef of the buffer or view was live and so long as it wasn't neutered. And to clarify, we will ensure that the returned buffer pointer was pinned by doing slowDownAndWasteMemory(). > > > What happens after neutering? > > It's interesting to note that neutering is purely a DOM construct - it will only happen if you use the JS API in conjunction with a WebView. > > Neutering will free the buffer so your pointer will become invalid.
Geoffrey Garen
Comment 8 2013-10-19 14:40:20 PDT
> > JSObjectGetTypedArrayBase(JSContextRef, JSValueRef) > > JSObjectGetTypedArrayByteLength(JSContextRef, JSValueRef) > OK, but out of curiosity, does it have to be? You can get a JSGenericTypedArrayView's base and length without an ExecState*. Whenever we’ve made the decision to leave out JSContextRef before, we’ve come to regret it. For example, we made that decision for strings, and now we regret it. In this case, I could imagine some implementations that might require an ExecState* in order to get a backing pointer. For example, if we did pin the pointer, and pinning required a GC allocation, then we would need an ExecState*. Or, if some typed arrays had a super-slow mode, in which their backing buffer pointers were maintained in an external hash table, that would require an ExecState*. Or if some typed arrays had an "I'm currently in GPU memory" mode, that would require an ExecState*.
Filip Pizlo
Comment 9 2013-10-19 14:43:40 PDT
(In reply to comment #8) > > > JSObjectGetTypedArrayBase(JSContextRef, JSValueRef) > > > JSObjectGetTypedArrayByteLength(JSContextRef, JSValueRef) > > > OK, but out of curiosity, does it have to be? You can get a JSGenericTypedArrayView's base and length without an ExecState*. > > Whenever we’ve made the decision to leave out JSContextRef before, we’ve come to regret it. For example, we made that decision for strings, and now we regret it. > > In this case, I could imagine some implementations that might require an ExecState* in order to get a backing pointer. For example, if we did pin the pointer, and pinning required a GC allocation, then we would need an ExecState*. Or, if some typed arrays had a super-slow mode, in which their backing buffer pointers were maintained in an external hash table, that would require an ExecState*. Or if some typed arrays had an "I'm currently in GPU memory" mode, that would require an ExecState*. Interestingly, slowDownAndWasteMemory() does require VM& but it doesn't take either VM& or ExecState*. It just uses heapFor(). That's because there were too many places that expected to be able to get a native buffer from a JS buffer and they didn't have an ExecState* lying around. But, sure, we don't have to expose such madness to the C API customers.
Alexey Proskuryakov
Comment 10 2013-11-06 09:42:35 PST
Found an older bug, duping to that. *** This bug has been marked as a duplicate of bug 120112 ***
Note You need to log in before you can comment on or make changes to this bug.