19258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org// Copyright 2008 the V8 project authors. All rights reserved.
29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Redistribution and use in source and binary forms, with or without
39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// modification, are permitted provided that the following conditions are
49a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// met:
59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Redistributions of source code must retain the above copyright
79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       notice, this list of conditions and the following disclaimer.
89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Redistributions in binary form must reproduce the above
99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       copyright notice, this list of conditions and the following
109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       disclaimer in the documentation and/or other materials provided
119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       with the distribution.
129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Neither the name of Google Inc. nor the names of its
139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       contributors may be used to endorse or promote products derived
149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       from this software without specific prior written permission.
159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#ifndef CCTEST_H_
299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#define CCTEST_H_
309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
32c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/isolate-inl.h"
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
359a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#ifndef TEST
36528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#define TEST(Name)                                                             \
37528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static void Test##Name();                                                    \
38528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, true);  \
39528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static void Test##Name()
40528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#endif
41528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
42528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#ifndef UNINITIALIZED_TEST
43528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#define UNINITIALIZED_TEST(Name)                                               \
44528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static void Test##Name();                                                    \
45528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, false); \
46245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  static void Test##Name()
47245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif
48245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
49245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifndef DEPENDENT_TEST
50528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#define DEPENDENT_TEST(Name, Dep)                                              \
51528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static void Test##Name();                                                    \
52528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true, true);  \
539258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  static void Test##Name()
549258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org#endif
559258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
56a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org#ifndef UNINITIALIZED_DEPENDENT_TEST
57a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org#define UNINITIALIZED_DEPENDENT_TEST(Name, Dep)                                \
58a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  static void Test##Name();                                                    \
59a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true, false); \
60a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  static void Test##Name()
61a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org#endif
62a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
639258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org#ifndef DISABLED_TEST
64528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#define DISABLED_TEST(Name)                                                    \
65528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static void Test##Name();                                                    \
66528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, false, true); \
679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  static void Test##Name()
689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#endif
699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
7043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org#define EXTENSION_LIST(V)                                                      \
7143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  V(GC_EXTENSION,       "v8/gc")                                               \
7243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  V(PRINT_EXTENSION,    "v8/print")                                            \
7343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  V(PROFILER_EXTENSION, "v8/profiler")                                         \
7443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  V(TRACE_EXTENSION,    "v8/trace")
75e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
76e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#define DEFINE_EXTENSION_ID(Name, Ident) Name##_ID,
77e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgenum CcTestExtensionIds {
78e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  EXTENSION_LIST(DEFINE_EXTENSION_ID)
79e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  kMaxExtensions
80e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org};
81e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#undef DEFINE_EXTENSION_ID
82e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
83e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef v8::internal::EnumSet<CcTestExtensionIds> CcTestExtensionFlags;
84e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#define DEFINE_EXTENSION_FLAG(Name, Ident)                               \
85e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const CcTestExtensionFlags Name(1 << Name##_ID);
86e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const CcTestExtensionFlags NO_EXTENSIONS(0);
87e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static const CcTestExtensionFlags ALL_EXTENSIONS((1 << kMaxExtensions) - 1);
88e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  EXTENSION_LIST(DEFINE_EXTENSION_FLAG)
89e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#undef DEFINE_EXTENSION_FLAG
90e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
91c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
923484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use this to expose protected methods in i::Heap.
933484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgclass TestHeap : public i::Heap {
943484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org public:
95a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  using i::Heap::AllocateByteArray;
96a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  using i::Heap::AllocateFixedArray;
973484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  using i::Heap::AllocateHeapNumber;
983484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  using i::Heap::AllocateJSObject;
993484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  using i::Heap::AllocateJSObjectFromMap;
100a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  using i::Heap::AllocateMap;
1013484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  using i::Heap::CopyCode;
1023484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org};
1033484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
1043484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
1059a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comclass CcTest {
1069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com public:
1079a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  typedef void (TestFunction)();
1089258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  CcTest(TestFunction* callback, const char* file, const char* name,
109528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org         const char* dependency, bool enabled, bool initialize);
110528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void Run();
1119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  static CcTest* last() { return last_; }
1129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  CcTest* prev() { return prev_; }
1139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  const char* file() { return file_; }
1149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  const char* name() { return name_; }
115245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  const char* dependency() { return dependency_; }
1169258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  bool enabled() { return enabled_; }
11757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
118528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static v8::Isolate* isolate() {
119528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    CHECK(isolate_ != NULL);
120528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    isolate_used_ = true;
121528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return isolate_;
12257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
12357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static i::Isolate* InitIsolateOnce() {
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (!initialize_called_) InitializeVM();
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return i_isolate();
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1292c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  static i::Isolate* i_isolate() {
130528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return reinterpret_cast<i::Isolate*>(isolate());
131528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
132528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
133528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static i::Heap* heap() {
134528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return i_isolate()->heap();
135528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
136528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1373484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  static TestHeap* test_heap() {
1383484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    return reinterpret_cast<TestHeap*>(i_isolate()->heap());
1393484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  }
1403484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static v8::base::RandomNumberGenerator* random_number_generator() {
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return InitIsolateOnce()->random_number_generator();
1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
145528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static v8::Local<v8::Object> global() {
146528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return isolate()->GetCurrentContext()->Global();
147528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
148528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
149528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // TODO(dcarney): Remove.
150528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // This must be called first in a test.
151528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static void InitializeVM() {
152528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    CHECK(!isolate_used_);
153528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    CHECK(!initialize_called_);
154528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    initialize_called_ = true;
155528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    v8::HandleScope handle_scope(CcTest::isolate());
156528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    v8::Context::New(CcTest::isolate())->Enter();
1572c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  }
1582c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org
159528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Only for UNINITIALIZED_TESTs
160528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static void DisableAutomaticDispose();
161528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
162528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Helper function to configure a context.
163528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Must be in a HandleScope.
164528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static v8::Local<v8::Context> NewContext(
165528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      CcTestExtensionFlags extensions,
166528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      v8::Isolate* isolate = CcTest::isolate());
16746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
16857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  static void TearDown() {
1690a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (isolate_ != NULL) isolate_->Dispose();
17057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
17157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
1729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com private:
17357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  friend int main(int argc, char** argv);
1749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  TestFunction* callback_;
1759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  const char* file_;
1769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  const char* name_;
177245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  const char* dependency_;
1789258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  bool enabled_;
179528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bool initialize_;
1809a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  CcTest* prev_;
181e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  static CcTest* last_;
182528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static v8::Isolate* isolate_;
183528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static bool initialize_called_;
184528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  static bool isolate_used_;
1859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
1869a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
187c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// Switches between all the Api tests using the threading support.
188c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// In order to get a surprising but repeatable pattern of thread
189c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// switching it has extra semaphores to control the order in which
190c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// the tests alternate, not relying solely on the big V8 lock.
191c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org//
192c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// A test is augmented with calls to ApiTestFuzzer::Fuzz() in its
193c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// callbacks.  This will have no effect when we are not running the
194c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// thread fuzzing test.  In the thread fuzzing test it will
195c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// pseudorandomly select a successor thread and switch execution
196c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// to that thread, suspending the current test.
1975de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgclass ApiTestFuzzer: public v8::base::Thread {
198c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org public:
199c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  void CallTest();
200c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
201c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // The ApiTestFuzzer is also a Thread, so it has a Run method.
202c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  virtual void Run();
203c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2041c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  enum PartOfTest { FIRST_PART,
2051c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                    SECOND_PART,
2061c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                    THIRD_PART,
2071c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                    FOURTH_PART,
2081c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                    LAST_PART = FOURTH_PART };
209c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
210f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  static void SetUp(PartOfTest part);
211c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static void RunAllTests();
212c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static void TearDown();
213c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // This method switches threads if we are running the Threading test.
214c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Otherwise it does nothing.
215c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static void Fuzz();
21683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
217c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org private:
21846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  explicit ApiTestFuzzer(int num)
2195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      : Thread(Options("ApiTestFuzzer")),
22046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org        test_number_(num),
221e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org        gate_(0),
2225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        active_(true) {}
223e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  ~ApiTestFuzzer() {}
22446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
225c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static bool fuzzing_;
226c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static int tests_being_run_;
227c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static int current_;
228c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static int active_tests_;
229c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static bool NextThread();
230c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  int test_number_;
2315de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  v8::base::Semaphore gate_;
232c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  bool active_;
233c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  void ContextSwitch();
234c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static int GetNextTestNumber();
2355de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  static v8::base::Semaphore all_tests_done_;
236c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org};
237c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
238c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
239c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#define THREADED_TEST(Name)                                          \
240c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static void Test##Name();                                          \
241c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  RegisterThreadedTest register_##Name(Test##Name, #Name);           \
242c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  /* */ TEST(Name)
243c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
244c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
245c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgclass RegisterThreadedTest {
246c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org public:
247c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  explicit RegisterThreadedTest(CcTest::TestFunction* callback,
248c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                                const char* name)
249c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      : fuzzer_(NULL), callback_(callback), name_(name) {
250c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    prev_ = first_;
251c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    first_ = this;
252c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    count_++;
253c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
254c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static int count() { return count_; }
255c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static RegisterThreadedTest* nth(int i) {
256c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    CHECK(i < count());
257c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    RegisterThreadedTest* current = first_;
258c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    while (i > 0) {
259c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      i--;
260c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      current = current->prev_;
261c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    }
262c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    return current;
263c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
264c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  CcTest::TestFunction* callback() { return callback_; }
265c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  ApiTestFuzzer* fuzzer_;
266c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  const char* name() { return name_; }
267c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
268c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org private:
269c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static RegisterThreadedTest* first_;
270c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static int count_;
271c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  CcTest::TestFunction* callback_;
272c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  RegisterThreadedTest* prev_;
273c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  const char* name_;
274c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org};
275c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
276c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// A LocalContext holds a reference to a v8::Context.
277c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgclass LocalContext {
278c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org public:
279528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  LocalContext(v8::Isolate* isolate,
280528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org               v8::ExtensionConfiguration* extensions = 0,
281528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org               v8::Handle<v8::ObjectTemplate> global_template =
282528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                   v8::Handle<v8::ObjectTemplate>(),
283528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org               v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) {
284528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Initialize(isolate, extensions, global_template, global_object);
285528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
286528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
287c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  LocalContext(v8::ExtensionConfiguration* extensions = 0,
288c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org               v8::Handle<v8::ObjectTemplate> global_template =
289c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                   v8::Handle<v8::ObjectTemplate>(),
29057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org               v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) {
291528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Initialize(CcTest::isolate(), extensions, global_template, global_object);
292c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
293c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
294c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  virtual ~LocalContext() {
295f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    v8::HandleScope scope(isolate_);
296f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    v8::Local<v8::Context>::New(isolate_, context_)->Exit();
297f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    context_.Reset();
298c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
299c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
300f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  v8::Context* operator->() {
301f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org    return *reinterpret_cast<v8::Context**>(&context_);
302f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  }
303f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  v8::Context* operator*() { return operator->(); }
304c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  bool IsReady() { return !context_.IsEmpty(); }
305c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
306c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  v8::Local<v8::Context> local() {
30757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    return v8::Local<v8::Context>::New(isolate_, context_);
308c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  }
309c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
310c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org private:
311528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void Initialize(v8::Isolate* isolate,
312528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                  v8::ExtensionConfiguration* extensions,
313528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                  v8::Handle<v8::ObjectTemplate> global_template,
314528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                  v8::Handle<v8::Value> global_object) {
315528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org     v8::HandleScope scope(isolate);
316528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org     v8::Local<v8::Context> context = v8::Context::New(isolate,
317528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                                       extensions,
318528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                                       global_template,
319528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                                       global_object);
320528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org     context_.Reset(isolate, context);
321528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org     context->Enter();
322528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org     // We can't do this later perhaps because of a fatal error.
323528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org     isolate_ = isolate;
324528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
325528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
326c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  v8::Persistent<v8::Context> context_;
327d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  v8::Isolate* isolate_;
328c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org};
329c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
330196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
331196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline uint16_t* AsciiToTwoByteString(const char* source) {
332196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  int array_length = i::StrLength(source) + 1;
333196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  uint16_t* converted = i::NewArray<uint16_t>(array_length);
334196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  for (int i = 0; i < array_length; i++) converted[i] = source[i];
335196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return converted;
336196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
337196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
338196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
339c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgstatic inline v8::Local<v8::Value> v8_num(double x) {
3400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return v8::Number::New(v8::Isolate::GetCurrent(), x);
341c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
342c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
343c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
344c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgstatic inline v8::Local<v8::String> v8_str(const char* x) {
345f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x);
346c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
347c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
348c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
349c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgstatic inline v8::Local<v8::Script> v8_compile(const char* x) {
350c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  return v8::Script::Compile(v8_str(x));
351c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
352c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
353c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
354bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgstatic inline v8::Local<v8::Script> v8_compile(v8::Local<v8::String> x) {
355bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  return v8::Script::Compile(x);
356bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
357bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
358bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
3596b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgstatic inline v8::Local<v8::Script> CompileWithOrigin(
3606b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org    v8::Local<v8::String> source, v8::Local<v8::String> origin_url) {
3616b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  v8::ScriptOrigin origin(origin_url);
36269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  v8::ScriptCompiler::Source script_source(source, origin);
3636b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  return v8::ScriptCompiler::Compile(
36469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      v8::Isolate::GetCurrent(), &script_source);
365bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
366bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
367bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
368bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgstatic inline v8::Local<v8::Script> CompileWithOrigin(
369bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    v8::Local<v8::String> source, const char* origin_url) {
3706b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  return CompileWithOrigin(source, v8_str(origin_url));
3716b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org}
3726b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
3736b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
3746b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgstatic inline v8::Local<v8::Script> CompileWithOrigin(const char* source,
3756b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org                                                      const char* origin_url) {
3766b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  return CompileWithOrigin(v8_str(source), v8_str(origin_url));
377bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
378bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
379bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
380bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org// Helper functions that compile and run the source.
381c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgstatic inline v8::Local<v8::Value> CompileRun(const char* source) {
382bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  return v8::Script::Compile(v8_str(source))->Run();
383bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
384bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
385bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
386bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgstatic inline v8::Local<v8::Value> CompileRun(v8::Local<v8::String> source) {
387bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  return v8::Script::Compile(source)->Run();
388c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org}
389c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
390c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
3914c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.orgstatic inline v8::Local<v8::Value> ParserCacheCompileRun(const char* source) {
3928f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // Compile once just to get the preparse data, then compile the second time
3938f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // using the data.
3946b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  v8::Isolate* isolate = v8::Isolate::GetCurrent();
3958f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  v8::ScriptCompiler::Source script_source(v8_str(source));
3968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  v8::ScriptCompiler::Compile(isolate, &script_source,
3974c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org                              v8::ScriptCompiler::kProduceParserCache);
3984c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org
3994c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  // Check whether we received cached data, and if so use it.
4004c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  v8::ScriptCompiler::CompileOptions options =
4014c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org      script_source.GetCachedData() ? v8::ScriptCompiler::kConsumeParserCache
4024c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org                                    : v8::ScriptCompiler::kNoCompileOptions;
4034c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org
4044c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  return v8::ScriptCompiler::Compile(isolate, &script_source, options)->Run();
405f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
406f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
407f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
408bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org// Helper functions that compile and run the source with given origin.
40933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgstatic inline v8::Local<v8::Value> CompileRunWithOrigin(const char* source,
41033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                                                        const char* origin_url,
41133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                                                        int line_number,
41233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org                                                        int column_number) {
413f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  v8::Isolate* isolate = v8::Isolate::GetCurrent();
414bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  v8::ScriptOrigin origin(v8_str(origin_url),
4150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                          v8::Integer::New(isolate, line_number),
4160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                          v8::Integer::New(isolate, column_number));
41769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  v8::ScriptCompiler::Source script_source(v8_str(source), origin);
41869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  return v8::ScriptCompiler::Compile(isolate, &script_source)->Run();
419bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org}
420bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
421bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
422bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgstatic inline v8::Local<v8::Value> CompileRunWithOrigin(
4236b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org    v8::Local<v8::String> source, const char* origin_url) {
42469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  v8::ScriptCompiler::Source script_source(
42569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      source, v8::ScriptOrigin(v8_str(origin_url)));
42669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &script_source)
42769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      ->Run();
4286b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org}
4296b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
4306b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
4316b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgstatic inline v8::Local<v8::Value> CompileRunWithOrigin(
4326b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org    const char* source, const char* origin_url) {
4336b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  return CompileRunWithOrigin(v8_str(source), origin_url);
43433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org}
43533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
43633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
437196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
438196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline void ExpectString(const char* code, const char* expected) {
439196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  v8::Local<v8::Value> result = CompileRun(code);
440196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(result->IsString());
441196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  v8::String::Utf8Value utf8(result);
442196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK_EQ(expected, *utf8);
443196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
444196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
445196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
446196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline void ExpectInt32(const char* code, int expected) {
447196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  v8::Local<v8::Value> result = CompileRun(code);
448196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(result->IsInt32());
449196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK_EQ(expected, result->Int32Value());
450196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
451196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
452196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
453196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline void ExpectBoolean(const char* code, bool expected) {
454196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  v8::Local<v8::Value> result = CompileRun(code);
455196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(result->IsBoolean());
456196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK_EQ(expected, result->BooleanValue());
457196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
458196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
459196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
460196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline void ExpectTrue(const char* code) {
461196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ExpectBoolean(code, true);
462196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
463196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
464196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
465196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline void ExpectFalse(const char* code) {
466196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ExpectBoolean(code, false);
467196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
468196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
469196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
470196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline void ExpectObject(const char* code,
471196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                v8::Local<v8::Value> expected) {
472196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  v8::Local<v8::Value> result = CompileRun(code);
473196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(result->SameValue(expected));
474196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
475196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
476196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
477196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgstatic inline void ExpectUndefined(const char* code) {
478196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  v8::Local<v8::Value> result = CompileRun(code);
479196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  CHECK(result->IsUndefined());
480196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
481196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
482196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
4832f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// Helper function that simulates a full new-space in the heap.
4848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgstatic inline void SimulateFullSpace(v8::internal::NewSpace* space) {
4858e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  int new_linear_size = static_cast<int>(
4868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      *space->allocation_limit_address() - *space->allocation_top_address());
487b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (new_linear_size == 0) return;
488a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  v8::internal::AllocationResult allocation =
489a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      space->AllocateRaw(new_linear_size);
490a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  v8::internal::FreeListNode* node =
491a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
4928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  node->set_size(space->heap(), new_linear_size);
4938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
4948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
4958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
4968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org// Helper function that simulates a full old-space in the heap.
4978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.orgstatic inline void SimulateFullSpace(v8::internal::PagedSpace* space) {
498b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  space->EmptyAllocationInfo();
4998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  space->ResetFreeList();
5008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  space->ClearStats();
5018e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
5028e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
5038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
5043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// Helper function that simulates many incremental marking steps until
5053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// marking is completed.
5063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic inline void SimulateIncrementalMarking(i::Heap* heap) {
5073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  i::MarkCompactCollector* collector = heap->mark_compact_collector();
5083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  i::IncrementalMarking* marking = heap->incremental_marking();
5093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (collector->sweeping_in_progress()) {
5103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    collector->EnsureSweepingCompleted();
5113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
5123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  CHECK(marking->IsMarking() || marking->IsStopped());
5133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (marking->IsStopped()) {
5143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    marking->Start();
5153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
5163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  CHECK(marking->IsMarking());
5173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  while (!marking->IsComplete()) {
5183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD);
5193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
5203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  CHECK(marking->IsComplete());
5213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
5223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
5233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
524a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org// Helper class for new allocations tracking and checking.
525a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org// To use checking of JS allocations tracking in a test,
526a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org// just create an instance of this class.
527a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgclass HeapObjectsTracker {
528a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org public:
529a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  HeapObjectsTracker() {
530a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    heap_profiler_ = i::Isolate::Current()->heap_profiler();
531a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    CHECK_NE(NULL, heap_profiler_);
532ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    heap_profiler_->StartHeapObjectsTracking(true);
533a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
534a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
535a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  ~HeapObjectsTracker() {
536a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    i::Isolate::Current()->heap()->CollectAllAvailableGarbage();
537ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org    CHECK_EQ(0, heap_profiler_->heap_object_map()->FindUntrackedObjects());
538ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    heap_profiler_->StopHeapObjectsTracking();
539a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
540a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
541a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org private:
542a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  i::HeapProfiler* heap_profiler_;
543a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org};
544a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
545a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
5467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass InitializedHandleScope {
5477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
5487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InitializedHandleScope()
5497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      : main_isolate_(CcTest::InitIsolateOnce()),
5507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        handle_scope_(main_isolate_) {}
5517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Prefixing the below with main_ reduces a lot of naming clashes.
5537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  i::Isolate* main_isolate() { return main_isolate_; }
5547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
5567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  i::Isolate* main_isolate_;
5577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  i::HandleScope handle_scope_;
5587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
5597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass HandleAndZoneScope : public InitializedHandleScope {
5627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
5637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  HandleAndZoneScope() : main_zone_(main_isolate()) {}
5647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Prefixing the below with main_ reduces a lot of naming clashes.
5667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  i::Zone* main_zone() { return &main_zone_; }
5677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
5697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  i::Zone main_zone_;
5707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
5717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#endif  // ifndef CCTEST_H_
573