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