libv8-node 16.20.0.0-arm64-darwin → 17.9.1.0-arm64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/libv8-node/location.rb +1 -1
- data/ext/libv8-node/paths.rb +1 -1
- data/lib/libv8/node/version.rb +3 -3
- data/vendor/v8/arm64-darwin/libv8/obj/libv8_monolith.a +0 -0
- data/vendor/v8/include/cppgc/allocation.h +11 -5
- data/vendor/v8/include/cppgc/cross-thread-persistent.h +78 -26
- data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +2 -2
- data/vendor/v8/include/cppgc/internal/finalizer-trait.h +2 -0
- data/vendor/v8/include/cppgc/internal/gc-info.h +90 -10
- data/vendor/v8/include/cppgc/internal/name-trait.h +11 -0
- data/vendor/v8/include/cppgc/internal/persistent-node.h +44 -12
- data/vendor/v8/include/cppgc/internal/pointer-policies.h +22 -11
- data/vendor/v8/include/cppgc/internal/write-barrier.h +9 -1
- data/vendor/v8/include/cppgc/persistent.h +1 -1
- data/vendor/v8/include/cppgc/prefinalizer.h +1 -1
- data/vendor/v8/include/v8-array-buffer.h +433 -0
- data/vendor/v8/include/v8-callbacks.h +377 -0
- data/vendor/v8/include/v8-container.h +129 -0
- data/vendor/v8/include/v8-context.h +418 -0
- data/vendor/v8/include/v8-cppgc.h +5 -2
- data/vendor/v8/include/v8-data.h +65 -0
- data/vendor/v8/include/v8-date.h +43 -0
- data/vendor/v8/include/v8-debug.h +151 -0
- data/vendor/v8/include/v8-embedder-heap.h +238 -0
- data/vendor/v8/include/v8-exception.h +224 -0
- data/vendor/v8/include/v8-extension.h +62 -0
- data/vendor/v8/include/v8-external.h +37 -0
- data/vendor/v8/include/v8-fast-api-calls.h +63 -11
- data/vendor/v8/include/v8-forward.h +81 -0
- data/vendor/v8/include/v8-function-callback.h +475 -0
- data/vendor/v8/include/v8-function.h +122 -0
- data/vendor/v8/include/v8-initialization.h +282 -0
- data/vendor/v8/include/v8-inspector.h +11 -21
- data/vendor/v8/include/v8-internal.h +85 -22
- data/vendor/v8/include/v8-isolate.h +1662 -0
- data/vendor/v8/include/v8-json.h +47 -0
- data/vendor/v8/include/v8-local-handle.h +459 -0
- data/vendor/v8/include/v8-locker.h +148 -0
- data/vendor/v8/include/v8-maybe.h +137 -0
- data/vendor/v8/include/v8-memory-span.h +43 -0
- data/vendor/v8/include/v8-message.h +241 -0
- data/vendor/v8/include/v8-metrics.h +37 -1
- data/vendor/v8/include/v8-microtask-queue.h +152 -0
- data/vendor/v8/include/v8-microtask.h +28 -0
- data/vendor/v8/include/v8-object.h +770 -0
- data/vendor/v8/include/v8-persistent-handle.h +590 -0
- data/vendor/v8/include/v8-platform.h +41 -17
- data/vendor/v8/include/v8-primitive-object.h +118 -0
- data/vendor/v8/include/v8-primitive.h +858 -0
- data/vendor/v8/include/v8-profiler.h +10 -11
- data/vendor/v8/include/v8-promise.h +174 -0
- data/vendor/v8/include/v8-proxy.h +50 -0
- data/vendor/v8/include/v8-regexp.h +105 -0
- data/vendor/v8/include/v8-script.h +771 -0
- data/vendor/v8/include/v8-snapshot.h +198 -0
- data/vendor/v8/include/v8-statistics.h +215 -0
- data/vendor/v8/include/v8-template.h +1052 -0
- data/vendor/v8/include/v8-traced-handle.h +605 -0
- data/vendor/v8/include/v8-typed-array.h +282 -0
- data/vendor/v8/include/v8-unwinder-state.h +4 -3
- data/vendor/v8/include/v8-unwinder.h +129 -0
- data/vendor/v8/include/v8-util.h +7 -1
- data/vendor/v8/include/v8-value-serializer.h +249 -0
- data/vendor/v8/include/v8-value.h +526 -0
- data/vendor/v8/include/v8-version.h +3 -3
- data/vendor/v8/include/v8-wasm.h +245 -0
- data/vendor/v8/include/v8-weak-callback-info.h +73 -0
- data/vendor/v8/include/v8.h +41 -12604
- metadata +47 -5
@@ -0,0 +1,47 @@
|
|
1
|
+
// Copyright 2021 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 INCLUDE_V8_JSON_H_
|
6
|
+
#define INCLUDE_V8_JSON_H_
|
7
|
+
|
8
|
+
#include "v8-local-handle.h" // NOLINT(build/include_directory)
|
9
|
+
#include "v8config.h" // NOLINT(build/include_directory)
|
10
|
+
|
11
|
+
namespace v8 {
|
12
|
+
|
13
|
+
class Context;
|
14
|
+
class Value;
|
15
|
+
class String;
|
16
|
+
|
17
|
+
/**
|
18
|
+
* A JSON Parser and Stringifier.
|
19
|
+
*/
|
20
|
+
class V8_EXPORT JSON {
|
21
|
+
public:
|
22
|
+
/**
|
23
|
+
* Tries to parse the string |json_string| and returns it as value if
|
24
|
+
* successful.
|
25
|
+
*
|
26
|
+
* \param the context in which to parse and create the value.
|
27
|
+
* \param json_string The string to parse.
|
28
|
+
* \return The corresponding value if successfully parsed.
|
29
|
+
*/
|
30
|
+
static V8_WARN_UNUSED_RESULT MaybeLocal<Value> Parse(
|
31
|
+
Local<Context> context, Local<String> json_string);
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Tries to stringify the JSON-serializable object |json_object| and returns
|
35
|
+
* it as string if successful.
|
36
|
+
*
|
37
|
+
* \param json_object The JSON-serializable object to stringify.
|
38
|
+
* \return The corresponding string if successfully stringified.
|
39
|
+
*/
|
40
|
+
static V8_WARN_UNUSED_RESULT MaybeLocal<String> Stringify(
|
41
|
+
Local<Context> context, Local<Value> json_object,
|
42
|
+
Local<String> gap = Local<String>());
|
43
|
+
};
|
44
|
+
|
45
|
+
} // namespace v8
|
46
|
+
|
47
|
+
#endif // INCLUDE_V8_JSON_H_
|
@@ -0,0 +1,459 @@
|
|
1
|
+
// Copyright 2021 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 INCLUDE_V8_LOCAL_HANDLE_H_
|
6
|
+
#define INCLUDE_V8_LOCAL_HANDLE_H_
|
7
|
+
|
8
|
+
#include <stddef.h>
|
9
|
+
|
10
|
+
#include <type_traits>
|
11
|
+
|
12
|
+
#include "v8-internal.h" // NOLINT(build/include_directory)
|
13
|
+
|
14
|
+
namespace v8 {
|
15
|
+
|
16
|
+
class Boolean;
|
17
|
+
template <class T>
|
18
|
+
class BasicTracedReference;
|
19
|
+
class Context;
|
20
|
+
class EscapableHandleScope;
|
21
|
+
template <class F>
|
22
|
+
class Eternal;
|
23
|
+
template <class F>
|
24
|
+
class FunctionCallbackInfo;
|
25
|
+
class Isolate;
|
26
|
+
template <class F>
|
27
|
+
class MaybeLocal;
|
28
|
+
template <class T>
|
29
|
+
class NonCopyablePersistentTraits;
|
30
|
+
class Object;
|
31
|
+
template <class T, class M = NonCopyablePersistentTraits<T>>
|
32
|
+
class Persistent;
|
33
|
+
template <class T>
|
34
|
+
class PersistentBase;
|
35
|
+
template <class F1, class F2, class F3>
|
36
|
+
class PersistentValueMapBase;
|
37
|
+
template <class F1, class F2>
|
38
|
+
class PersistentValueVector;
|
39
|
+
class Primitive;
|
40
|
+
class Private;
|
41
|
+
template <class F>
|
42
|
+
class PropertyCallbackInfo;
|
43
|
+
template <class F>
|
44
|
+
class ReturnValue;
|
45
|
+
class String;
|
46
|
+
template <class F>
|
47
|
+
class Traced;
|
48
|
+
template <class F>
|
49
|
+
class TracedGlobal;
|
50
|
+
template <class F>
|
51
|
+
class TracedReference;
|
52
|
+
class TracedReferenceBase;
|
53
|
+
class Utils;
|
54
|
+
|
55
|
+
namespace internal {
|
56
|
+
template <typename T>
|
57
|
+
class CustomArguments;
|
58
|
+
} // namespace internal
|
59
|
+
|
60
|
+
namespace api_internal {
|
61
|
+
// Called when ToLocalChecked is called on an empty Local.
|
62
|
+
V8_EXPORT void ToLocalEmpty();
|
63
|
+
} // namespace api_internal
|
64
|
+
|
65
|
+
/**
|
66
|
+
* A stack-allocated class that governs a number of local handles.
|
67
|
+
* After a handle scope has been created, all local handles will be
|
68
|
+
* allocated within that handle scope until either the handle scope is
|
69
|
+
* deleted or another handle scope is created. If there is already a
|
70
|
+
* handle scope and a new one is created, all allocations will take
|
71
|
+
* place in the new handle scope until it is deleted. After that,
|
72
|
+
* new handles will again be allocated in the original handle scope.
|
73
|
+
*
|
74
|
+
* After the handle scope of a local handle has been deleted the
|
75
|
+
* garbage collector will no longer track the object stored in the
|
76
|
+
* handle and may deallocate it. The behavior of accessing a handle
|
77
|
+
* for which the handle scope has been deleted is undefined.
|
78
|
+
*/
|
79
|
+
class V8_EXPORT V8_NODISCARD HandleScope {
|
80
|
+
public:
|
81
|
+
explicit HandleScope(Isolate* isolate);
|
82
|
+
|
83
|
+
~HandleScope();
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Counts the number of allocated handles.
|
87
|
+
*/
|
88
|
+
static int NumberOfHandles(Isolate* isolate);
|
89
|
+
|
90
|
+
V8_INLINE Isolate* GetIsolate() const {
|
91
|
+
return reinterpret_cast<Isolate*>(isolate_);
|
92
|
+
}
|
93
|
+
|
94
|
+
HandleScope(const HandleScope&) = delete;
|
95
|
+
void operator=(const HandleScope&) = delete;
|
96
|
+
|
97
|
+
protected:
|
98
|
+
V8_INLINE HandleScope() = default;
|
99
|
+
|
100
|
+
void Initialize(Isolate* isolate);
|
101
|
+
|
102
|
+
static internal::Address* CreateHandle(internal::Isolate* isolate,
|
103
|
+
internal::Address value);
|
104
|
+
|
105
|
+
private:
|
106
|
+
// Declaring operator new and delete as deleted is not spec compliant.
|
107
|
+
// Therefore declare them private instead to disable dynamic alloc
|
108
|
+
void* operator new(size_t size);
|
109
|
+
void* operator new[](size_t size);
|
110
|
+
void operator delete(void*, size_t);
|
111
|
+
void operator delete[](void*, size_t);
|
112
|
+
|
113
|
+
internal::Isolate* isolate_;
|
114
|
+
internal::Address* prev_next_;
|
115
|
+
internal::Address* prev_limit_;
|
116
|
+
|
117
|
+
// Local::New uses CreateHandle with an Isolate* parameter.
|
118
|
+
template <class F>
|
119
|
+
friend class Local;
|
120
|
+
|
121
|
+
// Object::GetInternalField and Context::GetEmbedderData use CreateHandle with
|
122
|
+
// a HeapObject in their shortcuts.
|
123
|
+
friend class Object;
|
124
|
+
friend class Context;
|
125
|
+
};
|
126
|
+
|
127
|
+
/**
|
128
|
+
* An object reference managed by the v8 garbage collector.
|
129
|
+
*
|
130
|
+
* All objects returned from v8 have to be tracked by the garbage collector so
|
131
|
+
* that it knows that the objects are still alive. Also, because the garbage
|
132
|
+
* collector may move objects, it is unsafe to point directly to an object.
|
133
|
+
* Instead, all objects are stored in handles which are known by the garbage
|
134
|
+
* collector and updated whenever an object moves. Handles should always be
|
135
|
+
* passed by value (except in cases like out-parameters) and they should never
|
136
|
+
* be allocated on the heap.
|
137
|
+
*
|
138
|
+
* There are two types of handles: local and persistent handles.
|
139
|
+
*
|
140
|
+
* Local handles are light-weight and transient and typically used in local
|
141
|
+
* operations. They are managed by HandleScopes. That means that a HandleScope
|
142
|
+
* must exist on the stack when they are created and that they are only valid
|
143
|
+
* inside of the HandleScope active during their creation. For passing a local
|
144
|
+
* handle to an outer HandleScope, an EscapableHandleScope and its Escape()
|
145
|
+
* method must be used.
|
146
|
+
*
|
147
|
+
* Persistent handles can be used when storing objects across several
|
148
|
+
* independent operations and have to be explicitly deallocated when they're no
|
149
|
+
* longer used.
|
150
|
+
*
|
151
|
+
* It is safe to extract the object stored in the handle by dereferencing the
|
152
|
+
* handle (for instance, to extract the Object* from a Local<Object>); the value
|
153
|
+
* will still be governed by a handle behind the scenes and the same rules apply
|
154
|
+
* to these values as to their handles.
|
155
|
+
*/
|
156
|
+
template <class T>
|
157
|
+
class Local {
|
158
|
+
public:
|
159
|
+
V8_INLINE Local() : val_(nullptr) {}
|
160
|
+
template <class S>
|
161
|
+
V8_INLINE Local(Local<S> that) : val_(reinterpret_cast<T*>(*that)) {
|
162
|
+
/**
|
163
|
+
* This check fails when trying to convert between incompatible
|
164
|
+
* handles. For example, converting from a Local<String> to a
|
165
|
+
* Local<Number>.
|
166
|
+
*/
|
167
|
+
static_assert(std::is_base_of<T, S>::value, "type check");
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Returns true if the handle is empty.
|
172
|
+
*/
|
173
|
+
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Sets the handle to be empty. IsEmpty() will then return true.
|
177
|
+
*/
|
178
|
+
V8_INLINE void Clear() { val_ = nullptr; }
|
179
|
+
|
180
|
+
V8_INLINE T* operator->() const { return val_; }
|
181
|
+
|
182
|
+
V8_INLINE T* operator*() const { return val_; }
|
183
|
+
|
184
|
+
/**
|
185
|
+
* Checks whether two handles are the same.
|
186
|
+
* Returns true if both are empty, or if the objects to which they refer
|
187
|
+
* are identical.
|
188
|
+
*
|
189
|
+
* If both handles refer to JS objects, this is the same as strict equality.
|
190
|
+
* For primitives, such as numbers or strings, a `false` return value does not
|
191
|
+
* indicate that the values aren't equal in the JavaScript sense.
|
192
|
+
* Use `Value::StrictEquals()` to check primitives for equality.
|
193
|
+
*/
|
194
|
+
template <class S>
|
195
|
+
V8_INLINE bool operator==(const Local<S>& that) const {
|
196
|
+
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
|
197
|
+
internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
|
198
|
+
if (a == nullptr) return b == nullptr;
|
199
|
+
if (b == nullptr) return false;
|
200
|
+
return *a == *b;
|
201
|
+
}
|
202
|
+
|
203
|
+
template <class S>
|
204
|
+
V8_INLINE bool operator==(const PersistentBase<S>& that) const {
|
205
|
+
internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
|
206
|
+
internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
|
207
|
+
if (a == nullptr) return b == nullptr;
|
208
|
+
if (b == nullptr) return false;
|
209
|
+
return *a == *b;
|
210
|
+
}
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Checks whether two handles are different.
|
214
|
+
* Returns true if only one of the handles is empty, or if
|
215
|
+
* the objects to which they refer are different.
|
216
|
+
*
|
217
|
+
* If both handles refer to JS objects, this is the same as strict
|
218
|
+
* non-equality. For primitives, such as numbers or strings, a `true` return
|
219
|
+
* value does not indicate that the values aren't equal in the JavaScript
|
220
|
+
* sense. Use `Value::StrictEquals()` to check primitives for equality.
|
221
|
+
*/
|
222
|
+
template <class S>
|
223
|
+
V8_INLINE bool operator!=(const Local<S>& that) const {
|
224
|
+
return !operator==(that);
|
225
|
+
}
|
226
|
+
|
227
|
+
template <class S>
|
228
|
+
V8_INLINE bool operator!=(const Persistent<S>& that) const {
|
229
|
+
return !operator==(that);
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* Cast a handle to a subclass, e.g. Local<Value> to Local<Object>.
|
234
|
+
* This is only valid if the handle actually refers to a value of the
|
235
|
+
* target type.
|
236
|
+
*/
|
237
|
+
template <class S>
|
238
|
+
V8_INLINE static Local<T> Cast(Local<S> that) {
|
239
|
+
#ifdef V8_ENABLE_CHECKS
|
240
|
+
// If we're going to perform the type check then we have to check
|
241
|
+
// that the handle isn't empty before doing the checked cast.
|
242
|
+
if (that.IsEmpty()) return Local<T>();
|
243
|
+
#endif
|
244
|
+
return Local<T>(T::Cast(*that));
|
245
|
+
}
|
246
|
+
|
247
|
+
/**
|
248
|
+
* Calling this is equivalent to Local<S>::Cast().
|
249
|
+
* In particular, this is only valid if the handle actually refers to a value
|
250
|
+
* of the target type.
|
251
|
+
*/
|
252
|
+
template <class S>
|
253
|
+
V8_INLINE Local<S> As() const {
|
254
|
+
return Local<S>::Cast(*this);
|
255
|
+
}
|
256
|
+
|
257
|
+
/**
|
258
|
+
* Create a local handle for the content of another handle.
|
259
|
+
* The referee is kept alive by the local handle even when
|
260
|
+
* the original handle is destroyed/disposed.
|
261
|
+
*/
|
262
|
+
V8_INLINE static Local<T> New(Isolate* isolate, Local<T> that) {
|
263
|
+
return New(isolate, that.val_);
|
264
|
+
}
|
265
|
+
|
266
|
+
V8_INLINE static Local<T> New(Isolate* isolate,
|
267
|
+
const PersistentBase<T>& that) {
|
268
|
+
return New(isolate, that.val_);
|
269
|
+
}
|
270
|
+
|
271
|
+
V8_INLINE static Local<T> New(Isolate* isolate,
|
272
|
+
const BasicTracedReference<T>& that) {
|
273
|
+
return New(isolate, *that);
|
274
|
+
}
|
275
|
+
|
276
|
+
private:
|
277
|
+
friend class TracedReferenceBase;
|
278
|
+
friend class Utils;
|
279
|
+
template <class F>
|
280
|
+
friend class Eternal;
|
281
|
+
template <class F>
|
282
|
+
friend class PersistentBase;
|
283
|
+
template <class F, class M>
|
284
|
+
friend class Persistent;
|
285
|
+
template <class F>
|
286
|
+
friend class Local;
|
287
|
+
template <class F>
|
288
|
+
friend class MaybeLocal;
|
289
|
+
template <class F>
|
290
|
+
friend class FunctionCallbackInfo;
|
291
|
+
template <class F>
|
292
|
+
friend class PropertyCallbackInfo;
|
293
|
+
friend class String;
|
294
|
+
friend class Object;
|
295
|
+
friend class Context;
|
296
|
+
friend class Isolate;
|
297
|
+
friend class Private;
|
298
|
+
template <class F>
|
299
|
+
friend class internal::CustomArguments;
|
300
|
+
friend Local<Primitive> Undefined(Isolate* isolate);
|
301
|
+
friend Local<Primitive> Null(Isolate* isolate);
|
302
|
+
friend Local<Boolean> True(Isolate* isolate);
|
303
|
+
friend Local<Boolean> False(Isolate* isolate);
|
304
|
+
friend class HandleScope;
|
305
|
+
friend class EscapableHandleScope;
|
306
|
+
template <class F1, class F2, class F3>
|
307
|
+
friend class PersistentValueMapBase;
|
308
|
+
template <class F1, class F2>
|
309
|
+
friend class PersistentValueVector;
|
310
|
+
template <class F>
|
311
|
+
friend class ReturnValue;
|
312
|
+
template <class F>
|
313
|
+
friend class Traced;
|
314
|
+
template <class F>
|
315
|
+
friend class TracedGlobal;
|
316
|
+
template <class F>
|
317
|
+
friend class BasicTracedReference;
|
318
|
+
template <class F>
|
319
|
+
friend class TracedReference;
|
320
|
+
|
321
|
+
explicit V8_INLINE Local(T* that) : val_(that) {}
|
322
|
+
V8_INLINE static Local<T> New(Isolate* isolate, T* that) {
|
323
|
+
if (that == nullptr) return Local<T>();
|
324
|
+
T* that_ptr = that;
|
325
|
+
internal::Address* p = reinterpret_cast<internal::Address*>(that_ptr);
|
326
|
+
return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
|
327
|
+
reinterpret_cast<internal::Isolate*>(isolate), *p)));
|
328
|
+
}
|
329
|
+
T* val_;
|
330
|
+
};
|
331
|
+
|
332
|
+
#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
|
333
|
+
// Handle is an alias for Local for historical reasons.
|
334
|
+
template <class T>
|
335
|
+
using Handle = Local<T>;
|
336
|
+
#endif
|
337
|
+
|
338
|
+
/**
|
339
|
+
* A MaybeLocal<> is a wrapper around Local<> that enforces a check whether
|
340
|
+
* the Local<> is empty before it can be used.
|
341
|
+
*
|
342
|
+
* If an API method returns a MaybeLocal<>, the API method can potentially fail
|
343
|
+
* either because an exception is thrown, or because an exception is pending,
|
344
|
+
* e.g. because a previous API call threw an exception that hasn't been caught
|
345
|
+
* yet, or because a TerminateExecution exception was thrown. In that case, an
|
346
|
+
* empty MaybeLocal is returned.
|
347
|
+
*/
|
348
|
+
template <class T>
|
349
|
+
class MaybeLocal {
|
350
|
+
public:
|
351
|
+
V8_INLINE MaybeLocal() : val_(nullptr) {}
|
352
|
+
template <class S>
|
353
|
+
V8_INLINE MaybeLocal(Local<S> that) : val_(reinterpret_cast<T*>(*that)) {
|
354
|
+
static_assert(std::is_base_of<T, S>::value, "type check");
|
355
|
+
}
|
356
|
+
|
357
|
+
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
|
358
|
+
|
359
|
+
/**
|
360
|
+
* Converts this MaybeLocal<> to a Local<>. If this MaybeLocal<> is empty,
|
361
|
+
* |false| is returned and |out| is left untouched.
|
362
|
+
*/
|
363
|
+
template <class S>
|
364
|
+
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local<S>* out) const {
|
365
|
+
out->val_ = IsEmpty() ? nullptr : this->val_;
|
366
|
+
return !IsEmpty();
|
367
|
+
}
|
368
|
+
|
369
|
+
/**
|
370
|
+
* Converts this MaybeLocal<> to a Local<>. If this MaybeLocal<> is empty,
|
371
|
+
* V8 will crash the process.
|
372
|
+
*/
|
373
|
+
V8_INLINE Local<T> ToLocalChecked() {
|
374
|
+
if (V8_UNLIKELY(val_ == nullptr)) api_internal::ToLocalEmpty();
|
375
|
+
return Local<T>(val_);
|
376
|
+
}
|
377
|
+
|
378
|
+
/**
|
379
|
+
* Converts this MaybeLocal<> to a Local<>, using a default value if this
|
380
|
+
* MaybeLocal<> is empty.
|
381
|
+
*/
|
382
|
+
template <class S>
|
383
|
+
V8_INLINE Local<S> FromMaybe(Local<S> default_value) const {
|
384
|
+
return IsEmpty() ? default_value : Local<S>(val_);
|
385
|
+
}
|
386
|
+
|
387
|
+
private:
|
388
|
+
T* val_;
|
389
|
+
};
|
390
|
+
|
391
|
+
/**
|
392
|
+
* A HandleScope which first allocates a handle in the current scope
|
393
|
+
* which will be later filled with the escape value.
|
394
|
+
*/
|
395
|
+
class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope {
|
396
|
+
public:
|
397
|
+
explicit EscapableHandleScope(Isolate* isolate);
|
398
|
+
V8_INLINE ~EscapableHandleScope() = default;
|
399
|
+
|
400
|
+
/**
|
401
|
+
* Pushes the value into the previous scope and returns a handle to it.
|
402
|
+
* Cannot be called twice.
|
403
|
+
*/
|
404
|
+
template <class T>
|
405
|
+
V8_INLINE Local<T> Escape(Local<T> value) {
|
406
|
+
internal::Address* slot =
|
407
|
+
Escape(reinterpret_cast<internal::Address*>(*value));
|
408
|
+
return Local<T>(reinterpret_cast<T*>(slot));
|
409
|
+
}
|
410
|
+
|
411
|
+
template <class T>
|
412
|
+
V8_INLINE MaybeLocal<T> EscapeMaybe(MaybeLocal<T> value) {
|
413
|
+
return Escape(value.FromMaybe(Local<T>()));
|
414
|
+
}
|
415
|
+
|
416
|
+
EscapableHandleScope(const EscapableHandleScope&) = delete;
|
417
|
+
void operator=(const EscapableHandleScope&) = delete;
|
418
|
+
|
419
|
+
private:
|
420
|
+
// Declaring operator new and delete as deleted is not spec compliant.
|
421
|
+
// Therefore declare them private instead to disable dynamic alloc
|
422
|
+
void* operator new(size_t size);
|
423
|
+
void* operator new[](size_t size);
|
424
|
+
void operator delete(void*, size_t);
|
425
|
+
void operator delete[](void*, size_t);
|
426
|
+
|
427
|
+
internal::Address* Escape(internal::Address* escape_value);
|
428
|
+
internal::Address* escape_slot_;
|
429
|
+
};
|
430
|
+
|
431
|
+
/**
|
432
|
+
* A SealHandleScope acts like a handle scope in which no handle allocations
|
433
|
+
* are allowed. It can be useful for debugging handle leaks.
|
434
|
+
* Handles can be allocated within inner normal HandleScopes.
|
435
|
+
*/
|
436
|
+
class V8_EXPORT V8_NODISCARD SealHandleScope {
|
437
|
+
public:
|
438
|
+
explicit SealHandleScope(Isolate* isolate);
|
439
|
+
~SealHandleScope();
|
440
|
+
|
441
|
+
SealHandleScope(const SealHandleScope&) = delete;
|
442
|
+
void operator=(const SealHandleScope&) = delete;
|
443
|
+
|
444
|
+
private:
|
445
|
+
// Declaring operator new and delete as deleted is not spec compliant.
|
446
|
+
// Therefore declare them private instead to disable dynamic alloc
|
447
|
+
void* operator new(size_t size);
|
448
|
+
void* operator new[](size_t size);
|
449
|
+
void operator delete(void*, size_t);
|
450
|
+
void operator delete[](void*, size_t);
|
451
|
+
|
452
|
+
internal::Isolate* const isolate_;
|
453
|
+
internal::Address* prev_limit_;
|
454
|
+
int prev_sealed_level_;
|
455
|
+
};
|
456
|
+
|
457
|
+
} // namespace v8
|
458
|
+
|
459
|
+
#endif // INCLUDE_V8_LOCAL_HANDLE_H_
|
@@ -0,0 +1,148 @@
|
|
1
|
+
// Copyright 2021 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 INCLUDE_V8_LOCKER_H_
|
6
|
+
#define INCLUDE_V8_LOCKER_H_
|
7
|
+
|
8
|
+
#include "v8config.h" // NOLINT(build/include_directory)
|
9
|
+
|
10
|
+
namespace v8 {
|
11
|
+
|
12
|
+
namespace internal {
|
13
|
+
class Isolate;
|
14
|
+
} // namespace internal
|
15
|
+
|
16
|
+
class Isolate;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Multiple threads in V8 are allowed, but only one thread at a time is allowed
|
20
|
+
* to use any given V8 isolate, see the comments in the Isolate class. The
|
21
|
+
* definition of 'using a V8 isolate' includes accessing handles or holding onto
|
22
|
+
* object pointers obtained from V8 handles while in the particular V8 isolate.
|
23
|
+
* It is up to the user of V8 to ensure, perhaps with locking, that this
|
24
|
+
* constraint is not violated. In addition to any other synchronization
|
25
|
+
* mechanism that may be used, the v8::Locker and v8::Unlocker classes must be
|
26
|
+
* used to signal thread switches to V8.
|
27
|
+
*
|
28
|
+
* v8::Locker is a scoped lock object. While it's active, i.e. between its
|
29
|
+
* construction and destruction, the current thread is allowed to use the locked
|
30
|
+
* isolate. V8 guarantees that an isolate can be locked by at most one thread at
|
31
|
+
* any time. In other words, the scope of a v8::Locker is a critical section.
|
32
|
+
*
|
33
|
+
* Sample usage:
|
34
|
+
* \code
|
35
|
+
* ...
|
36
|
+
* {
|
37
|
+
* v8::Locker locker(isolate);
|
38
|
+
* v8::Isolate::Scope isolate_scope(isolate);
|
39
|
+
* ...
|
40
|
+
* // Code using V8 and isolate goes here.
|
41
|
+
* ...
|
42
|
+
* } // Destructor called here
|
43
|
+
* \endcode
|
44
|
+
*
|
45
|
+
* If you wish to stop using V8 in a thread A you can do this either by
|
46
|
+
* destroying the v8::Locker object as above or by constructing a v8::Unlocker
|
47
|
+
* object:
|
48
|
+
*
|
49
|
+
* \code
|
50
|
+
* {
|
51
|
+
* isolate->Exit();
|
52
|
+
* v8::Unlocker unlocker(isolate);
|
53
|
+
* ...
|
54
|
+
* // Code not using V8 goes here while V8 can run in another thread.
|
55
|
+
* ...
|
56
|
+
* } // Destructor called here.
|
57
|
+
* isolate->Enter();
|
58
|
+
* \endcode
|
59
|
+
*
|
60
|
+
* The Unlocker object is intended for use in a long-running callback from V8,
|
61
|
+
* where you want to release the V8 lock for other threads to use.
|
62
|
+
*
|
63
|
+
* The v8::Locker is a recursive lock, i.e. you can lock more than once in a
|
64
|
+
* given thread. This can be useful if you have code that can be called either
|
65
|
+
* from code that holds the lock or from code that does not. The Unlocker is
|
66
|
+
* not recursive so you can not have several Unlockers on the stack at once, and
|
67
|
+
* you cannot use an Unlocker in a thread that is not inside a Locker's scope.
|
68
|
+
*
|
69
|
+
* An unlocker will unlock several lockers if it has to and reinstate the
|
70
|
+
* correct depth of locking on its destruction, e.g.:
|
71
|
+
*
|
72
|
+
* \code
|
73
|
+
* // V8 not locked.
|
74
|
+
* {
|
75
|
+
* v8::Locker locker(isolate);
|
76
|
+
* Isolate::Scope isolate_scope(isolate);
|
77
|
+
* // V8 locked.
|
78
|
+
* {
|
79
|
+
* v8::Locker another_locker(isolate);
|
80
|
+
* // V8 still locked (2 levels).
|
81
|
+
* {
|
82
|
+
* isolate->Exit();
|
83
|
+
* v8::Unlocker unlocker(isolate);
|
84
|
+
* // V8 not locked.
|
85
|
+
* }
|
86
|
+
* isolate->Enter();
|
87
|
+
* // V8 locked again (2 levels).
|
88
|
+
* }
|
89
|
+
* // V8 still locked (1 level).
|
90
|
+
* }
|
91
|
+
* // V8 Now no longer locked.
|
92
|
+
* \endcode
|
93
|
+
*/
|
94
|
+
class V8_EXPORT Unlocker {
|
95
|
+
public:
|
96
|
+
/**
|
97
|
+
* Initialize Unlocker for a given Isolate.
|
98
|
+
*/
|
99
|
+
V8_INLINE explicit Unlocker(Isolate* isolate) { Initialize(isolate); }
|
100
|
+
|
101
|
+
~Unlocker();
|
102
|
+
|
103
|
+
private:
|
104
|
+
void Initialize(Isolate* isolate);
|
105
|
+
|
106
|
+
internal::Isolate* isolate_;
|
107
|
+
};
|
108
|
+
|
109
|
+
class V8_EXPORT Locker {
|
110
|
+
public:
|
111
|
+
/**
|
112
|
+
* Initialize Locker for a given Isolate.
|
113
|
+
*/
|
114
|
+
V8_INLINE explicit Locker(Isolate* isolate) { Initialize(isolate); }
|
115
|
+
|
116
|
+
~Locker();
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Returns whether or not the locker for a given isolate, is locked by the
|
120
|
+
* current thread.
|
121
|
+
*/
|
122
|
+
static bool IsLocked(Isolate* isolate);
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Returns whether any v8::Locker has ever been used in this process.
|
126
|
+
* TODO(cbruni, chromium:1240851): Fix locking checks on a per-thread basis.
|
127
|
+
* The current implementation is quite confusing and leads to unexpected
|
128
|
+
* results if anybody uses v8::Locker in the current process.
|
129
|
+
*/
|
130
|
+
static bool WasEverUsed();
|
131
|
+
V8_DEPRECATE_SOON("Use WasEverUsed instead")
|
132
|
+
static bool IsActive();
|
133
|
+
|
134
|
+
// Disallow copying and assigning.
|
135
|
+
Locker(const Locker&) = delete;
|
136
|
+
void operator=(const Locker&) = delete;
|
137
|
+
|
138
|
+
private:
|
139
|
+
void Initialize(Isolate* isolate);
|
140
|
+
|
141
|
+
bool has_lock_;
|
142
|
+
bool top_level_;
|
143
|
+
internal::Isolate* isolate_;
|
144
|
+
};
|
145
|
+
|
146
|
+
} // namespace v8
|
147
|
+
|
148
|
+
#endif // INCLUDE_V8_LOCKER_H_
|