| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "JsrtPch.h"
- #include "JsrtRuntime.h"
- #include "Base/ThreadContextTlsEntry.h"
- static THREAD_LOCAL JsrtContext* s_tlvSlot = nullptr;
- JsrtContext::JsrtContext(JsrtRuntime * runtime) :
- runtime(runtime), javascriptLibrary(nullptr)
- {
- }
- void JsrtContext::SetJavascriptLibrary(Js::JavascriptLibrary * library)
- {
- this->javascriptLibrary = library;
- if (this->javascriptLibrary)
- {
- this->javascriptLibrary->SetJsrtContext(this);
- }
- }
- void JsrtContext::Link()
- {
- // Link this new JsrtContext up in the JsrtRuntime's context list
- this->next = runtime->contextList;
- this->previous = nullptr;
- if (runtime->contextList != nullptr)
- {
- Assert(runtime->contextList->previous == nullptr);
- runtime->contextList->previous = this;
- }
- runtime->contextList = this;
- }
- void JsrtContext::Unlink()
- {
- // Unlink from JsrtRuntime JsrtContext list
- if (this->previous == nullptr)
- {
- // Have to check this because if we failed while creating, it might
- // never have gotten linked in to the runtime at all.
- if (this->runtime->contextList == this)
- {
- this->runtime->contextList = this->next;
- }
- }
- else
- {
- Assert(this->previous->next == this);
- this->previous->next = this->next;
- }
- if (this->next != nullptr)
- {
- Assert(this->next->previous == this);
- this->next->previous = this->previous;
- }
- }
- /* static */
- JsrtContext * JsrtContext::GetCurrent()
- {
- return s_tlvSlot;
- }
- /* static */
- bool JsrtContext::TrySetCurrent(JsrtContext * context)
- {
- ThreadContext * threadContext;
- //We are not pinning the context after SetCurrentContext, so if the context is not pinned
- //it might be reclaimed half way during execution. In jsrtshell the runtime was optimized out
- //at time of JsrtContext::Run by the compiler.
- //The change is to pin the context at setconcurrentcontext, and unpin the previous one. In
- //JsDisposeRuntime we'll reject if current context is active, so that will make sure all
- //contexts are unpinned at time of JsDisposeRuntime.
- if (context != nullptr)
- {
- threadContext = context->GetScriptContext()->GetThreadContext();
- if (!ThreadContextTLSEntry::TrySetThreadContext(threadContext))
- {
- return false;
- }
- // no need to rootAddRef and Release for the same context
- if (s_tlvSlot == context) return true;
- threadContext->GetRecycler()->RootAddRef((LPVOID)context);
- }
- else
- {
- if (!ThreadContextTLSEntry::ClearThreadContext(true))
- {
- return false;
- }
- }
- JsrtContext* originalContext = s_tlvSlot;
- if (originalContext != nullptr)
- {
- originalContext->GetScriptContext()->GetRecycler()->RootRelease((LPVOID) originalContext);
- }
- s_tlvSlot = context;
- return true;
- }
- void JsrtContext::Mark(Recycler * recycler)
- {
- AssertMsg(false, "Mark called on object that isn't TrackableObject");
- }
|