LCOV - code coverage report
Current view: top level - test/cctest - cctest.h (source / functions) Hit Total Coverage
Test: app.info Lines: 161 182 88.5 %
Date: 2019-04-17 Functions: 39 53 73.6 %

          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 compiler {
      60             : 
      61             : class JSHeapBroker;
      62             : 
      63             : }  // namespace compiler
      64             : 
      65             : }  // namespace internal
      66             : 
      67             : }  // namespace v8
      68             : 
      69             : #ifndef TEST
      70             : #define TEST(Name)                                                      \
      71             :   static void Test##Name();                                             \
      72             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, true); \
      73             :   static void Test##Name()
      74             : #endif
      75             : 
      76             : #ifndef UNINITIALIZED_TEST
      77             : #define UNINITIALIZED_TEST(Name)                                         \
      78             :   static void Test##Name();                                              \
      79             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, false); \
      80             :   static void Test##Name()
      81             : #endif
      82             : 
      83             : #ifndef DISABLED_TEST
      84             : #define DISABLED_TEST(Name)                                              \
      85             :   static void Test##Name();                                              \
      86             :   CcTest register_test_##Name(Test##Name, __FILE__, #Name, false, true); \
      87             :   static void Test##Name()
      88             : #endif
      89             : 
      90             : #define EXTENSION_LIST(V)                                                      \
      91             :   V(GC_EXTENSION,       "v8/gc")                                               \
      92             :   V(PRINT_EXTENSION,    "v8/print")                                            \
      93             :   V(PROFILER_EXTENSION, "v8/profiler")                                         \
      94             :   V(TRACE_EXTENSION,    "v8/trace")
      95             : 
      96             : #define DEFINE_EXTENSION_ID(Name, Ident) Name##_ID,
      97             : enum CcTestExtensionId { EXTENSION_LIST(DEFINE_EXTENSION_ID) kMaxExtensions };
      98             : #undef DEFINE_EXTENSION_ID
      99             : 
     100             : using CcTestExtensionFlags = v8::base::EnumSet<CcTestExtensionId>;
     101             : 
     102             : #define DEFINE_EXTENSION_NAME(Name, Ident) Ident,
     103             : static constexpr const char* kExtensionName[kMaxExtensions] = {
     104             :     EXTENSION_LIST(DEFINE_EXTENSION_NAME)};
     105             : #undef DEFINE_EXTENSION_NAME
     106             : 
     107             : class CcTest {
     108             :  public:
     109             :   typedef void (TestFunction)();
     110             :   CcTest(TestFunction* callback, const char* file, const char* name,
     111             :          bool enabled, bool initialize);
     112   320999950 :   ~CcTest() { i::DeleteArray(file_); }
     113             :   void Run();
     114       38566 :   static CcTest* last() { return last_; }
     115             :   CcTest* prev() { return prev_; }
     116             :   const char* file() { return file_; }
     117             :   const char* name() { return name_; }
     118             :   bool enabled() { return enabled_; }
     119             : 
     120    16042708 :   static v8::Isolate* isolate() {
     121    16042708 :     CHECK_NOT_NULL(isolate_);
     122             :     v8::base::Relaxed_Store(&isolate_used_, 1);
     123    16042708 :     return isolate_;
     124             :   }
     125             : 
     126             :   static i::Isolate* InitIsolateOnce() {
     127    12916513 :     if (!initialize_called_) InitializeVM();
     128             :     return i_isolate();
     129             :   }
     130             : 
     131             :   static i::Isolate* i_isolate() {
     132    15786421 :     return reinterpret_cast<i::Isolate*>(isolate());
     133             :   }
     134             : 
     135             :   static i::Heap* heap();
     136             : 
     137             :   static void CollectGarbage(i::AllocationSpace space);
     138             :   static void CollectAllGarbage(i::Isolate* isolate = nullptr);
     139             :   static void CollectAllAvailableGarbage(i::Isolate* isolate = nullptr);
     140             :   static void PreciseCollectAllGarbage(i::Isolate* isolate = nullptr);
     141             : 
     142             :   static v8::base::RandomNumberGenerator* random_number_generator();
     143             : 
     144             :   static v8::Local<v8::Object> global();
     145             : 
     146             :   static v8::ArrayBuffer::Allocator* array_buffer_allocator() {
     147        1536 :     return allocator_;
     148             :   }
     149             : 
     150             :   static void set_array_buffer_allocator(
     151             :       v8::ArrayBuffer::Allocator* allocator) {
     152       26639 :     allocator_ = allocator;
     153             :   }
     154             : 
     155             :   // TODO(dcarney): Remove.
     156             :   // This must be called first in a test.
     157             :   static void InitializeVM();
     158             : 
     159             :   // Only for UNINITIALIZED_TESTs
     160             :   static void DisableAutomaticDispose();
     161             : 
     162             :   // Helper function to configure a context.
     163             :   // Must be in a HandleScope.
     164             :   static v8::Local<v8::Context> NewContext(
     165             :       v8::Isolate* isolate = CcTest::isolate()) {
     166             :     return NewContext({}, isolate);
     167             :   }
     168             :   static v8::Local<v8::Context> NewContext(
     169             :       CcTestExtensionFlags extension_flags,
     170             :       v8::Isolate* isolate = CcTest::isolate());
     171             : 
     172             :   static void TearDown();
     173             : 
     174             :  private:
     175             :   friend int main(int argc, char** argv);
     176             :   TestFunction* callback_;
     177             :   const char* file_;
     178             :   const char* name_;
     179             :   bool enabled_;
     180             :   bool initialize_;
     181             :   CcTest* prev_;
     182             :   static CcTest* last_;
     183             :   static v8::ArrayBuffer::Allocator* allocator_;
     184             :   static v8::Isolate* isolate_;
     185             :   static bool initialize_called_;
     186             :   static v8::base::Atomic32 isolate_used_;
     187             : };
     188             : 
     189             : // Switches between all the Api tests using the threading support.
     190             : // In order to get a surprising but repeatable pattern of thread
     191             : // switching it has extra semaphores to control the order in which
     192             : // the tests alternate, not relying solely on the big V8 lock.
     193             : //
     194             : // A test is augmented with calls to ApiTestFuzzer::Fuzz() in its
     195             : // callbacks.  This will have no effect when we are not running the
     196             : // thread fuzzing test.  In the thread fuzzing test it will
     197             : // pseudorandomly select a successor thread and switch execution
     198             : // to that thread, suspending the current test.
     199             : class ApiTestFuzzer: public v8::base::Thread {
     200             :  public:
     201             :   void CallTest();
     202             : 
     203             :   // The ApiTestFuzzer is also a Thread, so it has a Run method.
     204             :   void Run() override;
     205             : 
     206             :   enum PartOfTest {
     207             :     FIRST_PART,
     208             :     SECOND_PART,
     209             :     THIRD_PART,
     210             :     FOURTH_PART,
     211             :     FIFTH_PART,
     212             :     SIXTH_PART,
     213             :     SEVENTH_PART,
     214             :     EIGHTH_PART,
     215             :     LAST_PART = EIGHTH_PART
     216             :   };
     217             : 
     218             :   static void SetUp(PartOfTest part);
     219             :   static void RunAllTests();
     220             :   static void TearDown();
     221             :   // This method switches threads if we are running the Threading test.
     222             :   // Otherwise it does nothing.
     223             :   static void Fuzz();
     224             : 
     225             :  private:
     226         480 :   explicit ApiTestFuzzer(int num)
     227             :       : Thread(Options("ApiTestFuzzer")),
     228             :         test_number_(num),
     229             :         gate_(0),
     230         480 :         active_(true) {}
     231           0 :   ~ApiTestFuzzer() override = default;
     232             : 
     233             :   static bool fuzzing_;
     234             :   static int tests_being_run_;
     235             :   static int current_;
     236             :   static int active_tests_;
     237             :   static bool NextThread();
     238             :   int test_number_;
     239             :   v8::base::Semaphore gate_;
     240             :   bool active_;
     241             :   void ContextSwitch();
     242             :   static int GetNextTestNumber();
     243             :   static v8::base::Semaphore all_tests_done_;
     244             : };
     245             : 
     246             : 
     247             : #define THREADED_TEST(Name)                                          \
     248             :   static void Test##Name();                                          \
     249             :   RegisterThreadedTest register_##Name(Test##Name, #Name);           \
     250             :   /* */ TEST(Name)
     251             : 
     252             : class RegisterThreadedTest {
     253             :  public:
     254             :   explicit RegisterThreadedTest(CcTest::TestFunction* callback,
     255             :                                 const char* name)
     256    12786720 :       : fuzzer_(nullptr), callback_(callback), name_(name) {
     257    12786720 :     prev_ = first_;
     258    12786720 :     first_ = this;
     259    12786720 :     count_++;
     260             :   }
     261     3461289 :   static int count() { return count_; }
     262     3457433 :   static RegisterThreadedTest* nth(int i) {
     263     3457433 :     CHECK(i < count());
     264     3457433 :     RegisterThreadedTest* current = first_;
     265   208328149 :     while (i > 0) {
     266   102435358 :       i--;
     267   102435358 :       current = current->prev_;
     268             :     }
     269     3457433 :     return current;
     270             :   }
     271             :   CcTest::TestFunction* callback() { return callback_; }
     272             :   ApiTestFuzzer* fuzzer_;
     273             :   const char* name() { return name_; }
     274             : 
     275             :  private:
     276             :   static RegisterThreadedTest* first_;
     277             :   static int count_;
     278             :   CcTest::TestFunction* callback_;
     279             :   RegisterThreadedTest* prev_;
     280             :   const char* name_;
     281             : };
     282             : 
     283             : // A LocalContext holds a reference to a v8::Context.
     284             : class LocalContext {
     285             :  public:
     286             :   LocalContext(v8::Isolate* isolate,
     287             :                v8::ExtensionConfiguration* extensions = nullptr,
     288             :                v8::Local<v8::ObjectTemplate> global_template =
     289             :                    v8::Local<v8::ObjectTemplate>(),
     290        2461 :                v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) {
     291        2461 :     Initialize(isolate, extensions, global_template, global_object);
     292             :   }
     293             : 
     294             :   LocalContext(v8::ExtensionConfiguration* extensions = nullptr,
     295             :                v8::Local<v8::ObjectTemplate> global_template =
     296             :                    v8::Local<v8::ObjectTemplate>(),
     297        9441 :                v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) {
     298        9441 :     Initialize(CcTest::isolate(), extensions, global_template, global_object);
     299             :   }
     300             : 
     301             :   virtual ~LocalContext();
     302             : 
     303             :   v8::Context* operator->() {
     304      112796 :     return *reinterpret_cast<v8::Context**>(&context_);
     305             :   }
     306             :   v8::Context* operator*() { return operator->(); }
     307             :   bool IsReady() { return !context_.IsEmpty(); }
     308             : 
     309             :   v8::Local<v8::Context> local() {
     310      188204 :     return v8::Local<v8::Context>::New(isolate_, context_);
     311             :   }
     312             : 
     313             :  private:
     314             :   void Initialize(v8::Isolate* isolate, v8::ExtensionConfiguration* extensions,
     315             :                   v8::Local<v8::ObjectTemplate> global_template,
     316             :                   v8::Local<v8::Value> global_object);
     317             : 
     318             :   v8::Persistent<v8::Context> context_;
     319             :   v8::Isolate* isolate_;
     320             : };
     321             : 
     322             : 
     323       26762 : static inline uint16_t* AsciiToTwoByteString(const char* source) {
     324       26762 :   int array_length = i::StrLength(source) + 1;
     325       26762 :   uint16_t* converted = i::NewArray<uint16_t>(array_length);
     326      269362 :   for (int i = 0; i < array_length; i++) converted[i] = source[i];
     327       26762 :   return converted;
     328             : }
     329             : 
     330             : template <typename T>
     331         134 : static inline i::Handle<T> GetGlobal(const char* name) {
     332             :   i::Isolate* isolate = CcTest::i_isolate();
     333             :   i::Handle<i::String> str_name =
     334         134 :       isolate->factory()->InternalizeUtf8String(name);
     335             : 
     336             :   i::Handle<i::Object> value =
     337         268 :       i::Object::GetProperty(isolate, isolate->global_object(), str_name)
     338         268 :           .ToHandleChecked();
     339         134 :   return i::Handle<T>::cast(value);
     340             : }
     341             : 
     342             : static inline v8::Local<v8::Boolean> v8_bool(bool val) {
     343          60 :   return v8::Boolean::New(v8::Isolate::GetCurrent(), val);
     344             : }
     345             : 
     346       77377 : static inline v8::Local<v8::Value> v8_num(double x) {
     347       77377 :   return v8::Number::New(v8::Isolate::GetCurrent(), x);
     348             : }
     349             : 
     350             : static inline v8::Local<v8::Integer> v8_int(int32_t x) {
     351          40 :   return v8::Integer::New(v8::Isolate::GetCurrent(), x);
     352             : }
     353             : 
     354      516671 : static inline v8::Local<v8::String> v8_str(const char* x) {
     355      516672 :   return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x,
     356      516671 :                                  v8::NewStringType::kNormal)
     357      516671 :       .ToLocalChecked();
     358             : }
     359             : 
     360             : 
     361        1024 : static inline v8::Local<v8::String> v8_str(v8::Isolate* isolate,
     362             :                                            const char* x) {
     363        1024 :   return v8::String::NewFromUtf8(isolate, x, v8::NewStringType::kNormal)
     364        1024 :       .ToLocalChecked();
     365             : }
     366             : 
     367             : 
     368           5 : static inline v8::Local<v8::Symbol> v8_symbol(const char* name) {
     369           5 :   return v8::Symbol::New(v8::Isolate::GetCurrent(), v8_str(name));
     370             : }
     371             : 
     372             : 
     373      116858 : static inline v8::Local<v8::Script> v8_compile(v8::Local<v8::String> x) {
     374             :   v8::Local<v8::Script> result;
     375      233716 :   if (v8::Script::Compile(v8::Isolate::GetCurrent()->GetCurrentContext(), x)
     376             :           .ToLocal(&result)) {
     377      116848 :     return result;
     378             :   }
     379          10 :   return v8::Local<v8::Script>();
     380             : }
     381             : 
     382             : 
     383             : static inline v8::Local<v8::Script> v8_compile(const char* x) {
     384        2232 :   return v8_compile(v8_str(x));
     385             : }
     386             : 
     387             : 
     388        2054 : static inline int32_t v8_run_int32value(v8::Local<v8::Script> script) {
     389        2054 :   v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
     390        6162 :   return script->Run(context).ToLocalChecked()->Int32Value(context).FromJust();
     391             : }
     392             : 
     393          60 : static inline v8::Local<v8::Script> CompileWithOrigin(
     394             :     v8::Local<v8::String> source, v8::Local<v8::String> origin_url,
     395             :     v8::Local<v8::Boolean> is_shared_cross_origin) {
     396             :   v8::ScriptOrigin origin(origin_url, v8::Local<v8::Integer>(),
     397             :                           v8::Local<v8::Integer>(), is_shared_cross_origin);
     398             :   v8::ScriptCompiler::Source script_source(source, origin);
     399          60 :   return v8::ScriptCompiler::Compile(
     400          60 :              v8::Isolate::GetCurrent()->GetCurrentContext(), &script_source)
     401          60 :       .ToLocalChecked();
     402             : }
     403             : 
     404          23 : static inline v8::Local<v8::Script> CompileWithOrigin(
     405             :     v8::Local<v8::String> source, const char* origin_url,
     406             :     bool is_shared_cross_origin) {
     407             :   return CompileWithOrigin(source, v8_str(origin_url),
     408          23 :                            v8_bool(is_shared_cross_origin));
     409             : }
     410             : 
     411          27 : static inline v8::Local<v8::Script> CompileWithOrigin(
     412             :     const char* source, const char* origin_url, bool is_shared_cross_origin) {
     413             :   return CompileWithOrigin(v8_str(source), v8_str(origin_url),
     414          27 :                            v8_bool(is_shared_cross_origin));
     415             : }
     416             : 
     417             : // Helper functions that compile and run the source.
     418         273 : static inline v8::MaybeLocal<v8::Value> CompileRun(
     419             :     v8::Local<v8::Context> context, const char* source) {
     420         273 :   return v8::Script::Compile(context, v8_str(source))
     421             :       .ToLocalChecked()
     422         273 :       ->Run(context);
     423             : }
     424             : 
     425             : 
     426         543 : static inline v8::Local<v8::Value> CompileRunChecked(v8::Isolate* isolate,
     427             :                                                      const char* source) {
     428             :   v8::Local<v8::String> source_string =
     429         543 :       v8::String::NewFromUtf8(isolate, source, v8::NewStringType::kNormal)
     430         543 :           .ToLocalChecked();
     431         543 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     432             :   v8::Local<v8::Script> script =
     433         543 :       v8::Script::Compile(context, source_string).ToLocalChecked();
     434        1086 :   return script->Run(context).ToLocalChecked();
     435             : }
     436             : 
     437             : 
     438      114488 : static inline v8::Local<v8::Value> CompileRun(v8::Local<v8::String> source) {
     439             :   v8::Local<v8::Value> result;
     440      228978 :   if (v8_compile(source)
     441      228977 :           ->Run(v8::Isolate::GetCurrent()->GetCurrentContext())
     442             :           .ToLocal(&result)) {
     443      111876 :     return result;
     444             :   }
     445        2613 :   return v8::Local<v8::Value>();
     446             : }
     447             : 
     448             : 
     449             : // Helper functions that compile and run the source.
     450             : static inline v8::Local<v8::Value> CompileRun(const char* source) {
     451      112625 :   return CompileRun(v8_str(source));
     452             : }
     453             : 
     454             : 
     455          80 : static inline v8::Local<v8::Value> CompileRun(
     456             :     v8::Local<v8::Context> context, v8::ScriptCompiler::Source* script_source,
     457             :     v8::ScriptCompiler::CompileOptions options) {
     458             :   v8::Local<v8::Value> result;
     459         160 :   if (v8::ScriptCompiler::Compile(context, script_source, options)
     460             :           .ToLocalChecked()
     461          80 :           ->Run(context)
     462             :           .ToLocal(&result)) {
     463          60 :     return result;
     464             :   }
     465          20 :   return v8::Local<v8::Value>();
     466             : }
     467             : 
     468             : 
     469             : // Helper functions that compile and run the source with given origin.
     470          60 : static inline v8::Local<v8::Value> CompileRunWithOrigin(const char* source,
     471             :                                                         const char* origin_url,
     472             :                                                         int line_number,
     473             :                                                         int column_number) {
     474          60 :   v8::Isolate* isolate = v8::Isolate::GetCurrent();
     475          60 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     476             :   v8::ScriptOrigin origin(v8_str(origin_url),
     477             :                           v8::Integer::New(isolate, line_number),
     478          60 :                           v8::Integer::New(isolate, column_number));
     479          60 :   v8::ScriptCompiler::Source script_source(v8_str(source), origin);
     480             :   return CompileRun(context, &script_source,
     481         120 :                     v8::ScriptCompiler::CompileOptions());
     482             : }
     483             : 
     484             : 
     485          20 : static inline v8::Local<v8::Value> CompileRunWithOrigin(
     486             :     v8::Local<v8::String> source, const char* origin_url) {
     487          20 :   v8::Isolate* isolate = v8::Isolate::GetCurrent();
     488          20 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     489             :   v8::ScriptCompiler::Source script_source(
     490          20 :       source, v8::ScriptOrigin(v8_str(origin_url)));
     491             :   return CompileRun(context, &script_source,
     492          40 :                     v8::ScriptCompiler::CompileOptions());
     493             : }
     494             : 
     495             : 
     496             : static inline v8::Local<v8::Value> CompileRunWithOrigin(
     497             :     const char* source, const char* origin_url) {
     498          20 :   return CompileRunWithOrigin(v8_str(source), origin_url);
     499             : }
     500             : 
     501             : // Takes a JSFunction and runs it through the test version of the optimizing
     502             : // pipeline, allocating the temporary compilation artifacts in a given Zone.
     503             : // For possible {flags} values, look at OptimizedCompilationInfo::Flag.
     504             : // If passed a non-null pointer for {broker}, outputs the JSHeapBroker to it.
     505             : i::Handle<i::JSFunction> Optimize(
     506             :     i::Handle<i::JSFunction> function, i::Zone* zone, i::Isolate* isolate,
     507             :     uint32_t flags, i::compiler::JSHeapBroker** out_broker = nullptr);
     508             : 
     509         872 : static inline void ExpectString(const char* code, const char* expected) {
     510             :   v8::Local<v8::Value> result = CompileRun(code);
     511         872 :   CHECK(result->IsString());
     512        1744 :   v8::String::Utf8Value utf8(v8::Isolate::GetCurrent(), result);
     513         872 :   CHECK_EQ(0, strcmp(expected, *utf8));
     514         872 : }
     515             : 
     516             : 
     517        1238 : static inline void ExpectInt32(const char* code, int expected) {
     518             :   v8::Local<v8::Value> result = CompileRun(code);
     519        1238 :   CHECK(result->IsInt32());
     520        2476 :   CHECK_EQ(expected,
     521             :            result->Int32Value(v8::Isolate::GetCurrent()->GetCurrentContext())
     522             :                .FromJust());
     523        1238 : }
     524             : 
     525             : 
     526         882 : static inline void ExpectBoolean(const char* code, bool expected) {
     527             :   v8::Local<v8::Value> result = CompileRun(code);
     528         882 :   CHECK(result->IsBoolean());
     529         882 :   CHECK_EQ(expected, result->BooleanValue(v8::Isolate::GetCurrent()));
     530         882 : }
     531             : 
     532             : 
     533             : static inline void ExpectTrue(const char* code) {
     534         254 :   ExpectBoolean(code, true);
     535             : }
     536             : 
     537             : 
     538             : static inline void ExpectFalse(const char* code) {
     539          89 :   ExpectBoolean(code, false);
     540             : }
     541             : 
     542             : 
     543          92 : static inline void ExpectObject(const char* code,
     544             :                                 v8::Local<v8::Value> expected) {
     545             :   v8::Local<v8::Value> result = CompileRun(code);
     546          92 :   CHECK(result->SameValue(expected));
     547          92 : }
     548             : 
     549             : 
     550          42 : static inline void ExpectUndefined(const char* code) {
     551             :   v8::Local<v8::Value> result = CompileRun(code);
     552          42 :   CHECK(result->IsUndefined());
     553          42 : }
     554             : 
     555             : 
     556             : static inline void ExpectNull(const char* code) {
     557             :   v8::Local<v8::Value> result = CompileRun(code);
     558             :   CHECK(result->IsNull());
     559             : }
     560             : 
     561             : 
     562           5 : static inline void CheckDoubleEquals(double expected, double actual) {
     563             :   const double kEpsilon = 1e-10;
     564          10 :   CHECK_LE(expected, actual + kEpsilon);
     565          10 :   CHECK_GE(expected, actual - kEpsilon);
     566           5 : }
     567             : 
     568     4848298 : static v8::debug::DebugDelegate dummy_delegate;
     569             : 
     570             : static inline void EnableDebugger(v8::Isolate* isolate) {
     571          30 :   v8::debug::SetDebugDelegate(isolate, &dummy_delegate);
     572             : }
     573             : 
     574             : 
     575             : static inline void DisableDebugger(v8::Isolate* isolate) {
     576          25 :   v8::debug::SetDebugDelegate(isolate, nullptr);
     577             : }
     578             : 
     579             : 
     580       26183 : static inline void EmptyMessageQueues(v8::Isolate* isolate) {
     581       45340 :   while (v8::platform::PumpMessageLoop(v8::internal::V8::GetCurrentPlatform(),
     582             :                                        isolate)) {
     583             :   }
     584       26183 : }
     585             : 
     586             : class InitializedHandleScopeImpl;
     587             : 
     588     1446740 : class InitializedHandleScope {
     589             :  public:
     590             :   InitializedHandleScope();
     591             :   ~InitializedHandleScope();
     592             : 
     593             :   // Prefixing the below with main_ reduces a lot of naming clashes.
     594             :   i::Isolate* main_isolate() { return main_isolate_; }
     595             : 
     596             :  private:
     597             :   i::Isolate* main_isolate_;
     598             :   std::unique_ptr<InitializedHandleScopeImpl> initialized_handle_scope_impl_;
     599             : };
     600             : 
     601     2885760 : class HandleAndZoneScope : public InitializedHandleScope {
     602             :  public:
     603             :   HandleAndZoneScope();
     604             :   ~HandleAndZoneScope();
     605             : 
     606             :   // Prefixing the below with main_ reduces a lot of naming clashes.
     607             :   i::Zone* main_zone() { return main_zone_.get(); }
     608             : 
     609             :  private:
     610             :   v8::internal::AccountingAllocator allocator_;
     611             :   std::unique_ptr<i::Zone> main_zone_;
     612             : };
     613             : 
     614             : class StaticOneByteResource : public v8::String::ExternalOneByteStringResource {
     615             :  public:
     616           5 :   explicit StaticOneByteResource(const char* data) : data_(data) {}
     617             : 
     618          10 :   ~StaticOneByteResource() override = default;
     619             : 
     620          10 :   const char* data() const override { return data_; }
     621             : 
     622          20 :   size_t length() const override { return strlen(data_); }
     623             : 
     624             :  private:
     625             :   const char* data_;
     626             : };
     627             : 
     628             : class ManualGCScope {
     629             :  public:
     630             :   ManualGCScope()
     631             :       : flag_concurrent_marking_(i::FLAG_concurrent_marking),
     632             :         flag_concurrent_sweeping_(i::FLAG_concurrent_sweeping),
     633             :         flag_stress_incremental_marking_(i::FLAG_stress_incremental_marking),
     634             :         flag_parallel_marking_(i::FLAG_parallel_marking),
     635             :         flag_detect_ineffective_gcs_near_heap_limit_(
     636         502 :             i::FLAG_detect_ineffective_gcs_near_heap_limit) {
     637         507 :     i::FLAG_concurrent_marking = false;
     638         507 :     i::FLAG_concurrent_sweeping = false;
     639         507 :     i::FLAG_stress_incremental_marking = false;
     640             :     // Parallel marking has a dependency on concurrent marking.
     641         507 :     i::FLAG_parallel_marking = false;
     642         507 :     i::FLAG_detect_ineffective_gcs_near_heap_limit = false;
     643             :   }
     644             :   ~ManualGCScope() {
     645         507 :     i::FLAG_concurrent_marking = flag_concurrent_marking_;
     646         507 :     i::FLAG_concurrent_sweeping = flag_concurrent_sweeping_;
     647         507 :     i::FLAG_stress_incremental_marking = flag_stress_incremental_marking_;
     648         507 :     i::FLAG_parallel_marking = flag_parallel_marking_;
     649             :     i::FLAG_detect_ineffective_gcs_near_heap_limit =
     650         507 :         flag_detect_ineffective_gcs_near_heap_limit_;
     651             :   }
     652             : 
     653             :  private:
     654             :   bool flag_concurrent_marking_;
     655             :   bool flag_concurrent_sweeping_;
     656             :   bool flag_stress_incremental_marking_;
     657             :   bool flag_parallel_marking_;
     658             :   bool flag_detect_ineffective_gcs_near_heap_limit_;
     659             : };
     660             : 
     661             : // This is an abstract base class that can be overridden to implement a test
     662             : // platform. It delegates all operations to a given platform at the time
     663             : // of construction.
     664             : class TestPlatform : public v8::Platform {
     665             :  public:
     666             :   // v8::Platform implementation.
     667           0 :   v8::PageAllocator* GetPageAllocator() override {
     668           0 :     return old_platform_->GetPageAllocator();
     669             :   }
     670             : 
     671           0 :   void OnCriticalMemoryPressure() override {
     672           0 :     old_platform_->OnCriticalMemoryPressure();
     673           0 :   }
     674             : 
     675           0 :   bool OnCriticalMemoryPressure(size_t length) override {
     676           0 :     return old_platform_->OnCriticalMemoryPressure(length);
     677             :   }
     678             : 
     679         191 :   int NumberOfWorkerThreads() override {
     680         191 :     return old_platform_->NumberOfWorkerThreads();
     681             :   }
     682             : 
     683           6 :   std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
     684             :       v8::Isolate* isolate) override {
     685           6 :     return old_platform_->GetForegroundTaskRunner(isolate);
     686             :   }
     687             : 
     688           7 :   void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
     689          21 :     old_platform_->CallOnWorkerThread(std::move(task));
     690           7 :   }
     691             : 
     692           0 :   void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task,
     693             :                                  double delay_in_seconds) override {
     694           0 :     old_platform_->CallDelayedOnWorkerThread(std::move(task), delay_in_seconds);
     695           0 :   }
     696             : 
     697           0 :   void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override {
     698             :     // This is a deprecated function and should not be called anymore.
     699           0 :     UNREACHABLE();
     700             :   }
     701             : 
     702           0 :   void CallDelayedOnForegroundThread(v8::Isolate* isolate, v8::Task* task,
     703             :                                      double delay_in_seconds) override {
     704             :     // This is a deprecated function and should not be called anymore.
     705           0 :     UNREACHABLE();
     706             :   }
     707             : 
     708       18848 :   double MonotonicallyIncreasingTime() override {
     709       18848 :     return old_platform_->MonotonicallyIncreasingTime();
     710             :   }
     711             : 
     712           0 :   double CurrentClockTimeMillis() override {
     713           0 :     return old_platform_->CurrentClockTimeMillis();
     714             :   }
     715             : 
     716           0 :   void CallIdleOnForegroundThread(v8::Isolate* isolate,
     717             :                                   v8::IdleTask* task) override {
     718             :     // This is a deprecated function and should not be called anymore.
     719           0 :     UNREACHABLE();
     720             :   }
     721             : 
     722           0 :   bool IdleTasksEnabled(v8::Isolate* isolate) override {
     723           0 :     return old_platform_->IdleTasksEnabled(isolate);
     724             :   }
     725             : 
     726        3810 :   v8::TracingController* GetTracingController() override {
     727        3810 :     return old_platform_->GetTracingController();
     728             :   }
     729             : 
     730             :  protected:
     731         244 :   TestPlatform() : old_platform_(i::V8::GetCurrentPlatform()) {}
     732         458 :   ~TestPlatform() override { i::V8::SetPlatformForTesting(old_platform_); }
     733             : 
     734             :   v8::Platform* old_platform() const { return old_platform_; }
     735             : 
     736             :  private:
     737             :   v8::Platform* old_platform_;
     738             : 
     739             :   DISALLOW_COPY_AND_ASSIGN(TestPlatform);
     740             : };
     741             : 
     742             : #endif  // ifndef CCTEST_H_

Generated by: LCOV version 1.10