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

Generated by: LCOV version 1.10