AsmJsLink.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLanguagePch.h"
  6. #include "Library/BoundFunction.h"
  7. #ifndef TEMP_DISABLE_ASMJS
  8. namespace Js{
  9. bool ASMLink::CheckArrayBuffer(ScriptContext* scriptContext, Var bufferView, const AsmJsModuleInfo * info)
  10. {
  11. if (!bufferView)
  12. {
  13. return true;
  14. }
  15. if (!JavascriptArrayBuffer::Is(bufferView))
  16. {
  17. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : Buffer parameter is not an Array buffer"));
  18. return false;
  19. }
  20. JavascriptArrayBuffer* buffer = (JavascriptArrayBuffer*)bufferView;
  21. if (buffer->GetByteLength() <= info->GetMaxHeapAccess())
  22. {
  23. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : Buffer bytelength is smaller than constant accesses"));
  24. return false;
  25. }
  26. if (info->GetUsesChangeHeap())
  27. {
  28. if (buffer->GetByteLength() < 0x1000000)
  29. {
  30. Output::Print(_u("Asm.js Runtime Error : Buffer bytelength is not a valid size for asm.js\n"));
  31. return false;
  32. }
  33. if (info->GetMaxHeapAccess() >= 0x1000000)
  34. {
  35. Output::Print(_u("Asm.js Runtime Error : Cannot have such large constant accesses\n"));
  36. return false;
  37. }
  38. }
  39. if (!buffer->IsValidAsmJsBufferLength(buffer->GetByteLength(), true))
  40. {
  41. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : Buffer bytelength is not a valid size for asm.js"));
  42. return false;
  43. }
  44. return true;
  45. }
  46. bool ASMLink::CheckFFI(ScriptContext* scriptContext, AsmJsModuleInfo* info, const Var foreign)
  47. {
  48. if (info->GetFunctionImportCount() == 0 && info->GetVarImportCount() == 0)
  49. {
  50. return true;
  51. }
  52. Assert(foreign);
  53. if (!RecyclableObject::Is(foreign))
  54. {
  55. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : FFI is not an object"));
  56. return false;
  57. }
  58. TypeId foreignObjType = RecyclableObject::FromVar(foreign)->GetTypeId();
  59. if (StaticType::Is(foreignObjType) || TypeIds_Proxy == foreignObjType)
  60. {
  61. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : FFI is not an object"));
  62. return false;
  63. }
  64. return true;
  65. }
  66. bool ASMLink::CheckStdLib(ScriptContext* scriptContext, const AsmJsModuleInfo* info, const Var stdlib)
  67. {
  68. BVStatic<ASMMATH_BUILTIN_SIZE> mathBuiltinUsed = info->GetAsmMathBuiltinUsed();
  69. BVStatic<ASMARRAY_BUILTIN_SIZE> arrayBuiltinUsed = info->GetAsmArrayBuiltinUsed();
  70. BVStatic<ASMSIMD_BUILTIN_SIZE> simdBuiltinUsed = info->GetAsmSimdBuiltinUsed();
  71. if (mathBuiltinUsed.IsAllClear() && arrayBuiltinUsed.IsAllClear() && simdBuiltinUsed.IsAllClear())
  72. {
  73. return true;
  74. }
  75. Assert(stdlib);
  76. if (!RecyclableObject::Is(stdlib))
  77. {
  78. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : StdLib is not an object"));
  79. return false;
  80. }
  81. TypeId stdLibObjType = RecyclableObject::FromVar(stdlib)->GetTypeId();
  82. if (StaticType::Is(stdLibObjType) || TypeIds_Proxy == stdLibObjType)
  83. {
  84. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : StdLib is not an object"));
  85. return false;
  86. }
  87. Js::JavascriptLibrary* library = scriptContext->GetLibrary();
  88. if (mathBuiltinUsed.TestAndClear(AsmJSMathBuiltinFunction::AsmJSMathBuiltin_infinity))
  89. {
  90. Var asmInfinityObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Infinity, scriptContext);
  91. if (!JavascriptConversion::SameValue(asmInfinityObj, library->GetPositiveInfinite()))
  92. {
  93. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : Math constant Infinity is invalid"));
  94. return false;
  95. }
  96. }
  97. if (mathBuiltinUsed.TestAndClear(AsmJSMathBuiltinFunction::AsmJSMathBuiltin_nan))
  98. {
  99. Var asmNaNObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::NaN, scriptContext);
  100. if (!JavascriptConversion::SameValue(asmNaNObj, library->GetNaN()))
  101. {
  102. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : Math constant NaN is invalid"));
  103. return false;
  104. }
  105. }
  106. if (!mathBuiltinUsed.IsAllClear())
  107. {
  108. Var asmMathObject = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Math, scriptContext);
  109. for (int i = 0; i < AsmJSMathBuiltinFunction::AsmJSMathBuiltin_COUNT; i++)
  110. {
  111. //check if bit is set
  112. if (!mathBuiltinUsed.Test(i))
  113. {
  114. continue;
  115. }
  116. AsmJSMathBuiltinFunction mathBuiltinFunc = (AsmJSMathBuiltinFunction)i;
  117. if (!CheckMathLibraryMethod(scriptContext, asmMathObject, mathBuiltinFunc))
  118. {
  119. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : Math builtin function is invalid"));
  120. return false;
  121. }
  122. }
  123. }
  124. for (int i = 0; i < AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_COUNT; i++)
  125. {
  126. //check if bit is set
  127. if (!arrayBuiltinUsed.Test(i))
  128. {
  129. continue;
  130. }
  131. AsmJSTypedArrayBuiltinFunction arrayBuiltinFunc = (AsmJSTypedArrayBuiltinFunction)i;
  132. if (!CheckArrayLibraryMethod(scriptContext, stdlib, arrayBuiltinFunc))
  133. {
  134. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : Array builtin function is invalid"));
  135. return false;
  136. }
  137. }
  138. #ifdef ENABLE_SIMDJS
  139. if (!simdBuiltinUsed.IsAllClear())
  140. {
  141. Var asmSimdObject = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::SIMD, scriptContext);
  142. for (int i = 0; i < AsmJsSIMDBuiltinFunction::AsmJsSIMDBuiltin_COUNT; i++)
  143. {
  144. if (!simdBuiltinUsed.Test(i))
  145. {
  146. continue;
  147. }
  148. AsmJsSIMDBuiltinFunction simdBuiltinFunc = (AsmJsSIMDBuiltinFunction)i;
  149. if (!CheckSimdLibraryMethod(scriptContext, asmSimdObject, simdBuiltinFunc))
  150. {
  151. AsmJSCompiler::OutputError(scriptContext, _u("Asm.js Runtime Error : SIMD builtin function is invalid"));
  152. return false;
  153. }
  154. }
  155. }
  156. #endif
  157. return true;
  158. }
  159. bool ASMLink::CheckArrayLibraryMethod(ScriptContext* scriptContext, const Var stdlib, const AsmJSTypedArrayBuiltinFunction arrayLibMethod)
  160. {
  161. Var arrayFuncObj;
  162. switch (arrayLibMethod)
  163. {
  164. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_byteLength:
  165. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::byteLength, scriptContext);
  166. if (JavascriptFunction::Is(arrayFuncObj))
  167. {
  168. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  169. if (arrayLibFunc->IsBoundFunction())
  170. {
  171. BoundFunction* boundFunc = (BoundFunction*)arrayLibFunc;
  172. RecyclableObject* thisObj = boundFunc->GetBoundThis();
  173. if (JavascriptFunction::Is(thisObj))
  174. {
  175. JavascriptFunction * thisFunc = (JavascriptFunction*)thisObj;
  176. if (thisFunc->GetFunctionInfo()->GetOriginalEntryPoint() != (&ArrayBuffer::EntryInfo::GetterByteLength)->GetOriginalEntryPoint())
  177. {
  178. return false;
  179. }
  180. }
  181. JavascriptFunction* targetFunc = boundFunc->GetTargetFunction();
  182. return targetFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&JavascriptFunction::EntryInfo::Call)->GetOriginalEntryPoint();
  183. }
  184. }
  185. break;
  186. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Int8Array:
  187. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Int8Array, scriptContext);
  188. if (JavascriptFunction::Is(arrayFuncObj))
  189. {
  190. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  191. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Int8Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  192. }
  193. break;
  194. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Uint8Array:
  195. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Uint8Array, scriptContext);
  196. if (JavascriptFunction::Is(arrayFuncObj))
  197. {
  198. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  199. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Uint8Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  200. }
  201. break;
  202. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Int16Array:
  203. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Int16Array, scriptContext);
  204. if (JavascriptFunction::Is(arrayFuncObj))
  205. {
  206. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  207. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Int16Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  208. }
  209. break;
  210. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Uint16Array:
  211. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Uint16Array, scriptContext);
  212. if (JavascriptFunction::Is(arrayFuncObj))
  213. {
  214. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  215. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Uint16Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  216. }
  217. break;
  218. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Int32Array:
  219. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Int32Array, scriptContext);
  220. if (JavascriptFunction::Is(arrayFuncObj))
  221. {
  222. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  223. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Int32Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  224. }
  225. break;
  226. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Uint32Array:
  227. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Uint32Array, scriptContext);
  228. if (JavascriptFunction::Is(arrayFuncObj))
  229. {
  230. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  231. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Uint32Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  232. }
  233. break;
  234. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Float32Array:
  235. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Float32Array, scriptContext);
  236. if (JavascriptFunction::Is(arrayFuncObj))
  237. {
  238. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  239. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Float32Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  240. }
  241. break;
  242. case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Float64Array:
  243. arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Float64Array, scriptContext);
  244. if (JavascriptFunction::Is(arrayFuncObj))
  245. {
  246. JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj;
  247. return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Float64Array::EntryInfo::NewInstance)->GetOriginalEntryPoint();
  248. }
  249. break;
  250. default:
  251. Assume(UNREACHED);
  252. }
  253. return false;
  254. }
  255. bool ASMLink::CheckMathLibraryMethod(ScriptContext* scriptContext, const Var asmMathObject, const AsmJSMathBuiltinFunction mathLibMethod)
  256. {
  257. Var mathFuncObj;
  258. switch (mathLibMethod)
  259. {
  260. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sin:
  261. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::sin, scriptContext);
  262. if (JavascriptFunction::Is(mathFuncObj))
  263. {
  264. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  265. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Sin)->GetOriginalEntryPoint())
  266. {
  267. return true;
  268. }
  269. }
  270. break;
  271. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_cos:
  272. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::cos, scriptContext);
  273. if (JavascriptFunction::Is(mathFuncObj))
  274. {
  275. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  276. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Cos)->GetOriginalEntryPoint())
  277. {
  278. return true;
  279. }
  280. }
  281. break;
  282. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_tan:
  283. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::tan, scriptContext);
  284. if (JavascriptFunction::Is(mathFuncObj))
  285. {
  286. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  287. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Tan)->GetOriginalEntryPoint())
  288. {
  289. return true;
  290. }
  291. }
  292. break;
  293. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_asin:
  294. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::asin, scriptContext);
  295. if (JavascriptFunction::Is(mathFuncObj))
  296. {
  297. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  298. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Asin)->GetOriginalEntryPoint())
  299. {
  300. return true;
  301. }
  302. }
  303. break;
  304. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_acos:
  305. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::acos, scriptContext);
  306. if (JavascriptFunction::Is(mathFuncObj))
  307. {
  308. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  309. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Acos)->GetOriginalEntryPoint())
  310. {
  311. return true;
  312. }
  313. }
  314. break;
  315. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_atan:
  316. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::atan, scriptContext);
  317. if (JavascriptFunction::Is(mathFuncObj))
  318. {
  319. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  320. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Atan)->GetOriginalEntryPoint())
  321. {
  322. return true;
  323. }
  324. }
  325. break;
  326. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_ceil:
  327. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::ceil, scriptContext);
  328. if (JavascriptFunction::Is(mathFuncObj))
  329. {
  330. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  331. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Ceil)->GetOriginalEntryPoint())
  332. {
  333. return true;
  334. }
  335. }
  336. break;
  337. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_floor:
  338. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::floor, scriptContext);
  339. if (JavascriptFunction::Is(mathFuncObj))
  340. {
  341. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  342. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Floor)->GetOriginalEntryPoint())
  343. {
  344. return true;
  345. }
  346. }
  347. break;
  348. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_exp:
  349. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::exp, scriptContext);
  350. if (JavascriptFunction::Is(mathFuncObj))
  351. {
  352. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  353. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Exp)->GetOriginalEntryPoint())
  354. {
  355. return true;
  356. }
  357. }
  358. break;
  359. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_log:
  360. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::log, scriptContext);
  361. if (JavascriptFunction::Is(mathFuncObj))
  362. {
  363. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  364. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Log)->GetOriginalEntryPoint())
  365. {
  366. return true;
  367. }
  368. }
  369. break;
  370. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_pow:
  371. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::pow, scriptContext);
  372. if (JavascriptFunction::Is(mathFuncObj))
  373. {
  374. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  375. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Pow)->GetOriginalEntryPoint())
  376. {
  377. return true;
  378. }
  379. }
  380. break;
  381. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sqrt:
  382. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::sqrt, scriptContext);
  383. if (JavascriptFunction::Is(mathFuncObj))
  384. {
  385. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  386. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Sqrt)->GetOriginalEntryPoint())
  387. {
  388. return true;
  389. }
  390. }
  391. break;
  392. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_abs:
  393. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::abs, scriptContext);
  394. if (JavascriptFunction::Is(mathFuncObj))
  395. {
  396. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  397. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Abs)->GetOriginalEntryPoint())
  398. {
  399. return true;
  400. }
  401. }
  402. break;
  403. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_atan2:
  404. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::atan2, scriptContext);
  405. if (JavascriptFunction::Is(mathFuncObj))
  406. {
  407. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  408. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Atan2)->GetOriginalEntryPoint())
  409. {
  410. return true;
  411. }
  412. }
  413. break;
  414. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_imul:
  415. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::imul, scriptContext);
  416. if (JavascriptFunction::Is(mathFuncObj))
  417. {
  418. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  419. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Imul)->GetOriginalEntryPoint())
  420. {
  421. return true;
  422. }
  423. }
  424. break;
  425. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_clz32:
  426. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::clz32, scriptContext);
  427. if (JavascriptFunction::Is(mathFuncObj))
  428. {
  429. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  430. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Clz32)->GetOriginalEntryPoint())
  431. {
  432. return true;
  433. }
  434. }
  435. break;
  436. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_min:
  437. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::min, scriptContext);
  438. if (JavascriptFunction::Is(mathFuncObj))
  439. {
  440. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  441. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Min)->GetOriginalEntryPoint())
  442. {
  443. return true;
  444. }
  445. }
  446. break;
  447. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_max:
  448. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::max, scriptContext);
  449. if (JavascriptFunction::Is(mathFuncObj))
  450. {
  451. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  452. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Max)->GetOriginalEntryPoint())
  453. {
  454. return true;
  455. }
  456. }
  457. break;
  458. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_fround:
  459. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::fround, scriptContext);
  460. if (JavascriptFunction::Is(mathFuncObj))
  461. {
  462. JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj;
  463. if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Fround)->GetOriginalEntryPoint())
  464. {
  465. return true;
  466. }
  467. }
  468. break;
  469. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_e:
  470. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::E, scriptContext);
  471. if (JavascriptNumber::Is(mathFuncObj))
  472. {
  473. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  474. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::E))
  475. {
  476. return true;
  477. }
  478. }
  479. break;
  480. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_ln10:
  481. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LN10, scriptContext);
  482. if (JavascriptNumber::Is(mathFuncObj))
  483. {
  484. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  485. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LN10))
  486. {
  487. return true;
  488. }
  489. }
  490. break;
  491. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_ln2:
  492. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LN2, scriptContext);
  493. if (JavascriptNumber::Is(mathFuncObj))
  494. {
  495. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  496. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LN2))
  497. {
  498. return true;
  499. }
  500. }
  501. break;
  502. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_log2e:
  503. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LOG2E, scriptContext);
  504. if (JavascriptNumber::Is(mathFuncObj))
  505. {
  506. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  507. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LOG2E))
  508. {
  509. return true;
  510. }
  511. }
  512. break;
  513. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_log10e:
  514. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LOG10E, scriptContext);
  515. if (JavascriptNumber::Is(mathFuncObj))
  516. {
  517. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  518. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LOG10E))
  519. {
  520. return true;
  521. }
  522. }
  523. break;
  524. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_pi:
  525. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::PI, scriptContext);
  526. if (JavascriptNumber::Is(mathFuncObj))
  527. {
  528. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  529. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::PI))
  530. {
  531. return true;
  532. }
  533. }
  534. break;
  535. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sqrt1_2:
  536. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::SQRT1_2, scriptContext);
  537. if (JavascriptNumber::Is(mathFuncObj))
  538. {
  539. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  540. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::SQRT1_2))
  541. {
  542. return true;
  543. }
  544. }
  545. break;
  546. case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sqrt2:
  547. mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::SQRT2, scriptContext);
  548. if (JavascriptNumber::Is(mathFuncObj))
  549. {
  550. JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj;
  551. if (JavascriptNumber::GetValue(mathConstNumber) == (Math::SQRT2))
  552. {
  553. return true;
  554. }
  555. }
  556. break;
  557. default:
  558. Assume(UNREACHED);
  559. }
  560. return false;
  561. }
  562. #ifdef ENABLE_SIMDJS
  563. bool ASMLink::CheckSimdLibraryMethod(ScriptContext* scriptContext, const Var asmSimdObject, const AsmJsSIMDBuiltinFunction simdLibMethod)
  564. {
  565. Var simdConstructorObj, simdFuncObj;
  566. switch (simdLibMethod)
  567. {
  568. #define ASMJS_SIMD_C_NAMES(builtInId, propertyId, libName, entryPoint) \
  569. case AsmJsSIMDBuiltinFunction::AsmJsSIMDBuiltin_##builtInId: \
  570. simdFuncObj = JavascriptOperators::OP_GetProperty(asmSimdObject, PropertyIds::##libName, scriptContext); \
  571. if (JavascriptFunction::Is(simdFuncObj)) \
  572. { \
  573. JavascriptFunction* simdLibFunc = (JavascriptFunction*)simdFuncObj; \
  574. if (simdLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&SIMD##libName##Lib::EntryInfo::##entryPoint)->GetOriginalEntryPoint()) \
  575. { \
  576. return true; \
  577. }\
  578. } \
  579. break;
  580. #define ASMJS_SIMD_O_NAMES(builtInId, propertyId, libName, entryPoint) \
  581. case AsmJsSIMDBuiltinFunction::AsmJsSIMDBuiltin_##builtInId: \
  582. simdConstructorObj = JavascriptOperators::OP_GetProperty(asmSimdObject, PropertyIds::##libName, scriptContext); \
  583. simdFuncObj = JavascriptOperators::OP_GetProperty(simdConstructorObj, PropertyIds::##propertyId, scriptContext); \
  584. if (JavascriptFunction::Is(simdFuncObj)) \
  585. { \
  586. JavascriptFunction* simdLibFunc = (JavascriptFunction*)simdFuncObj; \
  587. if (simdLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&SIMD##libName##Lib::EntryInfo::##entryPoint)->GetOriginalEntryPoint()) \
  588. { \
  589. return true; \
  590. }\
  591. } \
  592. break;
  593. #include "AsmJsBuiltinNames.h"
  594. default:
  595. Assume(UNREACHED);
  596. }
  597. return false;
  598. }
  599. #endif
  600. bool ASMLink::CheckParams(ScriptContext* scriptContext, AsmJsModuleInfo* info, const Var stdlib, const Var foreign, const Var bufferView)
  601. {
  602. if (CheckStdLib(scriptContext, info, stdlib) && CheckArrayBuffer(scriptContext, bufferView, info) && CheckFFI(scriptContext, info, stdlib))
  603. {
  604. return true;
  605. }
  606. Output::Flush();
  607. return false;
  608. }
  609. }
  610. #endif