v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
contextual.h
Go to the documentation of this file.
1
// Copyright 2018 the V8 project authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
#ifndef V8_BASE_CONTEXTUAL_H_
6
#define V8_BASE_CONTEXTUAL_H_
7
8
#include <type_traits>
9
10
#include "
src/base/export-template.h
"
11
#include "
src/base/macros.h
"
12
#include "
src/base/platform/platform.h
"
13
14
namespace
v8::base
{
15
16
// {ContextualVariable} provides a clean alternative to a global variable.
17
// The contextual variable is mutable, and supports managing the value of
18
// a variable in a well-nested fashion via the {Scope} class.
19
// {ContextualVariable} only stores a pointer to the current value, which
20
// is stored in a {Scope} object. The most recent value can be retrieved
21
// via Get(). Because only {Scope} has actual storage, there must be at
22
// least one active {Scope} (i.e. in a surrounding C++ scope), whenever Get()
23
// is called.
24
// Note that contextual variables must only be used from the same thread,
25
// i.e. {Scope} and Get() have to be in the same thread.
26
template
<
class
Derived,
class
VarType>
27
class
V8_EXPORT_PRIVATE
ContextualVariable
{
28
public
:
29
using
VarT
= VarType;
30
31
// A {Scope} contains a new object of type {VarType} and gives
32
// ContextualVariable::Get() access to it. Upon destruction, the contextual
33
// variable is restored to the state before the {Scope} was created. Scopes
34
// have to follow a stack discipline: A {Scope} has to be destructed before
35
// any older scope is destructed.
36
class
V8_NODISCARD
Scope
{
37
public
:
38
template
<
class
... Args>
39
explicit
Scope
(Args&&...
args
)
40
:
value_
(
std
::forward<Args>(
args
)...), previous_(Top()) {
41
Top() =
this
;
42
}
43
~Scope
() {
44
// Ensure stack discipline.
45
DCHECK_EQ
(
this
, Top());
46
Top() = previous_;
47
}
48
49
Scope
(
const
Scope
&) =
delete
;
50
Scope
&
operator=
(
const
Scope
&) =
delete
;
51
52
VarType&
Value
() {
return
value_
; }
53
54
private
:
55
VarType
value_
;
56
Scope
*
previous_
;
57
58
static_assert
(std::is_base_of<ContextualVariable, Derived>::value,
59
"Curiously Recurring Template Pattern"
);
60
61
DISALLOW_NEW_AND_DELETE
()
62
};
63
64
static
VarType&
Get
() {
65
DCHECK
(HasScope());
66
return
Top()->Value();
67
}
68
69
static
bool
HasScope
() {
return
Top() !=
nullptr
; }
70
71
private
:
72
inline
static
thread_local
Scope
* top_ =
nullptr
;
73
74
#if defined(USING_V8_SHARED)
75
// Hide the access to `top_` from other DLLs/libraries, since access to
76
// thread_local variables from other DLLs/libraries does not work correctly.
77
static
Scope
*& Top() {
return
ExportedTop(); }
78
#else
79
static
Scope
*&
Top
() {
return
top_; }
80
#endif
81
// Same as `Top()`, but non-inline and exported to DLLs/libraries.
82
// If there is a linking error for `ExportedTop()`, then the contextual
83
// variable probably needs to be exported using EXPORT_CONTEXTUAL_VARIABLE.
84
static
Scope
*&
ExportedTop
();
85
};
86
87
// Usage: DECLARE_CONTEXTUAL_VARIABLE(VarName, VarType)
88
#define DECLARE_CONTEXTUAL_VARIABLE(VarName, ...) \
89
struct VarName : ::v8::base::ContextualVariable<VarName, __VA_ARGS__> {}
90
91
// Contextual variables that are accessed in tests need to be
92
// exported. For this, place the following macro in the global namespace inside
93
// of a .cc file.
94
#define EXPORT_CONTEXTUAL_VARIABLE(VarName) \
95
namespace v8::base { \
96
template <> \
97
V8_EXPORT_PRIVATE typename VarName::Scope*& \
98
ContextualVariable<VarName, typename VarName::VarT>::ExportedTop() { \
99
return top_; \
100
} \
101
}
102
103
// By inheriting from {ContextualClass} a class can become a contextual variable
104
// of itself, which is very similar to a singleton.
105
template
<
class
T>
106
using
ContextualClass
=
ContextualVariable<T, T>
;
107
108
// {ContextualVariableWithDefault} is similar to a {ContextualVariable},
109
// with the difference that a default value is used if there is no active
110
// {Scope} object.
111
template
<
class
Derived,
class
VarType,
auto
... default_args>
112
class
V8_EXPORT_PRIVATE
ContextualVariableWithDefault
113
:
public
ContextualVariable
<Derived, VarType> {
114
public
:
115
static
VarType&
Get
() {
116
return
Base::HasScope() ? Base::Get() : default_value_;
117
}
118
119
private
:
120
using
Base
=
ContextualVariable<Derived, VarType>
;
121
inline
static
thread_local
VarType default_value_{default_args...};
122
};
123
124
// Usage: DECLARE_CONTEXTUAL_VARIABLE_WITH_DEFAULT(VarName, VarType, Args...)
125
#define DECLARE_CONTEXTUAL_VARIABLE_WITH_DEFAULT(VarName, ...) \
126
struct VarName \
127
: ::v8::base::ContextualVariableWithDefault<VarName, __VA_ARGS__> {}
128
129
}
// namespace v8::base
130
131
#endif
// V8_BASE_CONTEXTUAL_H_
v8::base::ContextualVariableWithDefault
Definition
contextual.h:113
v8::base::ContextualVariableWithDefault::Get
static VarType & Get()
Definition
contextual.h:115
v8::base::ContextualVariable::Scope
Definition
contextual.h:36
v8::base::ContextualVariable::Scope::previous_
Scope * previous_
Definition
contextual.h:56
v8::base::ContextualVariable::Scope::Value
VarType & Value()
Definition
contextual.h:52
v8::base::ContextualVariable::Scope::operator=
Scope & operator=(const Scope &)=delete
v8::base::ContextualVariable::Scope::~Scope
~Scope()
Definition
contextual.h:43
v8::base::ContextualVariable::Scope::Scope
Scope(const Scope &)=delete
v8::base::ContextualVariable::Scope::Scope
Scope(Args &&... args)
Definition
contextual.h:39
v8::base::ContextualVariable::Scope::value_
VarType value_
Definition
contextual.h:55
v8::base::ContextualVariable
Definition
contextual.h:27
v8::base::ContextualVariable::VarT
VarType VarT
Definition
contextual.h:29
v8::base::ContextualVariable::Get
static VarType & Get()
Definition
contextual.h:64
v8::base::ContextualVariable::Top
static Scope *& Top()
Definition
contextual.h:79
v8::base::ContextualVariable::HasScope
static bool HasScope()
Definition
contextual.h:69
v8::base::ContextualVariable::ExportedTop
static Scope *& ExportedTop()
value_
Register const value_
Definition
code-generator-arm.cc:223
args
base::Vector< const DirectHandle< Object > > args
Definition
execution.cc:74
export-template.h
std
STL namespace.
v8::base
Definition
scopes.h:26
DCHECK
#define DCHECK(condition)
Definition
logging.h:482
DCHECK_EQ
#define DCHECK_EQ(v1, v2)
Definition
logging.h:485
macros.h
DISALLOW_NEW_AND_DELETE
#define DISALLOW_NEW_AND_DELETE()
Definition
macros.h:155
V8_EXPORT_PRIVATE
#define V8_EXPORT_PRIVATE
Definition
macros.h:460
platform.h
V8_NODISCARD
#define V8_NODISCARD
Definition
v8config.h:693
src
base
contextual.h
Generated on Sun Apr 6 2025 21:08:50 for v8 by
1.12.0