Line data Source code
1 : // Copyright 2012 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_API_H_
6 : #define V8_API_H_
7 :
8 : #include "include/v8-testing.h"
9 : #include "src/contexts.h"
10 : #include "src/debug/debug-interface.h"
11 : #include "src/detachable-vector.h"
12 : #include "src/heap/factory.h"
13 : #include "src/isolate.h"
14 : #include "src/objects.h"
15 : #include "src/objects/bigint.h"
16 : #include "src/objects/js-collection.h"
17 : #include "src/objects/js-generator.h"
18 : #include "src/objects/js-promise.h"
19 : #include "src/objects/js-proxy.h"
20 : #include "src/objects/module.h"
21 : #include "src/objects/shared-function-info.h"
22 :
23 : #include "src/objects/templates.h"
24 :
25 : namespace v8 {
26 :
27 : namespace internal {
28 : class JSArrayBufferView;
29 : } // namespace internal
30 :
31 : // Constants used in the implementation of the API. The most natural thing
32 : // would usually be to place these with the classes that use them, but
33 : // we want to keep them out of v8.h because it is an externally
34 : // visible file.
35 : class Consts {
36 : public:
37 : enum TemplateType {
38 : FUNCTION_TEMPLATE = 0,
39 : OBJECT_TEMPLATE = 1
40 : };
41 : };
42 :
43 : template <typename T>
44 : inline T ToCData(v8::internal::Object obj);
45 :
46 : template <>
47 : inline v8::internal::Address ToCData(v8::internal::Object obj);
48 :
49 : template <typename T>
50 : inline v8::internal::Handle<v8::internal::Object> FromCData(
51 : v8::internal::Isolate* isolate, T obj);
52 :
53 : template <>
54 : inline v8::internal::Handle<v8::internal::Object> FromCData(
55 : v8::internal::Isolate* isolate, v8::internal::Address obj);
56 :
57 : class ApiFunction {
58 : public:
59 3494921 : explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { }
60 3494921 : v8::internal::Address address() { return addr_; }
61 : private:
62 : v8::internal::Address addr_;
63 : };
64 :
65 :
66 :
67 : class RegisteredExtension {
68 : public:
69 : static void Register(Extension*);
70 : static void Register(std::unique_ptr<Extension>);
71 : static void UnregisterAll();
72 : Extension* extension() const {
73 : return legacy_unowned_extension_ ? legacy_unowned_extension_
74 666524 : : extension_.get();
75 : }
76 : RegisteredExtension* next() const { return next_; }
77 93943 : static RegisteredExtension* first_extension() { return first_extension_; }
78 : private:
79 : explicit RegisteredExtension(Extension*);
80 : explicit RegisteredExtension(std::unique_ptr<Extension>);
81 : // TODO(clemensh): Remove this after the 7.4 branch.
82 : Extension* legacy_unowned_extension_ = nullptr;
83 : std::unique_ptr<Extension> extension_;
84 : RegisteredExtension* next_ = nullptr;
85 : static RegisteredExtension* first_extension_;
86 : };
87 :
88 : #define OPEN_HANDLE_LIST(V) \
89 : V(Template, TemplateInfo) \
90 : V(FunctionTemplate, FunctionTemplateInfo) \
91 : V(ObjectTemplate, ObjectTemplateInfo) \
92 : V(Signature, FunctionTemplateInfo) \
93 : V(AccessorSignature, FunctionTemplateInfo) \
94 : V(Data, Object) \
95 : V(RegExp, JSRegExp) \
96 : V(Object, JSReceiver) \
97 : V(Array, JSArray) \
98 : V(Map, JSMap) \
99 : V(Set, JSSet) \
100 : V(ArrayBuffer, JSArrayBuffer) \
101 : V(ArrayBufferView, JSArrayBufferView) \
102 : V(TypedArray, JSTypedArray) \
103 : V(Uint8Array, JSTypedArray) \
104 : V(Uint8ClampedArray, JSTypedArray) \
105 : V(Int8Array, JSTypedArray) \
106 : V(Uint16Array, JSTypedArray) \
107 : V(Int16Array, JSTypedArray) \
108 : V(Uint32Array, JSTypedArray) \
109 : V(Int32Array, JSTypedArray) \
110 : V(Float32Array, JSTypedArray) \
111 : V(Float64Array, JSTypedArray) \
112 : V(DataView, JSDataView) \
113 : V(SharedArrayBuffer, JSArrayBuffer) \
114 : V(Name, Name) \
115 : V(String, String) \
116 : V(Symbol, Symbol) \
117 : V(Script, JSFunction) \
118 : V(UnboundModuleScript, SharedFunctionInfo) \
119 : V(UnboundScript, SharedFunctionInfo) \
120 : V(Module, Module) \
121 : V(Function, JSReceiver) \
122 : V(Message, JSMessageObject) \
123 : V(Context, Context) \
124 : V(External, Object) \
125 : V(StackTrace, FixedArray) \
126 : V(StackFrame, StackTraceFrame) \
127 : V(Proxy, JSProxy) \
128 : V(debug::GeneratorObject, JSGeneratorObject) \
129 : V(debug::Script, Script) \
130 : V(debug::WeakMap, JSWeakMap) \
131 : V(Promise, JSPromise) \
132 : V(Primitive, Object) \
133 : V(PrimitiveArray, FixedArray) \
134 : V(BigInt, BigInt) \
135 : V(ScriptOrModule, Script)
136 :
137 : class Utils {
138 : public:
139 : static inline bool ApiCheck(bool condition,
140 : const char* location,
141 : const char* message) {
142 464418071 : if (!condition) Utils::ReportApiFailure(location, message);
143 : return condition;
144 : }
145 : static void ReportOOMFailure(v8::internal::Isolate* isolate,
146 : const char* location, bool is_heap_oom);
147 :
148 : static inline Local<Context> ToLocal(
149 : v8::internal::Handle<v8::internal::Context> obj);
150 : static inline Local<Value> ToLocal(
151 : v8::internal::Handle<v8::internal::Object> obj);
152 : static inline Local<Module> ToLocal(
153 : v8::internal::Handle<v8::internal::Module> obj);
154 : static inline Local<Name> ToLocal(
155 : v8::internal::Handle<v8::internal::Name> obj);
156 : static inline Local<String> ToLocal(
157 : v8::internal::Handle<v8::internal::String> obj);
158 : static inline Local<Symbol> ToLocal(
159 : v8::internal::Handle<v8::internal::Symbol> obj);
160 : static inline Local<RegExp> ToLocal(
161 : v8::internal::Handle<v8::internal::JSRegExp> obj);
162 : static inline Local<Object> ToLocal(
163 : v8::internal::Handle<v8::internal::JSReceiver> obj);
164 : static inline Local<Object> ToLocal(
165 : v8::internal::Handle<v8::internal::JSObject> obj);
166 : static inline Local<Function> ToLocal(
167 : v8::internal::Handle<v8::internal::JSFunction> obj);
168 : static inline Local<Array> ToLocal(
169 : v8::internal::Handle<v8::internal::JSArray> obj);
170 : static inline Local<Map> ToLocal(
171 : v8::internal::Handle<v8::internal::JSMap> obj);
172 : static inline Local<Set> ToLocal(
173 : v8::internal::Handle<v8::internal::JSSet> obj);
174 : static inline Local<Proxy> ToLocal(
175 : v8::internal::Handle<v8::internal::JSProxy> obj);
176 : static inline Local<ArrayBuffer> ToLocal(
177 : v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
178 : static inline Local<ArrayBufferView> ToLocal(
179 : v8::internal::Handle<v8::internal::JSArrayBufferView> obj);
180 : static inline Local<DataView> ToLocal(
181 : v8::internal::Handle<v8::internal::JSDataView> obj);
182 : static inline Local<TypedArray> ToLocal(
183 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
184 : static inline Local<Uint8Array> ToLocalUint8Array(
185 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
186 : static inline Local<Uint8ClampedArray> ToLocalUint8ClampedArray(
187 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
188 : static inline Local<Int8Array> ToLocalInt8Array(
189 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
190 : static inline Local<Uint16Array> ToLocalUint16Array(
191 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
192 : static inline Local<Int16Array> ToLocalInt16Array(
193 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
194 : static inline Local<Uint32Array> ToLocalUint32Array(
195 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
196 : static inline Local<Int32Array> ToLocalInt32Array(
197 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
198 : static inline Local<Float32Array> ToLocalFloat32Array(
199 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
200 : static inline Local<Float64Array> ToLocalFloat64Array(
201 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
202 : static inline Local<BigInt64Array> ToLocalBigInt64Array(
203 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
204 : static inline Local<BigUint64Array> ToLocalBigUint64Array(
205 : v8::internal::Handle<v8::internal::JSTypedArray> obj);
206 :
207 : static inline Local<SharedArrayBuffer> ToLocalShared(
208 : v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
209 :
210 : static inline Local<Message> MessageToLocal(
211 : v8::internal::Handle<v8::internal::Object> obj);
212 : static inline Local<Promise> PromiseToLocal(
213 : v8::internal::Handle<v8::internal::JSObject> obj);
214 : static inline Local<StackTrace> StackTraceToLocal(
215 : v8::internal::Handle<v8::internal::FixedArray> obj);
216 : static inline Local<StackFrame> StackFrameToLocal(
217 : v8::internal::Handle<v8::internal::StackTraceFrame> obj);
218 : static inline Local<Number> NumberToLocal(
219 : v8::internal::Handle<v8::internal::Object> obj);
220 : static inline Local<Integer> IntegerToLocal(
221 : v8::internal::Handle<v8::internal::Object> obj);
222 : static inline Local<Uint32> Uint32ToLocal(
223 : v8::internal::Handle<v8::internal::Object> obj);
224 : static inline Local<BigInt> ToLocal(
225 : v8::internal::Handle<v8::internal::BigInt> obj);
226 : static inline Local<FunctionTemplate> ToLocal(
227 : v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
228 : static inline Local<ObjectTemplate> ToLocal(
229 : v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj);
230 : static inline Local<Signature> SignatureToLocal(
231 : v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
232 : static inline Local<AccessorSignature> AccessorSignatureToLocal(
233 : v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
234 : static inline Local<External> ExternalToLocal(
235 : v8::internal::Handle<v8::internal::JSObject> obj);
236 : static inline Local<Function> CallableToLocal(
237 : v8::internal::Handle<v8::internal::JSReceiver> obj);
238 : static inline Local<Primitive> ToLocalPrimitive(
239 : v8::internal::Handle<v8::internal::Object> obj);
240 : static inline Local<PrimitiveArray> ToLocal(
241 : v8::internal::Handle<v8::internal::FixedArray> obj);
242 : static inline Local<ScriptOrModule> ScriptOrModuleToLocal(
243 : v8::internal::Handle<v8::internal::Script> obj);
244 :
245 : #define DECLARE_OPEN_HANDLE(From, To) \
246 : static inline v8::internal::Handle<v8::internal::To> OpenHandle( \
247 : const From* that, bool allow_empty_handle = false);
248 :
249 : OPEN_HANDLE_LIST(DECLARE_OPEN_HANDLE)
250 :
251 : #undef DECLARE_OPEN_HANDLE
252 :
253 : template <class From, class To>
254 : static inline Local<To> Convert(v8::internal::Handle<From> obj);
255 :
256 : template <class T>
257 : static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
258 : const v8::Persistent<T>& persistent) {
259 : return v8::internal::Handle<v8::internal::Object>(
260 : reinterpret_cast<v8::internal::Address*>(persistent.val_));
261 : }
262 :
263 : template <class T>
264 : static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
265 : v8::Persistent<T>* persistent) {
266 : return OpenPersistent(*persistent);
267 : }
268 :
269 : template <class From, class To>
270 : static inline v8::internal::Handle<To> OpenHandle(v8::Local<From> handle) {
271 : return OpenHandle(*handle);
272 : }
273 :
274 48 : static inline CompiledWasmModule Convert(
275 : std::shared_ptr<i::wasm::NativeModule> native_module) {
276 96 : return CompiledWasmModule{std::move(native_module)};
277 : }
278 :
279 : private:
280 : static void ReportApiFailure(const char* location, const char* message);
281 : };
282 :
283 : template <class T>
284 : inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
285 : return reinterpret_cast<T*>(obj.location());
286 : }
287 :
288 : template <class T>
289 : inline v8::Local<T> ToApiHandle(
290 : v8::internal::Handle<v8::internal::Object> obj) {
291 : return Utils::Convert<v8::internal::Object, T>(obj);
292 : }
293 :
294 :
295 : template <class T>
296 : inline bool ToLocal(v8::internal::MaybeHandle<v8::internal::Object> maybe,
297 : Local<T>* local) {
298 : v8::internal::Handle<v8::internal::Object> handle;
299 3377323 : if (maybe.ToHandle(&handle)) {
300 : *local = Utils::Convert<v8::internal::Object, T>(handle);
301 : return true;
302 : }
303 : return false;
304 : }
305 :
306 : namespace internal {
307 :
308 : class V8_EXPORT_PRIVATE DeferredHandles {
309 : public:
310 : ~DeferredHandles();
311 :
312 : private:
313 : DeferredHandles(Address* first_block_limit, Isolate* isolate)
314 : : next_(nullptr),
315 : previous_(nullptr),
316 : first_block_limit_(first_block_limit),
317 7174 : isolate_(isolate) {
318 7174 : isolate->LinkDeferredHandles(this);
319 : }
320 :
321 : void Iterate(RootVisitor* v);
322 :
323 : std::vector<Address*> blocks_;
324 : DeferredHandles* next_;
325 : DeferredHandles* previous_;
326 : Address* first_block_limit_;
327 : Isolate* isolate_;
328 :
329 : friend class HandleScopeImplementer;
330 : friend class Isolate;
331 : };
332 :
333 :
334 : // This class is here in order to be able to declare it a friend of
335 : // HandleScope. Moving these methods to be members of HandleScope would be
336 : // neat in some ways, but it would expose internal implementation details in
337 : // our public header file, which is undesirable.
338 : //
339 : // An isolate has a single instance of this class to hold the current thread's
340 : // data. In multithreaded V8 programs this data is copied in and out of storage
341 : // so that the currently executing thread always has its own copy of this
342 : // data.
343 : class HandleScopeImplementer {
344 : public:
345 : class EnteredContextRewindScope {
346 : public:
347 : explicit EnteredContextRewindScope(HandleScopeImplementer* hsi)
348 : : hsi_(hsi), saved_entered_context_count_(hsi->EnteredContextCount()) {}
349 :
350 : ~EnteredContextRewindScope() {
351 : DCHECK_LE(saved_entered_context_count_, hsi_->EnteredContextCount());
352 51549 : while (saved_entered_context_count_ < hsi_->EnteredContextCount())
353 : hsi_->LeaveContext();
354 : }
355 :
356 : private:
357 : HandleScopeImplementer* hsi_;
358 : size_t saved_entered_context_count_;
359 : };
360 :
361 : explicit HandleScopeImplementer(Isolate* isolate)
362 : : isolate_(isolate),
363 : spare_(nullptr),
364 : call_depth_(0),
365 61049 : last_handle_before_deferred_block_(nullptr) {
366 : }
367 :
368 61034 : ~HandleScopeImplementer() {
369 61034 : DeleteArray(spare_);
370 61034 : }
371 :
372 : // Threading support for handle data.
373 : static int ArchiveSpacePerThread();
374 : char* RestoreThread(char* from);
375 : char* ArchiveThread(char* to);
376 : void FreeThreadResources();
377 :
378 : // Garbage collection support.
379 : void Iterate(v8::internal::RootVisitor* v);
380 : static char* Iterate(v8::internal::RootVisitor* v, char* data);
381 :
382 : inline internal::Address* GetSpareOrNewBlock();
383 : inline void DeleteExtensions(internal::Address* prev_limit);
384 :
385 : // Call depth represents nested v8 api calls.
386 12387920 : inline void IncrementCallDepth() {call_depth_++;}
387 12387912 : inline void DecrementCallDepth() {call_depth_--;}
388 : inline bool CallDepthIsZero() { return call_depth_ == 0; }
389 :
390 : inline void EnterContext(Context context);
391 : inline void LeaveContext();
392 : inline bool LastEnteredContextWas(Context context);
393 103083 : inline size_t EnteredContextCount() const { return entered_contexts_.size(); }
394 :
395 : inline void EnterMicrotaskContext(Context context);
396 :
397 : // Returns the last entered context or an empty handle if no
398 : // contexts have been entered.
399 : inline Handle<Context> LastEnteredContext();
400 : inline Handle<Context> LastEnteredOrMicrotaskContext();
401 :
402 : inline void SaveContext(Context context);
403 : inline Context RestoreContext();
404 : inline bool HasSavedContexts();
405 :
406 : inline DetachableVector<Address*>* blocks() { return &blocks_; }
407 : Isolate* isolate() const { return isolate_; }
408 :
409 : void ReturnBlock(Address* block) {
410 : DCHECK_NOT_NULL(block);
411 7174 : if (spare_ != nullptr) DeleteArray(spare_);
412 7174 : spare_ = block;
413 : }
414 :
415 : static const size_t kEnteredContextsOffset;
416 : static const size_t kIsMicrotaskContextOffset;
417 :
418 : private:
419 : void ResetAfterArchive() {
420 : blocks_.detach();
421 : entered_contexts_.detach();
422 : is_microtask_context_.detach();
423 : saved_contexts_.detach();
424 23397 : spare_ = nullptr;
425 23397 : last_handle_before_deferred_block_ = nullptr;
426 23397 : call_depth_ = 0;
427 : }
428 :
429 5906 : void Free() {
430 : DCHECK(blocks_.empty());
431 : DCHECK(entered_contexts_.empty());
432 : DCHECK(is_microtask_context_.empty());
433 : DCHECK(saved_contexts_.empty());
434 :
435 : blocks_.free();
436 : entered_contexts_.free();
437 : is_microtask_context_.free();
438 : saved_contexts_.free();
439 5906 : if (spare_ != nullptr) {
440 : DeleteArray(spare_);
441 5743 : spare_ = nullptr;
442 : }
443 : DCHECK_EQ(call_depth_, 0);
444 5906 : }
445 :
446 : void BeginDeferredScope();
447 : DeferredHandles* Detach(Address* prev_limit);
448 :
449 : Isolate* isolate_;
450 : DetachableVector<Address*> blocks_;
451 :
452 : // Used as a stack to keep track of entered contexts.
453 : // If |i|th item of |entered_contexts_| is added by EnterMicrotaskContext,
454 : // `is_microtask_context_[i]` is 1.
455 : // TODO(tzik): Remove |is_microtask_context_| after the deprecated
456 : // v8::Isolate::GetEnteredContext() is removed.
457 : DetachableVector<Context> entered_contexts_;
458 : DetachableVector<int8_t> is_microtask_context_;
459 :
460 : // Used as a stack to keep track of saved contexts.
461 : DetachableVector<Context> saved_contexts_;
462 : Address* spare_;
463 : int call_depth_;
464 :
465 : Address* last_handle_before_deferred_block_;
466 : // This is only used for threading support.
467 : HandleScopeData handle_scope_data_;
468 :
469 : void IterateThis(RootVisitor* v);
470 : char* RestoreThreadHelper(char* from);
471 : char* ArchiveThreadHelper(char* to);
472 :
473 : friend class DeferredHandles;
474 : friend class DeferredHandleScope;
475 : friend class HandleScopeImplementerOffsets;
476 :
477 : DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
478 : };
479 :
480 : const int kHandleBlockSize = v8::internal::KB - 2; // fit in one page
481 :
482 : void HandleScopeImplementer::SaveContext(Context context) {
483 4377998 : saved_contexts_.push_back(context);
484 : }
485 :
486 : Context HandleScopeImplementer::RestoreContext() {
487 4361391 : Context last_context = saved_contexts_.back();
488 : saved_contexts_.pop_back();
489 : return last_context;
490 : }
491 :
492 :
493 : bool HandleScopeImplementer::HasSavedContexts() {
494 : return !saved_contexts_.empty();
495 : }
496 :
497 4377331 : void HandleScopeImplementer::EnterContext(Context context) {
498 : DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
499 4377331 : entered_contexts_.push_back(context);
500 4377336 : is_microtask_context_.push_back(0);
501 4377338 : }
502 :
503 : void HandleScopeImplementer::LeaveContext() {
504 : DCHECK(!entered_contexts_.empty());
505 : DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
506 : entered_contexts_.pop_back();
507 : is_microtask_context_.pop_back();
508 : }
509 :
510 : bool HandleScopeImplementer::LastEnteredContextWas(Context context) {
511 8721460 : return !entered_contexts_.empty() && entered_contexts_.back() == context;
512 : }
513 :
514 0 : void HandleScopeImplementer::EnterMicrotaskContext(Context context) {
515 : DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
516 0 : entered_contexts_.push_back(context);
517 0 : is_microtask_context_.push_back(1);
518 0 : }
519 :
520 : // If there's a spare block, use it for growing the current scope.
521 : internal::Address* HandleScopeImplementer::GetSpareOrNewBlock() {
522 : internal::Address* block =
523 2683256 : (spare_ != nullptr) ? spare_
524 2683256 : : NewArray<internal::Address>(kHandleBlockSize);
525 2683256 : spare_ = nullptr;
526 : return block;
527 : }
528 :
529 2420764 : void HandleScopeImplementer::DeleteExtensions(internal::Address* prev_limit) {
530 7517621 : while (!blocks_.empty()) {
531 3020740 : internal::Address* block_start = blocks_.back();
532 3020740 : internal::Address* block_limit = block_start + kHandleBlockSize;
533 :
534 : // SealHandleScope may make the prev_limit to point inside the block.
535 : // Cast possibly-unrelated pointers to plain Addres before comparing them
536 : // to avoid undefined behavior.
537 6041480 : if (reinterpret_cast<Address>(block_start) <=
538 3020740 : reinterpret_cast<Address>(prev_limit) &&
539 3020740 : reinterpret_cast<Address>(prev_limit) <=
540 : reinterpret_cast<Address>(block_limit)) {
541 : #ifdef ENABLE_HANDLE_ZAPPING
542 : internal::HandleScope::ZapRange(prev_limit, block_limit);
543 : #endif
544 : break;
545 : }
546 :
547 5096857 : blocks_.pop_back();
548 : #ifdef ENABLE_HANDLE_ZAPPING
549 : internal::HandleScope::ZapRange(block_start, block_limit);
550 : #endif
551 2676093 : if (spare_ != nullptr) {
552 : DeleteArray(spare_);
553 : }
554 2676093 : spare_ = block_start;
555 : }
556 : DCHECK((blocks_.empty() && prev_limit == nullptr) ||
557 : (!blocks_.empty() && prev_limit != nullptr));
558 2420764 : }
559 :
560 : // Interceptor functions called from generated inline caches to notify
561 : // CPU profiler that external callbacks are invoked.
562 : void InvokeAccessorGetterCallback(
563 : v8::Local<v8::Name> property,
564 : const v8::PropertyCallbackInfo<v8::Value>& info,
565 : v8::AccessorNameGetterCallback getter);
566 :
567 : void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
568 : v8::FunctionCallback callback);
569 :
570 : class Testing {
571 : public:
572 26754 : static v8::Testing::StressType stress_type() { return stress_type_; }
573 : static void set_stress_type(v8::Testing::StressType stress_type) {
574 5538 : stress_type_ = stress_type;
575 : }
576 :
577 : private:
578 : static v8::Testing::StressType stress_type_;
579 : };
580 :
581 : } // namespace internal
582 : } // namespace v8
583 :
584 : #endif // V8_API_H_
|