AsmJsUtils.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. // Portions of this file are copyright 2014 Mozilla Foundation, available under the Apache 2.0 license.
  5. //-------------------------------------------------------------------------------------------------------
  6. //-------------------------------------------------------------------------------------------------------
  7. // Copyright 2014 Mozilla Foundation
  8. //
  9. // Licensed under the Apache License, Version 2.0 (the "License");
  10. // you may not use this file except in compliance with the License.
  11. // You may obtain a copy of the License at
  12. //
  13. // http ://www.apache.org/licenses/LICENSE-2.0
  14. //
  15. // Unless required by applicable law or agreed to in writing, software
  16. // distributed under the License is distributed on an "AS IS" BASIS,
  17. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. // See the License for the specific language governing permissions and
  19. // limitations under the License.
  20. //-------------------------------------------------------------------------------------------------------
  21. #pragma once
  22. #ifndef TEMP_DISABLE_ASMJS
  23. // Removed code from original location, if the expression is true, check if extra code needed
  24. #define MaybeTodo( expr ) AssertMsg( !(expr), "Unhandled scenario in asm.js" )
  25. namespace Js {
  26. static const int DOUBLE_SLOTS_SPACE = (sizeof(double) / sizeof(Var)); // 2 in x86 and 1 in x64
  27. static const double FLOAT_SLOTS_SPACE = (sizeof(float) / (double)sizeof(Var)); // 1 in x86 and 0.5 in x64
  28. static const double INT_SLOTS_SPACE = ( sizeof( int ) / (double)sizeof( Var ) ); // 1 in x86 and 0.5 in x64
  29. static const double SIMD_SLOTS_SPACE = (sizeof(SIMDValue) / sizeof(Var)); // 4 in x86 and 2 in x64
  30. Var AsmJsChangeHeapBuffer(RecyclableObject * function, CallInfo callInfo, ...);
  31. #if _M_X64
  32. int GetStackSizeForAsmJsUnboxing(ScriptFunction* func);
  33. void * UnboxAsmJsArguments(ScriptFunction* func, Var * origArgs, char * argDst, CallInfo callInfo);
  34. Var BoxAsmJsReturnValue(ScriptFunction* func, int intRetVal, double doubleRetVal, float floatRetVal);
  35. #endif
  36. class AsmJsCompilationException
  37. {
  38. char16 msg_[256];
  39. public:
  40. AsmJsCompilationException( const char16* _msg, ... );
  41. inline char16* msg() { return msg_; }
  42. };
  43. class ParserWrapper
  44. {
  45. public:
  46. static PropertyName FunctionName( ParseNode *node );
  47. static PropertyName VariableName( ParseNode *node );
  48. static ParseNode* FunctionArgsList( ParseNode *node, ArgSlot &numformals );
  49. static ParseNode* NextVar( ParseNode *node );
  50. static ParseNode* NextInList( ParseNode *node );
  51. static inline ParseNode *GetListHead( ParseNode *node );
  52. static inline bool IsNameDeclaration(ParseNode *node);
  53. static inline bool IsUInt(ParseNode *node);
  54. static inline uint GetUInt(ParseNode *node);
  55. static inline bool IsNegativeZero(ParseNode* node);
  56. static inline bool IsMinInt(ParseNode *node){ return node && node->nop == knopFlt && node->sxFlt.maybeInt && node->sxFlt.dbl == -2147483648.0; };
  57. static inline bool IsUnsigned(ParseNode *node)
  58. {
  59. return node &&
  60. node->nop == knopFlt &&
  61. node->sxFlt.maybeInt &&
  62. node->sxFlt.dbl > (double)INT_MAX &&
  63. node->sxFlt.dbl <= (double)UINT_MAX;
  64. }
  65. static bool IsDefinition( ParseNode *arg );
  66. static bool ParseVarOrConstStatement( AsmJSParser &parser, ParseNode **var );
  67. static inline bool IsNumericLiteral(ParseNode* node) { return node && (node->nop == knopInt || node->nop == knopFlt); }
  68. static inline bool IsFroundNumericLiteral(ParseNode* node) { return node && (IsNumericLiteral(node) || IsNegativeZero(node)); }
  69. static inline ParseNode* GetUnaryNode( ParseNode* node ){Assert(IsNodeUnary(node));return node->sxUni.pnode1;}
  70. static inline ParseNode* GetBinaryLeft( ParseNode* node ){Assert(IsNodeBinary(node));return node->sxBin.pnode1;}
  71. static inline ParseNode* GetBinaryRight( ParseNode* node ){Assert(IsNodeBinary(node));return node->sxBin.pnode2;}
  72. static inline ParseNode* DotBase( ParseNode *node );
  73. static inline bool IsDotMember( ParseNode *node );
  74. static inline PropertyName DotMember( ParseNode *node );
  75. // Get the VarDecl from the node or nullptr if unable to find
  76. static ParseNode* GetVarDeclList(ParseNode* node);
  77. // Goes through the nodes until the end of the list of VarDecl
  78. static void ReachEndVarDeclList( ParseNode** node );
  79. // nop utils
  80. static inline bool IsNodeBinary (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & (fnopBin|fnopBinList)); }
  81. static inline bool IsNodeUnary (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopUni ); }
  82. static inline bool IsNodeConst (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopConst ); }
  83. static inline bool IsNodeLeaf (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopLeaf ); }
  84. static inline bool IsNodeRelational(ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopRel ); }
  85. static inline bool IsNodeAssignment(ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopAsg ); }
  86. static inline bool IsNodeBreak (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopBreak ); }
  87. static inline bool IsNodeContinue (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopContinue ); }
  88. static inline bool IsNodeCleanUp (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopCleanup ); }
  89. static inline bool IsNodeJump (ParseNode* pnode){ return pnode && !!(ParseNode::Grfnop(pnode->nop) & fnopJump ); }
  90. static inline bool IsNodeExpression(ParseNode* pnode){ return pnode && !(ParseNode::Grfnop(pnode->nop) & fnopNotExprStmt); }
  91. };
  92. bool ParserWrapper::IsNameDeclaration( ParseNode *node )
  93. {
  94. return node->nop == knopName || node->nop == knopStr;
  95. }
  96. bool ParserWrapper::IsNegativeZero(ParseNode *node)
  97. {
  98. return node && ((node->nop == knopFlt && JavascriptNumber::IsNegZero(node->sxFlt.dbl)) ||
  99. (node->nop == knopNeg && node->sxUni.pnode1->nop == knopInt && node->sxUni.pnode1->sxInt.lw == 0));
  100. }
  101. bool ParserWrapper::IsUInt( ParseNode *node )
  102. {
  103. return node->nop == knopInt || IsUnsigned(node);
  104. }
  105. uint ParserWrapper::GetUInt( ParseNode *node )
  106. {
  107. Assert( IsUInt( node ) );
  108. if( node->nop == knopInt )
  109. {
  110. return (uint)node->sxInt.lw;
  111. }
  112. Assert( node->nop == knopFlt );
  113. return (uint)node->sxFlt.dbl;
  114. }
  115. bool ParserWrapper::IsDotMember( ParseNode *node )
  116. {
  117. return node && (node->nop == knopDot || node->nop == knopIndex);
  118. }
  119. PropertyName ParserWrapper::DotMember( ParseNode *node )
  120. {
  121. Assert( IsDotMember(node) );
  122. if( IsNameDeclaration( GetBinaryRight( node ) ) )
  123. {
  124. return GetBinaryRight( node )->name();
  125. }
  126. return nullptr;
  127. }
  128. ParseNode* ParserWrapper::DotBase( ParseNode *node )
  129. {
  130. Assert( IsDotMember( node ) );
  131. return GetBinaryLeft( node );
  132. }
  133. ParseNode * ParserWrapper::GetListHead( ParseNode *node )
  134. {
  135. Assert( node->nop == knopList );
  136. return node->sxBin.pnode1;
  137. }
  138. };
  139. #endif