LCOV - code coverage report
Current view: top level - test/cctest - cctest.h (source / functions) Hit Total Coverage
Test: app.info Lines: 165 186 88.7 %
Date: 2019-01-20 Functions: 41 55 74.5 %

          Line data    Source code
       1             : // Copyright 2008 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #ifndef CCTEST_H_
      29             : #define CCTEST_H_
      30             : 
      31             : #include <memory>
      32             : 
      33             : #include "include/libplatform/libplatform.h"
      34             : #include "include/v8-platform.h"
      35             : #include "src/base/enum-set.h"
      36             : #include "src/debug/debug-interface.h"
      37             : #include "src/flags.h"
      38             : #include "src/heap/factory.h"
      39             : #include "src/isolate.h"
      40             : #include "src/objects.h"
      41             : #include "src/register-configuration.h"
      42             : #include "src/v8.h"
      43             : #include "src/zone/accounting-allocator.h"
      44             : 
      45             : namespace v8 {
      46             : namespace base {
      47             : 
      48             : class RandomNumberGenerator;
      49             : 
      50             : }  // namespace base
      51             : 
      52             : namespace internal {
      53             : 
      54             : const auto GetRegConfig = RegisterConfiguration::Default;
      55             : 
      56             : class HandleScope;
      57             : class Zone;
      58             : 
      59             : }  // namespace internal
      60             : 
      61             : }  // namespace v8
      62             : 
      63             : #ifndef TEST
      64             : #define TEST(Name)                                                      \
      65             :   static void Test##Name();                                             \
      66             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, true); \
      67             :   static void Test##Name()
      68             : #endif
      69             : 
      70             : #ifndef UNINITIALIZED_TEST
      71             : #define UNINITIALIZED_TEST(Name)                                         \
      72             :   static void Test##Name();                                              \
      73             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, false); \
      74             :   static void Test##Name()
      75             : #endif
      76             : 
      77             : #ifndef DISABLED_TEST
      78             : #define DISABLED_TEST(Name)                                              \
      79             :   static void Test##Name();                                              \
      80             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, false, true); \
      81             :   static void Test##Name()
      82             : #endif
      83             : 
      84             : #define EXTENSION_LIST(V)                                                      \
      85             :   V(GC_EXTENSION,       "v8/gc")                                               \
      86             :   V(PRINT_EXTENSION,    "v8/print")                                            \
      87             :   V(PROFILER_EXTENSION, "v8/profiler")                                         \
      88             :   V(TRACE_EXTENSION,    "v8/trace")
      89             : 
      90             : #define DEFINE_EXTENSION_ID(Name, Ident) Name##_ID,
      91             : enum CcTestExtensionId { EXTENSION_LIST(DEFINE_EXTENSION_ID) kMaxExtensions };
      92             : #undef DEFINE_EXTENSION_ID
      93             : 
      94             : using CcTestExtensionFlags = v8::base::EnumSet<CcTestExtensionId>;
      95             : 
      96             : #define DEFINE_EXTENSION_NAME(Name, Ident) Ident,
      97             : static constexpr const char* kExtensionName[kMaxExtensions] = {
      98             :     EXTENSION_LIST(DEFINE_EXTENSION_NAME)};
      99             : #undef DEFINE_EXTENSION_NAME
     100             : 
     101             : class CcTest {
     102             :  public:
     103             :   typedef void (TestFunction)();
     104             :   CcTest(TestFunction* callback, const char* file, const char* name,
     105             :          bool enabled, bool initialize);
     106   324515324 :   ~CcTest() { i::DeleteArray(file_); }
     107             :   void Run();
     108       39654 :   static CcTest* last() { return last_; }
     109             :   CcTest* prev() { return prev_; }
     110             :   const char* file() { return file_; }
     111             :   const char* name() { return name_; }
     112             :   bool enabled() { return enabled_; }
     113             : 
     114    20447093 :   static v8::Isolate* isolate() {
     115    20447093 :     CHECK_NOT_NULL(isolate_);
     116             :     v8::base::Relaxed_Store(&isolate_used_, 1);
     117    20447093 :     return isolate_;
     118             :   }
     119             : 
     120    15618292 :   static i::Isolate* InitIsolateOnce() {
     121    15618292 :     if (!initialize_called_) InitializeVM();
     122    15618292 :     return i_isolate();
     123             :   }
     124             : 
     125             :   static i::Isolate* i_isolate() {
     126    20231902 :     return reinterpret_cast<i::Isolate*>(isolate());
     127             :   }
     128             : 
     129             :   static i::Heap* heap();
     130             : 
     131             :   static void CollectGarbage(i::AllocationSpace space);
     132             :   static void CollectAllGarbage(i::Isolate* isolate = nullptr);
     133             :   static void CollectAllAvailableGarbage(i::Isolate* isolate = nullptr);
     134             :   static void PreciseCollectAllGarbage(i::Isolate* isolate = nullptr);
     135             : 
     136             :   static v8::base::RandomNumberGenerator* random_number_generator();
     137             : 
     138             :   static v8::Local<v8::Object> global();
     139             : 
     140             :   static v8::ArrayBuffer::Allocator* array_buffer_allocator() {
     141        1548 :     return allocator_;
     142             :   }
     143             : 
     144             :   static void set_array_buffer_allocator(
     145             :       v8::ArrayBuffer::Allocator* allocator) {
     146       28337 :     allocator_ = allocator;
     147             :   }
     148             : 
     149             :   // TODO(dcarney): Remove.
     150             :   // This must be called first in a test.
     151             :   static void InitializeVM();
     152             : 
     153             :   // Only for UNINITIALIZED_TESTs
     154             :   static void DisableAutomaticDispose();
     155             : 
     156             :   // Helper function to configure a context.
     157             :   // Must be in a HandleScope.
     158             :   static v8::Local<v8::Context> NewContext(
     159             :       v8::Isolate* isolate = CcTest::isolate()) {
     160             :     return NewContext({}, isolate);
     161             :   }
     162             :   static v8::Local<v8::Context> NewContext(
     163             :       CcTestExtensionFlags extension_flags,
     164             :       v8::Isolate* isolate = CcTest::isolate());
     165             : 
     166             :   static void TearDown();
     167             : 
     168             :  private:
     169             :   friend int main(int argc, char** argv);
     170             :   TestFunction* callback_;
     171             :   const char* file_;
     172             :   const char* name_;
     173             :   bool enabled_;
     174             :   bool initialize_;
     175             :   CcTest* prev_;
     176             :   static CcTest* last_;
     177             :   static v8::ArrayBuffer::Allocator* allocator_;
     178             :   static v8::Isolate* isolate_;
     179             :   static bool initialize_called_;
     180             :   static v8::base::Atomic32 isolate_used_;
     181             : };
     182             : 
     183             : // Switches between all the Api tests using the threading support.
     184             : // In order to get a surprising but repeatable pattern of thread
     185             : // switching it has extra semaphores to control the order in which
     186             : // the tests alternate, not relying solely on the big V8 lock.
     187             : //
     188             : // A test is augmented with calls to ApiTestFuzzer::Fuzz() in its
     189             : // callbacks.  This will have no effect when we are not running the
     190             : // thread fuzzing test.  In the thread fuzzing test it will
     191             : // pseudorandomly select a successor thread and switch execution
     192             : // to that thread, suspending the current test.
     193             : class ApiTestFuzzer: public v8::base::Thread {
     194             :  public:
     195             :   void CallTest();
     196             : 
     197             :   // The ApiTestFuzzer is also a Thread, so it has a Run method.
     198             :   void Run() override;
     199             : 
     200             :   enum PartOfTest {
     201             :     FIRST_PART,
     202             :     SECOND_PART,
     203             :     THIRD_PART,
     204             :     FOURTH_PART,
     205             :     FIFTH_PART,
     206             :     SIXTH_PART,
     207             :     SEVENTH_PART,
     208             :     EIGHTH_PART,
     209             :     LAST_PART = EIGHTH_PART
     210             :   };
     211             : 
     212             :   static void SetUp(PartOfTest part);
     213             :   static void RunAllTests();
     214             :   static void TearDown();
     215             :   // This method switches threads if we are running the Threading test.
     216             :   // Otherwise it does nothing.
     217             :   static void Fuzz();
     218             : 
     219             :  private:
     220         480 :   explicit ApiTestFuzzer(int num)
     221             :       : Thread(Options("ApiTestFuzzer")),
     222             :         test_number_(num),
     223             :         gate_(0),
     224         480 :         active_(true) {}
     225           0 :   ~ApiTestFuzzer() override = default;
     226             : 
     227             :   static bool fuzzing_;
     228             :   static int tests_being_run_;
     229             :   static int current_;
     230             :   static int active_tests_;
     231             :   static bool NextThread();
     232             :   int test_number_;
     233             :   v8::base::Semaphore gate_;
     234             :   bool active_;
     235             :   void ContextSwitch();
     236             :   static int GetNextTestNumber();
     237             :   static v8::base::Semaphore all_tests_done_;
     238             : };
     239             : 
     240             : 
     241             : #define THREADED_TEST(Name)                                          \
     242             :   static void Test##Name();                                          \
     243             :   RegisterThreadedTest register_##Name(Test##Name, #Name);           \
     244             :   /* */ TEST(Name)
     245             : 
     246             : class RegisterThreadedTest {
     247             :  public:
     248             :   explicit RegisterThreadedTest(CcTest::TestFunction* callback,
     249             :                                 const char* name)
     250    13601760 :       : fuzzer_(nullptr), callback_(callback), name_(name) {
     251    13601760 :     prev_ = first_;
     252    13601760 :     first_ = this;
     253    13601760 :     count_++;
     254             :   }
     255     3439247 :   static int count() { return count_; }
     256     3435391 :   static RegisterThreadedTest* nth(int i) {
     257     3435391 :     CHECK(i < count());
     258     3435391 :     RegisterThreadedTest* current = first_;
     259   109900210 :     while (i > 0) {
     260   103029428 :       i--;
     261   103029428 :       current = current->prev_;
     262             :     }
     263     3435391 :     return current;
     264             :   }
     265             :   CcTest::TestFunction* callback() { return callback_; }
     266             :   ApiTestFuzzer* fuzzer_;
     267             :   const char* name() { return name_; }
     268             : 
     269             :  private:
     270             :   static RegisterThreadedTest* first_;
     271             :   static int count_;
     272             :   CcTest::TestFunction* callback_;
     273             :   RegisterThreadedTest* prev_;
     274             :   const char* name_;
     275             : };
     276             : 
     277             : // A LocalContext holds a reference to a v8::Context.
     278             : class LocalContext {
     279             :  public:
     280             :   LocalContext(v8::Isolate* isolate,
     281             :                v8::ExtensionConfiguration* extensions = nullptr,
     282             :                v8::Local<v8::ObjectTemplate> global_template =
     283             :                    v8::Local<v8::ObjectTemplate>(),
     284        2466 :                v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) {
     285        2466 :     Initialize(isolate, extensions, global_template, global_object);
     286             :   }
     287             : 
     288        9819 :   LocalContext(v8::ExtensionConfiguration* extensions = nullptr,
     289             :                v8::Local<v8::ObjectTemplate> global_template =
     290             :                    v8::Local<v8::ObjectTemplate>(),
     291        9819 :                v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) {
     292        9819 :     Initialize(CcTest::isolate(), extensions, global_template, global_object);
     293        9819 :   }
     294             : 
     295             :   virtual ~LocalContext();
     296             : 
     297             :   v8::Context* operator->() {
     298      112875 :     return *reinterpret_cast<v8::Context**>(&context_);
     299             :   }
     300             :   v8::Context* operator*() { return operator->(); }
     301             :   bool IsReady() { return !context_.IsEmpty(); }
     302             : 
     303      188988 :   v8::Local<v8::Context> local() {
     304      377976 :     return v8::Local<v8::Context>::New(isolate_, context_);
     305             :   }
     306             : 
     307             :  private:
     308             :   void Initialize(v8::Isolate* isolate, v8::ExtensionConfiguration* extensions,
     309             :                   v8::Local<v8::ObjectTemplate> global_template,
     310             :                   v8::Local<v8::Value> global_object);
     311             : 
     312             :   v8::Persistent<v8::Context> context_;
     313             :   v8::Isolate* isolate_;
     314             : };
     315             : 
     316             : 
     317       28460 : static inline uint16_t* AsciiToTwoByteString(const char* source) {
     318       28460 :   int array_length = i::StrLength(source) + 1;
     319       28460 :   uint16_t* converted = i::NewArray<uint16_t>(array_length);
     320       28460 :   for (int i = 0; i < array_length; i++) converted[i] = source[i];
     321       28460 :   return converted;
     322             : }
     323             : 
     324             : template <typename T>
     325          65 : static inline i::Handle<T> GetGlobal(const char* name) {
     326             :   i::Isolate* isolate = CcTest::i_isolate();
     327             :   i::Handle<i::String> str_name =
     328          65 :       isolate->factory()->InternalizeUtf8String(name);
     329             : 
     330             :   i::Handle<i::Object> value =
     331         130 :       i::Object::GetProperty(isolate, isolate->global_object(), str_name)
     332         130 :           .ToHandleChecked();
     333          65 :   return i::Handle<T>::cast(value);
     334             : }
     335             : 
     336       77456 : static inline v8::Local<v8::Value> v8_num(double x) {
     337       77456 :   return v8::Number::New(v8::Isolate::GetCurrent(), x);
     338             : }
     339             : 
     340             : static inline v8::Local<v8::Integer> v8_int(int32_t x) {
     341          40 :   return v8::Integer::New(v8::Isolate::GetCurrent(), x);
     342             : }
     343             : 
     344      517790 : static inline v8::Local<v8::String> v8_str(const char* x) {
     345             :   return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x,
     346      517790 :                                  v8::NewStringType::kNormal)
     347     1035580 :       .ToLocalChecked();
     348             : }
     349             : 
     350             : 
     351         913 : static inline v8::Local<v8::String> v8_str(v8::Isolate* isolate,
     352             :                                            const char* x) {
     353             :   return v8::String::NewFromUtf8(isolate, x, v8::NewStringType::kNormal)
     354        1826 :       .ToLocalChecked();
     355             : }
     356             : 
     357             : 
     358           5 : static inline v8::Local<v8::Symbol> v8_symbol(const char* name) {
     359           5 :   return v8::Symbol::New(v8::Isolate::GetCurrent(), v8_str(name));
     360             : }
     361             : 
     362             : 
     363      118046 : static inline v8::Local<v8::Script> v8_compile(v8::Local<v8::String> x) {
     364             :   v8::Local<v8::Script> result;
     365      236092 :   if (v8::Script::Compile(v8::Isolate::GetCurrent()->GetCurrentContext(), x)
     366      118046 :           .ToLocal(&result)) {
     367      118036 :     return result;
     368             :   }
     369          10 :   return v8::Local<v8::Script>();
     370             : }
     371             : 
     372             : 
     373             : static inline v8::Local<v8::Script> v8_compile(const char* x) {
     374        2219 :   return v8_compile(v8_str(x));
     375             : }
     376             : 
     377             : 
     378        2054 : static inline int32_t v8_run_int32value(v8::Local<v8::Script> script) {
     379        2054 :   v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
     380        6162 :   return script->Run(context).ToLocalChecked()->Int32Value(context).FromJust();
     381             : }
     382             : 
     383             : 
     384          60 : static inline v8::Local<v8::Script> CompileWithOrigin(
     385             :     v8::Local<v8::String> source, v8::Local<v8::String> origin_url) {
     386             :   v8::ScriptOrigin origin(origin_url);
     387             :   v8::ScriptCompiler::Source script_source(source, origin);
     388             :   return v8::ScriptCompiler::Compile(
     389          60 :              v8::Isolate::GetCurrent()->GetCurrentContext(), &script_source)
     390         120 :       .ToLocalChecked();
     391             : }
     392             : 
     393             : 
     394             : static inline v8::Local<v8::Script> CompileWithOrigin(
     395             :     v8::Local<v8::String> source, const char* origin_url) {
     396          17 :   return CompileWithOrigin(source, v8_str(origin_url));
     397             : }
     398             : 
     399             : 
     400          27 : static inline v8::Local<v8::Script> CompileWithOrigin(const char* source,
     401             :                                                       const char* origin_url) {
     402          27 :   return CompileWithOrigin(v8_str(source), v8_str(origin_url));
     403             : }
     404             : 
     405             : 
     406             : // Helper functions that compile and run the source.
     407         258 : static inline v8::MaybeLocal<v8::Value> CompileRun(
     408             :     v8::Local<v8::Context> context, const char* source) {
     409         258 :   return v8::Script::Compile(context, v8_str(source))
     410         258 :       .ToLocalChecked()
     411         258 :       ->Run(context);
     412             : }
     413             : 
     414             : 
     415         538 : static inline v8::Local<v8::Value> CompileRunChecked(v8::Isolate* isolate,
     416             :                                                      const char* source) {
     417             :   v8::Local<v8::String> source_string =
     418             :       v8::String::NewFromUtf8(isolate, source, v8::NewStringType::kNormal)
     419        1076 :           .ToLocalChecked();
     420         538 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     421             :   v8::Local<v8::Script> script =
     422         538 :       v8::Script::Compile(context, source_string).ToLocalChecked();
     423        1076 :   return script->Run(context).ToLocalChecked();
     424             : }
     425             : 
     426             : 
     427      115700 : static inline v8::Local<v8::Value> CompileRun(v8::Local<v8::String> source) {
     428             :   v8::Local<v8::Value> result;
     429      115700 :   if (v8_compile(source)
     430      231400 :           ->Run(v8::Isolate::GetCurrent()->GetCurrentContext())
     431      115700 :           .ToLocal(&result)) {
     432      113079 :     return result;
     433             :   }
     434        2621 :   return v8::Local<v8::Value>();
     435             : }
     436             : 
     437             : 
     438             : // Helper functions that compile and run the source.
     439             : static inline v8::Local<v8::Value> CompileRun(const char* source) {
     440      113858 :   return CompileRun(v8_str(source));
     441             : }
     442             : 
     443             : 
     444          80 : static inline v8::Local<v8::Value> CompileRun(
     445             :     v8::Local<v8::Context> context, v8::ScriptCompiler::Source* script_source,
     446             :     v8::ScriptCompiler::CompileOptions options) {
     447             :   v8::Local<v8::Value> result;
     448          80 :   if (v8::ScriptCompiler::Compile(context, script_source, options)
     449          80 :           .ToLocalChecked()
     450             :           ->Run(context)
     451          80 :           .ToLocal(&result)) {
     452          60 :     return result;
     453             :   }
     454          20 :   return v8::Local<v8::Value>();
     455             : }
     456             : 
     457             : 
     458             : // Helper functions that compile and run the source with given origin.
     459          60 : static inline v8::Local<v8::Value> CompileRunWithOrigin(const char* source,
     460             :                                                         const char* origin_url,
     461             :                                                         int line_number,
     462             :                                                         int column_number) {
     463          60 :   v8::Isolate* isolate = v8::Isolate::GetCurrent();
     464          60 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     465             :   v8::ScriptOrigin origin(v8_str(origin_url),
     466             :                           v8::Integer::New(isolate, line_number),
     467          60 :                           v8::Integer::New(isolate, column_number));
     468          60 :   v8::ScriptCompiler::Source script_source(v8_str(source), origin);
     469             :   return CompileRun(context, &script_source,
     470         120 :                     v8::ScriptCompiler::CompileOptions());
     471             : }
     472             : 
     473             : 
     474          20 : static inline v8::Local<v8::Value> CompileRunWithOrigin(
     475             :     v8::Local<v8::String> source, const char* origin_url) {
     476          20 :   v8::Isolate* isolate = v8::Isolate::GetCurrent();
     477          20 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     478             :   v8::ScriptCompiler::Source script_source(
     479          20 :       source, v8::ScriptOrigin(v8_str(origin_url)));
     480             :   return CompileRun(context, &script_source,
     481          40 :                     v8::ScriptCompiler::CompileOptions());
     482             : }
     483             : 
     484             : 
     485             : static inline v8::Local<v8::Value> CompileRunWithOrigin(
     486             :     const char* source, const char* origin_url) {
     487          20 :   return CompileRunWithOrigin(v8_str(source), origin_url);
     488             : }
     489             : 
     490             : 
     491             : 
     492         872 : static inline void ExpectString(const char* code, const char* expected) {
     493             :   v8::Local<v8::Value> result = CompileRun(code);
     494         872 :   CHECK(result->IsString());
     495         872 :   v8::String::Utf8Value utf8(v8::Isolate::GetCurrent(), result);
     496         872 :   CHECK_EQ(0, strcmp(expected, *utf8));
     497         872 : }
     498             : 
     499             : 
     500        1244 : static inline void ExpectInt32(const char* code, int expected) {
     501             :   v8::Local<v8::Value> result = CompileRun(code);
     502        1244 :   CHECK(result->IsInt32());
     503        2488 :   CHECK_EQ(expected,
     504             :            result->Int32Value(v8::Isolate::GetCurrent()->GetCurrentContext())
     505             :                .FromJust());
     506        1244 : }
     507             : 
     508             : 
     509         924 : static inline void ExpectBoolean(const char* code, bool expected) {
     510             :   v8::Local<v8::Value> result = CompileRun(code);
     511         924 :   CHECK(result->IsBoolean());
     512         924 :   CHECK_EQ(expected, result->BooleanValue(v8::Isolate::GetCurrent()));
     513         924 : }
     514             : 
     515             : 
     516             : static inline void ExpectTrue(const char* code) {
     517         254 :   ExpectBoolean(code, true);
     518             : }
     519             : 
     520             : 
     521             : static inline void ExpectFalse(const char* code) {
     522          89 :   ExpectBoolean(code, false);
     523             : }
     524             : 
     525             : 
     526          92 : static inline void ExpectObject(const char* code,
     527             :                                 v8::Local<v8::Value> expected) {
     528             :   v8::Local<v8::Value> result = CompileRun(code);
     529          92 :   CHECK(result->SameValue(expected));
     530          92 : }
     531             : 
     532             : 
     533          42 : static inline void ExpectUndefined(const char* code) {
     534             :   v8::Local<v8::Value> result = CompileRun(code);
     535          42 :   CHECK(result->IsUndefined());
     536          42 : }
     537             : 
     538             : 
     539             : static inline void ExpectNull(const char* code) {
     540             :   v8::Local<v8::Value> result = CompileRun(code);
     541             :   CHECK(result->IsNull());
     542             : }
     543             : 
     544             : 
     545           5 : static inline void CheckDoubleEquals(double expected, double actual) {
     546             :   const double kEpsilon = 1e-10;
     547          10 :   CHECK_LE(expected, actual + kEpsilon);
     548          10 :   CHECK_GE(expected, actual - kEpsilon);
     549           5 : }
     550             : 
     551     5100660 : static v8::debug::DebugDelegate dummy_delegate;
     552             : 
     553             : static inline void EnableDebugger(v8::Isolate* isolate) {
     554          30 :   v8::debug::SetDebugDelegate(isolate, &dummy_delegate);
     555             : }
     556             : 
     557             : 
     558             : static inline void DisableDebugger(v8::Isolate* isolate) {
     559          25 :   v8::debug::SetDebugDelegate(isolate, nullptr);
     560             : }
     561             : 
     562             : 
     563       28039 : static inline void EmptyMessageQueues(v8::Isolate* isolate) {
     564       79245 :   while (v8::platform::PumpMessageLoop(v8::internal::V8::GetCurrentPlatform(),
     565       51206 :                                        isolate)) {
     566             :   }
     567       28039 : }
     568             : 
     569             : class InitializedHandleScopeImpl;
     570             : 
     571        4570 : class InitializedHandleScope {
     572             :  public:
     573             :   InitializedHandleScope();
     574             :   ~InitializedHandleScope();
     575             : 
     576             :   // Prefixing the below with main_ reduces a lot of naming clashes.
     577             :   i::Isolate* main_isolate() { return main_isolate_; }
     578             : 
     579             :  private:
     580             :   i::Isolate* main_isolate_;
     581             :   std::unique_ptr<InitializedHandleScopeImpl> initialized_handle_scope_impl_;
     582             : };
     583             : 
     584     5270250 : class HandleAndZoneScope : public InitializedHandleScope {
     585             :  public:
     586             :   HandleAndZoneScope();
     587             :   ~HandleAndZoneScope();
     588             : 
     589             :   // Prefixing the below with main_ reduces a lot of naming clashes.
     590             :   i::Zone* main_zone() { return main_zone_.get(); }
     591             : 
     592             :  private:
     593             :   v8::internal::AccountingAllocator allocator_;
     594             :   std::unique_ptr<i::Zone> main_zone_;
     595             : };
     596             : 
     597             : class StaticOneByteResource : public v8::String::ExternalOneByteStringResource {
     598             :  public:
     599           5 :   explicit StaticOneByteResource(const char* data) : data_(data) {}
     600             : 
     601          10 :   ~StaticOneByteResource() override = default;
     602             : 
     603          40 :   const char* data() const override { return data_; }
     604             : 
     605          20 :   size_t length() const override { return strlen(data_); }
     606             : 
     607             :  private:
     608             :   const char* data_;
     609             : };
     610             : 
     611             : class ManualGCScope {
     612             :  public:
     613             :   ManualGCScope()
     614             :       : flag_concurrent_marking_(i::FLAG_concurrent_marking),
     615             :         flag_concurrent_sweeping_(i::FLAG_concurrent_sweeping),
     616             :         flag_stress_incremental_marking_(i::FLAG_stress_incremental_marking),
     617             :         flag_parallel_marking_(i::FLAG_parallel_marking),
     618             :         flag_detect_ineffective_gcs_near_heap_limit_(
     619         443 :             i::FLAG_detect_ineffective_gcs_near_heap_limit) {
     620         443 :     i::FLAG_concurrent_marking = false;
     621         443 :     i::FLAG_concurrent_sweeping = false;
     622         443 :     i::FLAG_stress_incremental_marking = false;
     623             :     // Parallel marking has a dependency on concurrent marking.
     624         443 :     i::FLAG_parallel_marking = false;
     625         443 :     i::FLAG_detect_ineffective_gcs_near_heap_limit = false;
     626             :   }
     627             :   ~ManualGCScope() {
     628         443 :     i::FLAG_concurrent_marking = flag_concurrent_marking_;
     629         443 :     i::FLAG_concurrent_sweeping = flag_concurrent_sweeping_;
     630         443 :     i::FLAG_stress_incremental_marking = flag_stress_incremental_marking_;
     631         443 :     i::FLAG_parallel_marking = flag_parallel_marking_;
     632             :     i::FLAG_detect_ineffective_gcs_near_heap_limit =
     633         443 :         flag_detect_ineffective_gcs_near_heap_limit_;
     634             :   }
     635             : 
     636             :  private:
     637             :   bool flag_concurrent_marking_;
     638             :   bool flag_concurrent_sweeping_;
     639             :   bool flag_stress_incremental_marking_;
     640             :   bool flag_parallel_marking_;
     641             :   bool flag_detect_ineffective_gcs_near_heap_limit_;
     642             : };
     643             : 
     644             : // This is an abstract base class that can be overridden to implement a test
     645             : // platform. It delegates all operations to a given platform at the time
     646             : // of construction.
     647             : class TestPlatform : public v8::Platform {
     648             :  public:
     649             :   // v8::Platform implementation.
     650           0 :   v8::PageAllocator* GetPageAllocator() override {
     651           0 :     return old_platform_->GetPageAllocator();
     652             :   }
     653             : 
     654           0 :   void OnCriticalMemoryPressure() override {
     655           0 :     old_platform_->OnCriticalMemoryPressure();
     656           0 :   }
     657             : 
     658           0 :   bool OnCriticalMemoryPressure(size_t length) override {
     659           0 :     return old_platform_->OnCriticalMemoryPressure(length);
     660             :   }
     661             : 
     662         206 :   int NumberOfWorkerThreads() override {
     663         206 :     return old_platform_->NumberOfWorkerThreads();
     664             :   }
     665             : 
     666           6 :   std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
     667             :       v8::Isolate* isolate) override {
     668           6 :     return old_platform_->GetForegroundTaskRunner(isolate);
     669             :   }
     670             : 
     671           7 :   void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
     672          21 :     old_platform_->CallOnWorkerThread(std::move(task));
     673           7 :   }
     674             : 
     675           0 :   void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task,
     676             :                                  double delay_in_seconds) override {
     677           0 :     old_platform_->CallDelayedOnWorkerThread(std::move(task), delay_in_seconds);
     678           0 :   }
     679             : 
     680           0 :   void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override {
     681             :     // This is a deprecated function and should not be called anymore.
     682           0 :     UNREACHABLE();
     683             :   }
     684             : 
     685           0 :   void CallDelayedOnForegroundThread(v8::Isolate* isolate, v8::Task* task,
     686             :                                      double delay_in_seconds) override {
     687             :     // This is a deprecated function and should not be called anymore.
     688           0 :     UNREACHABLE();
     689             :   }
     690             : 
     691       14025 :   double MonotonicallyIncreasingTime() override {
     692       14025 :     return old_platform_->MonotonicallyIncreasingTime();
     693             :   }
     694             : 
     695           0 :   double CurrentClockTimeMillis() override {
     696           0 :     return old_platform_->CurrentClockTimeMillis();
     697             :   }
     698             : 
     699           0 :   void CallIdleOnForegroundThread(v8::Isolate* isolate,
     700             :                                   v8::IdleTask* task) override {
     701             :     // This is a deprecated function and should not be called anymore.
     702           0 :     UNREACHABLE();
     703             :   }
     704             : 
     705           0 :   bool IdleTasksEnabled(v8::Isolate* isolate) override {
     706           0 :     return old_platform_->IdleTasksEnabled(isolate);
     707             :   }
     708             : 
     709        3584 :   v8::TracingController* GetTracingController() override {
     710        3584 :     return old_platform_->GetTracingController();
     711             :   }
     712             : 
     713             :  protected:
     714         275 :   TestPlatform() : old_platform_(i::V8::GetCurrentPlatform()) {}
     715         260 :   ~TestPlatform() override { i::V8::SetPlatformForTesting(old_platform_); }
     716             : 
     717             :   v8::Platform* old_platform() const { return old_platform_; }
     718             : 
     719             :  private:
     720             :   v8::Platform* old_platform_;
     721             : 
     722             :   DISALLOW_COPY_AND_ASSIGN(TestPlatform);
     723             : };
     724             : 
     725             : #endif  // ifndef CCTEST_H_

Generated by: LCOV version 1.10