node-linux-ppc64le 17.0.0 → 17.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/bin/node +0 -0
- package/include/node/node_version.h +1 -1
- package/include/node/v8-callbacks.h +374 -0
- package/include/node/v8-embedder-heap.h +238 -0
- package/include/node/v8-forward.h +79 -0
- package/include/node/v8-function-callback.h +475 -0
- package/include/node/v8-weak-callback-info.h +73 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
</tr>
|
|
9
9
|
<tr>
|
|
10
10
|
<td>
|
|
11
|
+
<a href="#17.0.1">17.0.1</a><br/>
|
|
11
12
|
<a href="#17.0.0">17.0.0</a><br/>
|
|
12
13
|
</td>
|
|
13
14
|
</tr>
|
|
@@ -32,6 +33,37 @@
|
|
|
32
33
|
* [io.js](CHANGELOG\_IOJS.md)
|
|
33
34
|
* [Archive](CHANGELOG\_ARCHIVE.md)
|
|
34
35
|
|
|
36
|
+
<a id="17.0.1"></a>
|
|
37
|
+
## 2021-10-20, Version 17.0.1 (Current), @targos
|
|
38
|
+
|
|
39
|
+
### Notable Changes
|
|
40
|
+
|
|
41
|
+
#### Fixed distribution for native addon builds
|
|
42
|
+
|
|
43
|
+
This release fixes an issue introduced in Node.js v17.0.0, where some V8 headers
|
|
44
|
+
were missing from the distributed tarball, making it impossible to build native
|
|
45
|
+
addons. These headers are now included. [#40526](https://github.com/nodejs/node/pull/40526)
|
|
46
|
+
|
|
47
|
+
#### Fixed stream issues
|
|
48
|
+
|
|
49
|
+
* Fixed a regression in `stream.promises.pipeline`, which was introduced in version
|
|
50
|
+
16.10.0, is fixed. It is now possible again to pass an array of streams to the
|
|
51
|
+
function. [#40193](https://github.com/nodejs/node/pull/40193)
|
|
52
|
+
* Fixed a bug in `stream.Duplex.from`, which didn't work properly when an async
|
|
53
|
+
generator function was passed to it. [#40499](https://github.com/nodejs/node/pull/40499)
|
|
54
|
+
|
|
55
|
+
### Commits
|
|
56
|
+
|
|
57
|
+
* [[`3f033556c3`](https://github.com/nodejs/node/commit/3f033556c3)] - **build**: include missing V8 headers in distribution (Michaël Zasso) [#40526](https://github.com/nodejs/node/pull/40526)
|
|
58
|
+
* [[`adbd92ef1d`](https://github.com/nodejs/node/commit/adbd92ef1d)] - **crypto**: avoid double free (Michael Dawson) [#40380](https://github.com/nodejs/node/pull/40380)
|
|
59
|
+
* [[`8dce85aadc`](https://github.com/nodejs/node/commit/8dce85aadc)] - **doc**: format doc/api/\*.md with markdown formatter (Rich Trott) [#40403](https://github.com/nodejs/node/pull/40403)
|
|
60
|
+
* [[`977016a72f`](https://github.com/nodejs/node/commit/977016a72f)] - **doc**: specify that maxFreeSockets is per host (Luigi Pinca) [#40483](https://github.com/nodejs/node/pull/40483)
|
|
61
|
+
* [[`f9f2442739`](https://github.com/nodejs/node/commit/f9f2442739)] - **src**: add missing inialization in agent.h (Michael Dawson) [#40379](https://github.com/nodejs/node/pull/40379)
|
|
62
|
+
* [[`111f0bd9b6`](https://github.com/nodejs/node/commit/111f0bd9b6)] - **stream**: fix fromAsyncGen (Robert Nagy) [#40499](https://github.com/nodejs/node/pull/40499)
|
|
63
|
+
* [[`b84f101049`](https://github.com/nodejs/node/commit/b84f101049)] - **stream**: support array of streams in promises pipeline (Mestery) [#40193](https://github.com/nodejs/node/pull/40193)
|
|
64
|
+
* [[`3f7c503b69`](https://github.com/nodejs/node/commit/3f7c503b69)] - **test**: adjust CLI flags test to ignore blank lines in doc (Rich Trott) [#40403](https://github.com/nodejs/node/pull/40403)
|
|
65
|
+
* [[`7c42d9fcc6`](https://github.com/nodejs/node/commit/7c42d9fcc6)] - **test**: split test-crypto-dh.js (Joyee Cheung) [#40451](https://github.com/nodejs/node/pull/40451)
|
|
66
|
+
|
|
35
67
|
<a id="17.0.0"></a>
|
|
36
68
|
## 2021-10-19, Version 17.0.0 (Current), @BethGriggs
|
|
37
69
|
|
package/bin/node
CHANGED
|
Binary file
|
|
@@ -0,0 +1,374 @@
|
|
|
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_ISOLATE_CALLBACKS_H_
|
|
6
|
+
#define INCLUDE_V8_ISOLATE_CALLBACKS_H_
|
|
7
|
+
|
|
8
|
+
#include <stddef.h>
|
|
9
|
+
|
|
10
|
+
#include <string>
|
|
11
|
+
|
|
12
|
+
#include "cppgc/common.h"
|
|
13
|
+
#include "v8-data.h" // NOLINT(build/include_directory)
|
|
14
|
+
#include "v8-local-handle.h" // NOLINT(build/include_directory)
|
|
15
|
+
#include "v8config.h" // NOLINT(build/include_directory)
|
|
16
|
+
|
|
17
|
+
#if defined(V8_OS_WIN)
|
|
18
|
+
struct _EXCEPTION_POINTERS;
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
namespace v8 {
|
|
22
|
+
|
|
23
|
+
template <typename T>
|
|
24
|
+
class FunctionCallbackInfo;
|
|
25
|
+
class Isolate;
|
|
26
|
+
class Message;
|
|
27
|
+
class Module;
|
|
28
|
+
class Object;
|
|
29
|
+
class Promise;
|
|
30
|
+
class ScriptOrModule;
|
|
31
|
+
class String;
|
|
32
|
+
class UnboundScript;
|
|
33
|
+
class Value;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A JIT code event is issued each time code is added, moved or removed.
|
|
37
|
+
*
|
|
38
|
+
* \note removal events are not currently issued.
|
|
39
|
+
*/
|
|
40
|
+
struct JitCodeEvent {
|
|
41
|
+
enum EventType {
|
|
42
|
+
CODE_ADDED,
|
|
43
|
+
CODE_MOVED,
|
|
44
|
+
CODE_REMOVED,
|
|
45
|
+
CODE_ADD_LINE_POS_INFO,
|
|
46
|
+
CODE_START_LINE_INFO_RECORDING,
|
|
47
|
+
CODE_END_LINE_INFO_RECORDING
|
|
48
|
+
};
|
|
49
|
+
// Definition of the code position type. The "POSITION" type means the place
|
|
50
|
+
// in the source code which are of interest when making stack traces to
|
|
51
|
+
// pin-point the source location of a stack frame as close as possible.
|
|
52
|
+
// The "STATEMENT_POSITION" means the place at the beginning of each
|
|
53
|
+
// statement, and is used to indicate possible break locations.
|
|
54
|
+
enum PositionType { POSITION, STATEMENT_POSITION };
|
|
55
|
+
|
|
56
|
+
// There are three different kinds of CodeType, one for JIT code generated
|
|
57
|
+
// by the optimizing compiler, one for byte code generated for the
|
|
58
|
+
// interpreter, and one for code generated from Wasm. For JIT_CODE and
|
|
59
|
+
// WASM_CODE, |code_start| points to the beginning of jitted assembly code,
|
|
60
|
+
// while for BYTE_CODE events, |code_start| points to the first bytecode of
|
|
61
|
+
// the interpreted function.
|
|
62
|
+
enum CodeType { BYTE_CODE, JIT_CODE, WASM_CODE };
|
|
63
|
+
|
|
64
|
+
// Type of event.
|
|
65
|
+
EventType type;
|
|
66
|
+
CodeType code_type;
|
|
67
|
+
// Start of the instructions.
|
|
68
|
+
void* code_start;
|
|
69
|
+
// Size of the instructions.
|
|
70
|
+
size_t code_len;
|
|
71
|
+
// Script info for CODE_ADDED event.
|
|
72
|
+
Local<UnboundScript> script;
|
|
73
|
+
// User-defined data for *_LINE_INFO_* event. It's used to hold the source
|
|
74
|
+
// code line information which is returned from the
|
|
75
|
+
// CODE_START_LINE_INFO_RECORDING event. And it's passed to subsequent
|
|
76
|
+
// CODE_ADD_LINE_POS_INFO and CODE_END_LINE_INFO_RECORDING events.
|
|
77
|
+
void* user_data;
|
|
78
|
+
|
|
79
|
+
struct name_t {
|
|
80
|
+
// Name of the object associated with the code, note that the string is not
|
|
81
|
+
// zero-terminated.
|
|
82
|
+
const char* str;
|
|
83
|
+
// Number of chars in str.
|
|
84
|
+
size_t len;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
struct line_info_t {
|
|
88
|
+
// PC offset
|
|
89
|
+
size_t offset;
|
|
90
|
+
// Code position
|
|
91
|
+
size_t pos;
|
|
92
|
+
// The position type.
|
|
93
|
+
PositionType position_type;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
struct wasm_source_info_t {
|
|
97
|
+
// Source file name.
|
|
98
|
+
const char* filename;
|
|
99
|
+
// Length of filename.
|
|
100
|
+
size_t filename_size;
|
|
101
|
+
// Line number table, which maps offsets of JITted code to line numbers of
|
|
102
|
+
// source file.
|
|
103
|
+
const line_info_t* line_number_table;
|
|
104
|
+
// Number of entries in the line number table.
|
|
105
|
+
size_t line_number_table_size;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
wasm_source_info_t* wasm_source_info;
|
|
109
|
+
|
|
110
|
+
union {
|
|
111
|
+
// Only valid for CODE_ADDED.
|
|
112
|
+
struct name_t name;
|
|
113
|
+
|
|
114
|
+
// Only valid for CODE_ADD_LINE_POS_INFO
|
|
115
|
+
struct line_info_t line_info;
|
|
116
|
+
|
|
117
|
+
// New location of instructions. Only valid for CODE_MOVED.
|
|
118
|
+
void* new_code_start;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
Isolate* isolate;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Option flags passed to the SetJitCodeEventHandler function.
|
|
126
|
+
*/
|
|
127
|
+
enum JitCodeEventOptions {
|
|
128
|
+
kJitCodeEventDefault = 0,
|
|
129
|
+
// Generate callbacks for already existent code.
|
|
130
|
+
kJitCodeEventEnumExisting = 1
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Callback function passed to SetJitCodeEventHandler.
|
|
135
|
+
*
|
|
136
|
+
* \param event code add, move or removal event.
|
|
137
|
+
*/
|
|
138
|
+
using JitCodeEventHandler = void (*)(const JitCodeEvent* event);
|
|
139
|
+
|
|
140
|
+
// --- Garbage Collection Callbacks ---
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Applications can register callback functions which will be called before and
|
|
144
|
+
* after certain garbage collection operations. Allocations are not allowed in
|
|
145
|
+
* the callback functions, you therefore cannot manipulate objects (set or
|
|
146
|
+
* delete properties for example) since it is possible such operations will
|
|
147
|
+
* result in the allocation of objects.
|
|
148
|
+
*/
|
|
149
|
+
enum GCType {
|
|
150
|
+
kGCTypeScavenge = 1 << 0,
|
|
151
|
+
kGCTypeMarkSweepCompact = 1 << 1,
|
|
152
|
+
kGCTypeIncrementalMarking = 1 << 2,
|
|
153
|
+
kGCTypeProcessWeakCallbacks = 1 << 3,
|
|
154
|
+
kGCTypeAll = kGCTypeScavenge | kGCTypeMarkSweepCompact |
|
|
155
|
+
kGCTypeIncrementalMarking | kGCTypeProcessWeakCallbacks
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* GCCallbackFlags is used to notify additional information about the GC
|
|
160
|
+
* callback.
|
|
161
|
+
* - kGCCallbackFlagConstructRetainedObjectInfos: The GC callback is for
|
|
162
|
+
* constructing retained object infos.
|
|
163
|
+
* - kGCCallbackFlagForced: The GC callback is for a forced GC for testing.
|
|
164
|
+
* - kGCCallbackFlagSynchronousPhantomCallbackProcessing: The GC callback
|
|
165
|
+
* is called synchronously without getting posted to an idle task.
|
|
166
|
+
* - kGCCallbackFlagCollectAllAvailableGarbage: The GC callback is called
|
|
167
|
+
* in a phase where V8 is trying to collect all available garbage
|
|
168
|
+
* (e.g., handling a low memory notification).
|
|
169
|
+
* - kGCCallbackScheduleIdleGarbageCollection: The GC callback is called to
|
|
170
|
+
* trigger an idle garbage collection.
|
|
171
|
+
*/
|
|
172
|
+
enum GCCallbackFlags {
|
|
173
|
+
kNoGCCallbackFlags = 0,
|
|
174
|
+
kGCCallbackFlagConstructRetainedObjectInfos = 1 << 1,
|
|
175
|
+
kGCCallbackFlagForced = 1 << 2,
|
|
176
|
+
kGCCallbackFlagSynchronousPhantomCallbackProcessing = 1 << 3,
|
|
177
|
+
kGCCallbackFlagCollectAllAvailableGarbage = 1 << 4,
|
|
178
|
+
kGCCallbackFlagCollectAllExternalMemory = 1 << 5,
|
|
179
|
+
kGCCallbackScheduleIdleGarbageCollection = 1 << 6,
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
using GCCallback = void (*)(GCType type, GCCallbackFlags flags);
|
|
183
|
+
|
|
184
|
+
using InterruptCallback = void (*)(Isolate* isolate, void* data);
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* This callback is invoked when the heap size is close to the heap limit and
|
|
188
|
+
* V8 is likely to abort with out-of-memory error.
|
|
189
|
+
* The callback can extend the heap limit by returning a value that is greater
|
|
190
|
+
* than the current_heap_limit. The initial heap limit is the limit that was
|
|
191
|
+
* set after heap setup.
|
|
192
|
+
*/
|
|
193
|
+
using NearHeapLimitCallback = size_t (*)(void* data, size_t current_heap_limit,
|
|
194
|
+
size_t initial_heap_limit);
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Callback function passed to SetUnhandledExceptionCallback.
|
|
198
|
+
*/
|
|
199
|
+
#if defined(V8_OS_WIN)
|
|
200
|
+
using UnhandledExceptionCallback =
|
|
201
|
+
int (*)(_EXCEPTION_POINTERS* exception_pointers);
|
|
202
|
+
#endif
|
|
203
|
+
|
|
204
|
+
// --- Counters Callbacks ---
|
|
205
|
+
|
|
206
|
+
using CounterLookupCallback = int* (*)(const char* name);
|
|
207
|
+
|
|
208
|
+
using CreateHistogramCallback = void* (*)(const char* name, int min, int max,
|
|
209
|
+
size_t buckets);
|
|
210
|
+
|
|
211
|
+
using AddHistogramSampleCallback = void (*)(void* histogram, int sample);
|
|
212
|
+
|
|
213
|
+
// --- Exceptions ---
|
|
214
|
+
|
|
215
|
+
using FatalErrorCallback = void (*)(const char* location, const char* message);
|
|
216
|
+
|
|
217
|
+
using OOMErrorCallback = void (*)(const char* location, bool is_heap_oom);
|
|
218
|
+
|
|
219
|
+
using MessageCallback = void (*)(Local<Message> message, Local<Value> data);
|
|
220
|
+
|
|
221
|
+
// --- Tracing ---
|
|
222
|
+
|
|
223
|
+
enum LogEventStatus : int { kStart = 0, kEnd = 1, kStamp = 2 };
|
|
224
|
+
using LogEventCallback = void (*)(const char* name,
|
|
225
|
+
int /* LogEventStatus */ status);
|
|
226
|
+
|
|
227
|
+
// --- Crashkeys Callback ---
|
|
228
|
+
enum class CrashKeyId {
|
|
229
|
+
kIsolateAddress,
|
|
230
|
+
kReadonlySpaceFirstPageAddress,
|
|
231
|
+
kMapSpaceFirstPageAddress,
|
|
232
|
+
kCodeSpaceFirstPageAddress,
|
|
233
|
+
kDumpType,
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
using AddCrashKeyCallback = void (*)(CrashKeyId id, const std::string& value);
|
|
237
|
+
|
|
238
|
+
// --- Enter/Leave Script Callback ---
|
|
239
|
+
using BeforeCallEnteredCallback = void (*)(Isolate*);
|
|
240
|
+
using CallCompletedCallback = void (*)(Isolate*);
|
|
241
|
+
|
|
242
|
+
// --- AllowCodeGenerationFromStrings callbacks ---
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Callback to check if code generation from strings is allowed. See
|
|
246
|
+
* Context::AllowCodeGenerationFromStrings.
|
|
247
|
+
*/
|
|
248
|
+
using AllowCodeGenerationFromStringsCallback = bool (*)(Local<Context> context,
|
|
249
|
+
Local<String> source);
|
|
250
|
+
|
|
251
|
+
struct ModifyCodeGenerationFromStringsResult {
|
|
252
|
+
// If true, proceed with the codegen algorithm. Otherwise, block it.
|
|
253
|
+
bool codegen_allowed = false;
|
|
254
|
+
// Overwrite the original source with this string, if present.
|
|
255
|
+
// Use the original source if empty.
|
|
256
|
+
// This field is considered only if codegen_allowed is true.
|
|
257
|
+
MaybeLocal<String> modified_source;
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Access type specification.
|
|
262
|
+
*/
|
|
263
|
+
enum AccessType {
|
|
264
|
+
ACCESS_GET,
|
|
265
|
+
ACCESS_SET,
|
|
266
|
+
ACCESS_HAS,
|
|
267
|
+
ACCESS_DELETE,
|
|
268
|
+
ACCESS_KEYS
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// --- Failed Access Check Callback ---
|
|
272
|
+
|
|
273
|
+
using FailedAccessCheckCallback = void (*)(Local<Object> target,
|
|
274
|
+
AccessType type, Local<Value> data);
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Callback to check if codegen is allowed from a source object, and convert
|
|
278
|
+
* the source to string if necessary. See: ModifyCodeGenerationFromStrings.
|
|
279
|
+
*/
|
|
280
|
+
using ModifyCodeGenerationFromStringsCallback =
|
|
281
|
+
ModifyCodeGenerationFromStringsResult (*)(Local<Context> context,
|
|
282
|
+
Local<Value> source);
|
|
283
|
+
using ModifyCodeGenerationFromStringsCallback2 =
|
|
284
|
+
ModifyCodeGenerationFromStringsResult (*)(Local<Context> context,
|
|
285
|
+
Local<Value> source,
|
|
286
|
+
bool is_code_like);
|
|
287
|
+
|
|
288
|
+
// --- WebAssembly compilation callbacks ---
|
|
289
|
+
using ExtensionCallback = bool (*)(const FunctionCallbackInfo<Value>&);
|
|
290
|
+
|
|
291
|
+
using AllowWasmCodeGenerationCallback = bool (*)(Local<Context> context,
|
|
292
|
+
Local<String> source);
|
|
293
|
+
|
|
294
|
+
// --- Callback for APIs defined on v8-supported objects, but implemented
|
|
295
|
+
// by the embedder. Example: WebAssembly.{compile|instantiate}Streaming ---
|
|
296
|
+
using ApiImplementationCallback = void (*)(const FunctionCallbackInfo<Value>&);
|
|
297
|
+
|
|
298
|
+
// --- Callback for WebAssembly.compileStreaming ---
|
|
299
|
+
using WasmStreamingCallback = void (*)(const FunctionCallbackInfo<Value>&);
|
|
300
|
+
|
|
301
|
+
// --- Callback for loading source map file for Wasm profiling support
|
|
302
|
+
using WasmLoadSourceMapCallback = Local<String> (*)(Isolate* isolate,
|
|
303
|
+
const char* name);
|
|
304
|
+
|
|
305
|
+
// --- Callback for checking if WebAssembly Simd is enabled ---
|
|
306
|
+
using WasmSimdEnabledCallback = bool (*)(Local<Context> context);
|
|
307
|
+
|
|
308
|
+
// --- Callback for checking if WebAssembly exceptions are enabled ---
|
|
309
|
+
using WasmExceptionsEnabledCallback = bool (*)(Local<Context> context);
|
|
310
|
+
|
|
311
|
+
// --- Callback for checking if the SharedArrayBuffer constructor is enabled ---
|
|
312
|
+
using SharedArrayBufferConstructorEnabledCallback =
|
|
313
|
+
bool (*)(Local<Context> context);
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* HostImportModuleDynamicallyWithImportAssertionsCallback is called when we
|
|
317
|
+
* require the embedder to load a module. This is used as part of the dynamic
|
|
318
|
+
* import syntax.
|
|
319
|
+
*
|
|
320
|
+
* The referrer contains metadata about the script/module that calls
|
|
321
|
+
* import.
|
|
322
|
+
*
|
|
323
|
+
* The specifier is the name of the module that should be imported.
|
|
324
|
+
*
|
|
325
|
+
* The import_assertions are import assertions for this request in the form:
|
|
326
|
+
* [key1, value1, key2, value2, ...] where the keys and values are of type
|
|
327
|
+
* v8::String. Note, unlike the FixedArray passed to ResolveModuleCallback and
|
|
328
|
+
* returned from ModuleRequest::GetImportAssertions(), this array does not
|
|
329
|
+
* contain the source Locations of the assertions.
|
|
330
|
+
*
|
|
331
|
+
* The embedder must compile, instantiate, evaluate the Module, and
|
|
332
|
+
* obtain its namespace object.
|
|
333
|
+
*
|
|
334
|
+
* The Promise returned from this function is forwarded to userland
|
|
335
|
+
* JavaScript. The embedder must resolve this promise with the module
|
|
336
|
+
* namespace object. In case of an exception, the embedder must reject
|
|
337
|
+
* this promise with the exception. If the promise creation itself
|
|
338
|
+
* fails (e.g. due to stack overflow), the embedder must propagate
|
|
339
|
+
* that exception by returning an empty MaybeLocal.
|
|
340
|
+
*/
|
|
341
|
+
using HostImportModuleDynamicallyWithImportAssertionsCallback =
|
|
342
|
+
MaybeLocal<Promise> (*)(Local<Context> context,
|
|
343
|
+
Local<ScriptOrModule> referrer,
|
|
344
|
+
Local<String> specifier,
|
|
345
|
+
Local<FixedArray> import_assertions);
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* HostInitializeImportMetaObjectCallback is called the first time import.meta
|
|
349
|
+
* is accessed for a module. Subsequent access will reuse the same value.
|
|
350
|
+
*
|
|
351
|
+
* The method combines two implementation-defined abstract operations into one:
|
|
352
|
+
* HostGetImportMetaProperties and HostFinalizeImportMeta.
|
|
353
|
+
*
|
|
354
|
+
* The embedder should use v8::Object::CreateDataProperty to add properties on
|
|
355
|
+
* the meta object.
|
|
356
|
+
*/
|
|
357
|
+
using HostInitializeImportMetaObjectCallback = void (*)(Local<Context> context,
|
|
358
|
+
Local<Module> module,
|
|
359
|
+
Local<Object> meta);
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* PrepareStackTraceCallback is called when the stack property of an error is
|
|
363
|
+
* first accessed. The return value will be used as the stack value. If this
|
|
364
|
+
* callback is registed, the |Error.prepareStackTrace| API will be disabled.
|
|
365
|
+
* |sites| is an array of call sites, specified in
|
|
366
|
+
* https://v8.dev/docs/stack-trace-api
|
|
367
|
+
*/
|
|
368
|
+
using PrepareStackTraceCallback = MaybeLocal<Value> (*)(Local<Context> context,
|
|
369
|
+
Local<Value> error,
|
|
370
|
+
Local<Array> sites);
|
|
371
|
+
|
|
372
|
+
} // namespace v8
|
|
373
|
+
|
|
374
|
+
#endif // INCLUDE_V8_ISOLATE_CALLBACKS_H_
|
|
@@ -0,0 +1,238 @@
|
|
|
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_EMBEDDER_HEAP_H_
|
|
6
|
+
#define INCLUDE_V8_EMBEDDER_HEAP_H_
|
|
7
|
+
|
|
8
|
+
#include <stddef.h>
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
|
|
11
|
+
#include <utility>
|
|
12
|
+
#include <vector>
|
|
13
|
+
|
|
14
|
+
#include "cppgc/common.h"
|
|
15
|
+
#include "v8-local-handle.h" // NOLINT(build/include_directory)
|
|
16
|
+
#include "v8-traced-handle.h" // NOLINT(build/include_directory)
|
|
17
|
+
#include "v8config.h" // NOLINT(build/include_directory)
|
|
18
|
+
|
|
19
|
+
namespace v8 {
|
|
20
|
+
|
|
21
|
+
class Data;
|
|
22
|
+
class Isolate;
|
|
23
|
+
class Value;
|
|
24
|
+
|
|
25
|
+
namespace internal {
|
|
26
|
+
class LocalEmbedderHeapTracer;
|
|
27
|
+
} // namespace internal
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Handler for embedder roots on non-unified heap garbage collections.
|
|
31
|
+
*/
|
|
32
|
+
class V8_EXPORT EmbedderRootsHandler {
|
|
33
|
+
public:
|
|
34
|
+
virtual ~EmbedderRootsHandler() = default;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns true if the TracedGlobal handle should be considered as root for
|
|
38
|
+
* the currently running non-tracing garbage collection and false otherwise.
|
|
39
|
+
* The default implementation will keep all TracedGlobal references as roots.
|
|
40
|
+
*
|
|
41
|
+
* If this returns false, then V8 may decide that the object referred to by
|
|
42
|
+
* such a handle is reclaimed. In that case:
|
|
43
|
+
* - No action is required if handles are used with destructors, i.e., by just
|
|
44
|
+
* using |TracedGlobal|.
|
|
45
|
+
* - When run without destructors, i.e., by using |TracedReference|, V8 calls
|
|
46
|
+
* |ResetRoot|.
|
|
47
|
+
*
|
|
48
|
+
* Note that the |handle| is different from the handle that the embedder holds
|
|
49
|
+
* for retaining the object. The embedder may use |WrapperClassId()| to
|
|
50
|
+
* distinguish cases where it wants handles to be treated as roots from not
|
|
51
|
+
* being treated as roots.
|
|
52
|
+
*/
|
|
53
|
+
virtual bool IsRoot(const v8::TracedReference<v8::Value>& handle) = 0;
|
|
54
|
+
virtual bool IsRoot(const v8::TracedGlobal<v8::Value>& handle) = 0;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Used in combination with |IsRoot|. Called by V8 when an
|
|
58
|
+
* object that is backed by a handle is reclaimed by a non-tracing garbage
|
|
59
|
+
* collection. It is up to the embedder to reset the original handle.
|
|
60
|
+
*
|
|
61
|
+
* Note that the |handle| is different from the handle that the embedder holds
|
|
62
|
+
* for retaining the object. It is up to the embedder to find the original
|
|
63
|
+
* handle via the object or class id.
|
|
64
|
+
*/
|
|
65
|
+
virtual void ResetRoot(const v8::TracedReference<v8::Value>& handle) = 0;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Interface for tracing through the embedder heap. During a V8 garbage
|
|
70
|
+
* collection, V8 collects hidden fields of all potential wrappers, and at the
|
|
71
|
+
* end of its marking phase iterates the collection and asks the embedder to
|
|
72
|
+
* trace through its heap and use reporter to report each JavaScript object
|
|
73
|
+
* reachable from any of the given wrappers.
|
|
74
|
+
*/
|
|
75
|
+
class V8_EXPORT EmbedderHeapTracer {
|
|
76
|
+
public:
|
|
77
|
+
using EmbedderStackState = cppgc::EmbedderStackState;
|
|
78
|
+
|
|
79
|
+
enum TraceFlags : uint64_t {
|
|
80
|
+
kNoFlags = 0,
|
|
81
|
+
kReduceMemory = 1 << 0,
|
|
82
|
+
kForced = 1 << 2,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Interface for iterating through TracedGlobal handles.
|
|
87
|
+
*/
|
|
88
|
+
class V8_EXPORT TracedGlobalHandleVisitor {
|
|
89
|
+
public:
|
|
90
|
+
virtual ~TracedGlobalHandleVisitor() = default;
|
|
91
|
+
virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& handle) {}
|
|
92
|
+
virtual void VisitTracedReference(const TracedReference<Value>& handle) {}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Summary of a garbage collection cycle. See |TraceEpilogue| on how the
|
|
97
|
+
* summary is reported.
|
|
98
|
+
*/
|
|
99
|
+
struct TraceSummary {
|
|
100
|
+
/**
|
|
101
|
+
* Time spent managing the retained memory in milliseconds. This can e.g.
|
|
102
|
+
* include the time tracing through objects in the embedder.
|
|
103
|
+
*/
|
|
104
|
+
double time = 0.0;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Memory retained by the embedder through the |EmbedderHeapTracer|
|
|
108
|
+
* mechanism in bytes.
|
|
109
|
+
*/
|
|
110
|
+
size_t allocated_size = 0;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
virtual ~EmbedderHeapTracer() = default;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Iterates all TracedGlobal handles created for the v8::Isolate the tracer is
|
|
117
|
+
* attached to.
|
|
118
|
+
*/
|
|
119
|
+
void IterateTracedGlobalHandles(TracedGlobalHandleVisitor* visitor);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Called by the embedder to set the start of the stack which is e.g. used by
|
|
123
|
+
* V8 to determine whether handles are used from stack or heap.
|
|
124
|
+
*/
|
|
125
|
+
void SetStackStart(void* stack_start);
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Called by the embedder to notify V8 of an empty execution stack.
|
|
129
|
+
*/
|
|
130
|
+
V8_DEPRECATE_SOON(
|
|
131
|
+
"This call only optimized internal caches which V8 is able to figure out "
|
|
132
|
+
"on its own now.")
|
|
133
|
+
void NotifyEmptyEmbedderStack();
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Called by v8 to register internal fields of found wrappers.
|
|
137
|
+
*
|
|
138
|
+
* The embedder is expected to store them somewhere and trace reachable
|
|
139
|
+
* wrappers from them when called through |AdvanceTracing|.
|
|
140
|
+
*/
|
|
141
|
+
virtual void RegisterV8References(
|
|
142
|
+
const std::vector<std::pair<void*, void*>>& embedder_fields) = 0;
|
|
143
|
+
|
|
144
|
+
void RegisterEmbedderReference(const BasicTracedReference<v8::Data>& ref);
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Called at the beginning of a GC cycle.
|
|
148
|
+
*/
|
|
149
|
+
virtual void TracePrologue(TraceFlags flags) {}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Called to advance tracing in the embedder.
|
|
153
|
+
*
|
|
154
|
+
* The embedder is expected to trace its heap starting from wrappers reported
|
|
155
|
+
* by RegisterV8References method, and report back all reachable wrappers.
|
|
156
|
+
* Furthermore, the embedder is expected to stop tracing by the given
|
|
157
|
+
* deadline. A deadline of infinity means that tracing should be finished.
|
|
158
|
+
*
|
|
159
|
+
* Returns |true| if tracing is done, and false otherwise.
|
|
160
|
+
*/
|
|
161
|
+
virtual bool AdvanceTracing(double deadline_in_ms) = 0;
|
|
162
|
+
|
|
163
|
+
/*
|
|
164
|
+
* Returns true if there no more tracing work to be done (see AdvanceTracing)
|
|
165
|
+
* and false otherwise.
|
|
166
|
+
*/
|
|
167
|
+
virtual bool IsTracingDone() = 0;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Called at the end of a GC cycle.
|
|
171
|
+
*
|
|
172
|
+
* Note that allocation is *not* allowed within |TraceEpilogue|. Can be
|
|
173
|
+
* overriden to fill a |TraceSummary| that is used by V8 to schedule future
|
|
174
|
+
* garbage collections.
|
|
175
|
+
*/
|
|
176
|
+
virtual void TraceEpilogue(TraceSummary* trace_summary) {}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Called upon entering the final marking pause. No more incremental marking
|
|
180
|
+
* steps will follow this call.
|
|
181
|
+
*/
|
|
182
|
+
virtual void EnterFinalPause(EmbedderStackState stack_state) = 0;
|
|
183
|
+
|
|
184
|
+
/*
|
|
185
|
+
* Called by the embedder to request immediate finalization of the currently
|
|
186
|
+
* running tracing phase that has been started with TracePrologue and not
|
|
187
|
+
* yet finished with TraceEpilogue.
|
|
188
|
+
*
|
|
189
|
+
* Will be a noop when currently not in tracing.
|
|
190
|
+
*
|
|
191
|
+
* This is an experimental feature.
|
|
192
|
+
*/
|
|
193
|
+
void FinalizeTracing();
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* See documentation on EmbedderRootsHandler.
|
|
197
|
+
*/
|
|
198
|
+
virtual bool IsRootForNonTracingGC(
|
|
199
|
+
const v8::TracedReference<v8::Value>& handle);
|
|
200
|
+
virtual bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle);
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* See documentation on EmbedderRootsHandler.
|
|
204
|
+
*/
|
|
205
|
+
virtual void ResetHandleInNonTracingGC(
|
|
206
|
+
const v8::TracedReference<v8::Value>& handle);
|
|
207
|
+
|
|
208
|
+
/*
|
|
209
|
+
* Called by the embedder to immediately perform a full garbage collection.
|
|
210
|
+
*
|
|
211
|
+
* Should only be used in testing code.
|
|
212
|
+
*/
|
|
213
|
+
void GarbageCollectionForTesting(EmbedderStackState stack_state);
|
|
214
|
+
|
|
215
|
+
/*
|
|
216
|
+
* Called by the embedder to signal newly allocated or freed memory. Not bound
|
|
217
|
+
* to tracing phases. Embedders should trade off when increments are reported
|
|
218
|
+
* as V8 may consult global heuristics on whether to trigger garbage
|
|
219
|
+
* collection on this change.
|
|
220
|
+
*/
|
|
221
|
+
void IncreaseAllocatedSize(size_t bytes);
|
|
222
|
+
void DecreaseAllocatedSize(size_t bytes);
|
|
223
|
+
|
|
224
|
+
/*
|
|
225
|
+
* Returns the v8::Isolate this tracer is attached too and |nullptr| if it
|
|
226
|
+
* is not attached to any v8::Isolate.
|
|
227
|
+
*/
|
|
228
|
+
v8::Isolate* isolate() const { return isolate_; }
|
|
229
|
+
|
|
230
|
+
protected:
|
|
231
|
+
v8::Isolate* isolate_ = nullptr;
|
|
232
|
+
|
|
233
|
+
friend class internal::LocalEmbedderHeapTracer;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
} // namespace v8
|
|
237
|
+
|
|
238
|
+
#endif // INCLUDE_V8_EMBEDDER_HEAP_H_
|
|
@@ -0,0 +1,79 @@
|
|
|
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_HANDLES_H_
|
|
6
|
+
#define INCLUDE_V8_LOCAL_HANDLES_H_
|
|
7
|
+
|
|
8
|
+
// This header is intended to be used by headers that pass around V8 types,
|
|
9
|
+
// either by pointer or using Local<Type>. The full definitions can be included
|
|
10
|
+
// either via v8.h or the more fine-grained headers.
|
|
11
|
+
|
|
12
|
+
#include "v8-local-handle.h" // NOLINT(build/include_directory)
|
|
13
|
+
|
|
14
|
+
namespace v8 {
|
|
15
|
+
|
|
16
|
+
class AccessorSignature;
|
|
17
|
+
class Array;
|
|
18
|
+
class ArrayBuffer;
|
|
19
|
+
class ArrayBufferView;
|
|
20
|
+
class BigInt;
|
|
21
|
+
class BigInt64Array;
|
|
22
|
+
class BigIntObject;
|
|
23
|
+
class BigUint64Array;
|
|
24
|
+
class Boolean;
|
|
25
|
+
class BooleanObject;
|
|
26
|
+
class Context;
|
|
27
|
+
class DataView;
|
|
28
|
+
class Data;
|
|
29
|
+
class Date;
|
|
30
|
+
class External;
|
|
31
|
+
class FixedArray;
|
|
32
|
+
class Float32Array;
|
|
33
|
+
class Float64Array;
|
|
34
|
+
class Function;
|
|
35
|
+
template <class F>
|
|
36
|
+
class FunctionCallbackInfo;
|
|
37
|
+
class FunctionTemplate;
|
|
38
|
+
class Int16Array;
|
|
39
|
+
class Int32;
|
|
40
|
+
class Int32Array;
|
|
41
|
+
class Int8Array;
|
|
42
|
+
class Integer;
|
|
43
|
+
class Isolate;
|
|
44
|
+
class Map;
|
|
45
|
+
class Module;
|
|
46
|
+
class Name;
|
|
47
|
+
class Number;
|
|
48
|
+
class NumberObject;
|
|
49
|
+
class Object;
|
|
50
|
+
class ObjectTemplate;
|
|
51
|
+
class Platform;
|
|
52
|
+
class Primitive;
|
|
53
|
+
class Private;
|
|
54
|
+
class Promise;
|
|
55
|
+
class Proxy;
|
|
56
|
+
class RegExp;
|
|
57
|
+
class Script;
|
|
58
|
+
class Set;
|
|
59
|
+
class SharedArrayBuffer;
|
|
60
|
+
class Signature;
|
|
61
|
+
class String;
|
|
62
|
+
class StringObject;
|
|
63
|
+
class Symbol;
|
|
64
|
+
class SymbolObject;
|
|
65
|
+
class Template;
|
|
66
|
+
class TypedArray;
|
|
67
|
+
class Uint16Array;
|
|
68
|
+
class Uint32;
|
|
69
|
+
class Uint32Array;
|
|
70
|
+
class Uint8Array;
|
|
71
|
+
class Uint8ClampedArray;
|
|
72
|
+
class UnboundModuleScript;
|
|
73
|
+
class Value;
|
|
74
|
+
class WasmMemoryObject;
|
|
75
|
+
class WasmModuleObject;
|
|
76
|
+
|
|
77
|
+
} // namespace v8
|
|
78
|
+
|
|
79
|
+
#endif // INCLUDE_V8_LOCAL_HANDLES_H_
|
|
@@ -0,0 +1,475 @@
|
|
|
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_FUNCTION_CALLBACK_H_
|
|
6
|
+
#define INCLUDE_V8_FUNCTION_CALLBACK_H_
|
|
7
|
+
|
|
8
|
+
#include "v8-local-handle.h" // NOLINT(build/include_directory)
|
|
9
|
+
#include "v8-primitive.h" // NOLINT(build/include_directory)
|
|
10
|
+
#include "v8config.h" // NOLINT(build/include_directory)
|
|
11
|
+
|
|
12
|
+
namespace v8 {
|
|
13
|
+
|
|
14
|
+
template <typename T>
|
|
15
|
+
class BasicTracedReference;
|
|
16
|
+
template <typename T>
|
|
17
|
+
class Global;
|
|
18
|
+
class Object;
|
|
19
|
+
class Value;
|
|
20
|
+
|
|
21
|
+
namespace internal {
|
|
22
|
+
class FunctionCallbackArguments;
|
|
23
|
+
class PropertyCallbackArguments;
|
|
24
|
+
} // namespace internal
|
|
25
|
+
|
|
26
|
+
namespace debug {
|
|
27
|
+
class ConsoleCallArguments;
|
|
28
|
+
} // namespace debug
|
|
29
|
+
|
|
30
|
+
template <typename T>
|
|
31
|
+
class ReturnValue {
|
|
32
|
+
public:
|
|
33
|
+
template <class S>
|
|
34
|
+
V8_INLINE ReturnValue(const ReturnValue<S>& that) : value_(that.value_) {
|
|
35
|
+
static_assert(std::is_base_of<T, S>::value, "type check");
|
|
36
|
+
}
|
|
37
|
+
// Local setters
|
|
38
|
+
template <typename S>
|
|
39
|
+
V8_INLINE void Set(const Global<S>& handle);
|
|
40
|
+
template <typename S>
|
|
41
|
+
V8_INLINE void Set(const BasicTracedReference<S>& handle);
|
|
42
|
+
template <typename S>
|
|
43
|
+
V8_INLINE void Set(const Local<S> handle);
|
|
44
|
+
// Fast primitive setters
|
|
45
|
+
V8_INLINE void Set(bool value);
|
|
46
|
+
V8_INLINE void Set(double i);
|
|
47
|
+
V8_INLINE void Set(int32_t i);
|
|
48
|
+
V8_INLINE void Set(uint32_t i);
|
|
49
|
+
// Fast JS primitive setters
|
|
50
|
+
V8_INLINE void SetNull();
|
|
51
|
+
V8_INLINE void SetUndefined();
|
|
52
|
+
V8_INLINE void SetEmptyString();
|
|
53
|
+
// Convenience getter for Isolate
|
|
54
|
+
V8_INLINE Isolate* GetIsolate() const;
|
|
55
|
+
|
|
56
|
+
// Pointer setter: Uncompilable to prevent inadvertent misuse.
|
|
57
|
+
template <typename S>
|
|
58
|
+
V8_INLINE void Set(S* whatever);
|
|
59
|
+
|
|
60
|
+
// Getter. Creates a new Local<> so it comes with a certain performance
|
|
61
|
+
// hit. If the ReturnValue was not yet set, this will return the undefined
|
|
62
|
+
// value.
|
|
63
|
+
V8_INLINE Local<Value> Get() const;
|
|
64
|
+
|
|
65
|
+
private:
|
|
66
|
+
template <class F>
|
|
67
|
+
friend class ReturnValue;
|
|
68
|
+
template <class F>
|
|
69
|
+
friend class FunctionCallbackInfo;
|
|
70
|
+
template <class F>
|
|
71
|
+
friend class PropertyCallbackInfo;
|
|
72
|
+
template <class F, class G, class H>
|
|
73
|
+
friend class PersistentValueMapBase;
|
|
74
|
+
V8_INLINE void SetInternal(internal::Address value) { *value_ = value; }
|
|
75
|
+
V8_INLINE internal::Address GetDefaultValue();
|
|
76
|
+
V8_INLINE explicit ReturnValue(internal::Address* slot);
|
|
77
|
+
internal::Address* value_;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The argument information given to function call callbacks. This
|
|
82
|
+
* class provides access to information about the context of the call,
|
|
83
|
+
* including the receiver, the number and values of arguments, and
|
|
84
|
+
* the holder of the function.
|
|
85
|
+
*/
|
|
86
|
+
template <typename T>
|
|
87
|
+
class FunctionCallbackInfo {
|
|
88
|
+
public:
|
|
89
|
+
/** The number of available arguments. */
|
|
90
|
+
V8_INLINE int Length() const;
|
|
91
|
+
/**
|
|
92
|
+
* Accessor for the available arguments. Returns `undefined` if the index
|
|
93
|
+
* is out of bounds.
|
|
94
|
+
*/
|
|
95
|
+
V8_INLINE Local<Value> operator[](int i) const;
|
|
96
|
+
/** Returns the receiver. This corresponds to the "this" value. */
|
|
97
|
+
V8_INLINE Local<Object> This() const;
|
|
98
|
+
/**
|
|
99
|
+
* If the callback was created without a Signature, this is the same
|
|
100
|
+
* value as This(). If there is a signature, and the signature didn't match
|
|
101
|
+
* This() but one of its hidden prototypes, this will be the respective
|
|
102
|
+
* hidden prototype.
|
|
103
|
+
*
|
|
104
|
+
* Note that this is not the prototype of This() on which the accessor
|
|
105
|
+
* referencing this callback was found (which in V8 internally is often
|
|
106
|
+
* referred to as holder [sic]).
|
|
107
|
+
*/
|
|
108
|
+
V8_INLINE Local<Object> Holder() const;
|
|
109
|
+
/** For construct calls, this returns the "new.target" value. */
|
|
110
|
+
V8_INLINE Local<Value> NewTarget() const;
|
|
111
|
+
/** Indicates whether this is a regular call or a construct call. */
|
|
112
|
+
V8_INLINE bool IsConstructCall() const;
|
|
113
|
+
/** The data argument specified when creating the callback. */
|
|
114
|
+
V8_INLINE Local<Value> Data() const;
|
|
115
|
+
/** The current Isolate. */
|
|
116
|
+
V8_INLINE Isolate* GetIsolate() const;
|
|
117
|
+
/** The ReturnValue for the call. */
|
|
118
|
+
V8_INLINE ReturnValue<T> GetReturnValue() const;
|
|
119
|
+
// This shouldn't be public, but the arm compiler needs it.
|
|
120
|
+
static const int kArgsLength = 6;
|
|
121
|
+
|
|
122
|
+
protected:
|
|
123
|
+
friend class internal::FunctionCallbackArguments;
|
|
124
|
+
friend class internal::CustomArguments<FunctionCallbackInfo>;
|
|
125
|
+
friend class debug::ConsoleCallArguments;
|
|
126
|
+
static const int kHolderIndex = 0;
|
|
127
|
+
static const int kIsolateIndex = 1;
|
|
128
|
+
static const int kReturnValueDefaultValueIndex = 2;
|
|
129
|
+
static const int kReturnValueIndex = 3;
|
|
130
|
+
static const int kDataIndex = 4;
|
|
131
|
+
static const int kNewTargetIndex = 5;
|
|
132
|
+
|
|
133
|
+
V8_INLINE FunctionCallbackInfo(internal::Address* implicit_args,
|
|
134
|
+
internal::Address* values, int length);
|
|
135
|
+
internal::Address* implicit_args_;
|
|
136
|
+
internal::Address* values_;
|
|
137
|
+
int length_;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The information passed to a property callback about the context
|
|
142
|
+
* of the property access.
|
|
143
|
+
*/
|
|
144
|
+
template <typename T>
|
|
145
|
+
class PropertyCallbackInfo {
|
|
146
|
+
public:
|
|
147
|
+
/**
|
|
148
|
+
* \return The isolate of the property access.
|
|
149
|
+
*/
|
|
150
|
+
V8_INLINE Isolate* GetIsolate() const;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* \return The data set in the configuration, i.e., in
|
|
154
|
+
* `NamedPropertyHandlerConfiguration` or
|
|
155
|
+
* `IndexedPropertyHandlerConfiguration.`
|
|
156
|
+
*/
|
|
157
|
+
V8_INLINE Local<Value> Data() const;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* \return The receiver. In many cases, this is the object on which the
|
|
161
|
+
* property access was intercepted. When using
|
|
162
|
+
* `Reflect.get`, `Function.prototype.call`, or similar functions, it is the
|
|
163
|
+
* object passed in as receiver or thisArg.
|
|
164
|
+
*
|
|
165
|
+
* \code
|
|
166
|
+
* void GetterCallback(Local<Name> name,
|
|
167
|
+
* const v8::PropertyCallbackInfo<v8::Value>& info) {
|
|
168
|
+
* auto context = info.GetIsolate()->GetCurrentContext();
|
|
169
|
+
*
|
|
170
|
+
* v8::Local<v8::Value> a_this =
|
|
171
|
+
* info.This()
|
|
172
|
+
* ->GetRealNamedProperty(context, v8_str("a"))
|
|
173
|
+
* .ToLocalChecked();
|
|
174
|
+
* v8::Local<v8::Value> a_holder =
|
|
175
|
+
* info.Holder()
|
|
176
|
+
* ->GetRealNamedProperty(context, v8_str("a"))
|
|
177
|
+
* .ToLocalChecked();
|
|
178
|
+
*
|
|
179
|
+
* CHECK(v8_str("r")->Equals(context, a_this).FromJust());
|
|
180
|
+
* CHECK(v8_str("obj")->Equals(context, a_holder).FromJust());
|
|
181
|
+
*
|
|
182
|
+
* info.GetReturnValue().Set(name);
|
|
183
|
+
* }
|
|
184
|
+
*
|
|
185
|
+
* v8::Local<v8::FunctionTemplate> templ =
|
|
186
|
+
* v8::FunctionTemplate::New(isolate);
|
|
187
|
+
* templ->InstanceTemplate()->SetHandler(
|
|
188
|
+
* v8::NamedPropertyHandlerConfiguration(GetterCallback));
|
|
189
|
+
* LocalContext env;
|
|
190
|
+
* env->Global()
|
|
191
|
+
* ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
|
|
192
|
+
* .ToLocalChecked()
|
|
193
|
+
* ->NewInstance(env.local())
|
|
194
|
+
* .ToLocalChecked())
|
|
195
|
+
* .FromJust();
|
|
196
|
+
*
|
|
197
|
+
* CompileRun("obj.a = 'obj'; var r = {a: 'r'}; Reflect.get(obj, 'x', r)");
|
|
198
|
+
* \endcode
|
|
199
|
+
*/
|
|
200
|
+
V8_INLINE Local<Object> This() const;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* \return The object in the prototype chain of the receiver that has the
|
|
204
|
+
* interceptor. Suppose you have `x` and its prototype is `y`, and `y`
|
|
205
|
+
* has an interceptor. Then `info.This()` is `x` and `info.Holder()` is `y`.
|
|
206
|
+
* The Holder() could be a hidden object (the global object, rather
|
|
207
|
+
* than the global proxy).
|
|
208
|
+
*
|
|
209
|
+
* \note For security reasons, do not pass the object back into the runtime.
|
|
210
|
+
*/
|
|
211
|
+
V8_INLINE Local<Object> Holder() const;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* \return The return value of the callback.
|
|
215
|
+
* Can be changed by calling Set().
|
|
216
|
+
* \code
|
|
217
|
+
* info.GetReturnValue().Set(...)
|
|
218
|
+
* \endcode
|
|
219
|
+
*
|
|
220
|
+
*/
|
|
221
|
+
V8_INLINE ReturnValue<T> GetReturnValue() const;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* \return True if the intercepted function should throw if an error occurs.
|
|
225
|
+
* Usually, `true` corresponds to `'use strict'`.
|
|
226
|
+
*
|
|
227
|
+
* \note Always `false` when intercepting `Reflect.set()`
|
|
228
|
+
* independent of the language mode.
|
|
229
|
+
*/
|
|
230
|
+
V8_INLINE bool ShouldThrowOnError() const;
|
|
231
|
+
|
|
232
|
+
// This shouldn't be public, but the arm compiler needs it.
|
|
233
|
+
static const int kArgsLength = 7;
|
|
234
|
+
|
|
235
|
+
protected:
|
|
236
|
+
friend class MacroAssembler;
|
|
237
|
+
friend class internal::PropertyCallbackArguments;
|
|
238
|
+
friend class internal::CustomArguments<PropertyCallbackInfo>;
|
|
239
|
+
static const int kShouldThrowOnErrorIndex = 0;
|
|
240
|
+
static const int kHolderIndex = 1;
|
|
241
|
+
static const int kIsolateIndex = 2;
|
|
242
|
+
static const int kReturnValueDefaultValueIndex = 3;
|
|
243
|
+
static const int kReturnValueIndex = 4;
|
|
244
|
+
static const int kDataIndex = 5;
|
|
245
|
+
static const int kThisIndex = 6;
|
|
246
|
+
|
|
247
|
+
V8_INLINE PropertyCallbackInfo(internal::Address* args) : args_(args) {}
|
|
248
|
+
internal::Address* args_;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
using FunctionCallback = void (*)(const FunctionCallbackInfo<Value>& info);
|
|
252
|
+
|
|
253
|
+
// --- Implementation ---
|
|
254
|
+
|
|
255
|
+
template <typename T>
|
|
256
|
+
ReturnValue<T>::ReturnValue(internal::Address* slot) : value_(slot) {}
|
|
257
|
+
|
|
258
|
+
template <typename T>
|
|
259
|
+
template <typename S>
|
|
260
|
+
void ReturnValue<T>::Set(const Global<S>& handle) {
|
|
261
|
+
static_assert(std::is_base_of<T, S>::value, "type check");
|
|
262
|
+
if (V8_UNLIKELY(handle.IsEmpty())) {
|
|
263
|
+
*value_ = GetDefaultValue();
|
|
264
|
+
} else {
|
|
265
|
+
*value_ = *reinterpret_cast<internal::Address*>(*handle);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
template <typename T>
|
|
270
|
+
template <typename S>
|
|
271
|
+
void ReturnValue<T>::Set(const BasicTracedReference<S>& handle) {
|
|
272
|
+
static_assert(std::is_base_of<T, S>::value, "type check");
|
|
273
|
+
if (V8_UNLIKELY(handle.IsEmpty())) {
|
|
274
|
+
*value_ = GetDefaultValue();
|
|
275
|
+
} else {
|
|
276
|
+
*value_ = *reinterpret_cast<internal::Address*>(handle.val_);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
template <typename T>
|
|
281
|
+
template <typename S>
|
|
282
|
+
void ReturnValue<T>::Set(const Local<S> handle) {
|
|
283
|
+
static_assert(std::is_void<T>::value || std::is_base_of<T, S>::value,
|
|
284
|
+
"type check");
|
|
285
|
+
if (V8_UNLIKELY(handle.IsEmpty())) {
|
|
286
|
+
*value_ = GetDefaultValue();
|
|
287
|
+
} else {
|
|
288
|
+
*value_ = *reinterpret_cast<internal::Address*>(*handle);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
template <typename T>
|
|
293
|
+
void ReturnValue<T>::Set(double i) {
|
|
294
|
+
static_assert(std::is_base_of<T, Number>::value, "type check");
|
|
295
|
+
Set(Number::New(GetIsolate(), i));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
template <typename T>
|
|
299
|
+
void ReturnValue<T>::Set(int32_t i) {
|
|
300
|
+
static_assert(std::is_base_of<T, Integer>::value, "type check");
|
|
301
|
+
using I = internal::Internals;
|
|
302
|
+
if (V8_LIKELY(I::IsValidSmi(i))) {
|
|
303
|
+
*value_ = I::IntToSmi(i);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
Set(Integer::New(GetIsolate(), i));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
template <typename T>
|
|
310
|
+
void ReturnValue<T>::Set(uint32_t i) {
|
|
311
|
+
static_assert(std::is_base_of<T, Integer>::value, "type check");
|
|
312
|
+
// Can't simply use INT32_MAX here for whatever reason.
|
|
313
|
+
bool fits_into_int32_t = (i & (1U << 31)) == 0;
|
|
314
|
+
if (V8_LIKELY(fits_into_int32_t)) {
|
|
315
|
+
Set(static_cast<int32_t>(i));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
Set(Integer::NewFromUnsigned(GetIsolate(), i));
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
template <typename T>
|
|
322
|
+
void ReturnValue<T>::Set(bool value) {
|
|
323
|
+
static_assert(std::is_base_of<T, Boolean>::value, "type check");
|
|
324
|
+
using I = internal::Internals;
|
|
325
|
+
int root_index;
|
|
326
|
+
if (value) {
|
|
327
|
+
root_index = I::kTrueValueRootIndex;
|
|
328
|
+
} else {
|
|
329
|
+
root_index = I::kFalseValueRootIndex;
|
|
330
|
+
}
|
|
331
|
+
*value_ = *I::GetRoot(GetIsolate(), root_index);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
template <typename T>
|
|
335
|
+
void ReturnValue<T>::SetNull() {
|
|
336
|
+
static_assert(std::is_base_of<T, Primitive>::value, "type check");
|
|
337
|
+
using I = internal::Internals;
|
|
338
|
+
*value_ = *I::GetRoot(GetIsolate(), I::kNullValueRootIndex);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
template <typename T>
|
|
342
|
+
void ReturnValue<T>::SetUndefined() {
|
|
343
|
+
static_assert(std::is_base_of<T, Primitive>::value, "type check");
|
|
344
|
+
using I = internal::Internals;
|
|
345
|
+
*value_ = *I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
template <typename T>
|
|
349
|
+
void ReturnValue<T>::SetEmptyString() {
|
|
350
|
+
static_assert(std::is_base_of<T, String>::value, "type check");
|
|
351
|
+
using I = internal::Internals;
|
|
352
|
+
*value_ = *I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
template <typename T>
|
|
356
|
+
Isolate* ReturnValue<T>::GetIsolate() const {
|
|
357
|
+
// Isolate is always the pointer below the default value on the stack.
|
|
358
|
+
return *reinterpret_cast<Isolate**>(&value_[-2]);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
template <typename T>
|
|
362
|
+
Local<Value> ReturnValue<T>::Get() const {
|
|
363
|
+
using I = internal::Internals;
|
|
364
|
+
if (*value_ == *I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex))
|
|
365
|
+
return Local<Value>(*Undefined(GetIsolate()));
|
|
366
|
+
return Local<Value>::New(GetIsolate(), reinterpret_cast<Value*>(value_));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
template <typename T>
|
|
370
|
+
template <typename S>
|
|
371
|
+
void ReturnValue<T>::Set(S* whatever) {
|
|
372
|
+
static_assert(sizeof(S) < 0, "incompilable to prevent inadvertent misuse");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
template <typename T>
|
|
376
|
+
internal::Address ReturnValue<T>::GetDefaultValue() {
|
|
377
|
+
// Default value is always the pointer below value_ on the stack.
|
|
378
|
+
return value_[-1];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
template <typename T>
|
|
382
|
+
FunctionCallbackInfo<T>::FunctionCallbackInfo(internal::Address* implicit_args,
|
|
383
|
+
internal::Address* values,
|
|
384
|
+
int length)
|
|
385
|
+
: implicit_args_(implicit_args), values_(values), length_(length) {}
|
|
386
|
+
|
|
387
|
+
template <typename T>
|
|
388
|
+
Local<Value> FunctionCallbackInfo<T>::operator[](int i) const {
|
|
389
|
+
// values_ points to the first argument (not the receiver).
|
|
390
|
+
if (i < 0 || length_ <= i) return Local<Value>(*Undefined(GetIsolate()));
|
|
391
|
+
return Local<Value>(reinterpret_cast<Value*>(values_ + i));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
template <typename T>
|
|
395
|
+
Local<Object> FunctionCallbackInfo<T>::This() const {
|
|
396
|
+
// values_ points to the first argument (not the receiver).
|
|
397
|
+
return Local<Object>(reinterpret_cast<Object*>(values_ - 1));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
template <typename T>
|
|
401
|
+
Local<Object> FunctionCallbackInfo<T>::Holder() const {
|
|
402
|
+
return Local<Object>(
|
|
403
|
+
reinterpret_cast<Object*>(&implicit_args_[kHolderIndex]));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
template <typename T>
|
|
407
|
+
Local<Value> FunctionCallbackInfo<T>::NewTarget() const {
|
|
408
|
+
return Local<Value>(
|
|
409
|
+
reinterpret_cast<Value*>(&implicit_args_[kNewTargetIndex]));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
template <typename T>
|
|
413
|
+
Local<Value> FunctionCallbackInfo<T>::Data() const {
|
|
414
|
+
return Local<Value>(reinterpret_cast<Value*>(&implicit_args_[kDataIndex]));
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
template <typename T>
|
|
418
|
+
Isolate* FunctionCallbackInfo<T>::GetIsolate() const {
|
|
419
|
+
return *reinterpret_cast<Isolate**>(&implicit_args_[kIsolateIndex]);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
template <typename T>
|
|
423
|
+
ReturnValue<T> FunctionCallbackInfo<T>::GetReturnValue() const {
|
|
424
|
+
return ReturnValue<T>(&implicit_args_[kReturnValueIndex]);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
template <typename T>
|
|
428
|
+
bool FunctionCallbackInfo<T>::IsConstructCall() const {
|
|
429
|
+
return !NewTarget()->IsUndefined();
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
template <typename T>
|
|
433
|
+
int FunctionCallbackInfo<T>::Length() const {
|
|
434
|
+
return length_;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
template <typename T>
|
|
438
|
+
Isolate* PropertyCallbackInfo<T>::GetIsolate() const {
|
|
439
|
+
return *reinterpret_cast<Isolate**>(&args_[kIsolateIndex]);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
template <typename T>
|
|
443
|
+
Local<Value> PropertyCallbackInfo<T>::Data() const {
|
|
444
|
+
return Local<Value>(reinterpret_cast<Value*>(&args_[kDataIndex]));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
template <typename T>
|
|
448
|
+
Local<Object> PropertyCallbackInfo<T>::This() const {
|
|
449
|
+
return Local<Object>(reinterpret_cast<Object*>(&args_[kThisIndex]));
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
template <typename T>
|
|
453
|
+
Local<Object> PropertyCallbackInfo<T>::Holder() const {
|
|
454
|
+
return Local<Object>(reinterpret_cast<Object*>(&args_[kHolderIndex]));
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
template <typename T>
|
|
458
|
+
ReturnValue<T> PropertyCallbackInfo<T>::GetReturnValue() const {
|
|
459
|
+
return ReturnValue<T>(&args_[kReturnValueIndex]);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
template <typename T>
|
|
463
|
+
bool PropertyCallbackInfo<T>::ShouldThrowOnError() const {
|
|
464
|
+
using I = internal::Internals;
|
|
465
|
+
if (args_[kShouldThrowOnErrorIndex] !=
|
|
466
|
+
I::IntToSmi(I::kInferShouldThrowMode)) {
|
|
467
|
+
return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(I::kDontThrow);
|
|
468
|
+
}
|
|
469
|
+
return v8::internal::ShouldThrowOnError(
|
|
470
|
+
reinterpret_cast<v8::internal::Isolate*>(GetIsolate()));
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
} // namespace v8
|
|
474
|
+
|
|
475
|
+
#endif // INCLUDE_V8_FUNCTION_CALLBACK_H_
|
|
@@ -0,0 +1,73 @@
|
|
|
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_WEAK_CALLBACK_INFO_H_
|
|
6
|
+
#define INCLUDE_V8_WEAK_CALLBACK_INFO_H_
|
|
7
|
+
|
|
8
|
+
#include "v8config.h" // NOLINT(build/include_directory)
|
|
9
|
+
|
|
10
|
+
namespace v8 {
|
|
11
|
+
|
|
12
|
+
class Isolate;
|
|
13
|
+
|
|
14
|
+
namespace api_internal {
|
|
15
|
+
V8_EXPORT void InternalFieldOutOfBounds(int index);
|
|
16
|
+
} // namespace api_internal
|
|
17
|
+
|
|
18
|
+
static const int kInternalFieldsInWeakCallback = 2;
|
|
19
|
+
static const int kEmbedderFieldsInWeakCallback = 2;
|
|
20
|
+
|
|
21
|
+
template <typename T>
|
|
22
|
+
class WeakCallbackInfo {
|
|
23
|
+
public:
|
|
24
|
+
using Callback = void (*)(const WeakCallbackInfo<T>& data);
|
|
25
|
+
|
|
26
|
+
WeakCallbackInfo(Isolate* isolate, T* parameter,
|
|
27
|
+
void* embedder_fields[kEmbedderFieldsInWeakCallback],
|
|
28
|
+
Callback* callback)
|
|
29
|
+
: isolate_(isolate), parameter_(parameter), callback_(callback) {
|
|
30
|
+
for (int i = 0; i < kEmbedderFieldsInWeakCallback; ++i) {
|
|
31
|
+
embedder_fields_[i] = embedder_fields[i];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
V8_INLINE Isolate* GetIsolate() const { return isolate_; }
|
|
36
|
+
V8_INLINE T* GetParameter() const { return parameter_; }
|
|
37
|
+
V8_INLINE void* GetInternalField(int index) const;
|
|
38
|
+
|
|
39
|
+
// When first called, the embedder MUST Reset() the Global which triggered the
|
|
40
|
+
// callback. The Global itself is unusable for anything else. No v8 other api
|
|
41
|
+
// calls may be called in the first callback. Should additional work be
|
|
42
|
+
// required, the embedder must set a second pass callback, which will be
|
|
43
|
+
// called after all the initial callbacks are processed.
|
|
44
|
+
// Calling SetSecondPassCallback on the second pass will immediately crash.
|
|
45
|
+
void SetSecondPassCallback(Callback callback) const { *callback_ = callback; }
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
Isolate* isolate_;
|
|
49
|
+
T* parameter_;
|
|
50
|
+
Callback* callback_;
|
|
51
|
+
void* embedder_fields_[kEmbedderFieldsInWeakCallback];
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// kParameter will pass a void* parameter back to the callback, kInternalFields
|
|
55
|
+
// will pass the first two internal fields back to the callback, kFinalizer
|
|
56
|
+
// will pass a void* parameter back, but is invoked before the object is
|
|
57
|
+
// actually collected, so it can be resurrected. In the last case, it is not
|
|
58
|
+
// possible to request a second pass callback.
|
|
59
|
+
enum class WeakCallbackType { kParameter, kInternalFields, kFinalizer };
|
|
60
|
+
|
|
61
|
+
template <class T>
|
|
62
|
+
void* WeakCallbackInfo<T>::GetInternalField(int index) const {
|
|
63
|
+
#ifdef V8_ENABLE_CHECKS
|
|
64
|
+
if (index < 0 || index >= kEmbedderFieldsInWeakCallback) {
|
|
65
|
+
api_internal::InternalFieldOutOfBounds(index);
|
|
66
|
+
}
|
|
67
|
+
#endif
|
|
68
|
+
return embedder_fields_[index];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
} // namespace v8
|
|
72
|
+
|
|
73
|
+
#endif // INCLUDE_V8_WEAK_CALLBACK_INFO_H_
|