Skip to content

Commit ba83a41

Browse files
committed
new api draft
1 parent c652026 commit ba83a41

File tree

2 files changed

+111
-56
lines changed

2 files changed

+111
-56
lines changed

JavaScriptCore/API/JSTypedArray.cpp

Lines changed: 102 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,39 @@
2727

2828
using namespace JSC;
2929

30-
// Better be safe than sorry!
30+
struct OpaqueJSData : public ThreadSafeRefCounted<OpaqueJSData> {
31+
32+
static PassRefPtr<OpaqueJSData> create(PassRefPtr<ArrayBuffer> buffer, void* baseAddress, size_t byteLength)
33+
{
34+
return adoptRef(new OpaqueJSData(buffer, baseAddress, byteLength));
35+
}
36+
37+
size_t length() {
38+
return m_byteLength;
39+
}
40+
41+
void* baseAddress() {
42+
return m_baseAddress;
43+
}
44+
45+
private:
46+
friend class WTF::ThreadSafeRefCounted<OpaqueJSData>;
47+
48+
OpaqueJSData(
49+
PassRefPtr<ArrayBuffer> buffer,
50+
void* baseAddress,
51+
size_t byteLength)
52+
: m_byteLength(byteLength)
53+
, m_baseAddress(baseAddress)
54+
, m_buffer(buffer)
55+
{}
56+
57+
unsigned m_byteLength;
58+
void* m_baseAddress;
59+
PassRefPtr<ArrayBuffer> m_buffer;
60+
};
61+
62+
3163
const JSTypedArrayType TypedArrayTypes[] = {
3264
[NotTypedArray] = kJSTypedArrayTypeNone,
3365
[TypeInt8] = kJSTypedArrayTypeInt8Array,
@@ -42,43 +74,8 @@ const JSTypedArrayType TypedArrayTypes[] = {
4274
/* not a TypedArray */ kJSTypedArrayTypeArrayBuffer
4375
};
4476

45-
const int kJSTypedArrayTypeLast = kJSTypedArrayTypeArrayBuffer;
46-
47-
48-
template <typename ArrayType>JSObject * CreateTypedArray(JSC::ExecState* exec, size_t length) {
49-
return ArrayType::create(length)->wrap(exec, exec->lexicalGlobalObject());
50-
}
51-
52-
template <typename BufferType>JSObject * CreateArrayBuffer(JSC::ExecState* exec, size_t length) {
53-
RefPtr<BufferType> buffer = BufferType::create(length, 1);
54-
if( !buffer ) {
55-
return NULL;
56-
}
57-
58-
JSArrayBuffer* result = JSArrayBuffer::create(
59-
exec->vm(), exec->lexicalGlobalObject()->arrayBufferStructure(), buffer);
60-
return result;
61-
}
62-
63-
typedef JSObject*(*CreateTypedArrayFuncPtr)(JSC::ExecState*, size_t);
64-
const CreateTypedArrayFuncPtr CreateTypedArrayFunc[] = {
65-
[kJSTypedArrayTypeNone] = NULL,
66-
[kJSTypedArrayTypeInt8Array] = CreateTypedArray<Int8Array>,
67-
[kJSTypedArrayTypeInt16Array] = CreateTypedArray<Int16Array>,
68-
[kJSTypedArrayTypeInt32Array] = CreateTypedArray<Int32Array>,
69-
[kJSTypedArrayTypeUint8Array] = CreateTypedArray<Uint8Array>,
70-
[kJSTypedArrayTypeUint8ClampedArray] = CreateTypedArray<Uint8ClampedArray>,
71-
[kJSTypedArrayTypeUint16Array] = CreateTypedArray<Uint16Array>,
72-
[kJSTypedArrayTypeUint32Array] = CreateTypedArray<Uint32Array>,
73-
[kJSTypedArrayTypeFloat32Array] = CreateTypedArray<Float32Array>,
74-
[kJSTypedArrayTypeFloat64Array] = CreateTypedArray<Float64Array>,
75-
[kJSTypedArrayTypeArrayBuffer] = CreateArrayBuffer<ArrayBuffer>,
76-
};
77-
78-
79-
80-
81-
JSTypedArrayType JSObjectGetTypedArrayType(JSContextRef ctx, JSObjectRef object) {
77+
JSTypedArrayType JSObjectGetTypedArrayType(JSContextRef ctx, JSObjectRef object)
78+
{
8279
ExecState* exec = toJS(ctx);
8380
APIEntryShim entryShim(exec);
8481

@@ -93,38 +90,88 @@ JSTypedArrayType JSObjectGetTypedArrayType(JSContextRef ctx, JSObjectRef object)
9390
return type;
9491
}
9592

96-
JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType, size_t numElements) {
93+
JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType, size_t numElements)
94+
{
9795
ExecState* exec = toJS(ctx);
9896
APIEntryShim entryShim(exec);
9997

100-
JSObject* result = NULL;
101-
if( arrayType > kJSTypedArrayTypeNone && arrayType <= kJSTypedArrayTypeLast ) {
102-
result = CreateTypedArrayFunc[arrayType]( exec, numElements );
98+
JSObject* result;
99+
JSGlobalObject* jsGlobal = exec->lexicalGlobalObject();
100+
switch( arrayType ) {
101+
case kJSTypedArrayTypeInt8Array:
102+
result = Int8Array::create(numElements)->wrap(exec, jsGlobal);
103+
break;
104+
case kJSTypedArrayTypeInt16Array:
105+
result = Int16Array::create(numElements)->wrap(exec, jsGlobal);
106+
break;
107+
case kJSTypedArrayTypeInt32Array:
108+
result = Int8Array::create(numElements)->wrap(exec, jsGlobal);
109+
break;
110+
case kJSTypedArrayTypeUint8Array:
111+
result = Int32Array::create(numElements)->wrap(exec, jsGlobal);
112+
break;
113+
case kJSTypedArrayTypeUint8ClampedArray:
114+
result = Uint8ClampedArray::create(numElements)->wrap(exec, jsGlobal);
115+
break;
116+
case kJSTypedArrayTypeUint16Array:
117+
result = Uint16Array::create(numElements)->wrap(exec, jsGlobal);
118+
break;
119+
case kJSTypedArrayTypeUint32Array:
120+
result = Uint32Array::create(numElements)->wrap(exec, jsGlobal);
121+
break;
122+
case kJSTypedArrayTypeFloat32Array:
123+
result = Float32Array::create(numElements)->wrap(exec, jsGlobal);
124+
break;
125+
case kJSTypedArrayTypeFloat64Array:
126+
result = Float64Array::create(numElements)->wrap(exec, jsGlobal);
127+
break;
128+
case kJSTypedArrayTypeArrayBuffer:
129+
result = JSArrayBuffer::create(
130+
exec->vm(), jsGlobal->arrayBufferStructure(), ArrayBuffer::create(numElements, 1));
131+
break;
132+
default:
133+
result = NULL;
134+
break;
103135
}
104136

105137
return toRef(result);
106138
}
107139

108-
void* JSObjectGetTypedArrayDataPtr(JSContextRef ctx, JSObjectRef object, size_t* byteLength) {
140+
JSDataRef JSObjectGetTypedArrayData(JSContextRef ctx, JSObjectRef object)
141+
{
109142
ExecState* exec = toJS(ctx);
110143
APIEntryShim entryShim(exec);
111144

112145
JSObject* jsObject = toJS(object);
113146
if( JSArrayBufferView * view = jsDynamicCast<JSArrayBufferView*>(jsObject) ) {
114-
if( byteLength ) {
115-
*byteLength = view->impl()->byteLength();
116-
}
117-
return view->impl()->baseAddress();
147+
return OpaqueJSData::create(view->buffer(), view->impl()->baseAddress(), view->impl()->byteLength()).leakRef();
118148
}
119149
else if( ArrayBuffer* buffer = toArrayBuffer(jsObject) ) {
120-
if( byteLength ) {
121-
*byteLength = buffer->byteLength();
122-
}
123-
return buffer->data();
124-
}
125-
126-
if( byteLength ) {
127-
*byteLength = 0;
150+
return OpaqueJSData::create(buffer, buffer->data(), buffer->byteLength()).leakRef();
128151
}
152+
129153
return NULL;
130154
}
155+
156+
void JSDataRetain(JSDataRef data)
157+
{
158+
if(data != nullptr)
159+
data->ref();
160+
}
161+
162+
void JSDataRelease(JSDataRef data)
163+
{
164+
if(data != nullptr)
165+
data->deref();
166+
}
167+
168+
void* JSDataGetBytesPtr(JSDataRef data)
169+
{
170+
return data->baseAddress();
171+
}
172+
173+
size_t JSDataGetLength(JSDataRef data)
174+
{
175+
return data->length();
176+
}
177+

JavaScriptCore/API/JSTypedArray.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ JS_EXPORT JSTypedArrayType JSObjectGetTypedArrayType(JSContextRef ctx, JSObjectR
5555
*/
5656
JS_EXPORT JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType, size_t numElements);
5757

58+
59+
typedef struct OpaqueJSData* JSDataRef;
60+
61+
JS_EXPORT void JSDataRetain(JSDataRef data);
62+
JS_EXPORT void JSDataRelease(JSDataRef data);
63+
JS_EXPORT void * JSDataGetBytesPtr(JSDataRef data);
64+
JS_EXPORT size_t JSDataGetLength(JSDataRef data);
65+
5866
/*!
5967
@function
6068
@abstract Returns a pointer to a Typed Array's data in memory
@@ -63,7 +71,7 @@ JS_EXPORT JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType
6371
@param byteLength A pointer to a size_t in which to store the byte length of the Typed Array
6472
@result A pointer to the Typed Array's data or NULL if the JSValue is not a Typed Array.
6573
*/
66-
JS_EXPORT void * JSObjectGetTypedArrayDataPtr(JSContextRef ctx, JSObjectRef object, size_t* byteLength);
74+
JS_EXPORT JSDataRef JSObjectGetTypedArrayData(JSContextRef ctx, JSObjectRef object);
6775

6876

6977
#ifdef __cplusplus

0 commit comments

Comments
 (0)