JavascriptSimdObject.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. #ifdef ENABLE_SIMDJS
  7. namespace Js
  8. {
  9. JavascriptSIMDObject::JavascriptSIMDObject(DynamicType * type)
  10. : DynamicObject(type), value(Js::TaggedInt::ToVarUnchecked(0))
  11. {
  12. Assert(type->GetTypeId() == TypeIds_SIMDObject);
  13. }
  14. JavascriptSIMDObject::JavascriptSIMDObject(Var value, DynamicType * type, TypeId typeDescriptor)
  15. : DynamicObject(type), typeDescriptor(typeDescriptor), value(value)
  16. {
  17. Assert(type->GetTypeId() == TypeIds_SIMDObject);
  18. switch (typeDescriptor)
  19. {
  20. //typeDescriptor is TypeIds_SIMDObject only while initializing the SIMDObject prototypes.
  21. //Dynamically created wrapper objects must have a concrete typeDescriptor of a SIMDType.
  22. case TypeIds_SIMDObject:
  23. numLanes = 0;
  24. break;
  25. case TypeIds_SIMDBool8x16:
  26. case TypeIds_SIMDInt8x16:
  27. case TypeIds_SIMDUint8x16:
  28. numLanes = 16;
  29. break;
  30. case TypeIds_SIMDBool16x8:
  31. case TypeIds_SIMDInt16x8:
  32. case TypeIds_SIMDUint16x8:
  33. numLanes = 8;
  34. break;
  35. case TypeIds_SIMDBool32x4:
  36. case TypeIds_SIMDInt32x4:
  37. case TypeIds_SIMDUint32x4:
  38. case TypeIds_SIMDFloat32x4:
  39. numLanes = 4;
  40. break;
  41. default:
  42. Assert(UNREACHED);
  43. }
  44. }
  45. void JavascriptSIMDObject::SetTypeDescriptor(TypeId tid)
  46. {
  47. Assert(tid != TypeIds_SIMDObject);
  48. typeDescriptor = tid;
  49. switch (typeDescriptor)
  50. {
  51. case TypeIds_SIMDBool8x16:
  52. case TypeIds_SIMDInt8x16:
  53. case TypeIds_SIMDUint8x16:
  54. numLanes = 16;
  55. break;
  56. case TypeIds_SIMDBool16x8:
  57. case TypeIds_SIMDInt16x8:
  58. case TypeIds_SIMDUint16x8:
  59. numLanes = 8;
  60. break;
  61. case TypeIds_SIMDBool32x4:
  62. case TypeIds_SIMDInt32x4:
  63. case TypeIds_SIMDUint32x4:
  64. case TypeIds_SIMDFloat32x4:
  65. numLanes = 4;
  66. break;
  67. default:
  68. Assert(UNREACHED);
  69. }
  70. }
  71. bool JavascriptSIMDObject::Is(Var aValue)
  72. {
  73. return JavascriptOperators::GetTypeId(aValue) == TypeIds_SIMDObject;
  74. }
  75. JavascriptSIMDObject* JavascriptSIMDObject::FromVar(Var aValue)
  76. {
  77. AssertMsg(Is(aValue), "Ensure var is actually a 'JavascriptSIMD'");
  78. return static_cast<JavascriptSIMDObject *>(RecyclableObject::FromVar(aValue));
  79. }
  80. Var JavascriptSIMDObject::Unwrap() const
  81. {
  82. return value;
  83. }
  84. Var JavascriptSIMDObject::ToString(ScriptContext* scriptContext) const
  85. {
  86. Assert(scriptContext);
  87. Assert(typeDescriptor != TypeIds_SIMDObject);
  88. BEGIN_TEMP_ALLOCATOR(tempAllocator, scriptContext, _u("fromCodePoint"));
  89. char16* stringBuffer = AnewArray(tempAllocator, char16, SIMD_STRING_BUFFER_MAX);
  90. SIMDValue simdValue;
  91. switch (typeDescriptor)
  92. {
  93. case TypeIds_SIMDBool8x16:
  94. simdValue = JavascriptSIMDBool8x16::FromVar(value)->GetValue();
  95. JavascriptSIMDBool8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  96. break;
  97. case TypeIds_SIMDInt8x16:
  98. simdValue = JavascriptSIMDInt8x16::FromVar(value)->GetValue();
  99. JavascriptSIMDInt8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  100. break;
  101. case TypeIds_SIMDUint8x16:
  102. simdValue = JavascriptSIMDUint8x16::FromVar(value)->GetValue();
  103. JavascriptSIMDUint8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  104. break;
  105. case TypeIds_SIMDBool16x8:
  106. simdValue = JavascriptSIMDBool16x8::FromVar(value)->GetValue();
  107. JavascriptSIMDBool16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  108. break;
  109. case TypeIds_SIMDInt16x8:
  110. simdValue = JavascriptSIMDInt16x8::FromVar(value)->GetValue();
  111. JavascriptSIMDInt16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  112. break;
  113. case TypeIds_SIMDUint16x8:
  114. simdValue = JavascriptSIMDUint16x8::FromVar(value)->GetValue();
  115. JavascriptSIMDUint16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  116. break;
  117. case TypeIds_SIMDBool32x4:
  118. simdValue = JavascriptSIMDBool32x4::FromVar(value)->GetValue();
  119. JavascriptSIMDBool32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  120. break;
  121. case TypeIds_SIMDInt32x4:
  122. simdValue = JavascriptSIMDInt32x4::FromVar(value)->GetValue();
  123. JavascriptSIMDInt32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  124. break;
  125. case TypeIds_SIMDUint32x4:
  126. simdValue = JavascriptSIMDUint32x4::FromVar(value)->GetValue();
  127. JavascriptSIMDUint32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  128. break;
  129. case TypeIds_SIMDFloat32x4:
  130. simdValue = JavascriptSIMDFloat32x4::FromVar(value)->GetValue();
  131. JavascriptSIMDFloat32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
  132. break;
  133. default:
  134. Assert(UNREACHED);
  135. }
  136. JavascriptString* string = JavascriptString::NewCopySzFromArena(stringBuffer, scriptContext, scriptContext->GeneralAllocator());
  137. END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
  138. return string;
  139. }
  140. template <typename T, size_t N>
  141. Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString, const T (&laneValues)[N],
  142. CallInfo* callInfo, ScriptContext* scriptContext) const
  143. {
  144. Assert(args);
  145. Assert(N == 4 || N == 8 || N == 16);
  146. if (typeDescriptor == TypeIds_SIMDBool8x16 ||
  147. typeDescriptor == TypeIds_SIMDBool16x8 ||
  148. typeDescriptor == TypeIds_SIMDBool32x4)
  149. {
  150. return ToString(scriptContext); //Boolean types does not have toLocaleString.
  151. }
  152. // Clamp to the first 3 arguments - we'll ignore more.
  153. if (numArgs > 3)
  154. {
  155. numArgs = 3;
  156. }
  157. // Creating a new arguments list for the JavascriptNumber generated from each lane.The optional SIMDToLocaleString Args are
  158. //added to this argument list.
  159. Var newArgs[3] = { nullptr, nullptr, nullptr };
  160. CallInfo newCallInfo((ushort)numArgs);
  161. if (numArgs > 1)
  162. {
  163. newArgs[1] = args[1];
  164. }
  165. if (numArgs > 2)
  166. {
  167. newArgs[2] = args[2];
  168. }
  169. //Locale specific separator??
  170. JavascriptString *seperator = JavascriptString::NewWithSz(_u(", "), scriptContext);
  171. uint idx = 0;
  172. Var laneVar = nullptr;
  173. BEGIN_TEMP_ALLOCATOR(tempAllocator, scriptContext, _u("fromCodePoint"));
  174. char16* stringBuffer = AnewArray(tempAllocator, char16, SIMD_STRING_BUFFER_MAX);
  175. JavascriptString *result = nullptr;
  176. swprintf_s(stringBuffer, SIMD_STRING_BUFFER_MAX, typeString);
  177. result = JavascriptString::NewCopySzFromArena(stringBuffer, scriptContext, scriptContext->GeneralAllocator());
  178. if (typeDescriptor == TypeIds_SIMDFloat32x4)
  179. {
  180. for (; idx < numLanes - 1; ++idx)
  181. {
  182. laneVar = JavascriptNumber::ToVarWithCheck(laneValues[idx], scriptContext);
  183. newArgs[0] = laneVar;
  184. JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, newCallInfo, scriptContext);
  185. result = JavascriptString::Concat(result, laneValue);
  186. result = JavascriptString::Concat(result, seperator);
  187. }
  188. laneVar = JavascriptNumber::ToVarWithCheck(laneValues[idx], scriptContext);
  189. newArgs[0] = laneVar;
  190. result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, newCallInfo, scriptContext));
  191. }
  192. else if (typeDescriptor == TypeIds_SIMDInt8x16 || typeDescriptor == TypeIds_SIMDInt16x8 || typeDescriptor == TypeIds_SIMDInt32x4)
  193. {
  194. for (; idx < numLanes - 1; ++idx)
  195. {
  196. laneVar = JavascriptNumber::ToVar(static_cast<int>(laneValues[idx]), scriptContext);
  197. newArgs[0] = laneVar;
  198. JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, newCallInfo, scriptContext);
  199. result = JavascriptString::Concat(result, laneValue);
  200. result = JavascriptString::Concat(result, seperator);
  201. }
  202. laneVar = JavascriptNumber::ToVar(static_cast<int>(laneValues[idx]), scriptContext);
  203. newArgs[0] = laneVar;
  204. result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, newCallInfo, scriptContext));
  205. }
  206. else
  207. {
  208. Assert((typeDescriptor == TypeIds_SIMDUint8x16 || typeDescriptor == TypeIds_SIMDUint16x8 || typeDescriptor == TypeIds_SIMDUint32x4));
  209. for (; idx < numLanes - 1; ++idx)
  210. {
  211. laneVar = JavascriptNumber::ToVar(static_cast<uint>(laneValues[idx]), scriptContext);
  212. newArgs[0] = laneVar;
  213. JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, newCallInfo, scriptContext);
  214. result = JavascriptString::Concat(result, laneValue);
  215. result = JavascriptString::Concat(result, seperator);
  216. }
  217. laneVar = JavascriptNumber::ToVar(static_cast<uint>(laneValues[idx]), scriptContext);
  218. newArgs[0] = laneVar;
  219. result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, newCallInfo, scriptContext));
  220. }
  221. END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
  222. return JavascriptString::Concat(result, JavascriptString::NewWithSz(_u(")"), scriptContext));
  223. }
  224. template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
  225. const float (&laneValues)[4], CallInfo* callInfo, ScriptContext* scriptContext) const;
  226. template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
  227. const int(&laneValues)[4], CallInfo* callInfo, ScriptContext* scriptContext) const;
  228. template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
  229. const int16(&laneValues)[8], CallInfo* callInfo, ScriptContext* scriptContext) const;
  230. template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
  231. const int8(&laneValues)[16], CallInfo* callInfo, ScriptContext* scriptContext) const;
  232. template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
  233. const uint(&laneValues)[4], CallInfo* callInfo, ScriptContext* scriptContext) const;
  234. template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
  235. const uint16(&laneValues)[8], CallInfo* callInfo, ScriptContext* scriptContext) const;
  236. template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
  237. const uint8(&laneValues)[16], CallInfo* callInfo, ScriptContext* scriptContext) const;
  238. Var JavascriptSIMDObject::GetValue() const
  239. {
  240. Assert(SIMDUtils::IsSimdType(value));
  241. return value;
  242. }
  243. }
  244. #endif