Bug 1168471 - Implement support for SharedArrayBuffers and SharedArrayViews in WebIDL. r=bz, r=lth, r=luke

--HG--
extra : rebase_source : 0eb1a42791c03a43113f6a81b066c0c932deb7c8
This commit is contained in:
Jukka Jylanki 2015-06-13 14:02:46 +03:00
parent 9eb9060846
commit 849a58bf98
8 changed files with 378 additions and 11 deletions

View File

@ -223,6 +223,39 @@ typedef TypedArray<uint8_t, js::UnwrapArrayBuffer, JS_GetArrayBufferData,
js::GetArrayBufferLengthAndData, JS_NewArrayBuffer>
ArrayBuffer;
typedef TypedArray<int8_t, js::UnwrapSharedInt8Array, JS_GetSharedInt8ArrayData,
js::GetSharedInt8ArrayLengthAndData, JS_NewSharedInt8Array>
SharedInt8Array;
typedef TypedArray<uint8_t, js::UnwrapSharedUint8Array, JS_GetSharedUint8ArrayData,
js::GetSharedUint8ArrayLengthAndData, JS_NewSharedUint8Array>
SharedUint8Array;
typedef TypedArray<uint8_t, js::UnwrapSharedUint8ClampedArray, JS_GetSharedUint8ClampedArrayData,
js::GetSharedUint8ClampedArrayLengthAndData, JS_NewSharedUint8ClampedArray>
SharedUint8ClampedArray;
typedef TypedArray<int16_t, js::UnwrapSharedInt16Array, JS_GetSharedInt16ArrayData,
js::GetSharedInt16ArrayLengthAndData, JS_NewSharedInt16Array>
SharedInt16Array;
typedef TypedArray<uint16_t, js::UnwrapSharedUint16Array, JS_GetSharedUint16ArrayData,
js::GetSharedUint16ArrayLengthAndData, JS_NewSharedUint16Array>
SharedUint16Array;
typedef TypedArray<int32_t, js::UnwrapSharedInt32Array, JS_GetSharedInt32ArrayData,
js::GetSharedInt32ArrayLengthAndData, JS_NewSharedInt32Array>
SharedInt32Array;
typedef TypedArray<uint32_t, js::UnwrapSharedUint32Array, JS_GetSharedUint32ArrayData,
js::GetSharedUint32ArrayLengthAndData, JS_NewSharedUint32Array>
SharedUint32Array;
typedef TypedArray<float, js::UnwrapSharedFloat32Array, JS_GetSharedFloat32ArrayData,
js::GetSharedFloat32ArrayLengthAndData, JS_NewSharedFloat32Array>
SharedFloat32Array;
typedef TypedArray<double, js::UnwrapSharedFloat64Array, JS_GetSharedFloat64ArrayData,
js::GetSharedFloat64ArrayLengthAndData, JS_NewSharedFloat64Array>
SharedFloat64Array;
typedef TypedArray_base<uint8_t, js::UnwrapSharedArrayBufferView, js::GetSharedArrayBufferViewLengthAndData>
SharedArrayBufferView;
typedef TypedArray<uint8_t, js::UnwrapSharedArrayBuffer, JS_GetSharedArrayBufferData,
js::GetSharedArrayBufferLengthAndData, JS_NewSharedArrayBuffer>
SharedArrayBuffer;
// A class for converting an nsTArray to a TypedArray
// Note: A TypedArrayCreator must not outlive the nsTArray it was created from.
// So this is best used to pass from things that understand nsTArray to

View File

@ -1729,9 +1729,18 @@ class IDLType(IDLObject):
def isArrayBufferView(self):
return False
def isSharedArrayBuffer(self):
return False
def isSharedArrayBufferView(self):
return False
def isTypedArray(self):
return False
def isSharedTypedArray(self):
return False
def isCallbackInterface(self):
return False
@ -1751,7 +1760,10 @@ class IDLType(IDLObject):
only returns true for the types from the TypedArray spec. """
return self.isInterface() and (self.isArrayBuffer() or \
self.isArrayBufferView() or \
self.isTypedArray())
self.isSharedArrayBuffer() or \
self.isSharedArrayBufferView() or \
self.isTypedArray() or \
self.isSharedTypedArray())
def isDictionary(self):
return False
@ -1933,9 +1945,18 @@ class IDLNullableType(IDLType):
def isArrayBufferView(self):
return self.inner.isArrayBufferView()
def isSharedArrayBuffer(self):
return self.inner.isSharedArrayBuffer()
def isSharedArrayBufferView(self):
return self.inner.isSharedArrayBufferView()
def isTypedArray(self):
return self.inner.isTypedArray()
def isSharedTypedArray(self):
return self.inner.isSharedTypedArray()
def isDictionary(self):
return self.inner.isDictionary()
@ -2424,9 +2445,18 @@ class IDLTypedefType(IDLType):
def isArrayBufferView(self):
return self.inner.isArrayBufferView()
def isSharedArrayBuffer(self):
return self.inner.isSharedArrayBuffer()
def isSharedArrayBufferView(self):
return self.inner.isSharedArrayBufferView()
def isTypedArray(self):
return self.inner.isTypedArray()
def isSharedTypedArray(self):
return self.inner.isSharedTypedArray()
def isInterface(self):
return self.inner.isInterface()
@ -2684,6 +2714,8 @@ class IDLBuiltinType(IDLType):
# Funny stuff
'ArrayBuffer',
'ArrayBufferView',
'SharedArrayBuffer',
'SharedArrayBufferView',
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
@ -2692,7 +2724,16 @@ class IDLBuiltinType(IDLType):
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array'
'Float64Array',
'SharedInt8Array',
'SharedUint8Array',
'SharedUint8ClampedArray',
'SharedInt16Array',
'SharedUint16Array',
'SharedInt32Array',
'SharedUint32Array',
'SharedFloat32Array',
'SharedFloat64Array'
)
TagLookup = {
@ -2718,6 +2759,8 @@ class IDLBuiltinType(IDLType):
Types.void: IDLType.Tags.void,
Types.ArrayBuffer: IDLType.Tags.interface,
Types.ArrayBufferView: IDLType.Tags.interface,
Types.SharedArrayBuffer: IDLType.Tags.interface,
Types.SharedArrayBufferView: IDLType.Tags.interface,
Types.Int8Array: IDLType.Tags.interface,
Types.Uint8Array: IDLType.Tags.interface,
Types.Uint8ClampedArray: IDLType.Tags.interface,
@ -2726,7 +2769,16 @@ class IDLBuiltinType(IDLType):
Types.Int32Array: IDLType.Tags.interface,
Types.Uint32Array: IDLType.Tags.interface,
Types.Float32Array: IDLType.Tags.interface,
Types.Float64Array: IDLType.Tags.interface
Types.Float64Array: IDLType.Tags.interface,
Types.SharedInt8Array: IDLType.Tags.interface,
Types.SharedUint8Array: IDLType.Tags.interface,
Types.SharedUint8ClampedArray: IDLType.Tags.interface,
Types.SharedInt16Array: IDLType.Tags.interface,
Types.SharedUint16Array: IDLType.Tags.interface,
Types.SharedInt32Array: IDLType.Tags.interface,
Types.SharedUint32Array: IDLType.Tags.interface,
Types.SharedFloat32Array: IDLType.Tags.interface,
Types.SharedFloat64Array: IDLType.Tags.interface
}
def __init__(self, location, name, type):
@ -2766,17 +2818,30 @@ class IDLBuiltinType(IDLType):
def isArrayBufferView(self):
return self._typeTag == IDLBuiltinType.Types.ArrayBufferView
def isSharedArrayBuffer(self):
return self._typeTag == IDLBuiltinType.Types.SharedArrayBuffer
def isSharedArrayBufferView(self):
return self._typeTag == IDLBuiltinType.Types.SharedArrayBufferView
def isTypedArray(self):
return self._typeTag >= IDLBuiltinType.Types.Int8Array and \
self._typeTag <= IDLBuiltinType.Types.Float64Array
def isSharedTypedArray(self):
return self._typeTag >= IDLBuiltinType.Types.SharedInt8Array and \
self._typeTag <= IDLBuiltinType.Types.SharedFloat64Array
def isInterface(self):
# TypedArray things are interface types per the TypedArray spec,
# but we handle them as builtins because SpiderMonkey implements
# all of it internally.
return self.isArrayBuffer() or \
self.isArrayBufferView() or \
self.isTypedArray()
self.isSharedArrayBuffer() or \
self.isSharedArrayBufferView() or \
self.isTypedArray() or \
self.isSharedTypedArray()
def isNonCallbackInterface(self):
# All the interfaces we can be are non-callback
@ -2847,15 +2912,20 @@ class IDLBuiltinType(IDLType):
# ArrayBuffer is distinguishable from everything
# that's not an ArrayBuffer or a callback interface
(self.isArrayBuffer() and not other.isArrayBuffer()) or
(self.isSharedArrayBuffer() and not other.isSharedArrayBuffer()) or
# ArrayBufferView is distinguishable from everything
# that's not an ArrayBufferView or typed array.
(self.isArrayBufferView() and not other.isArrayBufferView() and
not other.isTypedArray()) or
(self.isSharedArrayBufferView() and not other.isSharedArrayBufferView() and
not other.isSharedTypedArray()) or
# Typed arrays are distinguishable from everything
# except ArrayBufferView and the same type of typed
# array
(self.isTypedArray() and not other.isArrayBufferView() and not
(other.isTypedArray() and other.name == self.name)))))
(other.isTypedArray() and other.name == self.name)) or
(self.isSharedTypedArray() and not other.isSharedArrayBufferView() and not
(other.isSharedTypedArray() and other.name == self.name)))))
def _getDependentObjects(self):
return set()
@ -2927,6 +2997,12 @@ BuiltinTypes = {
IDLBuiltinType.Types.ArrayBufferView:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBufferView",
IDLBuiltinType.Types.ArrayBufferView),
IDLBuiltinType.Types.SharedArrayBuffer:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBuffer",
IDLBuiltinType.Types.SharedArrayBuffer),
IDLBuiltinType.Types.SharedArrayBufferView:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBufferView",
IDLBuiltinType.Types.SharedArrayBufferView),
IDLBuiltinType.Types.Int8Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array",
IDLBuiltinType.Types.Int8Array),
@ -2953,7 +3029,34 @@ BuiltinTypes = {
IDLBuiltinType.Types.Float32Array),
IDLBuiltinType.Types.Float64Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array",
IDLBuiltinType.Types.Float64Array)
IDLBuiltinType.Types.Float64Array),
IDLBuiltinType.Types.SharedInt8Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt8Array",
IDLBuiltinType.Types.SharedInt8Array),
IDLBuiltinType.Types.SharedUint8Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint8Array",
IDLBuiltinType.Types.SharedUint8Array),
IDLBuiltinType.Types.SharedUint8ClampedArray:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint8ClampedArray",
IDLBuiltinType.Types.SharedUint8ClampedArray),
IDLBuiltinType.Types.SharedInt16Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt16Array",
IDLBuiltinType.Types.SharedInt16Array),
IDLBuiltinType.Types.SharedUint16Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint16Array",
IDLBuiltinType.Types.SharedUint16Array),
IDLBuiltinType.Types.SharedInt32Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt32Array",
IDLBuiltinType.Types.SharedInt32Array),
IDLBuiltinType.Types.SharedUint32Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint32Array",
IDLBuiltinType.Types.SharedUint32Array),
IDLBuiltinType.Types.SharedFloat32Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedFloat32Array",
IDLBuiltinType.Types.SharedFloat32Array),
IDLBuiltinType.Types.SharedFloat64Array:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedFloat64Array",
IDLBuiltinType.Types.SharedFloat64Array)
}
@ -4413,6 +4516,7 @@ class Tokenizer(object):
"<": "LT",
">": "GT",
"ArrayBuffer": "ARRAYBUFFER",
"SharedArrayBuffer": "SHAREDARRAYBUFFER",
"or": "OR"
}
@ -5460,12 +5564,15 @@ class Parser(Tokenizer):
"""
NonAnyType : PrimitiveOrStringType TypeSuffix
| ARRAYBUFFER TypeSuffix
| SHAREDARRAYBUFFER TypeSuffix
| OBJECT TypeSuffix
"""
if p[1] == "object":
type = BuiltinTypes[IDLBuiltinType.Types.object]
elif p[1] == "ArrayBuffer":
type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer]
elif p[1] == "SharedArrayBuffer":
type = BuiltinTypes[IDLBuiltinType.Types.SharedArrayBuffer]
else:
type = BuiltinTypes[p[1]]
@ -5859,7 +5966,7 @@ class Parser(Tokenizer):
assert isinstance(scope, IDLScope)
# xrange omits the last value.
for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1):
for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.SharedFloat64Array + 1):
builtin = BuiltinTypes[x]
name = builtin.name
typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name)
@ -5920,6 +6027,7 @@ class Parser(Tokenizer):
_builtins = """
typedef unsigned long long DOMTimeStamp;
typedef (ArrayBufferView or ArrayBuffer) BufferSource;
typedef (SharedArrayBufferView or SharedArrayBuffer) SharedBufferSource;
"""
def main():

View File

@ -160,7 +160,8 @@ def WebIDLTest(parser, harness):
"optional Dict2", "sequence<long>", "sequence<short>",
"MozMap<object>", "MozMap<Dict>", "MozMap<long>",
"long[]", "short[]", "Date", "Date?", "any",
"USVString" ]
"USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer", "SharedArrayBufferView",
"Uint8Array", "SharedUint8Array", "Uint16Array", "SharedUint16Array" ]
# When we can parse Date and RegExp, we need to add them here.
# Try to categorize things a bit to keep list lengths down
@ -175,8 +176,10 @@ def WebIDLTest(parser, harness):
nonStrings = allBut(argTypes, strings)
nonObjects = primitives + strings
objects = allBut(argTypes, nonObjects )
bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"]
sharedBufferSourceTypes = ["SharedArrayBuffer", "SharedArrayBufferView", "SharedUint8Array", "SharedUint16Array"]
interfaces = [ "Interface", "Interface?", "AncestorInterface",
"UnrelatedInterface", "ImplementedInterface" ]
"UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
nullables = ["long?", "short?", "boolean?", "Interface?",
"CallbackInterface?", "optional Dict", "optional Dict2",
"Date?", "any"]
@ -186,7 +189,7 @@ def WebIDLTest(parser, harness):
nonUserObjects = nonObjects + interfaces + dates + sequences
otherObjects = allBut(argTypes, nonUserObjects + ["object"])
notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
otherObjects + dates + sequences)
otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
mozMaps = [ "MozMap<object>", "MozMap<Dict>", "MozMap<long>" ]
# Build a representation of the distinguishability table as a dict
@ -235,6 +238,14 @@ def WebIDLTest(parser, harness):
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
setDistinguishable("any", [])
setDistinguishable("ArrayBuffer", allBut(argTypes, ["ArrayBuffer", "object"]))
setDistinguishable("ArrayBufferView", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]))
setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]))
setDistinguishable("Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]))
setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"]))
setDistinguishable("SharedArrayBufferView", allBut(argTypes, ["SharedArrayBufferView", "SharedUint8Array", "SharedUint16Array", "object"]))
setDistinguishable("SharedUint8Array", allBut(argTypes, ["SharedArrayBufferView", "SharedUint8Array", "object"]))
setDistinguishable("SharedUint16Array", allBut(argTypes, ["SharedArrayBufferView", "SharedUint16Array", "object"]))
def areDistinguishable(type1, type2):
return data[type1].get(type2, False)

View File

@ -1697,6 +1697,12 @@ extern JS_FRIEND_API(JSObject*)
JS_NewSharedFloat64ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
uint32_t byteOffset, uint32_t length);
/*
* Create a new SharedArrayBuffer with the given byte length.
*/
extern JS_FRIEND_API(JSObject*)
JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes);
/*
* Create a new ArrayBuffer with the given byte length.
*/
@ -1821,6 +1827,13 @@ UnwrapSharedFloat32Array(JSObject* obj);
extern JS_FRIEND_API(JSObject*)
UnwrapSharedFloat64Array(JSObject* obj);
extern JS_FRIEND_API(JSObject*)
UnwrapSharedArrayBuffer(JSObject* obj);
extern JS_FRIEND_API(JSObject*)
UnwrapSharedArrayBufferView(JSObject* obj);
namespace detail {
extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr;
@ -1872,6 +1885,16 @@ JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedInt8, int8_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint8, uint8_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint8Clamped, uint8_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedInt16, int16_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint16, uint16_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedInt32, int32_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint32, uint32_t)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedFloat32, float)
JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedFloat64, double)
#undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR
// This one isn't inlined because it's rather tricky (by dint of having to deal
@ -1879,11 +1902,17 @@ JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double)
extern JS_FRIEND_API(void)
GetArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
extern JS_FRIEND_API(void)
GetSharedArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
// This one isn't inlined because there are a bunch of different ArrayBuffer
// classes that would have to be individually handled here.
extern JS_FRIEND_API(void)
GetArrayBufferLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
extern JS_FRIEND_API(void)
GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
} // namespace js
/*
@ -1924,6 +1953,9 @@ JS_GetObjectAsArrayBuffer(JSObject* obj, uint32_t* length, uint8_t** data);
extern JS_FRIEND_API(js::Scalar::Type)
JS_GetArrayBufferViewType(JSObject* obj);
extern JS_FRIEND_API(js::Scalar::Type)
JS_GetSharedArrayBufferViewType(JSObject* obj);
/*
* Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
* return false if a security wrapper is encountered that denies the
@ -2043,6 +2075,27 @@ JS_GetFloat32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(double*)
JS_GetFloat64ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(uint8_t*)
JS_GetSharedArrayBufferData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(int8_t*)
JS_GetSharedInt8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(uint8_t*)
JS_GetSharedUint8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(uint8_t*)
JS_GetSharedUint8ClampedArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(int16_t*)
JS_GetSharedInt16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(uint16_t*)
JS_GetSharedUint16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(int32_t*)
JS_GetSharedInt32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(uint32_t*)
JS_GetSharedUint32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(float*)
JS_GetSharedFloat32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
extern JS_FRIEND_API(double*)
JS_GetSharedFloat64ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
/*
* Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
* versions when possible.

View File

@ -42,6 +42,7 @@
#include "js/MemoryMetrics.h"
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"
#include "vm/SharedArrayObject.h"
#include "vm/WrapperObject.h"
#include "jsatominlines.h"
@ -1285,6 +1286,14 @@ js::UnwrapArrayBufferView(JSObject* obj)
return nullptr;
}
JS_FRIEND_API(JSObject*)
js::UnwrapSharedArrayBufferView(JSObject* obj)
{
if (JSObject* unwrapped = CheckedUnwrap(obj))
return unwrapped->is<SharedTypedArrayObject>() ? unwrapped : nullptr;
return nullptr;
}
JS_FRIEND_API(uint32_t)
JS_GetArrayBufferByteLength(JSObject* obj)
{
@ -1346,6 +1355,13 @@ JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes)
return ArrayBufferObject::create(cx, nbytes);
}
JS_FRIEND_API(JSObject*)
JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes)
{
MOZ_ASSERT(nbytes <= INT32_MAX);
return SharedArrayBufferObject::New(cx, nbytes);
}
JS_PUBLIC_API(JSObject*)
JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* data)
{
@ -1376,6 +1392,14 @@ js::UnwrapArrayBuffer(JSObject* obj)
return nullptr;
}
JS_FRIEND_API(JSObject*)
js::UnwrapSharedArrayBuffer(JSObject* obj)
{
if (JSObject* unwrapped = CheckedUnwrap(obj))
return unwrapped->is<SharedArrayBufferObject>() ? unwrapped : nullptr;
return nullptr;
}
JS_PUBLIC_API(void*)
JS_StealArrayBufferContents(JSContext* cx, HandleObject objArg)
{

View File

@ -382,9 +382,36 @@ js::AsSharedArrayBuffer(HandleObject obj)
return obj->as<SharedArrayBufferObject>();
}
JS_FRIEND_API(void)
js::GetSharedArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data)
{
MOZ_ASSERT(obj->is<SharedTypedArrayObject>());
*length = obj->as<SharedTypedArrayObject>().byteLength();
*data = static_cast<uint8_t*>(obj->as<SharedTypedArrayObject>().viewData());
}
JS_FRIEND_API(void)
js::GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data)
{
MOZ_ASSERT(obj->is<SharedArrayBufferObject>());
*length = obj->as<SharedArrayBufferObject>().byteLength();
*data = obj->as<SharedArrayBufferObject>().dataPointer();
}
JS_FRIEND_API(bool)
JS_IsSharedArrayBufferObject(JSObject* obj)
{
obj = CheckedUnwrap(obj);
return obj ? obj->is<ArrayBufferObject>() : false;
return obj ? obj->is<SharedArrayBufferObject>() : false;
}
JS_FRIEND_API(uint8_t*)
JS_GetSharedArrayBufferData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
return obj->as<SharedArrayBufferObject>().dataPointer();
}

View File

@ -999,6 +999,105 @@ SharedTypedArrayObject::setElement(SharedTypedArrayObject& obj, uint32_t index,
}
}
JS_FRIEND_API(int8_t*)
JS_GetSharedInt8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int8);
return static_cast<int8_t*>(tarr->viewData());
}
JS_FRIEND_API(uint8_t*)
JS_GetSharedUint8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8);
return static_cast<uint8_t*>(tarr->viewData());
}
JS_FRIEND_API(uint8_t*)
JS_GetSharedUint8ClampedArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8Clamped);
return static_cast<uint8_t*>(tarr->viewData());
}
JS_FRIEND_API(int16_t*)
JS_GetSharedInt16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int16);
return static_cast<int16_t*>(tarr->viewData());
}
JS_FRIEND_API(uint16_t*)
JS_GetSharedUint16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint16);
return static_cast<uint16_t*>(tarr->viewData());
}
JS_FRIEND_API(int32_t*)
JS_GetSharedInt32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int32);
return static_cast<int32_t*>(tarr->viewData());
}
JS_FRIEND_API(uint32_t*)
JS_GetSharedUint32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint32);
return static_cast<uint32_t*>(tarr->viewData());
}
JS_FRIEND_API(float*)
JS_GetSharedFloat32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float32);
return static_cast<float*>(tarr->viewData());
}
JS_FRIEND_API(double*)
JS_GetSharedFloat64ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{
obj = CheckedUnwrap(obj);
if (!obj)
return nullptr;
SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float64);
return static_cast<double*>(tarr->viewData());
}
#undef IMPL_SHARED_TYPED_ARRAY_STATICS
#undef IMPL_SHARED_TYPED_ARRAY_JSAPI_CONSTRUCTORS
#undef IMPL_SHARED_TYPED_ARRAY_COMBINED_UNWRAPPERS

View File

@ -2211,6 +2211,18 @@ JS_GetArrayBufferViewType(JSObject* obj)
MOZ_CRASH("invalid ArrayBufferView type");
}
JS_FRIEND_API(js::Scalar::Type)
JS_GetSharedArrayBufferViewType(JSObject* obj)
{
obj = CheckedUnwrap(obj);
if (!obj)
return Scalar::MaxTypedArrayViewType;
if (obj->is<SharedTypedArrayObject>())
return obj->as<SharedTypedArrayObject>().type();
MOZ_CRASH("invalid SharedArrayBufferView type");
}
JS_FRIEND_API(int8_t*)
JS_GetInt8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
{