JavascriptExceptionOperators.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. #pragma once
  6. #ifdef _M_AMD64
  7. extern "C" void *amd64_CallWithFakeFrame(void *target,
  8. void *frame,
  9. size_t spillSize,
  10. size_t argsSize,
  11. void *arg0 = nullptr) throw(...);
  12. #elif defined(_M_ARM)
  13. extern "C" void *arm_CallEhFrame(void *target, void *framePtr, void *localsPtr, size_t argsSize) throw(...);
  14. extern "C" void *arm_CallCatch(void *target, void *framePtr, void *localsPtr, size_t argsSize, void *catchObj) throw(...);
  15. #elif defined(_M_ARM64)
  16. extern "C" void *arm64_CallEhFrame(void *target, void *framePtr, void *localsPtr, size_t argsSize) throw(...);
  17. extern "C" void *arm64_CallCatch(void *target, void *framePtr, void *localsPtr, size_t argsSize, void *catchObj) throw(...);
  18. #endif
  19. namespace Js
  20. {
  21. class JavascriptExceptionContext;
  22. class JavascriptExceptionOperators /* All static */
  23. {
  24. public:
  25. static const uint64 DefaultStackTraceLimit = 10;
  26. static const uint64 MaxStackTraceLimit = _UI64_MAX;
  27. // AutoCatchHandlerExists tracks where an exception will be caught and not propagated out.
  28. // It should be included wherever an exception is caught and swallowed.
  29. class AutoCatchHandlerExists
  30. {
  31. private:
  32. bool m_previousCatchHandlerExists;
  33. bool m_previousCatchHandlerToUserCodeStatus;
  34. ThreadContext* m_threadContext;
  35. void FetchNonUserCodeStatus(ScriptContext *scriptContext);
  36. public:
  37. AutoCatchHandlerExists(ScriptContext* scriptContext);
  38. ~AutoCatchHandlerExists();
  39. };
  40. static void __declspec(noreturn) OP_Throw(Var object, ScriptContext* scriptContext);
  41. static void __declspec(noreturn) Throw(Var object, ScriptContext* scriptContext);
  42. static void __declspec(noreturn) ThrowExceptionObject(Js::JavascriptExceptionObject* exceptionObject, ScriptContext* scriptContext, bool considerPassingToDebugger = false, PVOID returnAddress = NULL, bool resetStack = false);
  43. static void __declspec(noreturn) RethrowExceptionObject(Js::JavascriptExceptionObject* exceptionObject, ScriptContext* scriptContext, bool considerPassingToDebugger = false);
  44. static void __declspec(noreturn) DoThrow(JavascriptExceptionObject* exceptionObject, ScriptContext* scriptContext);
  45. static void __declspec(noreturn) DoThrowCheckClone(JavascriptExceptionObject* exceptionObject, ScriptContext* scriptContext);
  46. #ifdef _M_X64
  47. static void *OP_TryCatch(void *try_, void *catch_, void *frame, size_t spillSize, size_t argsSize, int hasBailedOutOffset, ScriptContext *scriptContext);
  48. static void *OP_TryFinally(void *try_, void *finally_, void *frame, size_t spillSize, size_t argsSize, ScriptContext *scriptContext);
  49. #elif defined(_M_ARM32_OR_ARM64)
  50. static void* OP_TryCatch(void* continuationAddr, void* handlerAddr, void* framePtr, void *localsPtr, size_t argsSize, int hasBailedOutOffset, ScriptContext* scriptContext);
  51. static void* OP_TryFinally(void* continuationAddr, void* handlerAddr, void* framePtr, void *localsPtr, size_t argsSize, ScriptContext* scriptContext);
  52. #else
  53. static void* OP_TryCatch(void* continuationAddr, void* handlerAddr, void* framePtr, int hasBailedOutOffset, ScriptContext* scriptContext);
  54. static void* OP_TryFinally(void* continuationAddr, void* handlerAddr, void* framePtr, ScriptContext* scriptContext);
  55. #endif
  56. #if defined(DBG) && defined(_M_IX86)
  57. static void DbgCheckEHChain();
  58. #endif
  59. static JavascriptExceptionObject* GetOutOfMemoryExceptionObject(ScriptContext* scriptContext);
  60. static Var OP_RuntimeTypeError(MessageId messageId, ScriptContext* scriptContext);
  61. static Var OP_RuntimeRangeError(MessageId messageId, ScriptContext* scriptContext);
  62. static Var OP_RuntimeReferenceError(MessageId messageId, ScriptContext* scriptContext);
  63. static Var OP_WebAssemblyRuntimeError(MessageId messageId, ScriptContext* scriptContext);
  64. static void __declspec(noreturn) ThrowOutOfMemory(ScriptContext* scriptContext);
  65. static void __declspec(noreturn) ThrowStackOverflow(ScriptContext* scriptContext, PVOID returnAddress);
  66. static uint64 GetStackTraceLimit(Var thrownObject, ScriptContext* scriptContext);
  67. static Var ThrowTypeErrorRestrictedPropertyAccessor(RecyclableObject* function, CallInfo callInfo, ...);
  68. static Var StackTraceAccessor(RecyclableObject* function, CallInfo callInfo, ...);
  69. static void WalkStackForExceptionContext(ScriptContext& scriptContext, JavascriptExceptionContext& exceptionContext, Var thrownObject, uint64 stackCrawlLimit, PVOID returnAddress, bool isThrownException = true, bool resetSatck = false);
  70. static void AddStackTraceToObject(Var obj, JavascriptExceptionContext::StackTrace* stackTrace, ScriptContext& scriptContext, bool isThrownException = true, bool resetSatck = false);
  71. static uint64 StackCrawlLimitOnThrow(Var thrownObject, ScriptContext& scriptContext);
  72. class EntryInfo
  73. {
  74. public:
  75. static FunctionInfo StackTraceAccessor;
  76. // For strict mode
  77. static FunctionInfo ThrowTypeErrorRestrictedPropertyAccessor;
  78. };
  79. private:
  80. static JavascriptFunction * WalkStackForExceptionContextInternal(ScriptContext& scriptContext, JavascriptExceptionContext& exceptionContext, Var thrownObject, uint32& callerByteCodeOffset,
  81. uint64 stackCrawlLimit, PVOID returnAddress, bool isThrownException, bool resetStack = false);
  82. static void ThrowExceptionObjectInternal(Js::JavascriptExceptionObject * exceptionObject, ScriptContext* scriptContext, bool fillExceptionContext, bool considerPassingToDebugger, PVOID returnAddress, bool resetStack);
  83. static BOOL GetCaller(JavascriptStackWalker& walker, JavascriptFunction*& jsFunc);
  84. static void DumpStackTrace(JavascriptExceptionContext& exceptionContext, bool isThrownException = true);
  85. static JavascriptExceptionContext::StackTrace* TrimStackTraceForThrownObject(JavascriptExceptionContext::StackTrace* stackTraceOriginal, Var thrownObject, ScriptContext& scriptContext);
  86. static void AppendExternalFrameToStackTrace(CompoundString* bs, LPCWSTR functionName, LPCWSTR fileName, ULONG lineNumber, LONG characterPosition);
  87. static void AppendLibraryFrameToStackTrace(CompoundString* bs, LPCWSTR functionName);
  88. static bool IsErrorInstance(Var thrownObject);
  89. static bool CrawlStackForWER(Js::ScriptContext& scriptContext);
  90. static void DispatchExceptionToDebugger(Js::JavascriptExceptionObject * exceptionObject, ScriptContext* scriptContext);
  91. };
  92. } // namespace Js