screrror.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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 "ParserPch.h"
  6. #pragma hdrstop
  7. #include "errstr.h"
  8. void CopyException (EXCEPINFO *peiDest, const EXCEPINFO *peiSource)
  9. {
  10. FreeExcepInfo(peiDest);
  11. *peiDest = *peiSource;
  12. if (peiSource->bstrSource) {
  13. peiDest->bstrSource =
  14. SysAllocStringLen(peiSource->bstrSource, SysStringLen(peiSource->bstrSource));
  15. }
  16. if (peiSource->bstrDescription) {
  17. peiDest->bstrDescription =
  18. SysAllocStringLen(peiSource->bstrDescription, SysStringLen(peiSource->bstrDescription));
  19. }
  20. if (peiSource->bstrHelpFile) {
  21. peiDest->bstrHelpFile =
  22. SysAllocStringLen(peiSource->bstrHelpFile, SysStringLen(peiSource->bstrHelpFile));
  23. }
  24. }
  25. /***************************************************************************
  26. HRESULT mapping
  27. ***************************************************************************/
  28. template <rtErrors errnum> class ErrorTypeMap;
  29. #define RT_ERROR_MSG(name, errnum, str1, str2, jst, errorNumSource) \
  30. template <> class ErrorTypeMap<name> \
  31. { \
  32. public: \
  33. static const ErrorTypeEnum Type = jst; \
  34. };
  35. #define RT_PUBLICERROR_MSG(name, errnum, str1, str2, jst, errorNumSource) RT_ERROR_MSG(name, errnum, str1, str2, jst, errorNumSource)
  36. #include "rterrors.h"
  37. #undef RT_PUBLICERROR_MSG
  38. #undef RT_ERROR_MSG
  39. struct MHR
  40. {
  41. HRESULT hrIn;
  42. HRESULT hrOut;
  43. ErrorTypeEnum errorType;
  44. };
  45. // This table maps OLE errors to JScript errors. The comment on each line
  46. // shows the numeric value. The table must be sorted so we can do a binary
  47. // search on it.
  48. #define MAPHR(in, out) { HR(in), out, ErrorTypeMap<out>::Type }
  49. const MHR g_rgmhr[] =
  50. {
  51. // FACILITY_NULL errors
  52. /*0x80004001*/ MAPHR(E_NOTIMPL, VBSERR_ActionNotSupported),
  53. /*0x80004002*/ MAPHR(E_NOINTERFACE, VBSERR_OLENotSupported),
  54. // FACILITY_DISPATCH - IDispatch errors.
  55. /*0x80020001*/ MAPHR(DISP_E_UNKNOWNINTERFACE, VBSERR_OLENoPropOrMethod),
  56. /*0x80020003*/ MAPHR(DISP_E_MEMBERNOTFOUND, VBSERR_OLENoPropOrMethod),
  57. /*0x80020004*/ MAPHR(DISP_E_PARAMNOTFOUND, VBSERR_NamedParamNotFound),
  58. /*0x80020005*/ MAPHR(DISP_E_TYPEMISMATCH, VBSERR_TypeMismatch),
  59. /*0x80020006*/ MAPHR(DISP_E_UNKNOWNNAME, VBSERR_OLENoPropOrMethod),
  60. /*0x80020007*/ MAPHR(DISP_E_NONAMEDARGS, VBSERR_NamedArgsNotSupported),
  61. /*0x80020008*/ MAPHR(DISP_E_BADVARTYPE, VBSERR_InvalidTypeLibVariable),
  62. /*0x8002000A*/ MAPHR(DISP_E_OVERFLOW, VBSERR_Overflow),
  63. /*0x8002000B*/ MAPHR(DISP_E_BADINDEX, VBSERR_OutOfBounds),
  64. /*0x8002000C*/ MAPHR(DISP_E_UNKNOWNLCID, VBSERR_LocaleSettingNotSupported),
  65. /*0x8002000D*/ MAPHR(DISP_E_ARRAYISLOCKED, VBSERR_ArrayLocked),
  66. /*0x8002000E*/ MAPHR(DISP_E_BADPARAMCOUNT, VBSERR_FuncArityMismatch),
  67. /*0x8002000F*/ MAPHR(DISP_E_PARAMNOTOPTIONAL, VBSERR_ParameterNotOptional),
  68. /*0x80020011*/ MAPHR(DISP_E_NOTACOLLECTION, VBSERR_NotEnum),
  69. // FACILITY_DISPATCH - Typelib errors.
  70. /*0x8002802F*/ MAPHR(TYPE_E_DLLFUNCTIONNOTFOUND, VBSERR_InvalidDllFunctionName),
  71. /*0x80028CA0*/ MAPHR(TYPE_E_TYPEMISMATCH, VBSERR_TypeMismatch),
  72. /*0x80028CA1*/ MAPHR(TYPE_E_OUTOFBOUNDS, VBSERR_OutOfBounds),
  73. /*0x80028CA2*/ MAPHR(TYPE_E_IOERROR, VBSERR_IOError),
  74. /*0x80028CA3*/ MAPHR(TYPE_E_CANTCREATETMPFILE, VBSERR_CantCreateTmpFile),
  75. /*0x80029C4A*/ MAPHR(TYPE_E_CANTLOADLIBRARY, VBSERR_DLLLoadErr),
  76. // FACILITY_STORAGE errors
  77. /*0x80030002*/ MAPHR(STG_E_FILENOTFOUND, VBSERR_OLEFileNotFound),
  78. /*0x80030003*/ MAPHR(STG_E_PATHNOTFOUND, VBSERR_PathNotFound),
  79. /*0x80030004*/ MAPHR(STG_E_TOOMANYOPENFILES, VBSERR_TooManyFiles),
  80. /*0x80030005*/ MAPHR(STG_E_ACCESSDENIED, VBSERR_PermissionDenied),
  81. /*0x80030008*/ MAPHR(STG_E_INSUFFICIENTMEMORY, VBSERR_OutOfMemory),
  82. /*0x80030012*/ MAPHR(STG_E_NOMOREFILES, VBSERR_TooManyFiles),
  83. /*0x80030013*/ MAPHR(STG_E_DISKISWRITEPROTECTED, VBSERR_PermissionDenied),
  84. /*0x8003001D*/ MAPHR(STG_E_WRITEFAULT, VBSERR_IOError),
  85. /*0x8003001E*/ MAPHR(STG_E_READFAULT, VBSERR_IOError),
  86. /*0x80030020*/ MAPHR(STG_E_SHAREVIOLATION, VBSERR_PathFileAccess),
  87. /*0x80030021*/ MAPHR(STG_E_LOCKVIOLATION, VBSERR_PermissionDenied),
  88. /*0x80030050*/ MAPHR(STG_E_FILEALREADYEXISTS, VBSERR_FileAlreadyExists),
  89. /*0x80030070*/ MAPHR(STG_E_MEDIUMFULL, VBSERR_DiskFull),
  90. /*0x800300FC*/ MAPHR(STG_E_INVALIDNAME, VBSERR_FileNotFound),
  91. /*0x80030100*/ MAPHR(STG_E_INUSE, VBSERR_PermissionDenied),
  92. /*0x80030101*/ MAPHR(STG_E_NOTCURRENT, VBSERR_PermissionDenied),
  93. /*0x80030103*/ MAPHR(STG_E_CANTSAVE, VBSERR_IOError),
  94. // FACILITY_ITF errors.
  95. /*0x80040154*/ MAPHR(REGDB_E_CLASSNOTREG, VBSERR_CantCreateObject),
  96. /*0x800401E3*/ MAPHR(MK_E_UNAVAILABLE, VBSERR_CantCreateObject),
  97. /*0x800401E6*/ MAPHR(MK_E_INVALIDEXTENSION, VBSERR_OLEFileNotFound),
  98. /*0x800401EA*/ MAPHR(MK_E_CANTOPENFILE, VBSERR_OLEFileNotFound),
  99. /*0x800401F3*/ MAPHR(CO_E_CLASSSTRING, VBSERR_CantCreateObject),
  100. /*0x800401F5*/ MAPHR(CO_E_APPNOTFOUND, VBSERR_CantCreateObject),
  101. /*0x800401FE*/ MAPHR(CO_E_APPDIDNTREG, VBSERR_CantCreateObject),
  102. #if _WIN32
  103. // FACILITY_WIN32 errors
  104. /*0x80070005*/ MAPHR(E_ACCESSDENIED, VBSERR_PermissionDenied),
  105. /*0x8007000E*/ MAPHR(E_OUTOFMEMORY, VBSERR_OutOfMemory),
  106. /*0x80070057*/ MAPHR(E_INVALIDARG, VBSERR_IllegalFuncCall),
  107. /*0x800706BA*/ MAPHR(_HRESULT_TYPEDEF_(0x800706BA), VBSERR_ServerNotFound),
  108. // FACILITY_WINDOWS
  109. /*0x80080005*/ MAPHR(CO_E_SERVER_EXEC_FAILURE, VBSERR_CantCreateObject),
  110. #endif // _WIN32
  111. };
  112. const int32 kcmhr = sizeof(g_rgmhr) / sizeof(g_rgmhr[0]);
  113. HRESULT MapHr(HRESULT hr, ErrorTypeEnum * errorTypeOut)
  114. {
  115. int imhrMin, imhrLim, imhr;
  116. #if DEBUG
  117. // In debug, check that all the entries in the error map table are
  118. // sorted based on the HRESULT in ascending order. We will then binary
  119. // search the sorted array. We need do this only once per invocation.
  120. static BOOL fCheckSort = TRUE;
  121. if (fCheckSort)
  122. {
  123. fCheckSort = FALSE;
  124. for (imhr = 1; imhr < kcmhr; imhr++)
  125. Assert((uint32)g_rgmhr[imhr - 1].hrIn < (uint32)g_rgmhr[imhr].hrIn);
  126. }
  127. #endif // DEBUG
  128. if (errorTypeOut != nullptr)
  129. {
  130. *errorTypeOut = kjstError;
  131. }
  132. if (SUCCEEDED(hr))
  133. return NOERROR;
  134. if (FACILITY_CONTROL == HRESULT_FACILITY(hr))
  135. return hr;
  136. for (imhrMin = 0, imhrLim = kcmhr; imhrMin < imhrLim; )
  137. {
  138. imhr = (imhrMin + imhrLim) / 2;
  139. if ((uint32)g_rgmhr[imhr].hrIn < (uint32)hr)
  140. imhrMin = imhr + 1;
  141. else
  142. imhrLim = imhr;
  143. }
  144. if (imhrMin < kcmhr && hr == g_rgmhr[imhrMin].hrIn)
  145. {
  146. if (errorTypeOut != nullptr)
  147. {
  148. *errorTypeOut = g_rgmhr[imhrMin].errorType;
  149. }
  150. return g_rgmhr[imhrMin].hrOut;
  151. }
  152. return hr;
  153. }
  154. // === ScriptException ===
  155. ScriptException::~ScriptException(void)
  156. {
  157. FreeExcepInfo(&ei);
  158. }
  159. void ScriptException::CopyInto(ScriptException *pse)
  160. {
  161. pse->ichMin = ichMin;
  162. pse->ichLim = ichLim;
  163. CopyException(&(pse->ei), &ei);
  164. }
  165. void ScriptException::Free(void)
  166. {
  167. ichMin = ichLim = 0;
  168. FreeExcepInfo(&ei);
  169. }
  170. void ScriptException::GetError(HRESULT *phr, EXCEPINFO *pei)
  171. {
  172. Assert(phr);
  173. if (HR(SCRIPT_E_RECORDED) == *phr)
  174. {
  175. Assert(FAILED(HR(ei.scode)));
  176. if (nullptr == pei)
  177. *phr = HR(ei.scode);
  178. else
  179. {
  180. *phr = HR(DISP_E_EXCEPTION);
  181. js_memcpy_s(pei, sizeof(*pei), &ei, sizeof(*pei));
  182. memset(&ei, 0, sizeof(ei));
  183. if (nullptr != pei->pfnDeferredFillIn)
  184. {
  185. pei->pfnDeferredFillIn(pei);
  186. pei->pfnDeferredFillIn = nullptr;
  187. }
  188. }
  189. }
  190. }
  191. // === CompileScriptException ===
  192. CompileScriptException::~CompileScriptException()
  193. {
  194. SysFreeString(bstrLine);
  195. }
  196. void CompileScriptException::Free()
  197. {
  198. ScriptException::Free();
  199. line = ichMinLine = 0;
  200. if (nullptr != bstrLine)
  201. {
  202. SysFreeString(bstrLine);
  203. bstrLine = nullptr;
  204. }
  205. }
  206. void CompileScriptException::CopyInto(CompileScriptException* pse)
  207. {
  208. ScriptException::CopyInto(pse);
  209. pse->line = this->line;
  210. pse->ichMinLine = this->ichMinLine;
  211. pse->hasLineNumberInfo = this->hasLineNumberInfo;
  212. if (this->bstrLine)
  213. {
  214. pse->bstrLine = SysAllocStringLen(this->bstrLine, SysStringLen(this->bstrLine));
  215. }
  216. }
  217. HRESULT CompileScriptException::ProcessError(IScanner * pScan, HRESULT hr, ParseNode * pnodeBase, LPCWSTR stringOne, LPCWSTR stringTwo)
  218. {
  219. // fill in the ScriptException structure
  220. Free();
  221. ei.scode = GetScode(MapHr(hr));
  222. // get the error string
  223. if (FACILITY_CONTROL != HRESULT_FACILITY(ei.scode) ||
  224. nullptr == (ei.bstrDescription =
  225. BstrGetResourceString(HRESULT_CODE(ei.scode))))
  226. {
  227. OLECHAR szT[50];
  228. _snwprintf_s(szT, ARRAYSIZE(szT), ARRAYSIZE(szT)-1, _u("error %d"), ei.scode);
  229. if (nullptr == (ei.bstrDescription = SysAllocString(szT)))
  230. ei.scode = E_OUTOFMEMORY;
  231. }
  232. else if (wcslen(stringOne) > 0)
  233. {
  234. OLECHAR szT[128];
  235. _snwprintf_s(szT, ARRAYSIZE(szT), ARRAYSIZE(szT)-1, ei.bstrDescription, stringOne, stringTwo);
  236. SysFreeString(ei.bstrDescription);
  237. ei.bstrDescription = SysAllocString(szT);
  238. }
  239. ei.bstrSource = BstrGetResourceString(IDS_COMPILATION_ERROR_SOURCE);
  240. if (nullptr == pnodeBase && nullptr != pScan)
  241. {
  242. // parsing phase - get the line number from the scanner
  243. Assert(pScan);
  244. this->hasLineNumberInfo = true;
  245. pScan->GetErrorLineInfo(this->ichMin, this->ichLim, this->line, this->ichMinLine);
  246. HRESULT hrSysAlloc = pScan->SysAllocErrorLine(this->ichMinLine, &this->bstrLine);
  247. if( FAILED(hrSysAlloc) )
  248. {
  249. return hrSysAlloc;
  250. }
  251. if (ichMin < ichMinLine)
  252. ichMin = ichMinLine;
  253. }
  254. else
  255. {
  256. // TODO: Variable length registers.
  257. // Remove E_FAIL once we have this feature.
  258. // error during code gen - no line number info available
  259. // E_ABORT may result if compilation does stack probe while thread is in disabled state.
  260. Assert(hr == WASMERR_WasmCompileError || hr == JSERR_AsmJsCompileError || hr == ERRnoMemory || hr == VBSERR_OutOfStack || hr == E_OUTOFMEMORY || hr == E_FAIL || hr == E_ABORT);
  261. }
  262. return SCRIPT_E_RECORDED;
  263. }