diff --git a/dom/bindings/TypedArray.h b/dom/bindings/TypedArray.h index f4b2b7368eec..60da069152ba 100644 --- a/dom/bindings/TypedArray.h +++ b/dom/bindings/TypedArray.h @@ -223,6 +223,39 @@ typedef TypedArray ArrayBuffer; +typedef TypedArray + SharedInt8Array; +typedef TypedArray + SharedUint8Array; +typedef TypedArray + SharedUint8ClampedArray; +typedef TypedArray + SharedInt16Array; +typedef TypedArray + SharedUint16Array; +typedef TypedArray + SharedInt32Array; +typedef TypedArray + SharedUint32Array; +typedef TypedArray + SharedFloat32Array; +typedef TypedArray + SharedFloat64Array; +typedef TypedArray_base + SharedArrayBufferView; +typedef TypedArray + 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 diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 1b0ec436ff23..a831924ed2f2 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -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(""), "ArrayBufferView", IDLBuiltinType.Types.ArrayBufferView), + IDLBuiltinType.Types.SharedArrayBuffer: + IDLBuiltinType(BuiltinLocation(""), "SharedArrayBuffer", + IDLBuiltinType.Types.SharedArrayBuffer), + IDLBuiltinType.Types.SharedArrayBufferView: + IDLBuiltinType(BuiltinLocation(""), "SharedArrayBufferView", + IDLBuiltinType.Types.SharedArrayBufferView), IDLBuiltinType.Types.Int8Array: IDLBuiltinType(BuiltinLocation(""), "Int8Array", IDLBuiltinType.Types.Int8Array), @@ -2953,7 +3029,34 @@ BuiltinTypes = { IDLBuiltinType.Types.Float32Array), IDLBuiltinType.Types.Float64Array: IDLBuiltinType(BuiltinLocation(""), "Float64Array", - IDLBuiltinType.Types.Float64Array) + IDLBuiltinType.Types.Float64Array), + IDLBuiltinType.Types.SharedInt8Array: + IDLBuiltinType(BuiltinLocation(""), "SharedInt8Array", + IDLBuiltinType.Types.SharedInt8Array), + IDLBuiltinType.Types.SharedUint8Array: + IDLBuiltinType(BuiltinLocation(""), "SharedUint8Array", + IDLBuiltinType.Types.SharedUint8Array), + IDLBuiltinType.Types.SharedUint8ClampedArray: + IDLBuiltinType(BuiltinLocation(""), "SharedUint8ClampedArray", + IDLBuiltinType.Types.SharedUint8ClampedArray), + IDLBuiltinType.Types.SharedInt16Array: + IDLBuiltinType(BuiltinLocation(""), "SharedInt16Array", + IDLBuiltinType.Types.SharedInt16Array), + IDLBuiltinType.Types.SharedUint16Array: + IDLBuiltinType(BuiltinLocation(""), "SharedUint16Array", + IDLBuiltinType.Types.SharedUint16Array), + IDLBuiltinType.Types.SharedInt32Array: + IDLBuiltinType(BuiltinLocation(""), "SharedInt32Array", + IDLBuiltinType.Types.SharedInt32Array), + IDLBuiltinType.Types.SharedUint32Array: + IDLBuiltinType(BuiltinLocation(""), "SharedUint32Array", + IDLBuiltinType.Types.SharedUint32Array), + IDLBuiltinType.Types.SharedFloat32Array: + IDLBuiltinType(BuiltinLocation(""), "SharedFloat32Array", + IDLBuiltinType.Types.SharedFloat32Array), + IDLBuiltinType.Types.SharedFloat64Array: + IDLBuiltinType(BuiltinLocation(""), "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(""), 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(): diff --git a/dom/bindings/parser/tests/test_distinguishability.py b/dom/bindings/parser/tests/test_distinguishability.py index dbee9227c7d0..cbcd0985850d 100644 --- a/dom/bindings/parser/tests/test_distinguishability.py +++ b/dom/bindings/parser/tests/test_distinguishability.py @@ -160,7 +160,8 @@ def WebIDLTest(parser, harness): "optional Dict2", "sequence", "sequence", "MozMap", "MozMap", "MozMap", "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", "MozMap", "MozMap" ] # 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) diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 4014e8e8055c..e825b3590c71 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -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. diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 54033d847b31..d3da4999d3ca 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -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() ? 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() ? unwrapped : nullptr; + return nullptr; +} + JS_PUBLIC_API(void*) JS_StealArrayBufferContents(JSContext* cx, HandleObject objArg) { diff --git a/js/src/vm/SharedArrayObject.cpp b/js/src/vm/SharedArrayObject.cpp index 1774724df77e..0c2af6dcb3f6 100644 --- a/js/src/vm/SharedArrayObject.cpp +++ b/js/src/vm/SharedArrayObject.cpp @@ -382,9 +382,36 @@ js::AsSharedArrayBuffer(HandleObject obj) return obj->as(); } +JS_FRIEND_API(void) +js::GetSharedArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data) +{ + MOZ_ASSERT(obj->is()); + + *length = obj->as().byteLength(); + + *data = static_cast(obj->as().viewData()); +} + +JS_FRIEND_API(void) +js::GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data) +{ + MOZ_ASSERT(obj->is()); + *length = obj->as().byteLength(); + *data = obj->as().dataPointer(); +} + JS_FRIEND_API(bool) JS_IsSharedArrayBufferObject(JSObject* obj) { obj = CheckedUnwrap(obj); - return obj ? obj->is() : false; + return obj ? obj->is() : false; +} + +JS_FRIEND_API(uint8_t*) +JS_GetSharedArrayBufferData(JSObject* obj, const JS::AutoCheckCannotGC&) +{ + obj = CheckedUnwrap(obj); + if (!obj) + return nullptr; + return obj->as().dataPointer(); } diff --git a/js/src/vm/SharedTypedArrayObject.cpp b/js/src/vm/SharedTypedArrayObject.cpp index a159246b9c8e..d09c9d429c11 100644 --- a/js/src/vm/SharedTypedArrayObject.cpp +++ b/js/src/vm/SharedTypedArrayObject.cpp @@ -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(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int8); + return static_cast(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(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8); + return static_cast(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(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8Clamped); + return static_cast(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(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int16); + return static_cast(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(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint16); + return static_cast(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(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int32); + return static_cast(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(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint32); + return static_cast(tarr->viewData()); +} + +JS_FRIEND_API(float*) +JS_GetSharedFloat32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&) +{ + obj = CheckedUnwrap(obj); + if (!obj) + return nullptr; + SharedTypedArrayObject* tarr = &obj->as(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float32); + return static_cast(tarr->viewData()); +} + +JS_FRIEND_API(double*) +JS_GetSharedFloat64ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&) +{ + obj = CheckedUnwrap(obj); + if (!obj) + return nullptr; + SharedTypedArrayObject* tarr = &obj->as(); + MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float64); + return static_cast(tarr->viewData()); +} + #undef IMPL_SHARED_TYPED_ARRAY_STATICS #undef IMPL_SHARED_TYPED_ARRAY_JSAPI_CONSTRUCTORS #undef IMPL_SHARED_TYPED_ARRAY_COMBINED_UNWRAPPERS diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index fe391658863f..b1078378f673 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -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()) + return obj->as().type(); + MOZ_CRASH("invalid SharedArrayBufferView type"); +} + JS_FRIEND_API(int8_t*) JS_GetInt8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&) {