JsrtContext.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 "JsrtPch.h"
  6. #include "JsrtRuntime.h"
  7. #include "Base/ThreadContextTlsEntry.h"
  8. static THREAD_LOCAL JsrtContext* s_tlvSlot = nullptr;
  9. JsrtContext::JsrtContext(JsrtRuntime * runtime) :
  10. runtime(runtime), javascriptLibrary(nullptr)
  11. {
  12. }
  13. void JsrtContext::SetJavascriptLibrary(Js::JavascriptLibrary * library)
  14. {
  15. this->javascriptLibrary = library;
  16. }
  17. void JsrtContext::PinCurrentJsrtContext()
  18. {
  19. Assert(this->javascriptLibrary);
  20. this->javascriptLibrary->PinJsrtContextObject(this);
  21. }
  22. void JsrtContext::Link()
  23. {
  24. // Link this new JsrtContext up in the JsrtRuntime's context list
  25. this->next = runtime->contextList;
  26. this->previous = nullptr;
  27. if (runtime->contextList != nullptr)
  28. {
  29. Assert(runtime->contextList->previous == nullptr);
  30. runtime->contextList->previous = this;
  31. }
  32. runtime->contextList = this;
  33. }
  34. void JsrtContext::Unlink()
  35. {
  36. // Unlink from JsrtRuntime JsrtContext list
  37. if (this->previous == nullptr)
  38. {
  39. // Have to check this because if we failed while creating, it might
  40. // never have gotten linked in to the runtime at all.
  41. if (this->runtime->contextList == this)
  42. {
  43. this->runtime->contextList = this->next;
  44. }
  45. }
  46. else
  47. {
  48. Assert(this->previous->next == this);
  49. this->previous->next = this->next;
  50. }
  51. if (this->next != nullptr)
  52. {
  53. Assert(this->next->previous == this);
  54. this->next->previous = this->previous;
  55. }
  56. }
  57. /* static */
  58. JsrtContext * JsrtContext::GetCurrent()
  59. {
  60. return s_tlvSlot;
  61. }
  62. /* static */
  63. bool JsrtContext::TrySetCurrent(JsrtContext * context)
  64. {
  65. ThreadContext * threadContext;
  66. //We are not pinning the context after SetCurrentContext, so if the context is not pinned
  67. //it might be reclaimed half way during execution. In jsrtshell the runtime was optimized out
  68. //at time of JsrtContext::Run by the compiler.
  69. //The change is to pin the context at setconcurrentcontext, and unpin the previous one. In
  70. //JsDisposeRuntime we'll reject if current context is active, so that will make sure all
  71. //contexts are unpinned at time of JsDisposeRuntime.
  72. if (context != nullptr)
  73. {
  74. threadContext = context->GetScriptContext()->GetThreadContext();
  75. if (!ThreadContextTLSEntry::TrySetThreadContext(threadContext))
  76. {
  77. return false;
  78. }
  79. threadContext->GetRecycler()->RootAddRef((LPVOID)context);
  80. }
  81. else
  82. {
  83. if (!ThreadContextTLSEntry::ClearThreadContext(true))
  84. {
  85. return false;
  86. }
  87. }
  88. JsrtContext* originalContext = s_tlvSlot;
  89. if (originalContext != nullptr)
  90. {
  91. originalContext->GetScriptContext()->GetRecycler()->RootRelease((LPVOID) originalContext);
  92. }
  93. s_tlvSlot = context;
  94. return true;
  95. }
  96. void JsrtContext::Finalize(bool isShutdown)
  97. {
  98. }
  99. void JsrtContext::Mark(Recycler * recycler)
  100. {
  101. AssertMsg(false, "Mark called on object that isn't TrackableObject");
  102. }