forked from chakra-core/ChakraCore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjsrtcontext.cpp
More file actions
144 lines (119 loc) · 3.77 KB
/
jsrtcontext.cpp
File metadata and controls
144 lines (119 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//-------------------------------------------------------------------------------------------------------
// 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"
DWORD JsrtContext::s_tlsSlot = TLS_OUT_OF_INDEXES;
JsrtContext::JsrtContext(JsrtRuntime * runtime) :
runtime(runtime), scriptContext(nullptr)
{
}
void JsrtContext::SetScriptContext(Js::ScriptContext * scriptContext)
{
this->scriptContext = scriptContext;
}
void JsrtContext::PinCurrentJsrtContext()
{
Assert(this->scriptContext);
this->scriptContext->GetLibrary()->PinJsrtContextObject(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 */
bool JsrtContext::Initialize()
{
Assert(s_tlsSlot == TLS_OUT_OF_INDEXES);
s_tlsSlot = TlsAlloc();
if (s_tlsSlot == TLS_OUT_OF_INDEXES)
return false;
return true;
}
/* static */
void JsrtContext::Uninitialize()
{
if (s_tlsSlot != TLS_OUT_OF_INDEXES)
TlsFree(s_tlsSlot);
}
/* static */
JsrtContext * JsrtContext::GetCurrent()
{
Assert(s_tlsSlot != TLS_OUT_OF_INDEXES);
return (JsrtContext *)TlsGetValue(s_tlsSlot);
}
/* static */
bool JsrtContext::TrySetCurrent(JsrtContext * context)
{
Assert(s_tlsSlot != TLS_OUT_OF_INDEXES);
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;
}
threadContext->GetRecycler()->RootAddRef((LPVOID)context);
}
else
{
if (!ThreadContextTLSEntry::ClearThreadContext(true))
{
return false;
}
}
JsrtContext* originalContext = (JsrtContext*) TlsGetValue(s_tlsSlot);
if (originalContext != nullptr)
{
originalContext->GetScriptContext()->GetRecycler()->RootRelease((LPVOID) originalContext);
}
TlsSetValue(s_tlsSlot, context);
return true;
}
void JsrtContext::Finalize(bool isShutdown)
{
}
void JsrtContext::Mark(Recycler * recycler)
{
AssertMsg(false, "Mark called on object that isn't TrackableObject");
}