|
|
@@ -7,6 +7,7 @@
|
|
|
// can share the same array buffer.
|
|
|
//----------------------------------------------------------------------------
|
|
|
#include "RuntimeLibraryPch.h"
|
|
|
+#include "AtomicsOperations.h"
|
|
|
|
|
|
#define INSTANTIATE_BUILT_IN_ENTRYPOINTS(typeName) \
|
|
|
template Var typeName::NewInstance(RecyclableObject* function, CallInfo callInfo, ...); \
|
|
|
@@ -2932,160 +2933,85 @@ namespace Js
|
|
|
DIRECT_GET_VAR_CHECK_NO_DETACH_CHECK(Float64Array);
|
|
|
DIRECT_GET_VAR_CHECK_NO_DETACH_CHECK(Float64VirtualArray);
|
|
|
|
|
|
-#define TypedArrayBeginStub(type) \
|
|
|
+#define TypedArrayBeginStub(TypedArrayName) \
|
|
|
Assert(GetArrayBuffer() || GetArrayBuffer()->GetBuffer()); \
|
|
|
- Assert(index < GetLength()); \
|
|
|
+ Assert(accessIndex < GetLength()); \
|
|
|
ScriptContext *scriptContext = GetScriptContext(); \
|
|
|
- type *buffer = (type*)this->buffer + index;
|
|
|
+ typedef TypedArrayName::TypedArrayType type; \
|
|
|
+ type *buffer = (type*)this->buffer + accessIndex;
|
|
|
|
|
|
-#ifdef _WIN32
|
|
|
-#define InterlockedExchangeAdd8 _InterlockedExchangeAdd8
|
|
|
-#define InterlockedExchangeAdd16 _InterlockedExchangeAdd16
|
|
|
-
|
|
|
-#define InterlockedAnd8 _InterlockedAnd8
|
|
|
-#define InterlockedAnd16 _InterlockedAnd16
|
|
|
-
|
|
|
-#define InterlockedOr8 _InterlockedOr8
|
|
|
-#define InterlockedOr16 _InterlockedOr16
|
|
|
-
|
|
|
-#define InterlockedXor8 _InterlockedXor8
|
|
|
-#define InterlockedXor16 _InterlockedXor16
|
|
|
-
|
|
|
-#define InterlockedCompareExchange8 _InterlockedCompareExchange8
|
|
|
-#define InterlockedCompareExchange16 _InterlockedCompareExchange16
|
|
|
-
|
|
|
-#define InterlockedExchange8 _InterlockedExchange8
|
|
|
-#define InterlockedExchange16 _InterlockedExchange16
|
|
|
-#endif
|
|
|
-
|
|
|
-#define InterlockedExchangeAdd32 InterlockedExchangeAdd
|
|
|
-#define InterlockedAnd32 InterlockedAnd
|
|
|
-#define InterlockedOr32 InterlockedOr
|
|
|
-#define InterlockedXor32 InterlockedXor
|
|
|
-#define InterlockedCompareExchange32 InterlockedCompareExchange
|
|
|
-#define InterlockedExchange32 InterlockedExchange
|
|
|
-
|
|
|
-#define TypedArrayAddOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedAdd(__in uint32 index, __in Var second) \
|
|
|
- { \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- type result = (type)InterlockedExchangeAdd##bit((convertType*)buffer, (convertType)convertFn(second, scriptContext)); \
|
|
|
- return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
- }
|
|
|
-
|
|
|
-#define TypedArrayAndOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedAnd(__in uint32 index, __in Var second) \
|
|
|
- { \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- type result = (type)InterlockedAnd##bit((convertType*)buffer, (convertType)convertFn(second, scriptContext)); \
|
|
|
- return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
- }
|
|
|
-
|
|
|
-#define TypedArrayCompareExchangeOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedCompareExchange(__in uint32 index, __in Var comparand, __in Var replacementValue) \
|
|
|
- { \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- type result = (type)InterlockedCompareExchange##bit((convertType*)buffer, (convertType)convertFn(replacementValue, scriptContext), (convertType)convertFn(comparand, scriptContext)); \
|
|
|
- return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
- }
|
|
|
-
|
|
|
-#define TypedArrayExchangeOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedExchange(__in uint32 index, __in Var second) \
|
|
|
+#define TypedArrayStore(TypedArrayName, fnName, convertFn) \
|
|
|
+ template<>\
|
|
|
+ Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex, __in Var value) \
|
|
|
{ \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- type result = (type)InterlockedExchange##bit((convertType*)buffer, (convertType)convertFn(second, scriptContext)); \
|
|
|
- return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
+ TypedArrayBeginStub(TypedArrayName); \
|
|
|
+ double retVal = JavascriptConversion::ToInteger(value, scriptContext); \
|
|
|
+ AtomicsOperations::fnName(buffer, convertFn(retVal)); \
|
|
|
+ return JavascriptNumber::ToVarWithCheck(retVal, scriptContext); \
|
|
|
}
|
|
|
|
|
|
-#define TypedArrayLoadOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedLoad(__in uint32 index) \
|
|
|
+#define TypedArrayOp1(TypedArrayName, fnName, convertFn) \
|
|
|
+ template<>\
|
|
|
+ Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex) \
|
|
|
{ \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- MemoryBarrier(); \
|
|
|
- type result = (type)*buffer; \
|
|
|
+ TypedArrayBeginStub(TypedArrayName); \
|
|
|
+ type result = AtomicsOperations::fnName(buffer); \
|
|
|
return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
}
|
|
|
|
|
|
-#define TypedArrayOrOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedOr(__in uint32 index, __in Var second) \
|
|
|
+#define TypedArrayOp2(TypedArrayName, fnName, convertFn) \
|
|
|
+ template<>\
|
|
|
+ Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex, __in Var value) \
|
|
|
{ \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- type result = (type)InterlockedOr##bit((convertType*)buffer, (convertType)convertFn(second, scriptContext)); \
|
|
|
+ TypedArrayBeginStub(TypedArrayName); \
|
|
|
+ type result = AtomicsOperations::fnName(buffer, convertFn(value, scriptContext)); \
|
|
|
return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
}
|
|
|
|
|
|
- // Currently the TypedStore is just using the InterlockedExchange to store the value in the buffer.
|
|
|
- // TODO The InterlockedExchange will have the sequential consistency any way, not sure why do we need the Memory barrier or std::atomic::store to perform this.
|
|
|
-
|
|
|
-#define TypedArrayStoreOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedStore(__in uint32 index, __in Var second) \
|
|
|
+#define TypedArrayOp3(TypedArrayName, fnName, convertFn) \
|
|
|
+ template<>\
|
|
|
+ Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex, __in Var first, __in Var value) \
|
|
|
{ \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- double d = JavascriptConversion::ToInteger(second, scriptContext); \
|
|
|
- convertType s = (convertType)JavascriptConversion::ToUInt32(d); \
|
|
|
- InterlockedExchange##bit((convertType*)buffer, s); \
|
|
|
- return JavascriptNumber::ToVarWithCheck(d, scriptContext); \
|
|
|
- }
|
|
|
-
|
|
|
-#define TypedArraySubOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedSub(__in uint32 index, __in Var second) \
|
|
|
- { \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- type result = (type)InterlockedExchangeAdd##bit((convertType*)buffer, - (convertType)convertFn(second, scriptContext)); \
|
|
|
- return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
- }
|
|
|
-
|
|
|
-#define TypedArrayXorOp(TypedArrayName, bit, type, convertType, convertFn) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::TypedXor(__in uint32 index, __in Var second) \
|
|
|
- { \
|
|
|
- TypedArrayBeginStub(type); \
|
|
|
- type result = (type)InterlockedXor##bit((convertType*)buffer, (convertType)convertFn(second, scriptContext)); \
|
|
|
+ TypedArrayBeginStub(TypedArrayName); \
|
|
|
+ type result = AtomicsOperations::fnName(buffer, convertFn(first, scriptContext), convertFn(value, scriptContext)); \
|
|
|
return JavascriptNumber::ToVar(result, scriptContext); \
|
|
|
}
|
|
|
|
|
|
#define GenerateNotSupportedStub1(TypedArrayName, fnName) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex) \
|
|
|
+ template<>\
|
|
|
+ Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex) \
|
|
|
{ \
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray); \
|
|
|
}
|
|
|
|
|
|
#define GenerateNotSupportedStub2(TypedArrayName, fnName) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex, __in Var value) \
|
|
|
+ template<>\
|
|
|
+ Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex, __in Var value) \
|
|
|
{ \
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray); \
|
|
|
}
|
|
|
|
|
|
#define GenerateNotSupportedStub3(TypedArrayName, fnName) \
|
|
|
- template<> \
|
|
|
- inline Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex, __in Var first, __in Var value) \
|
|
|
+ template<>\
|
|
|
+ Var TypedArrayName##::Typed##fnName(__in uint32 accessIndex, __in Var first, __in Var value) \
|
|
|
{ \
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray); \
|
|
|
}
|
|
|
|
|
|
+
|
|
|
#define GENERATE_FOREACH_TYPEDARRAY(TYPEDARRAY_DEF, NOTSUPPORTEDSTUB, OP) \
|
|
|
- TYPEDARRAY_DEF(Int8Array, 8, int8, char, JavascriptConversion::ToInt8); \
|
|
|
- TYPEDARRAY_DEF(Int8VirtualArray, 8, int8, char, JavascriptConversion::ToInt8); \
|
|
|
- TYPEDARRAY_DEF(Uint8Array, 8, uint8, char, JavascriptConversion::ToUInt8); \
|
|
|
- TYPEDARRAY_DEF(Uint8VirtualArray, 8, uint8, char, JavascriptConversion::ToUInt8); \
|
|
|
- TYPEDARRAY_DEF(Int16Array, 16, int16, short, JavascriptConversion::ToInt16); \
|
|
|
- TYPEDARRAY_DEF(Int16VirtualArray, 16, int16, short, JavascriptConversion::ToInt16); \
|
|
|
- TYPEDARRAY_DEF(Uint16Array, 16, uint16, short, JavascriptConversion::ToUInt16); \
|
|
|
- TYPEDARRAY_DEF(Uint16VirtualArray, 16, uint16, short, JavascriptConversion::ToUInt16); \
|
|
|
- TYPEDARRAY_DEF(Int32Array, 32, int32, LONG, JavascriptConversion::ToInt32); \
|
|
|
- TYPEDARRAY_DEF(Int32VirtualArray, 32, int32, LONG, JavascriptConversion::ToInt32); \
|
|
|
- TYPEDARRAY_DEF(Uint32Array, 32, uint32, LONG, JavascriptConversion::ToUInt32); \
|
|
|
- TYPEDARRAY_DEF(Uint32VirtualArray, 32, uint32, LONG, JavascriptConversion::ToUInt32); \
|
|
|
+ TYPEDARRAY_DEF(Int8Array, OP, JavascriptConversion::ToInt8); \
|
|
|
+ TYPEDARRAY_DEF(Int8VirtualArray, OP, JavascriptConversion::ToInt8); \
|
|
|
+ TYPEDARRAY_DEF(Uint8Array, OP, JavascriptConversion::ToUInt8); \
|
|
|
+ TYPEDARRAY_DEF(Uint8VirtualArray, OP, JavascriptConversion::ToUInt8); \
|
|
|
+ TYPEDARRAY_DEF(Int16Array, OP, JavascriptConversion::ToInt16); \
|
|
|
+ TYPEDARRAY_DEF(Int16VirtualArray, OP, JavascriptConversion::ToInt16); \
|
|
|
+ TYPEDARRAY_DEF(Uint16Array, OP, JavascriptConversion::ToUInt16); \
|
|
|
+ TYPEDARRAY_DEF(Uint16VirtualArray, OP, JavascriptConversion::ToUInt16); \
|
|
|
+ TYPEDARRAY_DEF(Int32Array, OP, JavascriptConversion::ToInt32); \
|
|
|
+ TYPEDARRAY_DEF(Int32VirtualArray, OP, JavascriptConversion::ToInt32); \
|
|
|
+ TYPEDARRAY_DEF(Uint32Array, OP, JavascriptConversion::ToUInt32); \
|
|
|
+ TYPEDARRAY_DEF(Uint32VirtualArray, OP, JavascriptConversion::ToUInt32); \
|
|
|
NOTSUPPORTEDSTUB(Float32Array, OP); \
|
|
|
NOTSUPPORTEDSTUB(Float32VirtualArray, OP); \
|
|
|
NOTSUPPORTEDSTUB(Float64Array, OP); \
|
|
|
@@ -3096,15 +3022,15 @@ namespace Js
|
|
|
NOTSUPPORTEDSTUB(Uint8ClampedVirtualArray, OP); \
|
|
|
NOTSUPPORTEDSTUB(BoolArray, OP);
|
|
|
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayAddOp, GenerateNotSupportedStub2, Add)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayAndOp, GenerateNotSupportedStub2, And)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayCompareExchangeOp, GenerateNotSupportedStub3, CompareExchange)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayExchangeOp, GenerateNotSupportedStub2, Exchange)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayLoadOp, GenerateNotSupportedStub1, Load)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayOrOp, GenerateNotSupportedStub2, Or)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayStoreOp, GenerateNotSupportedStub2, Store)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArraySubOp, GenerateNotSupportedStub2, Sub)
|
|
|
- GENERATE_FOREACH_TYPEDARRAY(TypedArrayXorOp, GenerateNotSupportedStub2, Xor)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp2, GenerateNotSupportedStub2, Add)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp2, GenerateNotSupportedStub2, And)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp3, GenerateNotSupportedStub3, CompareExchange)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp2, GenerateNotSupportedStub2, Exchange)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp1, GenerateNotSupportedStub1, Load)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp2, GenerateNotSupportedStub2, Or)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayStore, GenerateNotSupportedStub2, Store)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp2, GenerateNotSupportedStub2, Sub)
|
|
|
+ GENERATE_FOREACH_TYPEDARRAY(TypedArrayOp2, GenerateNotSupportedStub2, Xor)
|
|
|
|
|
|
template<>
|
|
|
VTableValue Int8Array::DummyVirtualFunctionToHinderLinkerICF()
|
|
|
@@ -3700,22 +3626,22 @@ namespace Js
|
|
|
return DirectGetItem(index);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedAdd(__in uint32 index, Var second)
|
|
|
+ Var CharArray::TypedAdd(__in uint32 index, __in Var second)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedAnd(__in uint32 index, Var second)
|
|
|
+ Var CharArray::TypedAnd(__in uint32 index, __in Var second)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedCompareExchange(__in uint32 index, Var comparand, Var replacementValue)
|
|
|
+ Var CharArray::TypedCompareExchange(__in uint32 index, __in Var comparand, __in Var replacementValue)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedExchange(__in uint32 index, Var second)
|
|
|
+ Var CharArray::TypedExchange(__in uint32 index, __in Var second)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
@@ -3725,22 +3651,22 @@ namespace Js
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedOr(__in uint32 index, Var second)
|
|
|
+ Var CharArray::TypedOr(__in uint32 index, __in Var second)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedStore(__in uint32 index, Var second)
|
|
|
+ Var CharArray::TypedStore(__in uint32 index, __in Var second)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedSub(__in uint32 index, Var second)
|
|
|
+ Var CharArray::TypedSub(__in uint32 index, __in Var second)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|
|
|
|
|
|
- Var CharArray::TypedXor(__in uint32 index, Var second)
|
|
|
+ Var CharArray::TypedXor(__in uint32 index, __in Var second)
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_InvalidOperationOnTypedArray);
|
|
|
}
|