JavascriptSimdObject.cpp 12 KB

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