Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE

This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.

FPIIM-449

Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/test/cctest/compiler/test-run-bytecode-graph-builder.cc b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
index 88555b7..9a03822 100644
--- a/test/cctest/compiler/test-run-bytecode-graph-builder.cc
+++ b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
@@ -16,6 +16,14 @@
 namespace internal {
 namespace compiler {
 
+#define SHARD_TEST_BY_2(x)    \
+  TEST(x##_0) { Test##x(0); } \
+  TEST(x##_1) { Test##x(1); }
+#define SHARD_TEST_BY_4(x)    \
+  TEST(x##_0) { Test##x(0); } \
+  TEST(x##_1) { Test##x(1); } \
+  TEST(x##_2) { Test##x(2); } \
+  TEST(x##_3) { Test##x(3); }
 
 static const char kFunctionName[] = "f";
 
@@ -70,7 +78,7 @@
     i::FLAG_ignition = true;
     i::FLAG_always_opt = false;
     i::FLAG_allow_natives_syntax = true;
-    i::FLAG_ignition_fallback_on_eval_and_catch = false;
+    i::FLAG_loop_assignment_analysis = false;
     // Set ignition filter flag via SetFlagsFromString to avoid double-free
     // (or potential leak with StrDup() based on ownership confusion).
     ScopedVector<char> ignition_filter(64);
@@ -119,13 +127,13 @@
         Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
     CHECK(function->shared()->HasBytecodeArray());
 
+    // TODO(mstarzinger): We should be able to prime CompilationInfo without
+    // having to instantiate a ParseInfo first. Fix this!
     ParseInfo parse_info(zone_, function);
 
     CompilationInfo compilation_info(&parse_info);
-    compilation_info.SetOptimizing(BailoutId::None(), Handle<Code>());
+    compilation_info.SetOptimizing();
     compilation_info.MarkAsDeoptimizationEnabled();
-    // TODO(mythria): Remove this step once parse_info is not needed.
-    CHECK(Compiler::ParseAndAnalyze(&parse_info));
     compiler::Pipeline pipeline(&compilation_info);
     Handle<Code> code = pipeline.GenerateCode();
     function->ReplaceCode(*code);
@@ -205,8 +213,7 @@
       {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}},
       {"return NaN;", {factory->nan_value()}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -233,8 +240,7 @@
       {"return 25 % 7;", {factory->NewNumberFromInt(4)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -292,8 +298,7 @@
         factory->NewStringFromStaticChars("abc"),
         factory->NewStringFromStaticChars("def")}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1, p2) { %s }\n%s(0, 0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -337,8 +342,7 @@
         BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -394,8 +398,7 @@
         factory->NewNumberFromInt(100)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -409,8 +412,7 @@
   }
 }
 
-
-TEST(BytecodeGraphBuilderNamedStore) {
+void TestBytecodeGraphBuilderNamedStore(size_t shard) {
   HandleAndZoneScope scope;
   Isolate* isolate = scope.main_isolate();
   Zone* zone = scope.main_zone();
@@ -445,8 +447,8 @@
         BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    if ((i % 2) != shard) continue;
     ScopedVector<char> script(3072);
     SNPrintF(script, "function %s(p1) { %s };\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -459,8 +461,9 @@
   }
 }
 
+SHARD_TEST_BY_2(BytecodeGraphBuilderNamedStore)
 
-TEST(BytecodeGraphBuilderKeyedStore) {
+void TestBytecodeGraphBuilderKeyedStore(size_t shard) {
   HandleAndZoneScope scope;
   Isolate* isolate = scope.main_isolate();
   Zone* zone = scope.main_zone();
@@ -503,8 +506,8 @@
         factory->NewNumberFromInt(100)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    if ((i % 2) != shard) continue;
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1, p2) { %s };\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -517,6 +520,7 @@
   }
 }
 
+SHARD_TEST_BY_2(BytecodeGraphBuilderKeyedStore)
 
 TEST(BytecodeGraphBuilderPropertyCall) {
   HandleAndZoneScope scope;
@@ -538,8 +542,7 @@
             "  return a + b + c + d + e + f + g + h;}})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s({func() {}});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -582,8 +585,7 @@
        {factory->NewNumberFromInt(25)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -621,8 +623,7 @@
        {factory->NewNumberFromInt(25)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -649,8 +650,7 @@
         BytecodeGraphTester::NewObject("[1, 2, 3]")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<Handle<Object>>();
     Handle<Object> return_value =
@@ -659,8 +659,7 @@
   }
 }
 
-
-TEST(BytecodeGraphBuilderGlobals) {
+void TestBytecodeGraphBuilderGlobals(size_t shard) {
   HandleAndZoneScope scope;
   Isolate* isolate = scope.main_isolate();
   Zone* zone = scope.main_zone();
@@ -700,8 +699,8 @@
        {factory->NewStringFromStaticChars("number")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    if ((i % 2) != shard) continue;
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -709,6 +708,7 @@
   }
 }
 
+SHARD_TEST_BY_2(BytecodeGraphBuilderGlobals)
 
 TEST(BytecodeGraphBuilderToObject) {
   // TODO(mythria): tests for ToObject. Needs ForIn.
@@ -746,8 +746,7 @@
        {factory->NewNumberFromInt(10)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -778,8 +777,7 @@
        {factory->false_value(), factory->NewStringFromStaticChars("abc")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -816,8 +814,7 @@
         factory->NewStringFromStaticChars("abc")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -871,8 +868,7 @@
        {factory->nan_value(), factory->NewStringFromStaticChars("String")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -911,8 +907,7 @@
         BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -966,8 +961,7 @@
        {factory->true_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s %s({});", snippets[i].code_snippet, kFunctionName);
 
@@ -1003,8 +997,7 @@
       {"return delete z;", {factory->false_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
              function_epilogue);
@@ -1045,8 +1038,7 @@
       {"'use strict'; obj.val = 23.456; return obj.val;",
        {factory->NewNumber(23.456)}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
              function_epilogue);
@@ -1089,8 +1081,7 @@
       {"'use strict';" REPEAT_256(SPACE, "y = 2.3;") "return obj.val = 23.456;",
        {factory->NewNumber(23.456)}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(3072);
     SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
              function_epilogue);
@@ -1120,8 +1111,7 @@
        {handle(Smi::FromInt(30), isolate)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1173,8 +1163,7 @@
        {factory->NewStringFromStaticChars("object")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1202,8 +1191,7 @@
        {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1234,8 +1222,7 @@
        {factory->NewStringFromStaticChars("undefined")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -1366,8 +1353,7 @@
         factory->NewNumberFromInt(1)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1399,8 +1385,7 @@
        {factory->true_value(), factory->undefined_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1413,6 +1398,98 @@
   }
 }
 
+TEST(BytecodeGraphBuilderTryCatch) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var a = 1; try { a = 2 } catch(e) { a = 3 }; return a;",
+       {handle(Smi::FromInt(2), isolate)}},
+      {"var a; try { undef.x } catch(e) { a = 2 }; return a;",
+       {handle(Smi::FromInt(2), isolate)}},
+      {"var a; try { throw 1 } catch(e) { a = e + 2 }; return a;",
+       {handle(Smi::FromInt(3), isolate)}},
+      {"var a; try { throw 1 } catch(e) { a = e + 2 };"
+       "       try { throw a } catch(e) { a = e + 3 }; return a;",
+       {handle(Smi::FromInt(6), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderTryFinally1) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var a = 1; try { a = a + 1; } finally { a = a + 2; }; return a;",
+       {handle(Smi::FromInt(4), isolate)}},
+      {"var a = 1; try { a = 2; return 23; } finally { a = 3 }; return a;",
+       {handle(Smi::FromInt(23), isolate)}},
+      {"var a = 1; try { a = 2; throw 23; } finally { return a; };",
+       {handle(Smi::FromInt(2), isolate)}},
+      {"var a = 1; for (var i = 10; i < 20; i += 5) {"
+       "  try { a = 2; break; } finally { a = 3; }"
+       "} return a + i;",
+       {handle(Smi::FromInt(13), isolate)}},
+      {"var a = 1; for (var i = 10; i < 20; i += 5) {"
+       "  try { a = 2; continue; } finally { a = 3; }"
+       "} return a + i;",
+       {handle(Smi::FromInt(23), isolate)}},
+      {"var a = 1; try { a = 2;"
+       "  try { a = 3; throw 23; } finally { a = 4; }"
+       "} catch(e) { a = a + e; } return a;",
+       {handle(Smi::FromInt(27), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderTryFinally2) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0, const char*> snippets[] = {
+      {"var a = 1; try { a = 2; throw 23; } finally { a = 3 }; return a;",
+       {"Uncaught 23"}},
+      {"var a = 1; try { a = 2; throw 23; } finally { throw 42; };",
+       {"Uncaught 42"}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+    v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value());
+    CHECK(
+        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+            .FromJust());
+  }
+}
 
 TEST(BytecodeGraphBuilderThrow) {
   HandleAndZoneScope scope;
@@ -1426,15 +1503,14 @@
       {"throw 1;", {"Uncaught 1"}},
       {"throw 'Error';", {"Uncaught Error"}},
       {"throw 'Error1'; throw 'Error2'", {"Uncaught Error1"}},
-      // TODO(mythria): Enable these tests when JumpIfTrue is supported.
-      // {"var a = true; if (a) { throw 'Error'; }", {"Error"}},
+      {"var a = true; if (a) { throw 'Error'; }", {"Uncaught Error"}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
+
     BytecodeGraphTester tester(isolate, zone, script.start());
     v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
     v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value());
@@ -1492,8 +1568,7 @@
        {factory->NewStringFromStaticChars("innermost inner_changed outer")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s", snippets[i].code_snippet);
 
@@ -1558,8 +1633,7 @@
        "f(0);",
        {factory->NewNumberFromInt(24), factory->NewNumberFromInt(4)}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s", snippets[i].code_snippet);
 
@@ -1585,10 +1659,13 @@
        {factory->undefined_value()}},
       {"function f(a) {'use strict'; return arguments[0];}",
        {factory->undefined_value()}},
+      {"function f(...restArgs) {return restArgs[0];}",
+       {factory->undefined_value()}},
+      {"function f(a, ...restArgs) {return restArgs[0];}",
+       {factory->undefined_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
 
@@ -1631,8 +1708,7 @@
         factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
 
@@ -1647,6 +1723,48 @@
   }
 }
 
+TEST(BytecodeGraphBuilderCreateRestArguments) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<3> snippets[] = {
+      {"function f(...restArgs) {return restArgs[0];}",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, ...restArgs) {return restArgs[0];}",
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, ...restArgs) {return arguments[2];}",
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, ...restArgs) { return restArgs[2];}",
+       {factory->undefined_value(), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, ...restArgs) { return arguments[0] + restArgs[1];}",
+       {factory->NewNumberFromInt(4), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function inline_func(a, ...restArgs) { return restArgs[0] }"
+       "function f(a, b, c) {return inline_func(b, c) + arguments[0];}",
+       {factory->NewNumberFromInt(31), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable =
+        tester.GetCallable<Handle<Object>, Handle<Object>, Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0), snippets[i].parameter(1),
+                 snippets[i].parameter(2))
+            .ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
 
 TEST(BytecodeGraphBuilderRegExpLiterals) {
   HandleAndZoneScope scope;
@@ -1671,8 +1789,7 @@
        {factory->NewStringFromStaticChars("AbC")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(4096);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1712,8 +1829,7 @@
       {"var t = 't'; return [[t, t + 'est'], [1 + t]][1][0];",
        {factory->NewStringFromStaticChars("1t")}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(4096);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1778,8 +1894,7 @@
        {factory->NewNumberFromInt(987)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(4096);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1856,10 +1971,38 @@
        "   if (p1 < -10) { return -2; } else { return -1; }\n"
        "}",
        {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-10)}},
+      {"var b = 20, c;"
+       "if (p1 >= 0) {\n"
+       "   if (b > 0) { c = 2; } else { c = 3; }\n"
+       "} else {\n"
+       "   if (b < -10) { c = -2; } else { c = -1; }\n"
+       "}"
+       "return c;",
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-1)}},
+      {"var b = 20, c = 10;"
+       "if (p1 >= 0) {\n"
+       "   if (b < 0) { c = 2; }\n"
+       "} else {\n"
+       "   if (b < -10) { c = -2; } else { c = -1; }\n"
+       "}"
+       "return c;",
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(1)}},
+      {"var x = 2, a = 10, b = 20, c, d;"
+       "x = 0;"
+       "if (a) {\n"
+       "   b = x;"
+       "   if (b > 0) { c = 2; } else { c = 3; }\n"
+       "   x = 4; d = 2;"
+       "} else {\n"
+       "   d = 3;\n"
+       "}"
+       "x = d;"
+       "function f1() {x}"
+       "return x + c;",
+       {factory->NewNumberFromInt(5), factory->NewNumberFromInt(-1)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1890,8 +2033,7 @@
        {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(20)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1952,6 +2094,54 @@
   }
 }
 
+TEST(BytecodeGraphBuilderSwitchMerge) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  const char* switch_code =
+      "var x = 10;"
+      "switch (p1) {\n"
+      "  case 1: x = 0;\n"
+      "  case 2: x = 1;\n"
+      "  case 3:\n"
+      "  case 4: x = 2; break;\n"
+      "  case 5: x = 3;\n"
+      "  case 9: break;\n"
+      "  default: x = 4;\n"
+      "}\n"
+      "return x;";
+
+  ExpectedSnippet<1> snippets[] = {
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(2)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(4)}},
+      {switch_code,
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(5)}},
+      {switch_code,
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(9)}},
+      {switch_code,
+       {factory->NewNumberFromInt(4), factory->NewNumberFromInt(6)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
 
 TEST(BytecodeGraphBuilderNestedSwitch) {
   HandleAndZoneScope scope;
@@ -2294,12 +2484,102 @@
 }
 
 
-TEST(JumpWithConstantsAndWideConstants) {
+TEST(BytecodeGraphBuilderForOf) {
   HandleAndZoneScope scope;
-  auto isolate = scope.main_isolate();
-  const int kStep = 19;
-  int start = 7;
-  for (int constants = start; constants < 256 + 3 * kStep; constants += kStep) {
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+  ExpectedSnippet<0> snippets[] = {
+      {"  var r = 0;\n"
+       "  for (var a of [0,6,7,9]) { r += a; }\n"
+       "  return r;\n",
+       {handle(Smi::FromInt(22), isolate)}},
+      {"  var r = '';\n"
+       "  for (var a of 'foobar') { r = a + r; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("raboof")}},
+      {"  var a = [1, 2, 3];\n"
+       "  a.name = 4;\n"
+       "  var r = 0;\n"
+       "  for (var x of a) { r += x; }\n"
+       "  return r;\n",
+       {handle(Smi::FromInt(6), isolate)}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3]; \n"
+       "  for (a of data) { delete data[0]; r += a; } return r;",
+       {factory->NewStringFromStaticChars("123")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3]; \n"
+       "  for (a of data) { delete data[2]; r += a; } return r;",
+       {factory->NewStringFromStaticChars("12undefined")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3]; \n"
+       "  for (a of data) { delete data; r += a; } return r;",
+       {factory->NewStringFromStaticChars("123")}},
+      {"  var r = '';\n"
+       "  var input = 'foobar';\n"
+       "  for (var a of input) {\n"
+       "    if (a == 'b') break;\n"
+       "    r += a;\n"
+       "  }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("foo")}},
+      {"  var r = '';\n"
+       "  var input = 'foobar';\n"
+       "  for (var a of input) {\n"
+       "    if (a == 'b') continue;\n"
+       "    r += a;\n"
+       "  }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("fooar")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3, 4]; \n"
+       "  for (a of data) { data[2] = 567; r += a; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("125674")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3, 4]; \n"
+       "  for (a of data) { data[4] = 567; r += a; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("1234567")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3, 4]; \n"
+       "  for (a of data) { data[5] = 567; r += a; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("1234undefined567")}},
+      {"  var r = '';\n"
+       "  var obj = new Object();\n"
+       "  obj[Symbol.iterator] = function() { return {\n"
+       "    index: 3,\n"
+       "    data: ['a', 'b', 'c', 'd'],"
+       "    next: function() {"
+       "      return {"
+       "        done: this.index == -1,\n"
+       "        value: this.index < 0 ? undefined : this.data[this.index--]\n"
+       "      }\n"
+       "    }\n"
+       "    }}\n"
+       "  for (a of obj) { r += a }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("dcba")}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+void TestJumpWithConstantsAndWideConstants(size_t shard) {
+  const int kStep = 46;
+  int start = static_cast<int>(7 + 17 * shard);
+  for (int constants = start; constants < 300; constants += kStep) {
     std::stringstream filler_os;
     // Generate a string that consumes constant pool entries and
     // spread out branch distances in script below.
@@ -2321,11 +2601,14 @@
     script_os << "}\n";
     script_os << kFunctionName << "(0);\n";
     std::string script(script_os.str());
+
+    HandleAndZoneScope scope;
+    auto isolate = scope.main_isolate();
     auto factory = isolate->factory();
     auto zone = scope.main_zone();
+    BytecodeGraphTester tester(isolate, zone, script.c_str());
+    auto callable = tester.GetCallable<Handle<Object>>();
     for (int a = 0; a < 3; a++) {
-      BytecodeGraphTester tester(isolate, zone, script.c_str());
-      auto callable = tester.GetCallable<Handle<Object>>();
       Handle<Object> return_val =
           callable(factory->NewNumberFromInt(a)).ToHandleChecked();
       static const int results[] = {11, 12, 2};
@@ -2334,6 +2617,368 @@
   }
 }
 
+SHARD_TEST_BY_4(JumpWithConstantsAndWideConstants)
+
+TEST(BytecodeGraphBuilderDoExpressions) {
+  bool old_flag = FLAG_harmony_do_expressions;
+  FLAG_harmony_do_expressions = true;
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+  ExpectedSnippet<0> snippets[] = {
+      {"var a = do {}; return a;", {factory->undefined_value()}},
+      {"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
+      {"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
+      {"var a = do { var x = 100; x++; }; return a;",
+       {handle(Smi::FromInt(100), isolate)}},
+      {"var i = 0; for (; i < 5;) { i = do { if (i == 3) { break; }; i + 1; }};"
+       "return i;",
+       {handle(Smi::FromInt(3), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  FLAG_harmony_do_expressions = old_flag;
+}
+
+TEST(BytecodeGraphBuilderWithStatement) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"with({x:42}) return x;", {handle(Smi::FromInt(42), isolate)}},
+      {"with({}) { var y = 10; return y;}",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var y = {x:42};"
+       " function inner() {"
+       "   var x = 20;"
+       "   with(y) return x;"
+       "}"
+       "return inner();",
+       {handle(Smi::FromInt(42), isolate)}},
+      {"var y = {x:42};"
+       " function inner(o) {"
+       "   var x = 20;"
+       "   with(o) return x;"
+       "}"
+       "return inner(y);",
+       {handle(Smi::FromInt(42), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderConstDeclaration) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"const x = 3; return x;", {handle(Smi::FromInt(3), isolate)}},
+      {"let x = 10; x = x + 20; return x;",
+       {handle(Smi::FromInt(30), isolate)}},
+      {"let x = 10; x = 20; return x;", {handle(Smi::FromInt(20), isolate)}},
+      {"let x; x = 20; return x;", {handle(Smi::FromInt(20), isolate)}},
+      {"let x; return x;", {factory->undefined_value()}},
+      {"var x = 10; { let x = 30; } return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"let x = 10; { let x = 20; } return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; eval('let x = 20;'); return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; eval('const x = 20;'); return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; { const x = 20; } return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; { const x = 20; return x;} return -1;",
+       {handle(Smi::FromInt(20), isolate)}},
+      {"var a = 10;\n"
+       "for (var i = 0; i < 10; ++i) {\n"
+       " const x = i;\n"  // const declarations are block scoped.
+       " a = a + x;\n"
+       "}\n"
+       "return a;\n",
+       {handle(Smi::FromInt(55), isolate)}},
+  };
+
+  // Tests for sloppy mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  // Tests for strict mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderConstDeclarationLookupSlots) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"const x = 3; function f1() {return x;}; return x;",
+       {handle(Smi::FromInt(3), isolate)}},
+      {"let x = 10; x = x + 20; function f1() {return x;}; return x;",
+       {handle(Smi::FromInt(30), isolate)}},
+      {"let x; x = 20; function f1() {return x;}; return x;",
+       {handle(Smi::FromInt(20), isolate)}},
+      {"let x; function f1() {return x;}; return x;",
+       {factory->undefined_value()}},
+  };
+
+  // Tests for sloppy mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  // Tests for strict mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderConstInLookupContextChain) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  const char* prologue =
+      "function OuterMost() {\n"
+      "  const outerConst = 10;\n"
+      "  let outerLet = 20;\n"
+      "  function Outer() {\n"
+      "    function Inner() {\n"
+      "      this.innerFunc = function() { ";
+  const char* epilogue =
+      "      }\n"
+      "    }\n"
+      "    this.getInnerFunc ="
+      "         function() {return new Inner().innerFunc;}\n"
+      "  }\n"
+      "  this.getOuterFunc ="
+      "     function() {return new Outer().getInnerFunc();}"
+      "}\n"
+      "var f = new OuterMost().getOuterFunc();\n"
+      "f();\n";
+
+  // Tests for let / constant.
+  ExpectedSnippet<0> const_decl[] = {
+      {"return outerConst;", {handle(Smi::FromInt(10), isolate)}},
+      {"return outerLet;", {handle(Smi::FromInt(20), isolate)}},
+      {"outerLet = 30; return outerLet;", {handle(Smi::FromInt(30), isolate)}},
+      {"var outerLet = 40; return outerLet;",
+       {handle(Smi::FromInt(40), isolate)}},
+      {"var outerConst = 50; return outerConst;",
+       {handle(Smi::FromInt(50), isolate)}},
+      {"try { outerConst = 30 } catch(e) { return -1; }",
+       {handle(Smi::FromInt(-1), isolate)}}};
+
+  for (size_t i = 0; i < arraysize(const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s %s %s", prologue, const_decl[i].code_snippet,
+             epilogue);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "*");
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*const_decl[i].return_value()));
+  }
+
+  // Tests for Legacy constant.
+  bool old_flag_legacy_const = FLAG_legacy_const;
+  FLAG_legacy_const = true;
+
+  ExpectedSnippet<0> legacy_const_decl[] = {
+      {"return outerConst = 23;", {handle(Smi::FromInt(23), isolate)}},
+      {"outerConst = 30; return outerConst;",
+       {handle(Smi::FromInt(10), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(legacy_const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s %s %s", prologue, legacy_const_decl[i].code_snippet,
+             epilogue);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "*");
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*legacy_const_decl[i].return_value()));
+  }
+
+  FLAG_legacy_const = old_flag_legacy_const;
+}
+
+TEST(BytecodeGraphBuilderIllegalConstDeclaration) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0, const char*> illegal_const_decl[] = {
+      {"const x = x = 10 + 3; return x;",
+       {"Uncaught ReferenceError: x is not defined"}},
+      {"const x = 10; x = 20; return x;",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+      {"const x = 10; { x = 20; } return x;",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+      {"const x = 10; eval('x = 20;'); return x;",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+      {"let x = x + 10; return x;",
+       {"Uncaught ReferenceError: x is not defined"}},
+      {"'use strict'; (function f1() { f1 = 123; })() ",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+  };
+
+  // Tests for sloppy mode.
+  for (size_t i = 0; i < arraysize(illegal_const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             illegal_const_decl[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+    v8::Local<v8::String> expected_string =
+        v8_str(illegal_const_decl[i].return_value());
+    CHECK(
+        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+            .FromJust());
+  }
+
+  // Tests for strict mode.
+  for (size_t i = 0; i < arraysize(illegal_const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+             illegal_const_decl[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+    v8::Local<v8::String> expected_string =
+        v8_str(illegal_const_decl[i].return_value());
+    CHECK(
+        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+            .FromJust());
+  }
+}
+
+TEST(BytecodeGraphBuilderLegacyConstDeclaration) {
+  bool old_flag_legacy_const = FLAG_legacy_const;
+  FLAG_legacy_const = true;
+
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"const x = (x = 10) + 3; return x;",
+       {handle(Smi::FromInt(13), isolate)}},
+      {"const x = 10; x = 20; return x;", {handle(Smi::FromInt(10), isolate)}},
+      {"var a = 10;\n"
+       "for (var i = 0; i < 10; ++i) {\n"
+       " const x = i;\n"  // Legacy constants are not block scoped.
+       " a = a + x;\n"
+       "}\n"
+       "return a;\n",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"const x = 20; eval('x = 10;'); return x;",
+       {handle(Smi::FromInt(20), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  FLAG_legacy_const = old_flag_legacy_const;
+}
+
+TEST(BytecodeGraphBuilderDebuggerStatement) {
+  FLAG_expose_debug_as = "debug";
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippet = {
+      "var Debug = debug.Debug;"
+      "var count = 0;"
+      "function f() {"
+      "  debugger;"
+      "}"
+      "function listener(event) {"
+      "  if (event == Debug.DebugEvent.Break) count++;"
+      "}"
+      "Debug.setListener(listener);"
+      "f();"
+      "Debug.setListener(null);"
+      "return count;",
+      {handle(Smi::FromInt(1), isolate)}};
+
+  ScopedVector<char> script(1024);
+  SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+           snippet.code_snippet, kFunctionName);
+
+  BytecodeGraphTester tester(isolate, zone, script.start());
+  auto callable = tester.GetCallable<>();
+  Handle<Object> return_value = callable().ToHandleChecked();
+  CHECK(return_value->SameValue(*snippet.return_value()));
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8