Import Cobalt 20.master.0.234144

Includes the following patches:
  https://cobalt-review.googlesource.com/c/cobalt/+/5590
  by n1214.hwang@samsung.com

  https://cobalt-review.googlesource.com/c/cobalt/+/5530
  by errong.leng@samsung.com

  https://cobalt-review.googlesource.com/c/cobalt/+/5570
  by devin.cai@mediatek.com
diff --git a/src/v8/test/debugger/debug/compiler/debug-catch-prediction.js b/src/v8/test/debugger/debug/compiler/debug-catch-prediction.js
index 50fbf58..60ac95b 100644
--- a/src/v8/test/debugger/debug/compiler/debug-catch-prediction.js
+++ b/src/v8/test/debugger/debug/compiler/debug-catch-prediction.js
@@ -34,6 +34,7 @@
       return e;
     }
   }
+  %PrepareFunctionForOptimization(f);
   assertEquals("boom1", f(1));
   assertEquals("boom2", f(2));
   %OptimizeFunctionOnNextCall(f);
@@ -51,6 +52,7 @@
       return a + 10;
     }
   }
+  %PrepareFunctionForOptimization(f);
   assertEquals(11, f(1));
   assertEquals(12, f(2));
   %OptimizeFunctionOnNextCall(f);
@@ -70,6 +72,7 @@
       // Nothing.
     }
   }
+  %PrepareFunctionForOptimization(f);
   assertEquals("wosh11", f(1));
   assertEquals("wosh22", f(2));
   %OptimizeFunctionOnNextCall(f);
@@ -91,6 +94,7 @@
       return e + a;
     }
   }
+  %PrepareFunctionForOptimization(f);
   assertEquals("bang11", f(1));
   assertEquals("bang22", f(2));
   %OptimizeFunctionOnNextCall(f);
@@ -112,6 +116,7 @@
       return a + 10;
     }
   }
+  %PrepareFunctionForOptimization(f);
   assertEquals(11, f(1));
   assertEquals(12, f(2));
   %OptimizeFunctionOnNextCall(f);
@@ -133,6 +138,7 @@
       return a + 10;
     }
   }
+  %PrepareFunctionForOptimization(f);
   assertEquals(11, f(1));
   assertEquals(12, f(2));
   %OptimizeFunctionOnNextCall(f);
diff --git a/src/v8/test/debugger/debug/compiler/osr-typing-debug-change.js b/src/v8/test/debugger/debug/compiler/osr-typing-debug-change.js
index 92eb899..e0346dd 100644
--- a/src/v8/test/debugger/debug/compiler/osr-typing-debug-change.js
+++ b/src/v8/test/debugger/debug/compiler/osr-typing-debug-change.js
@@ -37,6 +37,7 @@
   }
   return j;
 }
+%PrepareFunctionForOptimization(ChangeSmiConstantAndOsr);
 var r1 = ChangeSmiConstantAndOsr();
 if (changed) {
   assertEquals("result", r1);
@@ -54,6 +55,7 @@
   }
   return j;
 }
+%PrepareFunctionForOptimization(ChangeFloatConstantAndOsr);
 var r2 = ChangeFloatConstantAndOsr();
 if (changed) {
   assertEquals("result", r2);
@@ -72,6 +74,7 @@
   }
   return j;
 }
+%PrepareFunctionForOptimization(ChangeFloatVarAndOsr);
 var r3 = ChangeFloatVarAndOsr();
 if (changed) {
   assertEquals("result0.1", r3);
@@ -105,6 +108,7 @@
   }
   return j;
 }
+%PrepareFunctionForOptimization(ChangeIntVarAndOsr);
 
 var r4 = ChangeIntVarAndOsr();
 if (changed) {
diff --git a/src/v8/test/debugger/debug/debug-backtrace.js b/src/v8/test/debugger/debug/debug-backtrace.js
index 63bbe10..79087d4 100644
--- a/src/v8/test/debugger/debug/debug-backtrace.js
+++ b/src/v8/test/debugger/debug/debug-backtrace.js
@@ -42,8 +42,8 @@
 
 Debug = debug.Debug
 
-listenerCalled = false;
-exception = false;
+let listenerCalled = false;
+let exceptionThrown = false;
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -82,7 +82,7 @@
       listenerCalled = true;
     }
   } catch (e) {
-    exception = e;
+    exceptionThrown = true;
   };
 };
 
@@ -94,5 +94,5 @@
 g();
 
 // Make sure that the debug event listener vas invoked.
-assertFalse(exception, "exception in listener");
+assertFalse(exceptionThrown, "exception in listener");
 assertTrue(listenerCalled);
diff --git a/src/v8/test/debugger/debug/debug-bigint.js b/src/v8/test/debugger/debug/debug-bigint.js
new file mode 100644
index 0000000..0ed09b0
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-bigint.js
@@ -0,0 +1,22 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug
+let exceptionThrown = false;
+
+Debug.setListener(function(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    const o = exec_state.frame(0).evaluate("42n", true);
+    assertEquals("bigint", o.type());
+    assertFalse(o.isUndefined());
+    assertEquals("bigint", typeof(o.value()));
+    assertEquals(42n, o.value());
+  } catch (e) {
+    exceptionThrown = true;
+  };
+});
+
+!function() { debugger; }();
+assertFalse(exceptionThrown, "exception in listener")
diff --git a/src/v8/test/debugger/debug/debug-break-class-fields.js b/src/v8/test/debugger/debug/debug-break-class-fields.js
new file mode 100644
index 0000000..b6b9c93
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-break-class-fields.js
@@ -0,0 +1,139 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-public-fields --harmony-static-fields --allow-natives-syntax
+
+Debug = debug.Debug
+
+Debug.setListener(function() {});
+
+class Y {
+  x = 1;
+  y = 2;
+  z = 3;
+}
+
+var initializer = %GetInitializerFunction(Y);
+var b1, b2, b3;
+
+// class Y {
+//   x = [B0]1;
+//   y = [B1]2;
+//   z = [B2]3;
+// }
+b1 = Debug.setBreakPoint(initializer, 0, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === 0);
+Debug.clearBreakPoint(b1);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === -1);
+
+b2 = Debug.setBreakPoint(initializer, 1, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") > 0);
+Debug.clearBreakPoint(b2);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") === -1);
+
+b3 = Debug.setBreakPoint(initializer, 2, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B0]3") > 0);
+Debug.clearBreakPoint(b3);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B0]3") === -1);
+
+b1 = Debug.setBreakPoint(initializer, 0, 0);
+b2 = Debug.setBreakPoint(initializer, 1, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B1]2;") > 0);
+Debug.clearBreakPoint(b1);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === -1);
+Debug.clearBreakPoint(b2);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B1]2;") === -1);
+
+b1 = Debug.setBreakPoint(initializer, 0, 0);
+b3 = Debug.setBreakPoint(initializer, 2, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") > 0);
+Debug.clearBreakPoint(b1);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === -1);
+Debug.clearBreakPoint(b3);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") === -1);
+
+b2 = Debug.setBreakPoint(initializer, 1, 0);
+b3 = Debug.setBreakPoint(initializer, 2, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") > 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") > 0);
+Debug.clearBreakPoint(b2);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") === -1);
+Debug.clearBreakPoint(b3);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") === -1);
+
+function foo() {}
+var bar = "bar";
+
+class X {
+  [foo()] = 1;
+  [bar] = 2;
+  baz = foo();
+}
+
+// The computed properties are evaluated during class construction,
+// not as part of the initializer function. As a consequence of which,
+// they aren't breakable here in the initializer function, but
+// instead, are part of the enclosing function.
+//
+// class X {
+//   [foo()] = [B0]1;
+//   [bar] = [B1]2;
+//   [baz] = [B2]foo();
+// }
+
+initializer = %GetInitializerFunction(X);
+b1 = Debug.setBreakPoint(initializer, 0, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[foo()] = [B0]1;") === 0);
+Debug.clearBreakPoint(b1);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[foo()] = [B0]1;") === -1);
+
+b2 = Debug.setBreakPoint(initializer, 1, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[bar] = [B0]2;") > 0);
+Debug.clearBreakPoint(b2);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[bar] = [B0]2;") === -1);
+
+b3 = Debug.setBreakPoint(initializer, 2, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("baz = [B0]foo()") > 0);
+Debug.clearBreakPoint(b3);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("baz = [B0]foo()") === -1);
+
+b1 = Debug.setBreakPoint(initializer, 0, 0);
+b2 = Debug.setBreakPoint(initializer, 1, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[foo()] = [B0]1;") === 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[bar] = [B1]2;") > 0);
+Debug.clearBreakPoint(b1);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[foo()] = [B0]1;") === -1);
+Debug.clearBreakPoint(b2);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[bar] = [B1]2;") === -1);
+
+b1 = Debug.setBreakPoint(initializer, 0, 0);
+b3 = Debug.setBreakPoint(initializer, 2, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[foo()] = [B0]1;") === 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("baz = [B1]foo()") > 0);
+Debug.clearBreakPoint(b1);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[foo()] = [B0]1;") === -1);
+Debug.clearBreakPoint(b3);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("baz = [B1]foo()") === -1);
+
+b2 = Debug.setBreakPoint(initializer, 1, 0);
+b3 = Debug.setBreakPoint(initializer, 2, 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[bar] = [B0]2;") > 0);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("baz = [B1]foo()") > 0);
+Debug.clearBreakPoint(b2);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[bar] = [B0]2;") === -1);
+Debug.clearBreakPoint(b3);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("baz = [B1]foo()") === -1);
+
+function t() {
+  class X {
+    [foo()] = 1;
+  }
+}
+
+b1 = Debug.setBreakPoint(t, 0, 0);
+assertTrue(Debug.showBreakPoints(t).indexOf("[[B0]foo()] = 1;")> 0);
+Debug.clearBreakPoint(b1);
+assertTrue(Debug.showBreakPoints(initializer).indexOf("[[B0]foo()] = 1;") === -1);
diff --git a/src/v8/test/debugger/debug/debug-break-inline.js b/src/v8/test/debugger/debug/debug-break-inline.js
index 18574ec..1b23f3d 100644
--- a/src/v8/test/debugger/debug/debug-break-inline.js
+++ b/src/v8/test/debugger/debug/debug-break-inline.js
@@ -63,6 +63,7 @@
   debugger;
 }
 
+%PrepareFunctionForOptimization(f);
 f();f();f();
 %OptimizeFunctionOnNextCall(f);
 f();
diff --git a/src/v8/test/debugger/debug/debug-break-native.js b/src/v8/test/debugger/debug/debug-break-native.js
index 10ed405..68f9c9d 100644
--- a/src/v8/test/debugger/debug/debug-break-native.js
+++ b/src/v8/test/debugger/debug/debug-break-native.js
@@ -26,7 +26,6 @@
 }                                  // break
 
 Debug.setBreakPoint(f, 0, 0);      // break
-Debug.scripts();                   // break
 
 new Error("123").stack;            // break
 Math.sin(0);                       // break
diff --git a/src/v8/test/debugger/debug/debug-break-return.js b/src/v8/test/debugger/debug/debug-break-return.js
new file mode 100644
index 0000000..478162a
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-break-return.js
@@ -0,0 +1,40 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug
+
+function foo(){}
+
+let breakpoint_count = 0;
+let last_source_line = 0;
+let last_source_column = 0;
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    ++breakpoint_count;
+    last_source_line = exec_state.frame(0).sourceLine();
+    last_source_column = exec_state.frame(0).sourceColumn();
+  }
+};
+
+Debug.setListener(listener);
+
+// Run without breakpoints.
+foo();
+assertEquals(breakpoint_count, 0);
+
+// Run with breakpoint.
+const breakpoint = Debug.setBreakPoint(foo, 0);
+foo();
+assertEquals(breakpoint_count, 1);
+assertEquals(last_source_line, 7);
+assertEquals(last_source_column, 15);
+foo();
+assertEquals(breakpoint_count, 2);
+assertEquals(last_source_line, 7);
+assertEquals(last_source_column, 15);
+
+// Run without breakpoints
+Debug.clearBreakPoint(breakpoint);
+foo();
+assertEquals(breakpoint_count, 2);
diff --git a/src/v8/test/debugger/debug/debug-clearbreakpoint.js b/src/v8/test/debugger/debug/debug-clearbreakpoint.js
index 0c8267c..303eaf1 100644
--- a/src/v8/test/debugger/debug/debug-clearbreakpoint.js
+++ b/src/v8/test/debugger/debug/debug-clearbreakpoint.js
@@ -28,8 +28,8 @@
 Debug = debug.Debug
 
 // Simple function which stores the last debug event.
-listenerComplete = false;
-exception = false;
+let listenerComplete = false;
+let exceptionThrown = false;
 
 var breakpoint = -1;
 
@@ -42,7 +42,7 @@
       listenerComplete = true;
     }
   } catch (e) {
-    exception = e
+    exceptionThrown = true;
   };
 };
 
@@ -57,4 +57,4 @@
 
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerComplete, "listener did not run to completion");
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener")
diff --git a/src/v8/test/debugger/debug/debug-compile-event.js b/src/v8/test/debugger/debug/debug-compile-event.js
index 2e52609..6c92bd7 100644
--- a/src/v8/test/debugger/debug/debug-compile-event.js
+++ b/src/v8/test/debugger/debug/debug-compile-event.js
@@ -27,7 +27,7 @@
 
 Debug = debug.Debug
 
-var exception = false;  // Exception in debug event listener.
+var exceptionThrown = false;  // Exception in debug event listener.
 var after_compile_count = 0;
 var compile_error_count = 0;
 var current_source = '';  // Current source being compiled.
@@ -85,7 +85,7 @@
       }
     }
   } catch (e) {
-    exception = e
+    exceptionThrown = true;
   }
 };
 
@@ -110,7 +110,7 @@
 }
 
 // Make sure that the debug event listener was invoked.
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener")
 
 // Number of before and after + error events should be the same.
 assertEquals(compile_error_count, 1);
diff --git a/src/v8/test/debugger/debug/debug-compile-optimized.js b/src/v8/test/debugger/debug/debug-compile-optimized.js
index 33f199a..a48b250 100644
--- a/src/v8/test/debugger/debug/debug-compile-optimized.js
+++ b/src/v8/test/debugger/debug/debug-compile-optimized.js
@@ -9,6 +9,7 @@
 Debug.setListener(function() {});
 
 function f() {}
+%PrepareFunctionForOptimization(f);
 f();
 f();
 %OptimizeFunctionOnNextCall(f);
@@ -17,6 +18,7 @@
 
 var bp = Debug.setBreakPoint(f);
 assertUnoptimized(f);
+%PrepareFunctionForOptimization(f);
 f();
 f();
 %OptimizeFunctionOnNextCall(f);
@@ -24,6 +26,7 @@
 assertUnoptimized(f);
 
 Debug.clearBreakPoint(bp);
+%PrepareFunctionForOptimization(f);
 %OptimizeFunctionOnNextCall(f);
 f();
 assertOptimized(f);
diff --git a/src/v8/test/debugger/debug/debug-evaluate-arguments.js b/src/v8/test/debugger/debug/debug-evaluate-arguments.js
index 8cf18d7..0c65a86 100644
--- a/src/v8/test/debugger/debug/debug-evaluate-arguments.js
+++ b/src/v8/test/debugger/debug/debug-evaluate-arguments.js
@@ -30,6 +30,7 @@
   }
   return bar(1,2,a);
 }
+%PrepareFunctionForOptimization(foo);
 
 listened = false;
 foo_expected = [3];
@@ -53,6 +54,7 @@
 listened = false;
 foo_expected = [3,4,5];
 bar_expected = [1,2,3];
+%PrepareFunctionForOptimization(foo);
 %OptimizeFunctionOnNextCall(foo);
 assertEquals(6, foo(3,4,5));
 assertTrue(listened);
diff --git a/src/v8/test/debugger/debug/debug-evaluate-bool-constructor.js b/src/v8/test/debugger/debug/debug-evaluate-bool-constructor.js
index 83a0f06..2c30df9 100644
--- a/src/v8/test/debugger/debug/debug-evaluate-bool-constructor.js
+++ b/src/v8/test/debugger/debug/debug-evaluate-bool-constructor.js
@@ -29,7 +29,7 @@
 Debug = debug.Debug
 
 var listenerComplete = false;
-var exception = false;
+var exceptionThrown = false;
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -43,7 +43,7 @@
     }
   } catch (e) {
     print(e);
-    exception = e
+    exceptionThrown = true;
   };
 };
 
@@ -60,5 +60,5 @@
 
 
 // Make sure that the debug event listener vas invoked.
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener")
 assertTrue(listenerComplete, "listener did not run to completion");
diff --git a/src/v8/test/debugger/debug/debug-evaluate-dead-function-fails.js b/src/v8/test/debugger/debug/debug-evaluate-dead-function-fails.js
new file mode 100644
index 0000000..ffa2916
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-evaluate-dead-function-fails.js
@@ -0,0 +1,35 @@
+// Copyright 2019 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --no-always-opt --no-stress-opt
+
+Debug = debug.Debug
+
+var exception = null;
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    // Evaluating the live function should succeed.
+    assertEquals(exec_state.frame(0).evaluate("live()").value(), 1);
+    // Evaluating the dead function should fail.
+    assertThrows(()=>exec_state.frame(0).evaluate("dead()"), ReferenceError);
+  } catch (e) {
+    exception = e;
+    print(e + e.stack);
+  }
+}
+
+Debug.setListener(listener);
+
+(function() {
+  "use strict";
+  function live() { return 1; }
+  function dead() { return 2; }
+  // Use 'foo' to make it non-dead.
+  live;
+  debugger;
+})();
+
+Debug.setListener(null);
+assertNull(exception);
diff --git a/src/v8/test/debugger/debug/debug-evaluate-function-var.js b/src/v8/test/debugger/debug/debug-evaluate-function-var.js
new file mode 100644
index 0000000..42a6716
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-evaluate-function-var.js
@@ -0,0 +1,42 @@
+// Copyright 2019 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      var frame = exec_state.frame(0);
+      try {
+        assertTrue(frame.evaluate("f").value().startsWith("function f()"));
+      } catch {
+        assertTrue(frame.sourceLineText().endsWith("throws"));
+      }
+    }
+  } catch(e) {
+    exception = e;
+    print(e, e.stack);
+  }
+};
+
+Debug.setListener(listener);
+
+(function f() {
+  f;
+  debugger;  // works
+})();
+
+(function f() {
+  () => f;
+  debugger;  // works
+})();
+
+(function f() {
+  debugger;  // throws
+})();
+
+assertNull(exception);
+
+Debug.setListener(null);
diff --git a/src/v8/test/debugger/debug/debug-evaluate-locals-optimized-double.js b/src/v8/test/debugger/debug/debug-evaluate-locals-optimized-double.js
index 462194c..2160b97 100644
--- a/src/v8/test/debugger/debug/debug-evaluate-locals-optimized-double.js
+++ b/src/v8/test/debugger/debug/debug-evaluate-locals-optimized-double.js
@@ -30,7 +30,7 @@
 Debug = debug.Debug
 
 var listenerComplete = false;
-var exception = false;
+var exceptionThrown = false;
 
 var testingConstructCall = false;
 
@@ -127,10 +127,11 @@
       listenerComplete = true;
     }
   } catch (e) {
-    exception = e.toString() + e.stack;
+    exceptionThrown = true;
   };
 };
 
+%PrepareFunctionForOptimization(f);
 for (var i = 0; i < 4; i++) f(input.length - 1, 11.11, 12.12);
 %OptimizeFunctionOnNextCall(f);
 f(input.length - 1, 11.11, 12.12);
@@ -191,7 +192,7 @@
 new f(input.length - 1, 11.11, 12.12, "");
 
 // Make sure that the debug event listener was invoked.
-assertFalse(exception, "exception in listener " + exception)
+assertFalse(exceptionThrown, "exception in listener");
 assertTrue(listenerComplete);
 
 //Throw away type information for next run.
diff --git a/src/v8/test/debugger/debug/debug-evaluate-locals-optimized.js b/src/v8/test/debugger/debug/debug-evaluate-locals-optimized.js
index 93c90b5..057ceff 100644
--- a/src/v8/test/debugger/debug/debug-evaluate-locals-optimized.js
+++ b/src/v8/test/debugger/debug/debug-evaluate-locals-optimized.js
@@ -30,7 +30,7 @@
 Debug = debug.Debug
 
 var listenerComplete = false;
-var exception = false;
+var exceptionThrown = false;
 
 var testingConstructCall = false;
 
@@ -118,10 +118,11 @@
       listenerComplete = true;
     }
   } catch (e) {
-    exception = e.toString() + e.stack;
+    exceptionThrown = true;
   };
 };
 
+%PrepareFunctionForOptimization(f);
 for (var i = 0; i < 4; i++) f(expected.length - 1, 11, 12);
 %OptimizeFunctionOnNextCall(f);
 f(expected.length - 1, 11, 12);
@@ -172,7 +173,7 @@
 new f(expected.length - 1, 11, 12, 0);
 
 // Make sure that the debug event listener was invoked.
-assertFalse(exception, "exception in listener " + exception)
+assertFalse(exceptionThrown, "exception in listener");
 assertTrue(listenerComplete);
 
 // Throw away type information for next run.
diff --git a/src/v8/test/debugger/debug/debug-evaluate-locals.js b/src/v8/test/debugger/debug/debug-evaluate-locals.js
index 0108acf..edc27e6 100644
--- a/src/v8/test/debugger/debug/debug-evaluate-locals.js
+++ b/src/v8/test/debugger/debug/debug-evaluate-locals.js
@@ -27,8 +27,8 @@
 
 Debug = debug.Debug
 
-listenerComplete = false;
-exception = false;
+let listenerComplete = false;
+let exceptionThrown = false;
 
 
 function h() {
@@ -132,7 +132,7 @@
       listenerComplete = true;
     }
   } catch (e) {
-    exception = e;
+    exceptionThrown = true;
     print("Caught something. " + e + " " + e.stack);
   };
 };
@@ -145,5 +145,5 @@
 assertEquals("foobar", f_result);
 
 // Make sure that the debug event listener was invoked.
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener");
 assertTrue(listenerComplete);
diff --git a/src/v8/test/debugger/debug/debug-evaluate-modify-catch-block-scope.js b/src/v8/test/debugger/debug/debug-evaluate-modify-catch-block-scope.js
index 656399b..deb0d42 100644
--- a/src/v8/test/debugger/debug/debug-evaluate-modify-catch-block-scope.js
+++ b/src/v8/test/debugger/debug/debug-evaluate-modify-catch-block-scope.js
@@ -33,6 +33,8 @@
       a *= 2;
       e *= 2;
     }
+    // Make sure bar is 'used' so that it is visible to the debugger.
+    bar;
     debugger;
     assertEquals(5, a);
     assertEquals(7, e);
diff --git a/src/v8/test/debugger/debug/debug-evaluate-with.js b/src/v8/test/debugger/debug/debug-evaluate-with.js
index 260114d..640d050 100644
--- a/src/v8/test/debugger/debug/debug-evaluate-with.js
+++ b/src/v8/test/debugger/debug/debug-evaluate-with.js
@@ -30,9 +30,9 @@
 
 Debug = debug.Debug
 
-listenerComplete = false;
-exception = false;
-breakPointCount = 0;
+let listenerComplete = false;
+let exceptionThrown = false;
+let breakPointCount = 0;
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -53,7 +53,7 @@
       }
     }
   } catch (e) {
-    exception = e
+    exceptionThrown = true;
   };
 };
 
@@ -79,4 +79,4 @@
 
 // Make sure that the debug event listener vas invoked.
 assertEquals(3, breakPointCount);
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener");
diff --git a/src/v8/test/debugger/debug/debug-evaluate.js b/src/v8/test/debugger/debug/debug-evaluate.js
index 9328c32..922bad8 100644
--- a/src/v8/test/debugger/debug/debug-evaluate.js
+++ b/src/v8/test/debugger/debug/debug-evaluate.js
@@ -27,8 +27,8 @@
 
 Debug = debug.Debug
 
-listenerComplete = false;
-exception = false;
+let listenerComplete = false;
+let exceptionThrown = false;
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -51,7 +51,7 @@
       listenerComplete = true;
     }
   } catch (e) {
-   exception = e
+   exceptionThrown = true;
   };
 };
 
@@ -80,6 +80,6 @@
 Debug.setBreakPoint(f, 2, 0);
 g();
 
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener");
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerComplete, "listener did not run to completion");
diff --git a/src/v8/test/debugger/debug/debug-liveedit-1.js b/src/v8/test/debugger/debug/debug-liveedit-1.js
index 950a2fa..a3fe1bf 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-1.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-1.js
@@ -25,6 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -34,13 +35,11 @@
 
 assertEquals("Cat", ChooseAnimal());
 
-var script = Debug.findScript(ChooseAnimal);
-
 var orig_animal = "Cat";
-var patch_pos = script.source.indexOf(orig_animal);
 var new_animal_patch = "Cap' + 'y' + 'bara";
+var new_source =
+    Debug.scriptSource(ChooseAnimal).replace(orig_animal, new_animal_patch);
 
-var change_log = new Array();
-Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, orig_animal.length, new_animal_patch, change_log);
+%LiveEditPatchScript(ChooseAnimal, new_source);
 
 assertEquals("Capybara", ChooseAnimal());
diff --git a/src/v8/test/debugger/debug/debug-liveedit-2.js b/src/v8/test/debugger/debug/debug-liveedit-2.js
index 408ee5a..f52ec26 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-2.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-2.js
@@ -25,8 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --noalways-opt
-
+// Flags: --noalways-opt --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -43,19 +42,12 @@
 
 assertEquals("Cat", old_closure());
 
-var script = Debug.findScript(ChooseAnimal);
-
-var orig_animal = "'Cat'";
-var patch_pos = script.source.indexOf(orig_animal);
-var new_animal_patch = "'Capybara' + p";
-
 // We patch innermost function "Chooser".
 // However, this does not actually patch existing "Chooser" instances,
 // because old value of parameter "p" was not saved.
 // Instead it patches ChooseAnimal.
-var change_log = new Array();
-Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, orig_animal.length, new_animal_patch, change_log);
-print("Change log: " + JSON.stringify(change_log) + "\n");
+%LiveEditPatchScript(
+    ChooseAnimal, Debug.scriptSource(ChooseAnimal).replace("'Cat'", "'Capybara' + p"));
 
 var new_closure = ChooseAnimal(19);
 // New instance of closure is patched.
diff --git a/src/v8/test/debugger/debug/debug-liveedit-3.js b/src/v8/test/debugger/debug/debug-liveedit-3.js
index c075453..790137d 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-3.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-3.js
@@ -30,6 +30,7 @@
 // hasen't been changed. However actually function became one level more nested
 // and must be recompiled because it uses variable from outer scope.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -49,15 +50,11 @@
 var z6 = Factory(6);
 assertEquals(8, z6());
 
-var script = Debug.findScript(Factory);
+var new_source = Debug.scriptSource(Factory).replace(
+    function_z_text,
+    'function Intermediate() {\nreturn (\n' + function_z_text + ')\n;\n}\n');
 
-var new_source = script.source.replace(function_z_text, "function Intermediate() {\nreturn (\n" + function_z_text + ")\n;\n}\n");
-print("new source: " + new_source);
-
-var change_log = new Array();
-var result = Debug.LiveEdit.SetScriptSource(script, new_source, false, change_log);
-print("Result: " + JSON.stringify(result) + "\n");
-print("Change log: " + JSON.stringify(change_log) + "\n");
+%LiveEditPatchScript(Factory, new_source);
 
 assertEquals(8, z6());
 
diff --git a/src/v8/test/debugger/debug/debug-liveedit-4.js b/src/v8/test/debugger/debug/debug-liveedit-4.js
index 0b94ece..eef7f20 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-4.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-4.js
@@ -31,6 +31,7 @@
 // hasen't been changed. However actually function became one level more nested
 // and must be recompiled because it uses variable from outer scope.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -53,14 +54,10 @@
 print(res);
 assertEquals('a,c', res);
 
-var script = Debug.findScript(TestFunction);
-var new_source = script.source.replace("2013", "b");
+var new_source = Debug.scriptSource(TestFunction).replace('2013', 'b');
 print("new source: " + new_source);
-var change_log = new Array();
-var result = Debug.LiveEdit.SetScriptSource(script, new_source, false, change_log);
 
-print("Result: " + JSON.stringify(result) + "\n");
-print("Change log: " + JSON.stringify(change_log) + "\n");
+%LiveEditPatchScript(TestFunction, new_source);
 
 var res = TestFunction();
 print(res);
diff --git a/src/v8/test/debugger/debug/debug-liveedit-arrow-function-at-start.js b/src/v8/test/debugger/debug/debug-liveedit-arrow-function-at-start.js
new file mode 100644
index 0000000..ce0fe39
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-liveedit-arrow-function-at-start.js
@@ -0,0 +1,13 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+// ()=>42 will have the same start and end position as the top-level script.
+var foo = eval("()=>{ return 42 }");
+assertEquals(42, foo());
+
+%LiveEditPatchScript(foo, "()=>{ return 13 }");
+
+assertEquals(13, foo());
diff --git a/src/v8/test/debugger/debug/debug-liveedit-check-stack.js b/src/v8/test/debugger/debug/debug-liveedit-check-stack.js
index e016a53..e2e9c64 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-check-stack.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-check-stack.js
@@ -25,6 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -33,35 +34,26 @@
 function TestBase(name) {
   print("TestBase constructor: " + name);
 
-  this.ChooseAnimal = eval(
-      "/* " + unique_id + "*/\n" +
-      "(function ChooseAnimal(callback) {\n " +
-      "  callback();\n" +
-      "  return 'Cat';\n" +
-      "})\n"
-  );
+  const original_source = '/* ' + unique_id + '*/\n' +
+      '(function ChooseAnimal(callback) {\n ' +
+      '  callback();\n' +
+      '  return \'Cat\';\n' +
+      '})\n';
+  const updated_source = original_source.replace('\'Cat\'', '\'Capybara\'');
+
+  this.ChooseAnimal = eval(original_source);
   // Prevents eval script caching.
   unique_id++;
 
-  var script = Debug.findScript(this.ChooseAnimal);
-
-  var orig_animal = "'Cat'";
-  var patch_pos = script.source.indexOf(orig_animal);
-  var new_animal_patch = "'Capybara'";
+  const func = this.ChooseAnimal;
 
   var got_exception = false;
   var successfully_changed = false;
 
   // Should be called from Debug context.
-  this.ScriptChanger = function() {
+  this.ScriptChanger = () => {
     assertEquals(false, successfully_changed, "applying patch second time");
-    // Runs in debugger context.
-    var change_log = new Array();
-    try {
-      Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, orig_animal.length, new_animal_patch, change_log);
-    } finally {
-      print("Change log: " + JSON.stringify(change_log) + "\n");
-    }
+    %LiveEditPatchScript(func, updated_source);
     successfully_changed = true;
   };
 }
@@ -74,7 +66,7 @@
     try {
       f();
     } catch (e) {
-      if (e instanceof Debug.LiveEdit.Failure) {
+      if (e.startsWith('LiveEdit failed')) {
         holder[0] = e;
       } else {
         throw e;
diff --git a/src/v8/test/debugger/debug/debug-liveedit-compile-error.js b/src/v8/test/debugger/debug/debug-liveedit-compile-error.js
index 24068eb..33953a3 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-compile-error.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-compile-error.js
@@ -25,6 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -34,23 +35,16 @@
 
 assertEquals("Cat", ChooseAnimal());
 
-var script = Debug.findScript(ChooseAnimal);
+var new_source =
+    Debug.scriptSource(ChooseAnimal).replace('Cat', 'Cap\' + ) + \'bara');
+print('new source: ' + new_source);
 
-var orig_animal = "Cat";
-var patch_pos = script.source.indexOf(orig_animal);
-var new_animal_patch = "Cap' + ) + 'bara";
-
-var change_log = new Array();
 var caught_exception = null;
 try {
-  Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos,
-      orig_animal.length, new_animal_patch, change_log);
+  %LiveEditPatchScript(ChooseAnimal, new_source);
 } catch (e) {
   caught_exception = e;
 }
 
 assertNotNull(caught_exception);
-assertEquals("Unexpected token )",
-    caught_exception.details.syntaxErrorMessage);
-
-assertEquals(2, caught_exception.details.position.start.line);
+assertEquals('LiveEdit failed: COMPILE_ERROR', caught_exception);
diff --git a/src/v8/test/debugger/debug/debug-liveedit-double-call.js b/src/v8/test/debugger/debug/debug-liveedit-double-call.js
index 77d800e..1de6bd3 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-double-call.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-double-call.js
@@ -78,8 +78,6 @@
 
   var test_fun = eval(script_text_generator.get());
 
-  var script = Debug.findScript(test_fun);
-
   var scenario_pos = 0;
 
   function DebuggerStatementHandler() {
@@ -92,8 +90,7 @@
       }
       script_text_generator.change(change_var);
       try {
-        Debug.LiveEdit.SetScriptSource(script, script_text_generator.get(),
-            false, []);
+        %LiveEditPatchScript(test_fun, script_text_generator.get())
       } catch (e) {
         print("LiveEdit exception: " + e);
         throw e;
diff --git a/src/v8/test/debugger/debug/debug-liveedit-exceptions.js b/src/v8/test/debugger/debug/debug-liveedit-exceptions.js
index 36463b3..091f1af 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-exceptions.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-exceptions.js
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
-
 function BestEditor() {
   throw 'Emacs';
 }
@@ -37,11 +37,8 @@
 };
 
 function Replace(fun, original, patch) {
-  var script = Debug.findScript(fun);
   if (fun.toString().indexOf(original) < 0) return;
-  var patch_pos = script.source.indexOf(original);
-  var change_log = [];
-  Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, original.length, patch, change_log);
+  %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
 }
 
 Debug.setListener(listener);
diff --git a/src/v8/test/debugger/debug/debug-liveedit-inline.js b/src/v8/test/debugger/debug/debug-liveedit-inline.js
index 4d20991..1e0671e 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-inline.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-inline.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file
 
-// Flags: --allow-natives-syntax --enable-inspector
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -12,19 +12,16 @@
 
 function foo() {  return ChooseAnimal() }
 
+%PrepareFunctionForOptimization(foo);
 assertEquals("Cat", foo());
-    %OptimizeFunctionOnNextCall(foo);
+%OptimizeFunctionOnNextCall(foo);
 
 foo();
 
-var script = Debug.findScript(ChooseAnimal);
+var new_source =
+    Debug.scriptSource(ChooseAnimal).replace('Cat', "Cap' + 'y' + 'bara");
+print('new source: ' + new_source);
 
-var orig_animal = "Cat";
-var patch_pos = script.source.indexOf(orig_animal);
-var new_animal_patch = "Cap' + 'y' + 'bara";
-
-var change_log = new Array();
-
-Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, orig_animal.length, new_animal_patch, change_log);
+%LiveEditPatchScript(ChooseAnimal, new_source);
 
 assertEquals("Capybara", foo());
diff --git a/src/v8/test/debugger/debug/debug-liveedit-literals.js b/src/v8/test/debugger/debug/debug-liveedit-literals.js
index 08edec3..65ba12c 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-literals.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-literals.js
@@ -25,6 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -46,14 +47,9 @@
         assertEquals("Cat", ChooseAnimalArray[i]());
     }
 
-    var script = Debug.findScript(ChooseAnimalArray[0]);
-
-    var patch_pos = script.source.indexOf(old_expression);
-    var new_animal_patch = new_expression;
-
-    var change_log = new Array();
-    Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos,
-        old_expression.length, new_expression, change_log);
+    var new_source =
+        Debug.scriptSource(ChooseAnimalArray[0]).replace(old_expression, new_expression);
+    %LiveEditPatchScript(ChooseAnimalArray[0], new_source);
 
     for (var i = 0; i < ChooseAnimalArray.length; i++) {
         assertEquals("Capybara", ChooseAnimalArray[i]());
diff --git a/src/v8/test/debugger/debug/debug-liveedit-newsource.js b/src/v8/test/debugger/debug/debug-liveedit-newsource.js
index e6f55bb..08b9017 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-newsource.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-newsource.js
@@ -25,6 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 
@@ -47,9 +48,7 @@
 assertEquals("Cat", ChooseAnimal());
 assertEquals(25, something1);
 
-var script = Debug.findScript(ChooseAnimal);
-
-var new_source = script.source.replace("Cat", "Cap' + 'yb' + 'ara");
+var new_source = Debug.scriptSource(ChooseAnimal).replace("Cat", "Cap' + 'yb' + 'ara");
 var new_source = new_source.replace("25", "26");
 var new_source = new_source.replace("Help", "Hello");
 var new_source = new_source.replace("17", "18");
@@ -62,10 +61,7 @@
 var new_source = new_source.replace("// Array", "Array");
 print("new source: " + new_source);
 
-var change_log = new Array();
-var result = Debug.LiveEdit.SetScriptSource(script, new_source, false, change_log);
-print("Result: " + JSON.stringify(result) + "\n");
-print("Change log: " + JSON.stringify(change_log) + "\n");
+%LiveEditPatchScript(ChooseAnimal, new_source);
 
 assertEquals("Capybara", ChooseAnimal());
 // Global variable do not get changed (without restarting script).
diff --git a/src/v8/test/debugger/debug/debug-liveedit-patch-positions-replace.js b/src/v8/test/debugger/debug/debug-liveedit-patch-positions-replace.js
index 374ffde..21d2d36 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-patch-positions-replace.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-patch-positions-replace.js
@@ -34,6 +34,7 @@
 // change they are 114 characters away from each other. New instance of Code is
 // required when those numbers cross the border value of 64 (in any direction).
 
+// Flags: --allow-natives-syntax
 Debug = debug.Debug
 
 eval(
@@ -46,19 +47,13 @@
     "}"
 );
 
-var script = Debug.findScript(BeingReplaced);
-
-var orig_body = "{}";
-var patch_pos = script.source.indexOf(orig_body);
-// Line long enough to change rinfo encoding.
-var new_body_patch = "{return 'Capybara';" +
-    "                                                                          " +
-    "}";
-
-var change_log = new Array();
 function Changer() {
-  Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, orig_body.length, new_body_patch, change_log);
-  print("Change log: " + JSON.stringify(change_log) + "\n");
+  // Line long enough to change rinfo encoding.
+  var new_source =
+    Debug.scriptSource(BeingReplaced).replace("{}", "{return 'Capybara';" +
+    "                                                                          " +
+    "}");
+  %LiveEditPatchScript(BeingReplaced, new_source);
 }
 
 function NoOp() {
diff --git a/src/v8/test/debugger/debug/debug-liveedit-recursion.js b/src/v8/test/debugger/debug/debug-liveedit-recursion.js
new file mode 100644
index 0000000..6328a9b
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-liveedit-recursion.js
@@ -0,0 +1,40 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+Debug = debug.Debug;
+
+function test(i) {
+  if (i == 3) {
+    return (function* gen() { yield test(i - 1); })().next().value;
+  } else if (i > 1) {
+    return test(i - 1);
+  } else {
+    debugger;
+    return 5;
+  }
+}
+
+let patch = null, exception = null;
+
+Debug.setListener(listener);
+patch = ['return 5', 'return 3'];
+assertEquals(3, test(2)); // no running generator
+patch = ['return 3', 'return -1'];
+assertEquals(3, test(3)); // there is running generator
+assertEquals(exception,
+    'LiveEdit failed: BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME');
+Debug.setListener(null);
+
+function listener(event) {
+  if (event != Debug.DebugEvent.Break || !patch) return;
+  try {
+    %LiveEditPatchScript(test,
+        Debug.scriptSource(test).replace(patch[0], patch[1]));
+  } catch (e) {
+    exception = e;
+  }
+  patch = null;
+}
diff --git a/src/v8/test/debugger/debug/debug-liveedit-replace-code.js b/src/v8/test/debugger/debug/debug-liveedit-replace-code.js
index a3b83bb..c517c67 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-replace-code.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-replace-code.js
@@ -2,25 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Flags: --allow-natives-syntax
+
 Debug = debug.Debug
 var counter = 0;
 var exception = null;
-
 function f() {
   if (++counter > 5) return;
   debugger;
   return counter;
-}
+};
 
 function listener(event, exec_state, event_data, data) {
   if (event != Debug.DebugEvent.Break) return;
   try {
-    var script = Debug.findScript(f);
     var original = 'debugger;';
     var patch = 'debugger;\n';
-    var position = script.source.indexOf(original);
-    Debug.LiveEdit.TestApi.ApplySingleChunkPatch(
-        script, position, original.length, patch, []);
+    %LiveEditPatchScript(f, Debug.scriptSource(f).replace(original, patch));
   } catch (e) {
     exception = e;
   }
diff --git a/src/v8/test/debugger/debug/debug-liveedit-stepin.js b/src/v8/test/debugger/debug/debug-liveedit-stepin.js
index f96a079..10264dd 100644
--- a/src/v8/test/debugger/debug/debug-liveedit-stepin.js
+++ b/src/v8/test/debugger/debug/debug-liveedit-stepin.js
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
-
 function BestEditor() {
   return 'Emacs';
 }
@@ -39,11 +39,8 @@
 };
 
 function Replace(fun, original, patch) {
-  var script = Debug.findScript(fun);
   if (fun.toString().indexOf(original) < 0) return;
-  var patch_pos = script.source.indexOf(original);
-  var change_log = [];
-  Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos, original.length, patch, change_log);
+  %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
 }
 
 Debug.setListener(listener);
@@ -56,7 +53,6 @@
 
 assertNull(exception);
 assertEquals(["Emacs", "Eclipse", "Vim"], results);
-print(JSON.stringify(log, 1));
 assertEquals([
   "debugger;",
   "results.push(BestEditor());",
diff --git a/src/v8/test/debugger/debug/debug-materialized.js b/src/v8/test/debugger/debug/debug-materialized.js
index dd22e1e..857bbb8 100644
--- a/src/v8/test/debugger/debug/debug-materialized.js
+++ b/src/v8/test/debugger/debug/debug-materialized.js
@@ -18,6 +18,8 @@
   return t.a;
 }
 
+%PrepareFunctionForOptimization(foo);
+%PrepareFunctionForOptimization(bar);
 foo(1);
 foo(1);
 bar(1);
diff --git a/src/v8/test/debugger/debug/debug-modules-set-variable-value.mjs b/src/v8/test/debugger/debug/debug-modules-set-variable-value.mjs
new file mode 100644
index 0000000..368ab49
--- /dev/null
+++ b/src/v8/test/debugger/debug/debug-modules-set-variable-value.mjs
@@ -0,0 +1,376 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Flags: --no-always-opt --no-opt
+
+// The first part of this file is copied over from debug-set-variable-value.js
+// (a few tests were removed because they make no sense for modules). The second
+// part is new.
+
+var Debug = debug.Debug;
+
+// Accepts a function/closure 'fun' that must have a debugger statement inside.
+// A variable 'variable_name' must be initialized before debugger statement
+// and returned after the statement. The test will alter variable value when
+// on debugger statement and check that returned value reflects the change.
+function RunPauseTest(scope_number, expected_old_result, variable_name,
+    new_value, expected_new_result, fun) {
+  var actual_old_result = fun();
+  assertEquals(expected_old_result, actual_old_result);
+
+  var listener_delegate;
+  var listener_called = false;
+  var exception = null;
+
+  function listener_delegate(exec_state) {
+    var scope = exec_state.frame(0).scope(scope_number);
+    scope.setVariableValue(variable_name, new_value);
+  }
+
+  function listener(event, exec_state, event_data, data) {
+    try {
+      if (event == Debug.DebugEvent.Break) {
+        listener_called = true;
+        listener_delegate(exec_state);
+      }
+    } catch (e) {
+      exception = e;
+    }
+  }
+
+  // Add the debug event listener.
+  Debug.setListener(listener);
+
+  var actual_new_result;
+  try {
+    actual_new_result = fun();
+  } finally {
+    Debug.setListener(null);
+  }
+
+  if (exception != null) {
+   assertUnreachable("Exception in listener\n" + exception.stack);
+  }
+  assertTrue(listener_called);
+
+  assertEquals(expected_new_result, actual_new_result);
+}
+
+
+function ClosureTestCase(scope_index, old_result, variable_name, new_value,
+    new_result, success_expected, factory) {
+  this.scope_index_ = scope_index;
+  this.old_result_ = old_result;
+  this.variable_name_ = variable_name;
+  this.new_value_ = new_value;
+  this.new_result_ = new_result;
+  this.success_expected_ = success_expected;
+  this.factory_ = factory;
+}
+
+ClosureTestCase.prototype.run_pause_test = function() {
+  var th = this;
+  var fun = this.factory_(true);
+  this.run_and_catch_(function() {
+    RunPauseTest(th.scope_index_ + 1, th.old_result_, th.variable_name_,
+        th.new_value_, th.new_result_, fun);
+  });
+}
+
+ClosureTestCase.prototype.run_and_catch_ = function(runnable) {
+  if (this.success_expected_) {
+    runnable();
+  } else {
+    assertThrows(runnable);
+  }
+}
+
+
+// Test scopes visible from closures.
+
+var closure_test_cases = [
+  new ClosureTestCase(0, 'cat', 'v1', 5, 5, true,
+      function Factory(debug_stop) {
+    var v1 = 'cat';
+    return function() {
+      if (debug_stop) debugger;
+      return v1;
+    }
+  }),
+
+  new ClosureTestCase(0, 4, 't', 7, 9, true, function Factory(debug_stop) {
+    var t = 2;
+    var r = eval("t");
+    return function() {
+      if (debug_stop) debugger;
+      return r + t;
+    }
+  }),
+
+  new ClosureTestCase(0, 6, 't', 10, 13, true, function Factory(debug_stop) {
+    var t = 2;
+    var r = eval("t = 3");
+    return function() {
+      if (debug_stop) debugger;
+      return r + t;
+    }
+  }),
+
+  new ClosureTestCase(2, 'capybara', 'foo', 77, 77, true,
+      function Factory(debug_stop) {
+    var foo = "capybara";
+    return (function() {
+      var bar = "fish";
+      try {
+        throw {name: "test exception"};
+      } catch (e) {
+        return function() {
+          if (debug_stop) debugger;
+          bar = "beast";
+          return foo;
+        }
+      }
+    })();
+  }),
+
+  new ClosureTestCase(0, 'AlphaBeta', 'eee', 5, '5Beta', true,
+      function Factory(debug_stop) {
+    var foo = "Beta";
+    return (function() {
+      var bar = "fish";
+      try {
+        throw "Alpha";
+      } catch (eee) {
+        return function() {
+          if (debug_stop) debugger;
+          return eee + foo;
+        }
+      }
+    })();
+  })
+];
+
+for (var i = 0; i < closure_test_cases.length; i++) {
+  closure_test_cases[i].run_pause_test();
+}
+
+
+// Test local scope.
+
+RunPauseTest(0, 'HelloYou', 'u', 'We', 'HelloWe', (function Factory() {
+  return function() {
+    var u = "You";
+    var v = "Hello";
+    debugger;
+    return v + u;
+  }
+})());
+
+RunPauseTest(0, 'Helloworld', 'p', 'GoodBye', 'HelloGoodBye',
+    (function Factory() {
+  function H(p) {
+    var v = "Hello";
+    debugger;
+    return v + p;
+  }
+  return function() {
+    return H("world");
+  }
+})());
+
+RunPauseTest(0, 'mouse', 'v1', 'dog', 'dog', (function Factory() {
+  return function() {
+    var v1 = 'cat';
+    eval("v1 = 'mouse'");
+    debugger;
+    return v1;
+  }
+})());
+
+// Check that we correctly update local variable that
+// is referenced from an inner closure.
+RunPauseTest(0, 'Blue', 'v', 'Green', 'Green', (function Factory() {
+  return function() {
+    function A() {
+      var v = "Blue";
+      function Inner() {
+        return void v;
+      }
+      debugger;
+      return v;
+    }
+    return A();
+  }
+})());
+
+// Check that we correctly update parameter, that is known to be stored
+// both on stack and in heap.
+RunPauseTest(0, 5, 'p', 2012, 2012, (function Factory() {
+  return function() {
+    function A(p) {
+      function Inner() {
+        return void p;
+      }
+      debugger;
+      return p;
+    }
+    return A(5);
+  }
+})());
+
+
+////////////////////////////////////////////////////////////////////////////////
+// From here on we test the module scope.
+////////////////////////////////////////////////////////////////////////////////
+
+
+// Non-existing variable.
+{
+  let exception;
+  function listener(event, exec_state) {
+    if (event == Debug.DebugEvent.Break) {
+      let module_scope = exec_state.frame().scope(1);
+      assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+      try {
+        module_scope.setVariableValue('spargel', 42);
+      } catch(e) { exception = e; }
+    }
+  }
+
+  Debug.setListener(listener);
+  assertThrows(() => spargel, ReferenceError);
+  debugger;
+  assertThrows(() => spargel, ReferenceError);
+  assertTrue(exception !== undefined);
+}
+
+
+// Local (non-exported) variable.
+let salat = 12;
+{
+  function listener(event, exec_state) {
+    if (event == Debug.DebugEvent.Break) {
+      let module_scope = exec_state.frame().scope(1);
+      assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+      module_scope.setVariableValue('salat', 42);
+    }
+  }
+
+  Debug.setListener(listener);
+  assertEquals(12, salat);
+  debugger;
+  assertEquals(42, salat);
+}
+
+
+// Local (non-exported) variable, nested access.
+let salad = 12;
+{
+  function listener(event, exec_state) {
+    if (event == Debug.DebugEvent.Break) {
+      let scope_count = exec_state.frame().scopeCount();
+      let module_scope = exec_state.frame().scope(1);
+      assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+      module_scope.setVariableValue('salad', 42);
+    }
+  }
+
+  Debug.setListener(listener);
+  function foo() {
+    assertEquals(12, salad);
+    debugger;
+    assertEquals(42, salad);
+  };
+  foo();
+}
+
+
+// Exported variable.
+export let salami = 1;
+{
+  function listener(event, exec_state) {
+    if (event == Debug.DebugEvent.Break) {
+      let module_scope = exec_state.frame().scope(1);
+      assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+      module_scope.setVariableValue('salami', 2);
+    }
+  }
+
+  Debug.setListener(listener);
+  assertEquals(1, salami);
+  debugger;
+  assertEquals(2, salami);
+}
+
+
+// Exported variable, nested access.
+export let ham = 1;
+{
+  function listener(event, exec_state) {
+    if (event == Debug.DebugEvent.Break) {
+      let scope_count = exec_state.frame().scopeCount();
+      let module_scope = exec_state.frame().scope(1);
+      assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+      module_scope.setVariableValue('ham', 2);
+    }
+  }
+
+  Debug.setListener(listener);
+  function foo() {
+    assertEquals(1, ham);
+    debugger;
+    assertEquals(2, ham);
+  };
+  foo();
+}
+
+
+// Imported variable. Setting is currently not supported.
+import { salami as wurst } from "./debug-modules-set-variable-value.mjs";
+{
+  let exception;
+  function listener(event, exec_state) {
+    if (event == Debug.DebugEvent.Break) {
+      let module_scope = exec_state.frame().scope(1);
+      assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+      try {
+        module_scope.setVariableValue('wurst', 3);
+      } catch(e) { exception = e; }
+    }
+  }
+
+  Debug.setListener(listener);
+  assertEquals(2, wurst);
+  debugger;
+  assertEquals(2, wurst);
+  assertTrue(exception !== undefined);
+}
+
+
+// Imported variable, nested access. Setting is currently not supported.
+import { salami as wurstl } from "./debug-modules-set-variable-value.mjs";
+{
+  let exception;
+  function listener(event, exec_state) {
+    if (event == Debug.DebugEvent.Break) {
+      let scope_count = exec_state.frame().scopeCount();
+      let module_scope = exec_state.frame().scope(2);
+      assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+      try {
+        module_scope.setVariableValue('wurstl', 3);
+      } catch(e) { exception = e; }
+    }
+  }
+
+  Debug.setListener(listener);
+  function foo() {
+    assertEquals(2, wurstl);
+    debugger;
+    assertEquals(2, wurstl);
+    assertTrue(exception !== undefined);
+  };
+  foo();
+}
+
+
+Debug.setListener(null);
diff --git a/src/v8/test/debugger/debug/debug-optimize.js b/src/v8/test/debugger/debug/debug-optimize.js
index f296816..1945683 100644
--- a/src/v8/test/debugger/debug/debug-optimize.js
+++ b/src/v8/test/debugger/debug/debug-optimize.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --opt --no-always-opt
+// Flags: --opt --no-always-opt --turbo-inlining
 
 var Debug = debug.Debug;
 
@@ -24,6 +24,7 @@
 
 
 function optimize(f) {
+  %PrepareFunctionForOptimization(f);
   f();
   f();
   %OptimizeFunctionOnNextCall(f);
diff --git a/src/v8/test/debugger/debug/debug-return-value.js b/src/v8/test/debugger/debug/debug-return-value.js
index 77717ce..4e8db7e 100644
--- a/src/v8/test/debugger/debug/debug-return-value.js
+++ b/src/v8/test/debugger/debug/debug-return-value.js
@@ -27,12 +27,12 @@
 
 Debug = debug.Debug
 
-listener_complete = false;
-exception = false;
-break_count = 0;
-expected_return_value = 0;
-expected_source_position = [];
-debugger_source_position = 0;
+let listener_complete = false;
+let exceptionThrown = false;
+let break_count = 0;
+let expected_return_value = 0;
+let expected_source_position = [];
+let debugger_source_position = 0;
 
 // Listener which expects to do four steps to reach returning from the function.
 function listener(event, exec_state, event_data, data) {
@@ -72,7 +72,7 @@
       }
     }
   } catch (e) {
-    exception = e
+    exceptionThrown = true;
     print(e + e.stack)
   };
 };
@@ -93,7 +93,7 @@
 expected_source_position = [10, 38, 47];
 listener_complete = false;
 f();
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener");
 assertTrue(listener_complete);
 assertEquals(4, break_count);
 
@@ -102,7 +102,7 @@
 expected_source_position = [10, 19, 28];
 listener_complete = false;
 f(true);
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener");
 assertTrue(listener_complete);
 assertEquals(4, break_count);
 
@@ -111,6 +111,6 @@
 expected_source_position = [10, 38, 47];
 listener_complete = false;
 f(false);
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener");
 assertTrue(listener_complete);
 assertEquals(4, break_count);
diff --git a/src/v8/test/debugger/debug/debug-scopes-suspended-generators.js b/src/v8/test/debugger/debug/debug-scopes-suspended-generators.js
index 2d9d253..8d09e9c 100644
--- a/src/v8/test/debugger/debug/debug-scopes-suspended-generators.js
+++ b/src/v8/test/debugger/debug/debug-scopes-suspended-generators.js
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Flags: --no-analyze-environment-liveness
+
 // The functions used for testing backtraces. They are at the top to make the
 // testing of source line/column easier.
 
diff --git a/src/v8/test/debugger/debug/debug-scopes.js b/src/v8/test/debugger/debug/debug-scopes.js
index 6f01cec..08e8d36 100644
--- a/src/v8/test/debugger/debug/debug-scopes.js
+++ b/src/v8/test/debugger/debug/debug-scopes.js
@@ -123,7 +123,7 @@
   assertEquals(names.length, all_scopes.length, "FrameMirror.allScopes length");
   for (var i = 0; i < names.length; i++) {
     var scope = exec_state.frame().scope(i);
-    assertEquals(names[i], scope.details().name())
+    // assertEquals(names[i], scope.details().name())
   }
 }
 
@@ -175,8 +175,8 @@
     if (!position)
       continue;
 
-    assertEquals(position.start, scope.details().startPosition())
-    assertEquals(position.end, scope.details().endPosition())
+    // assertEquals(position.start, scope.details().startPosition())
+    // assertEquals(position.end, scope.details().endPosition())
   }
 }
 
@@ -457,6 +457,7 @@
     debugger;
   }
 }
+%PrepareFunctionForOptimization(with_7);
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.With,
@@ -722,6 +723,89 @@
 EndTest();
 
 
+// Closure with inferred name.
+BeginTest("Closure with Inferred Name 1");
+
+function closure_1_inferred_name(a) {
+  let foo = {};
+  foo.bar = function() {
+    debugger;
+    return a;
+  };
+  return foo.bar;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1}, 1, exec_state);
+  CheckScopeChainNames(["foo.bar", "closure_1_inferred_name", undefined,
+      undefined], exec_state);
+};
+closure_1_inferred_name(1)();
+EndTest();
+
+// Closure with nested inferred name.
+BeginTest("Closure with Inferred Name 2");
+
+function closure_2_inferred_name(a) {
+  let foo = {};
+  function FooBar(b) {
+    foo.baz = function() {
+      debugger;
+      return a+b;
+    }
+    return foo.baz;
+  };
+  return FooBar;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({b:0x1235}, 1, exec_state);
+  CheckScopeContent({a:0x1234}, 2, exec_state);
+  CheckScopeChainNames(["FooBar.foo.baz", "FooBar", "closure_2_inferred_name",
+      undefined, undefined], exec_state);
+};
+closure_2_inferred_name(0x1234)(0x1235)();
+EndTest();
+
+
+// Closure with nested inferred name.
+BeginTest("Closure with Inferred Name 3");
+
+function closure_3_inferred_name(a) {
+  let foo = {};
+  foo.bar = function(b) {
+    foo.baz = function() {
+      debugger;
+      return a+b;
+    }
+    return foo.baz;
+  };
+  return foo.bar;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({b:0x1235}, 1, exec_state);
+  CheckScopeContent({a:0x1234}, 2, exec_state);
+  CheckScopeChainNames(["foo.baz", "foo.bar", "closure_3_inferred_name",
+      undefined, undefined], exec_state);
+};
+closure_3_inferred_name(0x1234)(0x1235)();
+EndTest();
+
 BeginTest("Closure passed to optimized Array.prototype.forEach");
 function closure_10(a) {
   var x = a + 2;
@@ -742,6 +826,7 @@
   CheckScopeChainNames(
       ["closure_11", "closure_10", undefined, undefined], exec_state);
 };
+%PrepareFunctionForOptimization(closure_10);
 begin_test_count++; closure_10(5); end_test_count++;
 begin_test_count++; closure_10(5); end_test_count++;
 %OptimizeFunctionOnNextCall(closure_10);
@@ -1069,6 +1154,7 @@
     debugger;
   }
 };
+%PrepareFunctionForOptimization(catch_block_7);
 
 
 listener_delegate = function(exec_state) {
diff --git a/src/v8/test/debugger/debug/debug-step-end-of-script.js b/src/v8/test/debugger/debug/debug-step-end-of-script.js
index 92a381e..ec5eb37 100644
--- a/src/v8/test/debugger/debug/debug-step-end-of-script.js
+++ b/src/v8/test/debugger/debug/debug-step-end-of-script.js
@@ -4,7 +4,7 @@
 
 
 var Debug = debug.Debug;
-var expected = ["debugger;", "debugger;"];
+var expected = ["debugger;", ""];
 
 function listener(event, exec_state, event_data, data) {
   if (event != Debug.DebugEvent.Break) return;
diff --git a/src/v8/test/debugger/debug/debug-step-microtask.js b/src/v8/test/debugger/debug/debug-step-microtask.js
index 258f235..633bac8 100644
--- a/src/v8/test/debugger/debug/debug-step-microtask.js
+++ b/src/v8/test/debugger/debug/debug-step-microtask.js
@@ -44,7 +44,7 @@
   Debug.setListener(null);
   assertNull(exception);
   var expectation =
-    ["debugger;","debugger;","  print(1);","}","  return 2;","  return 2;",
+    ["debugger;","","  print(1);","}","  return 2;","  return 2;",
      "  throw new Error();","  print(3);","}  // STOP"];
   assertEquals(log, expectation);
 });
diff --git a/src/v8/test/debugger/debug/debug-step-turbofan.js b/src/v8/test/debugger/debug/debug-step-turbofan.js
index a40114b..0ffc2c8 100644
--- a/src/v8/test/debugger/debug/debug-step-turbofan.js
+++ b/src/v8/test/debugger/debug/debug-step-turbofan.js
@@ -44,6 +44,7 @@
   }
 }
 
+%PrepareFunctionForOptimization(g);
 f(0);
 f(0);
 %OptimizeFunctionOnNextCall(g);
diff --git a/src/v8/test/debugger/debug/deserialize-script-id.js b/src/v8/test/debugger/debug/deserialize-script-id.js
new file mode 100644
index 0000000..680f60d
--- /dev/null
+++ b/src/v8/test/debugger/debug/deserialize-script-id.js
@@ -0,0 +1,15 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --cache=code
+// Test that script ids are unique and we found the correct ones.
+
+var Debug = debug.Debug;
+Debug.setListener(function(){});
+
+var ids = %DebugGetLoadedScriptIds();
+ids.sort((a, b) => a - b);
+ids.reduce((prev, cur) => assertTrue(prev === undefined || prev != cur));
+
+Debug.setListener(null);
diff --git a/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-1.js b/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-1.js
index 40dc816b..ea8765c 100644
--- a/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-1.js
+++ b/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-1.js
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-
 // Test that live-editing a frame that uses new.target fails.
+// Flags: --allow-natives-syntax
 
 Debug = debug.Debug
 var calls = 0;
@@ -43,16 +43,10 @@
 
 function Replace(fun, original, patch) {
   ExecuteInDebugContext(function() {
-    var change_log = [];
     try {
-      var script = Debug.findScript(fun);
-      var patch_pos = script.source.indexOf(original);
-      Debug.LiveEdit.TestApi.ApplySingleChunkPatch(
-          script, patch_pos, original.length, patch, change_log);
+      %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
     } catch (e) {
-      assertEquals("BLOCKED_NO_NEW_TARGET_ON_RESTART",
-          change_log[0].functions_on_stack[0].replace_problem);
-      assertInstanceof(e, Debug.LiveEdit.Failure);
+      assertEquals(e, 'LiveEdit failed: BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME');
       exceptions++;
     }
   });
diff --git a/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-2.js b/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-2.js
index 764c57c..63b5fac 100644
--- a/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-2.js
+++ b/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-2.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-
+// Flags: --allow-natives-syntax
 // Test that live-editing a frame to introduce new.target fails.
 
 Debug = debug.Debug
@@ -40,16 +40,10 @@
 
 function Replace(fun, original, patch) {
   ExecuteInDebugContext(function() {
-    var change_log = [];
     try {
-      var script = Debug.findScript(fun);
-      var patch_pos = script.source.indexOf(original);
-      Debug.LiveEdit.TestApi.ApplySingleChunkPatch(
-          script, patch_pos, original.length, patch, change_log);
+      %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
     } catch (e) {
-      assertEquals("BLOCKED_NO_NEW_TARGET_ON_RESTART",
-                   change_log[0].functions_on_stack[0].replace_problem);
-      assertInstanceof(e, Debug.LiveEdit.Failure);
+      assertEquals(e, 'LiveEdit failed: BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME');
       exceptions++;
     }
   });
diff --git a/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-3.js b/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-3.js
index 60ec9a7..c607290 100644
--- a/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-3.js
+++ b/src/v8/test/debugger/debug/es6/debug-liveedit-new-target-3.js
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-
 // Test that live-editing a frame above one that uses new.target succeeds.
+// Flags: --allow-natives-syntax
 
-Debug = debug.Debug
+Debug = debug.Debug;
 var wrapper_calls = 0;
 var construct_calls = 0;
 var exceptions = 0;
@@ -47,10 +47,7 @@
   ExecuteInDebugContext(function() {
     var change_log = [];
     try {
-      var script = Debug.findScript(fun);
-      var patch_pos = script.source.indexOf(original);
-      Debug.LiveEdit.TestApi.ApplySingleChunkPatch(
-          script, patch_pos, original.length, patch, change_log);
+      %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
     } catch (e) {
       exceptions++;
     }
diff --git a/src/v8/test/debugger/debug/es6/debug-promises/evaluate-across-microtasks.js b/src/v8/test/debugger/debug/es6/debug-promises/evaluate-across-microtasks.js
index 71b0747..ec3555d 100644
--- a/src/v8/test/debugger/debug/es6/debug-promises/evaluate-across-microtasks.js
+++ b/src/v8/test/debugger/debug/es6/debug-promises/evaluate-across-microtasks.js
@@ -51,7 +51,7 @@
 // Make sure that the debug event listener was invoked.
 assertTrue(listenerComplete);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 var expectation =
   [ "[0] debugger", "[1] start", "[1] then 1",
diff --git a/src/v8/test/debugger/debug/es6/debug-promises/proxy-as-promise.js b/src/v8/test/debugger/debug/es6/debug-promises/proxy-as-promise.js
new file mode 100644
index 0000000..431837c
--- /dev/null
+++ b/src/v8/test/debugger/debug/es6/debug-promises/proxy-as-promise.js
@@ -0,0 +1,42 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the exception thrown in a Promise.
+// We expect a normal Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var expected_events = 1;
+var log = [];
+
+
+class P extends Promise {
+    constructor(...args) {
+        super(...args);
+        return new Proxy(this, {
+            get(target, property, receiver) {
+                if (property in target) {
+                    return Reflect.get(target, property, receiver);
+                } else {
+                    return (...args) =>
+                        new Promise((resolve, reject) =>
+                            target.then(v => resolve(v[property](...args)))
+                                .catch(reject)
+                        );
+                }
+            }
+        });
+    }
+}
+
+P.resolve({doStuff(){log.push(1)}}).doStuff()
+
+function listener(event, exec_state, event_data, data) {}
+
+Debug.setBreakOnUncaughtException();
+Debug.setListener(listener);
+
+%PerformMicrotaskCheckpoint();
diff --git a/src/v8/test/debugger/debug/es6/debug-promises/reject-in-constructor-opt.js b/src/v8/test/debugger/debug/es6/debug-promises/reject-in-constructor-opt.js
new file mode 100644
index 0000000..d0658fc
--- /dev/null
+++ b/src/v8/test/debugger/debug/es6/debug-promises/reject-in-constructor-opt.js
@@ -0,0 +1,64 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+// Test exercises code paths for catching exceptions in the promise constructor
+// in conjunction with deoptimization.
+
+Debug = debug.Debug;
+
+var expected_events = 4;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Exception) {
+      expected_events--;
+      assertTrue(expected_events >= 0);
+      assertEquals("uncaught", event_data.exception().message);
+      assertTrue(event_data.uncaught());
+      // The frame comes from the Promise.reject call
+      assertNotNull(/\/\/ EXCEPTION/.exec(event_data.sourceLineText()));
+      assertTrue(event_data.uncaught());
+    }
+  } catch (e) {
+    %AbortJS(e + "\n" + e.stack);
+  }
+}
+
+Debug.setBreakOnException();
+Debug.setListener(listener);
+
+function foo(a,b) {
+    let P = new Promise((resolve, reject) => { bar(a,b); resolve()})
+    return P;
+}
+
+function bar(a,b) {
+  %DeoptimizeFunction(foo);
+  throw new Error("uncaught"); // EXCEPTION
+}
+
+%PrepareFunctionForOptimization(foo);
+
+foo();
+%PerformMicrotaskCheckpoint();
+
+foo();
+%PerformMicrotaskCheckpoint();
+
+%OptimizeFunctionOnNextCall(foo);
+
+// bar likely gets inlined into foo.
+foo();
+%PerformMicrotaskCheckpoint();
+
+%NeverOptimizeFunction(bar);
+%PrepareFunctionForOptimization(foo);
+%OptimizeFunctionOnNextCall(foo);
+
+// bar does not get inlined into foo.
+foo();
+%PerformMicrotaskCheckpoint();
+
+assertEquals(0, expected_events);
diff --git a/src/v8/test/debugger/debug/es6/debug-promises/throw-with-throw-in-reject.js b/src/v8/test/debugger/debug/es6/debug-promises/throw-with-throw-in-reject.js
index b17054b..5cca2f9 100644
--- a/src/v8/test/debugger/debug/es6/debug-promises/throw-with-throw-in-reject.js
+++ b/src/v8/test/debugger/debug/es6/debug-promises/throw-with-throw-in-reject.js
@@ -3,15 +3,13 @@
 // found in the LICENSE file.
 
 
-// Test debug events when an exception is thrown inside a Promise, which is
-// caught by a custom promise, which throws a new exception in its reject
-// handler. We expect two Exception debug events:
-//  1) when the exception is thrown in the promise q.
-//  2) when the custom reject closure in MyPromise throws an exception.
+// Test debug events when an exception is thrown inside a Promise,
+// which is caught by a custom promise, which throws a new exception
+// in its reject handler. We expect no Exception debug events.
 
 Debug = debug.Debug;
 
-var expected_events = 1;
+var expected_events = 0;
 var log = [];
 
 var p = new Promise(function(resolve, reject) {
@@ -21,11 +19,9 @@
 
 function MyPromise(resolver) {
   var reject = function() {
-    log.push("throw in reject");
     throw new Error("reject");  // event
   };
   var resolve = function() { };
-  log.push("construct");
   resolver(resolve, reject);
 };
 
@@ -42,16 +38,7 @@
 function listener(event, exec_state, event_data, data) {
   try {
     if (event == Debug.DebugEvent.Exception) {
-      expected_events--;
-      assertTrue(expected_events >= 0);
-      if (expected_events == 0) {
-        assertEquals(["resolve", "construct", "end main",
-                      "throw caught"], log);
-        assertEquals("caught", event_data.exception().message);
-      } else {
-        assertUnreachable();
-      }
-      assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
+      assertUnreachable();
     }
   } catch (e) {
     %AbortJS(e + "\n" + e.stack);
@@ -68,8 +55,8 @@
     try {
       assertTrue(iteration < 10);
       if (expected_events === 0) {
-        assertEquals(["resolve", "construct", "end main",
-                      "throw caught", "throw in reject"], log);
+        assertEquals(["resolve", "end main",
+                      "throw caught"], log);
       } else {
         testDone(iteration + 1);
       }
diff --git a/src/v8/test/debugger/debug/es6/debug-step-destructuring-bind.js b/src/v8/test/debugger/debug/es6/debug-step-destructuring-bind.js
index 2e707b9..1ada64d 100644
--- a/src/v8/test/debugger/debug/es6/debug-step-destructuring-bind.js
+++ b/src/v8/test/debugger/debug/es6/debug-step-destructuring-bind.js
@@ -21,7 +21,7 @@
   } catch (e) {
     exception = e;
     print(e);
-  }
+  }                                               // B34
 };
 
 Debug.setListener(listener);
@@ -41,7 +41,7 @@
   function f2([
                 a,                                // B7
                 b = id(3)                         // B8
-              ]) {
+             ]) {
     assertEquals([4, 3], [a, b]);                 // B11
   }                                               // B12
   f2([4]);                                        // B6
@@ -49,7 +49,7 @@
   function f3({
                 x: a,                             // B14
                 y: b                              // B15
-              }) {
+             }) {
     assertEquals([5, 6], [a, b]);                 // B16
   }                                               // B17
   f3({y: 6, x: 5});                               // B13
@@ -60,7 +60,7 @@
                   b,                              // B20
                   c,                              // B21
                 }
-              ]) {
+              ]) {                                // B19
     assertEquals([2, 4, 6], [a, b, c]);           // B22
   }                                               // B23
   f4([2, {c: 6, b: 4}]);                          // B18
@@ -98,12 +98,12 @@
   }
 
   var {
-    x: a,
-    y: b = 9
+    x: a,                                         // B47
+    y: b = 9                                      // B48
   } = { x: 4 };                                   // B46
-  assertEquals([4, 9], [a, b]);                   // B47
-}                                                 // B48
+  assertEquals([4, 9], [a, b]);                   // B49
+}                                                 // B50
 
 test();
-Debug.setListener(null);                          // B49
+Debug.setListener(null);                          // B51
 assertNull(exception);
diff --git a/src/v8/test/debugger/debug/es6/generators-debug-liveedit.js b/src/v8/test/debugger/debug/es6/generators-debug-liveedit.js
index 3ae359a..2627c8d 100644
--- a/src/v8/test/debugger/debug/es6/generators-debug-liveedit.js
+++ b/src/v8/test/debugger/debug/es6/generators-debug-liveedit.js
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-
+// Flags: --allow-natives-syntax
 var Debug = debug.Debug;
-var LiveEdit = Debug.LiveEdit;
 
 unique_id = 0;
 
@@ -62,15 +61,7 @@
 
 function patch(fun, from, to) {
   function debug() {
-    var log = new Array();
-    var script = Debug.findScript(fun);
-    var pos = script.source.indexOf(from);
-    try {
-      LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
-                                             log);
-    } finally {
-      print("Change log: " + JSON.stringify(log) + "\n");
-    }
+    %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(from, to));
   }
   ExecuteInDebugContext(debug);
 }
@@ -84,8 +75,9 @@
   function attempt_gen_patch() {
     assertFalse(gen_patch_attempted);
     gen_patch_attempted = true;
-    assertThrows(function() { patch(generator, "'Cat'", "'Capybara'") },
-                 LiveEdit.Failure);
+    assertThrowsEquals(function() {
+      patch(generator, '\'Cat\'', '\'Capybara\'')
+    }, 'LiveEdit failed: BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME');
   };
   var iter = generator(attempt_gen_patch);
   assertIteratorResult(undefined, false, iter.next());
@@ -104,8 +96,9 @@
   // Patching will fail however when a live iterator is suspended.
   iter = generator(function(){});
   assertIteratorResult(undefined, false, iter.next());
-  assertThrows(function() { patch(generator, "'Capybara'", "'Tapir'") },
-               LiveEdit.Failure);
+  assertThrowsEquals(function() {
+    patch(generator, '\'Capybara\'', '\'Tapir\'')
+  }, 'LiveEdit failed: BLOCKED_BY_RUNNING_GENERATOR');
   assertIteratorResult("Capybara", true, iter.next());
 
   // Try to patch functions with activations inside and outside generator
@@ -123,8 +116,9 @@
     }
     fun_patch_attempted = true;
     // Patching outside a generator activation must fail.
-    assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
-                 LiveEdit.Failure);
+    assertThrowsEquals(function() {
+      patch(fun_outside, '\'Cat\'', '\'Cobra\'')
+    }, 'LiveEdit failed: BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME');
     // Patching inside a generator activation may succeed.
     patch(fun_inside, "'Cat'", "'Koala'");
   }
diff --git a/src/v8/test/debugger/debug/es6/generators-debug-scopes.js b/src/v8/test/debugger/debug/es6/generators-debug-scopes.js
index a46dc8b..14752af 100644
--- a/src/v8/test/debugger/debug/es6/generators-debug-scopes.js
+++ b/src/v8/test/debugger/debug/es6/generators-debug-scopes.js
@@ -42,8 +42,7 @@
   run(function () { return fun.apply(null, args) });
   run(function () { return gen.apply(null, args).next().value });
 
-  // TODO(wingo): Uncomment after bug 2838 is fixed.
-  // Debug.setListener(null);
+  Debug.setListener(null);
 }
 
 // Check that two scope are the same.
diff --git a/src/v8/test/debugger/debug/es8/async-debug-basic.js b/src/v8/test/debugger/debug/es8/async-debug-basic.js
index 9423fe5..ea87c67 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-basic.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-basic.js
@@ -4,8 +4,9 @@
 
 Debug = debug.Debug
 
-listenerComplete = false;
-breakPointCount = 0;
+let listenerComplete = false;
+let breakPointCount = 0;
+let exceptionThrown = false;
 
 async function f() {
   await (async function() { var a = "a"; await 1; debugger; })();
@@ -13,7 +14,7 @@
   var b = "b";
 
   assertTrue(listenerDone);
-  assertFalse(exception);
+  assertFalse(exceptionThrown);
   assertEquals(1, breakpointCount);
 }
 
@@ -27,7 +28,7 @@
     assertEquals("b", exec_state.frame(1).evaluate("b"));
     assertEquals("c", exec_state.frame(2).evaluate("c"));
   } catch (e) {
-    exception = e;
+    exceptionThrown = true;
   };
 };
 
diff --git a/src/v8/test/debugger/debug/es8/async-debug-builtin-predictions.js b/src/v8/test/debugger/debug/es8/async-debug-builtin-predictions.js
index 70f1b57..bcd9908 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-builtin-predictions.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-builtin-predictions.js
@@ -57,7 +57,7 @@
 
 foo();
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 Debug.setListener(null);
 Debug.clearBreakOnException();
diff --git a/src/v8/test/debugger/debug/es8/async-debug-caught-exception-cases.js b/src/v8/test/debugger/debug/es8/async-debug-caught-exception-cases.js
index f5c1ed9..24cf598 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-caught-exception-cases.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-caught-exception-cases.js
@@ -197,7 +197,7 @@
 
     events = 0;
     consumer(producer);
-    %RunMicrotasks();
+    %PerformMicrotaskCheckpoint();
 
     Debug.setListener(null);
     if (caught) {
diff --git a/src/v8/test/debugger/debug/es8/async-debug-caught-exception.js b/src/v8/test/debugger/debug/es8/async-debug-caught-exception.js
index 2feecc0..de0c4e9 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-caught-exception.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-caught-exception.js
@@ -37,7 +37,7 @@
 Debug.setListener(listener);
 Debug.setBreakOnException();
 caught_throw();
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 Debug.setListener(null);
 Debug.clearBreakOnException();
 assertEquals(["a"], log);
@@ -48,7 +48,7 @@
 Debug.setListener(listener);
 Debug.setBreakOnUncaughtException();
 caught_throw();
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 Debug.setListener(null);
 Debug.clearBreakOnUncaughtException();
 assertEquals([], log);
@@ -69,7 +69,7 @@
 Debug.setListener(listener);
 Debug.setBreakOnException();
 caught_reject();
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 Debug.setListener(null);
 Debug.clearBreakOnException();
 assertEquals([], log);
@@ -80,7 +80,7 @@
 Debug.setListener(listener);
 Debug.setBreakOnUncaughtException();
 caught_reject();
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 Debug.setListener(null);
 Debug.clearBreakOnUncaughtException();
 assertEquals([], log);
@@ -95,7 +95,7 @@
 async function propagate_outer() { return propagate_inner(); }
 
 propagate_outer();
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 assertEquals(["a"], log);
 assertNull(exception);
 
@@ -104,7 +104,7 @@
 async function propagate_await() { await 1; return thrower(); }
 async function propagate_await_outer() { return propagate_await(); }
 propagate_await_outer();
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 assertEquals(["a"], log);
 assertNull(exception);
 
@@ -113,7 +113,7 @@
 
 log = [];
 Promise.resolve().then(() => Promise.reject()).catch(() => log.push("d")); // Exception c
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 assertEquals(["d"], log);
 assertNull(exception);
 
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-abort-at-break.js b/src/v8/test/debugger/debug/es8/async-debug-step-abort-at-break.js
index 85232b0..47605ce 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-abort-at-break.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-abort-at-break.js
@@ -48,6 +48,6 @@
 
 late_resolve(3);     // B4 Continue
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 assertEquals(5, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-continue-at-break.js b/src/v8/test/debugger/debug/es8/async-debug-step-continue-at-break.js
index a4726bd..79dcad6 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-continue-at-break.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-continue-at-break.js
@@ -37,8 +37,8 @@
   a +=
        await         // B1 StepIn
              g();    // B2 StepIn
-  return a;          // B4 StepNext
-}                    // B5 Continue
+  return a;          // B4 Continue
+}
 
 f();
 
@@ -48,6 +48,6 @@
 
 late_resolve(3);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
-assertEquals(6, step_count);
+assertEquals(5, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-in-and-out.js b/src/v8/test/debugger/debug/es8/async-debug-step-in-and-out.js
index 43fb16f..5d64e5a 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-in-and-out.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-in-and-out.js
@@ -37,13 +37,13 @@
   a +=
        await           // B1 StepIn
              g();
-  return a;            // B3 StepNext
-}                      // B4 Continue
+  return a;            // B3 Continue
+}
 
 f();
 
 late_resolve(3);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
-assertEquals(5, step_count);
+assertEquals(4, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-in-out-out.js b/src/v8/test/debugger/debug/es8/async-debug-step-in-out-out.js
index c1d8fd7..7702742 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-in-out-out.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-in-out-out.js
@@ -44,6 +44,6 @@
 
 late_resolve(3);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 assertEquals(4, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-in.js b/src/v8/test/debugger/debug/es8/async-debug-step-in.js
index c32fa2f..fe84e4b 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-in.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-in.js
@@ -37,13 +37,13 @@
   a +=
        await           // B1 StepIn
              g();
-  return a;            // B6 StepIn
-}                      // B7 Continue
+  return a;            // B6 Continue
+}
 
 f().then(value => assertEquals(4, value));
 
 late_resolve(3);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
-assertEquals(8, step_count);
+assertEquals(7, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-nested.js b/src/v8/test/debugger/debug/es8/async-debug-step-nested.js
index 79e8dfaa..74432a6 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-nested.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-nested.js
@@ -37,8 +37,8 @@
   a +=
        await         // B1 StepIn
              f2();   // B2 StepIn
-  return a;          // B5 StepNext
-}                    // B6 Continue
+  return a;          // B5 Continue
+}
 
 async function f2() {
   var b = 0 +        // B2 StepIn
@@ -51,6 +51,6 @@
 
 late_resolve(3);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
-assertEquals(7, step_count);
+assertEquals(6, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-next-constant.js b/src/v8/test/debugger/debug/es8/async-debug-step-next-constant.js
index 32833ac..2b43263 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-next-constant.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-next-constant.js
@@ -27,11 +27,11 @@
   a +=               // B1 StepNext
        await
              5;
-  return a;          // B2 StepNext
-}                    // B3 Continue
+  return a;          // B2 Continue
+}
 
 f();
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
-assertEquals(4, step_count);
+assertEquals(3, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-next.js b/src/v8/test/debugger/debug/es8/async-debug-step-next.js
index 597afd3..0fdbd73 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-next.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-next.js
@@ -37,13 +37,13 @@
   a +=
        await       // B1 StepNext
              g();
-  return a;        // B2 StepNext
-}                  // B3 Continue
+  return a;        // B2 Continue
+}
 
 f();
 
 late_resolve(3);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
-assertEquals(4, step_count);
+assertEquals(3, step_count);
diff --git a/src/v8/test/debugger/debug/es8/async-debug-step-out.js b/src/v8/test/debugger/debug/es8/async-debug-step-out.js
index 3ec6dd3..d37ce58 100644
--- a/src/v8/test/debugger/debug/es8/async-debug-step-out.js
+++ b/src/v8/test/debugger/debug/es8/async-debug-step-out.js
@@ -42,6 +42,6 @@
 
 late_resolve(3);   // B2 Continue
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 assertEquals(3, step_count);
diff --git a/src/v8/test/debugger/debug/es8/debug-async-break-on-stack.js b/src/v8/test/debugger/debug/es8/debug-async-break-on-stack.js
index df389f3..124cbab 100644
--- a/src/v8/test/debugger/debug/es8/debug-async-break-on-stack.js
+++ b/src/v8/test/debugger/debug/es8/debug-async-break-on-stack.js
@@ -21,7 +21,7 @@
 
   assertFalse(hadValue || hadError);
 
-  %RunMicrotasks();
+  %PerformMicrotaskCheckpoint();
 
   if (hadError) throw actual;
 
@@ -67,7 +67,7 @@
 
 f();
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 assertEqualsAsync(2, async () => break_count);
 assertEqualsAsync(null, async () => exception);
diff --git a/src/v8/test/debugger/debug/es8/debug-async-break.js b/src/v8/test/debugger/debug/es8/debug-async-break.js
index 3e07ba9..8a29820 100644
--- a/src/v8/test/debugger/debug/es8/debug-async-break.js
+++ b/src/v8/test/debugger/debug/es8/debug-async-break.js
@@ -21,7 +21,7 @@
 
   assertFalse(hadValue || hadError);
 
-  %RunMicrotasks();
+  %PerformMicrotaskCheckpoint();
 
   if (hadError) throw actual;
 
@@ -65,7 +65,7 @@
 
 f();
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 assertEqualsAsync(3, async () => break_count);
 assertEqualsAsync(null, async () => exception);
diff --git a/src/v8/test/debugger/debug/es8/debug-async-liveedit.js b/src/v8/test/debugger/debug/es8/debug-async-liveedit.js
index 761a24f..e85cbe3 100644
--- a/src/v8/test/debugger/debug/es8/debug-async-liveedit.js
+++ b/src/v8/test/debugger/debug/es8/debug-async-liveedit.js
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Flags: --allow-natives-syntax
+
 var Debug = debug.Debug;
-var LiveEdit = Debug.LiveEdit;
 
 unique_id = 0;
 
@@ -69,16 +70,7 @@
 
 function patch(fun, from, to) {
   function debug() {
-    var log = new Array();
-    var script = Debug.findScript(fun);
-    var pos = script.source.indexOf(from);
-    print(`pos ${pos}`);
-    try {
-      LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
-                                             log);
-    } finally {
-      print("Change log: " + JSON.stringify(log) + "\n");
-    }
+    %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(from, to));
   }
   ExecuteInDebugContext(debug);
 }
@@ -92,8 +84,9 @@
   function attempt_patch() {
     assertFalse(patch_attempted);
     patch_attempted = true;
-    assertThrows(function() { patch(asyncfn, "'Cat'", "'Capybara'") },
-                 LiveEdit.Failure);
+    assertThrowsEquals(function() {
+      patch(asyncfn, '\'Cat\'', '\'Capybara\'')
+    }, 'LiveEdit failed: BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME');
   };
   var promise = asyncfn(attempt_patch);
   // Patch should not succeed because there is a live async function activation
@@ -101,7 +94,7 @@
   assertPromiseValue("Cat", promise);
   assertTrue(patch_attempted);
 
-  %RunMicrotasks();
+  %PerformMicrotaskCheckpoint();
 
   // At this point one iterator is live, but closed, so the patch will succeed.
   patch(asyncfn, "'Cat'", "'Capybara'");
@@ -112,15 +105,16 @@
   // Patching will fail however when an async function is suspended.
   var resolve;
   promise = asyncfn(function(){return new Promise(function(r){resolve = r})});
-  assertThrows(function() { patch(asyncfn, "'Capybara'", "'Tapir'") },
-               LiveEdit.Failure);
+  assertThrowsEquals(function() {
+    patch(asyncfn, '\'Capybara\'', '\'Tapir\'')
+  }, 'LiveEdit failed: BLOCKED_BY_RUNNING_GENERATOR');
   resolve();
   assertPromiseValue("Capybara", promise);
 
   // Try to patch functions with activations inside and outside async
   // function activations.  We should succeed in the former case, but not in the
   // latter.
-  var fun_outside = MakeFunction();
+  var fun_outside = eval('((callback) => { callback(); return \'Cat\';})');
   var fun_inside = MakeFunction();
   var fun_patch_attempted = false;
   var fun_patch_restarted = false;
@@ -132,18 +126,21 @@
     }
     fun_patch_attempted = true;
     // Patching outside an async function activation must fail.
-    assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
-                 LiveEdit.Failure);
+    assertThrowsEquals(function() {
+      patch(fun_outside, '\'Cat\'', '\'Cobra\'')
+    }, 'LiveEdit failed: BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME');
     // Patching inside an async function activation may succeed.
     patch(fun_inside, "'Cat'", "'Koala'");
   }
-  promise = asyncfn(function() { return fun_inside(attempt_fun_patches) });
+  result = fun_outside(() => asyncfn(function() {
+    return fun_inside(attempt_fun_patches);
+  }));
   assertEquals('Cat',
                fun_outside(function () {
-                 assertPromiseValue('Capybara', promise);
+                 assertEquals(result, 'Cat');
                  assertTrue(fun_patch_restarted);
                  assertTrue(fun_inside.toString().includes("'Koala'"));
                }));
 })();
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
diff --git a/src/v8/test/debugger/debug/es8/promise-finally.js b/src/v8/test/debugger/debug/es8/promise-finally.js
index 2598ae0..dc7833e 100644
--- a/src/v8/test/debugger/debug/es8/promise-finally.js
+++ b/src/v8/test/debugger/debug/es8/promise-finally.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-promise-finally
-
 Debug = debug.Debug
 
 var exception = null;
@@ -37,7 +35,7 @@
   .finally(() => thenable)
   .catch(e => caughtException = e);
 
-%RunMicrotasks();
+%PerformMicrotaskCheckpoint();
 
 Debug.setListener(null);
 Debug.clearBreakOnException();
diff --git a/src/v8/test/debugger/debug/for-in-opt.js b/src/v8/test/debugger/debug/for-in-opt.js
index 405199d..2b97e49 100644
--- a/src/v8/test/debugger/debug/for-in-opt.js
+++ b/src/v8/test/debugger/debug/for-in-opt.js
@@ -14,6 +14,8 @@
   return result;
 }
 
+%PrepareFunctionForOptimization(f);
+
 assertEquals(["0"], f("a"));
 assertEquals(["0"], f("a"));
 
@@ -62,6 +64,8 @@
   property_descriptor_keys.length = 0;
 }
 
+%PrepareFunctionForOptimization(f2);
+
 check_f2();
 check_f2();
 
@@ -71,6 +75,7 @@
 check_f2();
 
 // Test lazy deopt after FILTER_KEY
+%PrepareFunctionForOptimization(f2);
 %OptimizeFunctionOnNextCall(f2);
 deopt_property_descriptor = true;
 check_f2();
@@ -81,6 +86,7 @@
   }
 }
 
+%PrepareFunctionForOptimization(f3);
 f3({__proto__:{x:1}});
 f3({__proto__:{x:1}});
 
@@ -106,6 +112,8 @@
   property_descriptor_keys.length = 0;
 }
 
+%PrepareFunctionForOptimization(f4);
+
 check_f4();
 check_f4();
 
@@ -146,6 +154,7 @@
 
 x = false;
 
+%PrepareFunctionForOptimization(f5);
 f5(); f5(); f5();
 %OptimizeFunctionOnNextCall(f5);
 x = true;
diff --git a/src/v8/test/debugger/debug/harmony/modules-debug-scopes1.mjs b/src/v8/test/debugger/debug/harmony/modules-debug-scopes1.mjs
new file mode 100644
index 0000000..1789798
--- /dev/null
+++ b/src/v8/test/debugger/debug/harmony/modules-debug-scopes1.mjs
@@ -0,0 +1,870 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Flags: --allow-natives-syntax --noanalyze-environment-liveness
+
+// These tests are copied from mjsunit/debug-scopes.js and adapted for modules.
+
+
+var Debug = debug.Debug;
+
+var test_name;
+var listener_delegate;
+var listener_called;
+var exception;
+var begin_test_count = 0;
+var end_test_count = 0;
+var break_count = 0;
+
+
+// Debug event listener which delegates.
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      break_count++;
+      listener_called = true;
+      listener_delegate(exec_state);
+    }
+  } catch (e) {
+    exception = e;
+  }
+}
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+
+// Initialize for a new test.
+function BeginTest(name) {
+  test_name = name;
+  listener_delegate = null;
+  listener_called = false;
+  exception = null;
+  begin_test_count++;
+}
+
+
+// Check result of a test.
+function EndTest() {
+  assertTrue(listener_called, "listener not called for " + test_name);
+  assertNull(exception, test_name + " / " + exception);
+  end_test_count++;
+}
+
+
+// Check that two scope are the same.
+function assertScopeMirrorEquals(scope1, scope2) {
+  assertEquals(scope1.scopeType(), scope2.scopeType());
+  assertEquals(scope1.frameIndex(), scope2.frameIndex());
+  assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
+  assertPropertiesEqual(scope1.scopeObject().value(),
+                        scope2.scopeObject().value());
+}
+
+function CheckFastAllScopes(scopes, exec_state)
+{
+  var fast_all_scopes = exec_state.frame().allScopes(true);
+  var length = fast_all_scopes.length;
+  assertTrue(scopes.length >= length);
+  for (var i = 0; i < scopes.length && i < length; i++) {
+    var scope = fast_all_scopes[length - i - 1];
+    assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
+  }
+}
+
+
+// Check that the scope chain contains the expected types of scopes.
+function CheckScopeChain(scopes, exec_state) {
+  var all_scopes = exec_state.frame().allScopes();
+  assertEquals(scopes.length, exec_state.frame().scopeCount());
+  assertEquals(scopes.length, all_scopes.length,
+               "FrameMirror.allScopes length");
+  for (var i = 0; i < scopes.length; i++) {
+    var scope = exec_state.frame().scope(i);
+    assertEquals(scopes[i], scope.scopeType());
+    assertScopeMirrorEquals(all_scopes[i], scope);
+  }
+  CheckFastAllScopes(scopes, exec_state);
+}
+
+
+// Check that the scope chain contains the expected names of scopes.
+function CheckScopeChainNames(names, exec_state) {
+  var all_scopes = exec_state.frame().allScopes();
+  assertEquals(names.length, all_scopes.length, "FrameMirror.allScopes length");
+  for (var i = 0; i < names.length; i++) {
+    var scope = exec_state.frame().scope(i);
+    // assertEquals(names[i], scope.details().name())
+  }
+}
+
+
+// Check that the scope contains at least minimum_content. For functions just
+// check that there is a function.
+function CheckScopeContent(minimum_content, number, exec_state) {
+  var scope = exec_state.frame().scope(number);
+  var minimum_count = 0;
+  for (var p in minimum_content) {
+    var property_mirror = scope.scopeObject().property(p);
+    assertFalse(property_mirror.isUndefined(),
+                'property ' + p + ' not found in scope');
+    assertEquals(minimum_content[p], property_mirror.value().value(),
+                 'property ' + p + ' has unexpected value');
+    minimum_count++;
+  }
+
+  // 'arguments' and might be exposed in the local and closure scope. Just
+  // ignore this.
+  var scope_size = scope.scopeObject().properties().length;
+  if (!scope.scopeObject().property('arguments').isUndefined()) {
+    scope_size--;
+  }
+  // Ditto for 'this'.
+  if (!scope.scopeObject().property('this').isUndefined()) {
+    scope_size--;
+  }
+  // Temporary variables introduced by the parser have not been materialized.
+  assertTrue(scope.scopeObject().property('').isUndefined());
+
+  if (scope_size < minimum_count) {
+    print('Names found in scope:');
+    var names = scope.scopeObject().propertyNames();
+    for (var i = 0; i < names.length; i++) {
+      print(names[i]);
+    }
+  }
+  assertTrue(scope_size >= minimum_count);
+}
+
+// Check that the scopes have positions as expected.
+function CheckScopeChainPositions(positions, exec_state) {
+  var all_scopes = exec_state.frame().allScopes();
+  assertTrue(positions.length <= all_scopes.length,
+             "FrameMirror.allScopes length");
+  for (var i = 0; i < positions.length; i++) {
+    var scope = exec_state.frame().scope(i);
+    var position = positions[i];
+    if (!position)
+      continue;
+
+    print(
+        `Checking position.start = ${position.start}, .end = ${position.end}`);
+    // assertEquals(position.start, scope.details().startPosition())
+    // assertEquals(position.end, scope.details().endPosition())
+  }
+}
+
+// Simple empty local scope.
+BeginTest("Local 1");
+
+function local_1() {
+  debugger;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({}, 0, exec_state);
+};
+local_1();
+EndTest();
+
+
+// Local scope with a parameter.
+BeginTest("Local 2");
+
+function local_2(a) {
+  debugger;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1}, 0, exec_state);
+};
+local_2(1);
+EndTest();
+
+
+// Local scope with a parameter and a local variable.
+BeginTest("Local 3");
+
+function local_3(a) {
+  var x = 3;
+  debugger;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1,x:3}, 0, exec_state);
+};
+local_3(1);
+EndTest();
+
+
+// Local scope with parameters and local variables.
+BeginTest("Local 4");
+
+function local_4(a, b) {
+  var x = 3;
+  var y = 4;
+  debugger;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
+};
+local_4(1, 2);
+EndTest();
+
+
+// Empty local scope with use of eval.
+BeginTest("Local 5");
+
+function local_5() {
+  eval('');
+  debugger;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({}, 0, exec_state);
+};
+local_5();
+EndTest();
+
+
+// Local introducing local variable using eval.
+BeginTest("Local 6");
+
+function local_6() {
+  eval('var i = 5');
+  debugger;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({}, 0, exec_state);
+};
+local_6();
+EndTest();
+
+
+// Local scope with parameters and local variables.
+BeginTest("Local 7");
+
+function local_7(a, b) {
+  var x = 3;
+  var y = 4;
+  eval('var i = 5');
+  eval('var j = 6');
+  debugger;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
+};
+local_7(1, 2);
+EndTest();
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments.
+BeginTest("Closure 1");
+
+function closure_1(a) {
+  function f() {
+    debugger;
+    return a;
+  };
+  return f;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1}, 1, exec_state);
+  CheckScopeChainNames(["f", "closure_1", undefined, undefined, undefined], exec_state)
+};
+closure_1(1)();
+EndTest();
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. Due to VM optimizations parts of the actual closure is
+// missing from the debugger information.
+BeginTest("Closure 2");
+
+function closure_2(a, b) {
+  var x = a + 2;
+  var y = b + 2;
+  function f() {
+    debugger;
+    return a + x;
+  };
+  return f;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1,x:3}, 1, exec_state);
+  CheckScopeChainNames(["f", "closure_2", undefined, undefined, undefined],
+                       exec_state)
+};
+closure_2(1, 2)();
+EndTest();
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. Using all arguments and locals from the outer function
+// in the inner function makes these part of the debugger information on the
+// closure.
+BeginTest("Closure 3");
+
+function closure_3(a, b) {
+  var x = a + 2;
+  var y = b + 2;
+  function f() {
+    debugger;
+    return a + b + x + y;
+  };
+  return f;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
+  CheckScopeChainNames(["f", "closure_3", undefined, undefined, undefined],
+                       exec_state)
+};
+closure_3(1, 2)();
+EndTest();
+
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. Using all arguments and locals from the outer function
+// in the inner function makes these part of the debugger information on the
+// closure. Use the inner function as well...
+BeginTest("Closure 4");
+
+function closure_4(a, b) {
+  var x = a + 2;
+  var y = b + 2;
+  function f() {
+    debugger;
+    if (f) {
+      return a + b + x + y;
+    }
+  };
+  return f;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1,b:2,x:3,y:4,f:undefined}, 1, exec_state);
+  CheckScopeChainNames(["f", "closure_4", undefined, undefined, undefined],
+                       exec_state)
+};
+closure_4(1, 2)();
+EndTest();
+
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. In the presence of eval all arguments and locals
+// (including the inner function itself) from the outer function becomes part of
+// the debugger infformation on the closure.
+BeginTest("Closure 5");
+
+function closure_5(a, b) {
+  var x = 3;
+  var y = 4;
+  function f() {
+    eval('');
+    debugger;
+    return 1;
+  };
+  return f;
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1,b:2,x:3,y:4,f:undefined}, 1, exec_state);
+  CheckScopeChainNames(["f", "closure_5", undefined, undefined, undefined],
+                       exec_state)
+};
+closure_5(1, 2)();
+EndTest();
+
+
+// Two closures. Due to optimizations only the parts actually used are provided
+// through the debugger information.
+BeginTest("Closure 6");
+let some_global;
+function closure_6(a, b) {
+  function f(a, b) {
+    var x = 3;
+    var y = 4;
+    return function() {
+      var x = 3;
+      var y = 4;
+      debugger;
+      some_global = a;
+      return f;
+    };
+  }
+  return f(a, b);
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({a:1}, 1, exec_state);
+  CheckScopeContent({f:undefined}, 2, exec_state);
+  CheckScopeChainNames(
+      [undefined, "f", "closure_6", undefined, undefined, undefined],
+      exec_state);
+};
+closure_6(1, 2)();
+EndTest();
+
+
+// Two closures. In the presence of eval all information is provided as the
+// compiler cannot determine which parts are used.
+BeginTest("Closure 7");
+function closure_7(a, b) {
+  var x = 3;
+  var y = 4;
+  eval('var i = 5');
+  eval('var j = 6');
+  function f(a, b) {
+    var x = 3;
+    var y = 4;
+    eval('var i = 5');
+    eval('var j = 6');
+    return function() {
+      debugger;
+      some_global = a;
+      return f;
+    };
+  }
+  return f(a, b);
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({}, 0, exec_state);
+  CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
+  CheckScopeContent({a:1,b:2,x:3,y:4,f:undefined}, 2, exec_state);
+  CheckScopeChainNames(
+      [undefined, "f", "closure_7", undefined, undefined, undefined],
+      exec_state);
+};
+closure_7(1, 2)();
+EndTest();
+
+
+// Closure that may be optimized out.
+BeginTest("Closure 8");
+function closure_8() {
+  (function inner(x) {
+    debugger;
+  })(2);
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x: 2}, 0, exec_state);
+  CheckScopeChainNames(["inner", undefined, undefined, undefined], exec_state);
+};
+closure_8();
+EndTest();
+
+
+BeginTest("Closure 9");
+let closure_9 = Function(' \
+  eval("var y = 1;"); \
+  eval("var z = 1;"); \
+  (function inner(x) { \
+    y++; \
+    z++; \
+    debugger; \
+  })(2); \
+')
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeChainNames(["inner", undefined, undefined, undefined], exec_state);
+};
+closure_9();
+EndTest();
+
+
+// Test global scope.
+BeginTest("Global");
+listener_delegate = function(exec_state) {
+  CheckScopeChain(
+      [debug.ScopeType.Module, debug.ScopeType.Script, debug.ScopeType.Global],
+      exec_state);
+  CheckScopeChainNames([undefined, undefined, undefined], exec_state);
+};
+debugger;
+EndTest();
+
+
+BeginTest("Catch block 1");
+function catch_block_1() {
+  try {
+    throw 'Exception';
+  } catch (e) {
+    debugger;
+  }
+};
+
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({e:'Exception'}, 0, exec_state);
+  CheckScopeChainNames(
+      ["catch_block_1", "catch_block_1", undefined, undefined, undefined],
+      exec_state);
+};
+catch_block_1();
+EndTest();
+
+
+BeginTest("Catch block 3");
+function catch_block_3() {
+  eval("var y = 78;");
+  try {
+    throw 'Exception';
+  } catch (e) {
+    debugger;
+  }
+};
+
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({e:'Exception'}, 0, exec_state);
+  CheckScopeContent({}, 1, exec_state);
+  CheckScopeChainNames(
+      ["catch_block_3", "catch_block_3", undefined, undefined, undefined],
+      exec_state);
+};
+catch_block_3();
+EndTest();
+
+
+// Test catch in global scope.
+BeginTest("Catch block 5");
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({e:'Exception'}, 0, exec_state);
+  CheckScopeChainNames([undefined, undefined, undefined, undefined],
+                       exec_state);
+};
+
+try {
+  throw 'Exception';
+} catch (e) {
+  debugger;
+}
+
+EndTest();
+
+
+// Closure inside catch in global code.
+BeginTest("Catch block 6");
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Catch,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({x: 2}, 0, exec_state);
+  CheckScopeContent({e:'Exception'}, 1, exec_state);
+  CheckScopeChainNames([undefined, undefined, undefined, undefined, undefined],
+                       exec_state);
+};
+
+try {
+  throw 'Exception';
+} catch (e) {
+  (function(x) {
+    debugger;
+  })(2);
+}
+EndTest();
+
+
+// Catch block in function that is marked for optimization while being executed.
+BeginTest("Catch block 7");
+function catch_block_7() {
+  %OptimizeFunctionOnNextCall(catch_block_7);
+  try {
+    throw 'Exception';
+  } catch (e) {
+    debugger;
+  }
+};
+
+%PrepareFunctionForOptimization(catch_block_7);
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({e:'Exception'}, 0, exec_state);
+  CheckScopeChainNames(
+      ["catch_block_7", "catch_block_7", undefined, undefined, undefined],
+      exec_state);
+};
+catch_block_7();
+EndTest();
+
+
+BeginTest("Classes and methods 1");
+
+listener_delegate = function(exec_state) {
+  "use strict"
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({}, 1, exec_state);
+  CheckScopeChainNames(["m", undefined, undefined, undefined], exec_state);
+};
+
+(function() {
+  "use strict";
+  class C1 {
+    m() {
+      debugger;
+    }
+  }
+  new C1().m();
+})();
+
+EndTest();
+
+BeginTest("Scope positions");
+var code1 = "function f() {        \n" +
+            "  var a = 1;          \n" +
+            "  function b() {      \n" +
+            "    debugger;         \n" +
+            "    return a + 1;     \n" +
+            "  }                   \n" +
+            "  b();                \n" +
+            "}                     \n" +
+            "f();                  \n";
+
+listener_delegate = function(exec_state) {
+  CheckScopeChainPositions([{start: 58, end: 118}, {start: 10, end: 162}],
+                           exec_state);
+}
+eval(code1);
+EndTest();
+
+
+BeginTest("Scope positions in for statement");
+var code3 = "function for_statement() {         \n" +
+            "  for (let i = 0; i < 1; i++) {    \n" +
+            "    debugger;                      \n" +
+            "  }                                \n" +
+            "}                                  \n" +
+            "for_statement();                   \n";
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeChainPositions([{start: 42, end: 111}, {start: 22, end: 145}],
+                           exec_state);
+}
+eval(code3);
+EndTest();
+
+BeginTest("Scope positions in for statement with lexical block");
+var code4 = "function for_statement() {         \n" +
+            "  for (let i = 0; i < 1; i++) {    \n" +
+            "    let j;                         \n" +
+            "    debugger;                      \n" +
+            "  }                                \n" +
+            "}                                  \n" +
+            "for_statement();                   \n";
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeChainPositions([{start: 66, end: 147},
+                            {start: 42, end: 147},
+                            {start: 22, end: 181}], exec_state);
+}
+eval(code4);
+EndTest();
+
+BeginTest("Scope positions in lexical for each statement");
+var code5 = "function for_each_statement() {    \n" +
+            "  for (let i of [0]) {             \n" +
+            "    debugger;                      \n" +
+            "  }                                \n" +
+            "}                                  \n" +
+            "for_each_statement();              \n";
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeChainPositions([{start: 55, end: 111}, {start: 27, end: 145}],
+                           exec_state);
+}
+eval(code5);
+EndTest();
+
+BeginTest("Scope positions in lexical for each statement with lexical block");
+var code6 = "function for_each_statement() {    \n" +
+            "  for (let i of [0]) {             \n" +
+            "    let j;                         \n" +
+            "    debugger;                      \n" +
+            "  }                                \n" +
+            "}                                  \n" +
+            "for_each_statement();              \n";
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeChainPositions([{start: 57, end: 147},
+                            {start: 55, end: 147},
+                            {start: 27, end: 181}], exec_state);
+}
+eval(code6);
+EndTest();
+
+BeginTest("Scope positions in non-lexical for each statement");
+var code7 = "function for_each_statement() {    \n" +
+            "  var i;                           \n" +
+            "  for (i of [0]) {                 \n" +
+            "    debugger;                      \n" +
+            "  }                                \n" +
+            "}                                  \n" +
+            "for_each_statement();              \n";
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeChainPositions([{start: 27, end: 181}], exec_state);
+}
+eval(code7);
+EndTest();
+
+BeginTest(
+    "Scope positions in non-lexical for each statement with lexical block");
+var code8 = "function for_each_statement() {    \n" +
+            "  var i;                           \n" +
+            "  for (i of [0]) {                 \n" +
+            "    let j;                         \n" +
+            "    debugger;                      \n" +
+            "  }                                \n" +
+            "}                                  \n" +
+            "for_each_statement();              \n";
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeChainPositions([{start: 89, end: 183}, {start: 27, end: 217}],
+                           exec_state);
+}
+eval(code8);
+EndTest();
+
+assertEquals(begin_test_count, break_count,
+             'one or more tests did not enter the debugger');
+assertEquals(begin_test_count, end_test_count,
+             'one or more tests did not have its result checked');
diff --git a/src/v8/test/debugger/debug/harmony/modules-debug-scopes2.mjs b/src/v8/test/debugger/debug/harmony/modules-debug-scopes2.mjs
new file mode 100644
index 0000000..a23ee9f
--- /dev/null
+++ b/src/v8/test/debugger/debug/harmony/modules-debug-scopes2.mjs
@@ -0,0 +1,184 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var Debug = debug.Debug;
+
+var test_name;
+var listener_delegate;
+var listener_called;
+var exception;
+var begin_test_count = 0;
+var end_test_count = 0;
+var break_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      break_count++;
+      listener_called = true;
+      listener_delegate(exec_state);
+    }
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+
+function BeginTest(name) {
+  test_name = name;
+  listener_delegate = null;
+  listener_called = false;
+  exception = null;
+  begin_test_count++;
+}
+
+function EndTest() {
+  assertTrue(listener_called, "listener not called for " + test_name);
+  assertNull(exception, test_name + " / " + exception);
+  end_test_count++;
+}
+
+
+// Check that two scope are the same.
+function assertScopeMirrorEquals(scope1, scope2) {
+  assertEquals(scope1.scopeType(), scope2.scopeType());
+  assertEquals(scope1.frameIndex(), scope2.frameIndex());
+  assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
+  assertPropertiesEqual(scope1.scopeObject().value(),
+                        scope2.scopeObject().value());
+}
+
+function CheckFastAllScopes(scopes, exec_state)
+{
+  var fast_all_scopes = exec_state.frame().allScopes(true);
+  var length = fast_all_scopes.length;
+  assertTrue(scopes.length >= length);
+  for (var i = 0; i < scopes.length && i < length; i++) {
+    var scope = fast_all_scopes[length - i - 1];
+    assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
+  }
+}
+
+
+// Check that the scope chain contains the expected types of scopes.
+function CheckScopeChain(scopes, exec_state) {
+  var all_scopes = exec_state.frame().allScopes();
+  assertEquals(scopes.length, exec_state.frame().scopeCount());
+  assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes length");
+  for (var i = 0; i < scopes.length; i++) {
+    var scope = exec_state.frame().scope(i);
+    assertEquals(scopes[i], scope.scopeType());
+    assertScopeMirrorEquals(all_scopes[i], scope);
+  }
+  CheckFastAllScopes(scopes, exec_state);
+}
+
+
+function CheckScopeDoesNotHave(properties, number, exec_state) {
+  var scope = exec_state.frame().scope(number);
+  for (var p of properties) {
+    var property_mirror = scope.scopeObject().property(p);
+    assertTrue(property_mirror.isUndefined(),
+               'property ' + p + ' found in scope');
+  }
+}
+
+
+// Check that the scope contains at least minimum_content. For functions just
+// check that there is a function.
+function CheckScopeContent(minimum_content, number, exec_state) {
+  var scope = exec_state.frame().scope(number);
+  var minimum_count = 0;
+  for (var p in minimum_content) {
+    var property_mirror = scope.scopeObject().property(p);
+    assertFalse(property_mirror.isUndefined(),
+                'property ' + p + ' not found in scope');
+    assertEquals(minimum_content[p], property_mirror.value().value(),
+                 'property ' + p + ' has unexpected value');
+    minimum_count++;
+  }
+
+  // 'arguments' and might be exposed in the local and closure scope. Just
+  // ignore this.
+  var scope_size = scope.scopeObject().properties().length;
+  if (!scope.scopeObject().property('arguments').isUndefined()) {
+    scope_size--;
+  }
+  // Ditto for 'this'.
+  if (!scope.scopeObject().property('this').isUndefined()) {
+    scope_size--;
+  }
+  // Temporary variables introduced by the parser have not been materialized.
+  assertTrue(scope.scopeObject().property('').isUndefined());
+
+  if (scope_size < minimum_count) {
+    print('Names found in scope:');
+    var names = scope.scopeObject().propertyNames();
+    for (var i = 0; i < names.length; i++) {
+      print(names[i]);
+    }
+  }
+  assertTrue(scope_size >= minimum_count);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Actual tests.
+////////////////////////////////////////////////////////////////////////////////
+
+
+BeginTest();
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent(
+      {exported_var: undefined, imported_var: undefined},
+      0, exec_state);
+  CheckScopeDoesNotHave(
+      ["doesntexist", "exported_let", "imported_let"],
+      0, exec_state);
+};
+debugger;
+EndTest();
+
+let local_let = 1;
+var local_var = 2;
+export let exported_let = 3;
+export var exported_var = 4;
+import {exported_let as imported_let} from "modules-debug-scopes2.mjs";
+import {exported_var as imported_var} from "modules-debug-scopes2.mjs";
+
+BeginTest();
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent(
+      {exported_let: 3, exported_var: 4,
+       imported_let: 3, imported_var: 4}, 0, exec_state);
+  CheckScopeDoesNotHave([], 0, exec_state);
+};
+debugger;
+EndTest();
+
+local_let += 10;
+local_var += 10;
+exported_let += 10;
+exported_var += 10;
+
+BeginTest();
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Module,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent(
+      {exported_let: 13, exported_var: 14,
+       imported_let: 13, imported_var: 14}, 0, exec_state);
+  CheckScopeDoesNotHave([], 0, exec_state);
+};
+debugger;
+EndTest();
diff --git a/src/v8/test/debugger/debug/ignition/optimized-debug-frame.js b/src/v8/test/debugger/debug/ignition/optimized-debug-frame.js
index cc85b47..a317350 100644
--- a/src/v8/test/debugger/debug/ignition/optimized-debug-frame.js
+++ b/src/v8/test/debugger/debug/ignition/optimized-debug-frame.js
@@ -23,6 +23,7 @@
   break_count++;
 }
 
+%PrepareFunctionForOptimization(g);
 g();
 g();
 %OptimizeFunctionOnNextCall(g);
diff --git a/src/v8/test/debugger/debug/lazy-deopt-then-flush-bytecode.js b/src/v8/test/debugger/debug/lazy-deopt-then-flush-bytecode.js
new file mode 100644
index 0000000..6820dc0
--- /dev/null
+++ b/src/v8/test/debugger/debug/lazy-deopt-then-flush-bytecode.js
@@ -0,0 +1,49 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --opt --noalways-opt --stress-flush-bytecode
+// Flags: --expose-gc
+
+Debug = debug.Debug
+
+function foo() {
+  return 44;
+}
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+
+  // Optimize foo.
+  %PrepareFunctionForOptimization(foo);
+  %OptimizeFunctionOnNextCall(foo);
+  foo();
+  assertOptimized(foo);
+
+  // Lazily deopt foo, which marks the code for deoptimization and invalidates
+  // the DeoptimizationData, but doesn't unlink the optimized code entry in
+  // foo's JSFunction.
+  %DeoptimizeFunction(foo);
+
+  // Run the GC. Since the DeoptimizationData is now dead, the bytecode
+  // associated with the optimized code is free to be flushed, which also
+  // free's the feedback vector meta-data.
+  gc();
+
+  // Execute foo with side-effect checks, which causes the debugger to call
+  // DeoptimizeFunction on foo. Even though the code is already marked for
+  // deoptimization, this will try to unlink the optimized code from the
+  // feedback vector, which will fail due to the feedback meta-data being
+  // flushed. The deoptimizer should call JSFunction::ResetIfBytecodeFlushed
+  // before trying to do this, which will clear the whole feedback vector and
+  // reset the JSFunction's code entry field to CompileLazy.
+  exec_state.frame(0).evaluate("foo()", true);
+}
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+}
+f();
diff --git a/src/v8/test/debugger/debug/regress-3225.js b/src/v8/test/debugger/debug/regress-3225.js
index 454ff6e..4ba6777 100644
--- a/src/v8/test/debugger/debug/regress-3225.js
+++ b/src/v8/test/debugger/debug/regress-3225.js
@@ -32,6 +32,8 @@
 
 function* generator(a, b) {
   function set_a_to_5() { a = 5 }
+  // Make sure set_a_to_5 is 'used' so that it is visible to the debugger.
+  set_a_to_5;
   var b = 3;  // Shadows a parameter.
   debugger;
   yield a;
diff --git a/src/v8/test/debugger/debug/regress/regress-1081309.js b/src/v8/test/debugger/debug/regress/regress-1081309.js
index 5e4cd88..0b32fa5 100644
--- a/src/v8/test/debugger/debug/regress/regress-1081309.js
+++ b/src/v8/test/debugger/debug/regress/regress-1081309.js
@@ -29,8 +29,8 @@
 
 // Make sure that the backtrace command can be processed when the receiver is
 // undefined.
-listenerCalled = false;
-exception = false;
+let listenerCalled = false;
+let exceptionThrown = false;
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -47,7 +47,7 @@
     }
   } catch (e) {
     print(e);
-    exception = e
+    exceptionThrown = true;
   };
 };
 
@@ -67,6 +67,6 @@
   // Ignore the exception "Cannot call method 'x' of undefined"
 }
 
-assertFalse(exception, "exception in listener", exception)
+assertFalse(exceptionThrown, "exception in listener");
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerCalled, "listener not called");
diff --git a/src/v8/test/debugger/debug/regress/regress-1170187.js b/src/v8/test/debugger/debug/regress/regress-1170187.js
index 165a308..e41cc7e 100644
--- a/src/v8/test/debugger/debug/regress/regress-1170187.js
+++ b/src/v8/test/debugger/debug/regress/regress-1170187.js
@@ -31,8 +31,8 @@
 
 Debug = debug.Debug
 
-listenerCalled = false;
-exception = false;
+let listenerCalled = false;
+let exceptionThrown = false;
 
 
 function checkName(name) {
@@ -64,7 +64,7 @@
       listenerCalled = true;
     }
   } catch (e) {
-    exception = e;
+    exceptionThrown = true;
   };
 };
 
@@ -73,8 +73,14 @@
 
 // Call a function with local variables passing a different number parameters
 // that the number of arguments.
-(function(x,y){var a,b,c; debugger; return 3})()
+(function(x,y){
+  var a,b,c;
+  // Make sure a, b, and c are used.
+  a,b,c;
+  debugger;
+  return 3
+})()
 
 // Make sure that the debug event listener vas invoked (again).
 assertTrue(listenerCalled);
-assertFalse(exception, "exception in listener")
+assertFalse(exceptionThrown, "exception in listener")
diff --git a/src/v8/test/debugger/debug/regress/regress-119609.js b/src/v8/test/debugger/debug/regress/regress-119609.js
index b6da891..a1ad32a 100644
--- a/src/v8/test/debugger/debug/regress/regress-119609.js
+++ b/src/v8/test/debugger/debug/regress/regress-119609.js
@@ -28,7 +28,7 @@
 
 Debug = debug.Debug;
 
-var exception = false;
+var exceptionThrown = false;
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -44,7 +44,7 @@
       assertThrows(() => lookup("b"), ReferenceError);
     }
   } catch (e) {
-    exception = e.toString() + e.stack;
+    exceptionThrown = true;
   }
 }
 
@@ -63,4 +63,4 @@
 
 f(1, 2)(3, 4);
 
-assertFalse(exception);
+assertFalse(exceptionThrown);
diff --git a/src/v8/test/debugger/debug/regress/regress-131994.js b/src/v8/test/debugger/debug/regress/regress-131994.js
index 66bde74..ee431d0 100644
--- a/src/v8/test/debugger/debug/regress/regress-131994.js
+++ b/src/v8/test/debugger/debug/regress/regress-131994.js
@@ -33,7 +33,7 @@
 
 Debug = debug.Debug;
 
-var exception = false;
+var exceptionThrown = false;
 
 function listener(event, exec_state, event_data, data) {
   if (event != Debug.DebugEvent.Break) return;
@@ -44,7 +44,7 @@
     // Assert correct value.
     assertEquals(3, breakpoint.evaluate('x').value());
   } catch (e) {
-    exception = e;
+    exceptionThrown = true;
   }
 }
 
@@ -67,4 +67,4 @@
 
 h();
 
-assertFalse(exception);
+assertFalse(exceptionThrown);
diff --git a/src/v8/test/debugger/debug/regress/regress-1639.js b/src/v8/test/debugger/debug/regress/regress-1639.js
index eaaca51..cf5f8f5 100644
--- a/src/v8/test/debugger/debug/regress/regress-1639.js
+++ b/src/v8/test/debugger/debug/regress/regress-1639.js
@@ -27,7 +27,7 @@
 
 Debug = debug.Debug
 var breaks = 0;
-var exception = false;
+var exceptionThrown = false;
 
 function listener(event, exec_state, event_data, data) {
   try {
@@ -43,7 +43,7 @@
     }
   } catch (e) {
     print(e);
-    exception = true;
+    exceptionThrown = true;
   }
 }
 
@@ -72,4 +72,4 @@
 a(b);
 a(); // BREAK 3
 
-assertFalse(exception);
+assertFalse(exceptionThrown);
diff --git a/src/v8/test/debugger/debug/regress/regress-2825.js b/src/v8/test/debugger/debug/regress/regress-2825.js
index 01bdddf..720b21c 100644
--- a/src/v8/test/debugger/debug/regress/regress-2825.js
+++ b/src/v8/test/debugger/debug/regress/regress-2825.js
Binary files differ
diff --git a/src/v8/test/debugger/debug/regress/regress-392114.js b/src/v8/test/debugger/debug/regress/regress-392114.js
index b9ca4ed..2661909 100644
--- a/src/v8/test/debugger/debug/regress/regress-392114.js
+++ b/src/v8/test/debugger/debug/regress/regress-392114.js
@@ -52,6 +52,7 @@
 Debug.setListener(function () {});
 
 var d = create_closure();
+%PrepareFunctionForOptimization(d);
 %OptimizeFunctionOnNextCall(d);
 // Thanks to the debugger, we recreate the full code too. We deopt and run
 // it, stomping on the unexpected AllocationSite in the type vector slot.
diff --git a/src/v8/test/debugger/debug/regress/regress-4309-1.js b/src/v8/test/debugger/debug/regress/regress-4309-1.js
index 2e7ef47..ef1aee6 100644
--- a/src/v8/test/debugger/debug/regress/regress-4309-1.js
+++ b/src/v8/test/debugger/debug/regress/regress-4309-1.js
@@ -25,6 +25,8 @@
   debugger;
 }
 
+%PrepareFunctionForOptimization(f);
+
 f();
 f();
 
diff --git a/src/v8/test/debugger/debug/regress/regress-4309-2.js b/src/v8/test/debugger/debug/regress/regress-4309-2.js
index e93c8ec..698be3c 100644
--- a/src/v8/test/debugger/debug/regress/regress-4309-2.js
+++ b/src/v8/test/debugger/debug/regress/regress-4309-2.js
@@ -22,6 +22,8 @@
   debugger;
 }
 
+%PrepareFunctionForOptimization(f);
+
 f();
 f();
 
diff --git a/src/v8/test/debugger/debug/regress/regress-4309-3.js b/src/v8/test/debugger/debug/regress/regress-4309-3.js
index 026a7cb..71664d6 100644
--- a/src/v8/test/debugger/debug/regress/regress-4309-3.js
+++ b/src/v8/test/debugger/debug/regress/regress-4309-3.js
@@ -27,6 +27,8 @@
   }
 }
 
+%PrepareFunctionForOptimization(f);
+
 f();
 f();
 
diff --git a/src/v8/test/debugger/debug/regress/regress-4320.js b/src/v8/test/debugger/debug/regress/regress-4320.js
index 5d88cc3..763a9f3 100644
--- a/src/v8/test/debugger/debug/regress/regress-4320.js
+++ b/src/v8/test/debugger/debug/regress/regress-4320.js
@@ -9,6 +9,7 @@
 
 function g() { }
 
+%PrepareFunctionForOptimization(f);
 f();
 f();
 %OptimizeFunctionOnNextCall(f);
diff --git a/src/v8/test/debugger/debug/regress/regress-514362.js b/src/v8/test/debugger/debug/regress/regress-514362.js
index beebf4c..8422c99 100644
--- a/src/v8/test/debugger/debug/regress/regress-514362.js
+++ b/src/v8/test/debugger/debug/regress/regress-514362.js
@@ -7,6 +7,7 @@
 function foo() { bar(arguments[0]); }
 function wrap() { return foo(1); }
 
+%PrepareFunctionForOptimization(wrap);
 wrap();
 wrap();
 %OptimizeFunctionOnNextCall(wrap);
diff --git a/src/v8/test/debugger/debug/regress/regress-5164.js b/src/v8/test/debugger/debug/regress/regress-5164.js
index 2ac9d7a..1da7890 100644
--- a/src/v8/test/debugger/debug/regress/regress-5164.js
+++ b/src/v8/test/debugger/debug/regress/regress-5164.js
@@ -27,17 +27,17 @@
 
 foo.next()
 assertEquals(2, args.length);
-assertEquals(undefined, args[0]);
-assertEquals(undefined, args[1]);
+assertEquals(1, args[0]);
+assertEquals(2, args[1]);
 
 foo.next()
 assertEquals(2, args.length);
-assertEquals(undefined, args[0]);
-assertEquals(undefined, args[1]);
+assertEquals(1, args[0]);
+assertEquals(2, args[1]);
 
 foo.next()
 assertEquals(2, args.length);
-assertEquals(undefined, args[0]);
-assertEquals(undefined, args[1]);
+assertEquals(1, args[0]);
+assertEquals(2, args[1]);
 
 assertNull(failure);
diff --git a/src/v8/test/debugger/debug/regress/regress-5279.js b/src/v8/test/debugger/debug/regress/regress-5279.js
index 4a30ac5..0f6f96f 100644
--- a/src/v8/test/debugger/debug/regress/regress-5279.js
+++ b/src/v8/test/debugger/debug/regress/regress-5279.js
@@ -7,9 +7,14 @@
 
 Debug.setListener(() => undefined);
 
-const myObj = {};
+function f() {
+  const myObj = {};
 
-for (let i = 0; i < 10; i++) {
-  %OptimizeOsr();
-  %ScheduleBreak();
+  for (let i = 0; i < 10; i++) {
+    %OptimizeOsr();
+    %ScheduleBreak();
+    %PrepareFunctionForOptimization(f);
+  }
 }
+%PrepareFunctionForOptimization(f);
+f()
diff --git a/src/v8/test/debugger/debug/regress/regress-9067.js b/src/v8/test/debugger/debug/regress/regress-9067.js
new file mode 100644
index 0000000..300c1d2
--- /dev/null
+++ b/src/v8/test/debugger/debug/regress/regress-9067.js
@@ -0,0 +1,22 @@
+// Copyright 2019 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-gc --stress-flush-bytecode
+
+var Debug = debug.Debug
+var bp;
+
+Debug.setListener(function (event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    Debug.clearBreakPoint(bp);
+    gc();
+  }
+});
+
+function f() {
+  (function () {})();
+}
+
+bp = Debug.setBreakPoint(f, 0, 0);
+f();
diff --git a/src/v8/test/debugger/debug/regress/regress-crbug-323936.js b/src/v8/test/debugger/debug/regress/regress-crbug-323936.js
index 391b095..17ffce1 100644
--- a/src/v8/test/debugger/debug/regress/regress-crbug-323936.js
+++ b/src/v8/test/debugger/debug/regress/regress-crbug-323936.js
@@ -37,11 +37,16 @@
     // and 'e' binds to the exception.
     function write_0(v) { e = v }
     function write_1(v) { x = v }
+    // Make sure write_0 and write_1 are 'used' so that they are visible to the
+    // debugger.
+    write_0, write_1;
     debugger;
     assertEquals("foo", e);  // overwritten by the debugger
   }
   assertEquals("argument", e);  // debugger did not overwrite
   function write_2(v) { e = v }
+  // Make sure write_2 is 'used' so that it is visible to the debugger.
+  write_2;
   debugger;
   assertEquals("bar", e);
   assertEquals("modified", x);
diff --git a/src/v8/test/debugger/debug/regress/regress-crbug-387599.js b/src/v8/test/debugger/debug/regress/regress-crbug-387599.js
index bf15cba..6eee8d7 100644
--- a/src/v8/test/debugger/debug/regress/regress-crbug-387599.js
+++ b/src/v8/test/debugger/debug/regress/regress-crbug-387599.js
@@ -7,10 +7,15 @@
 Debug.setListener(function() {});
 
 function f() {
-  for (var i = 0; i < 100; i++) %OptimizeOsr();
+  for (var i = 0; i < 100; i++) {
+    %OptimizeOsr();
+    %PrepareFunctionForOptimization(f);
+  }
 }
+%PrepareFunctionForOptimization(f);
 
 Debug.setBreakPoint(f, 0, 0);
 f();
+%PrepareFunctionForOptimization(f);
 f();
 Debug.setListener(null);
diff --git a/src/v8/test/debugger/debug/regress/regress-crbug-633999.js b/src/v8/test/debugger/debug/regress/regress-crbug-633999.js
index ebaabd7..94ca890 100644
--- a/src/v8/test/debugger/debug/regress/regress-crbug-633999.js
+++ b/src/v8/test/debugger/debug/regress/regress-crbug-633999.js
@@ -28,6 +28,7 @@
     } catch (e) {
     }
   }
+  %PrepareFunctionForOptimization(f);
   f();
   f();
   %OptimizeFunctionOnNextCall(f);
diff --git a/src/v8/test/debugger/debug/regress/regress-debug-code-recompilation.js b/src/v8/test/debugger/debug/regress/regress-debug-code-recompilation.js
index ce6ce86..5223ed6 100644
--- a/src/v8/test/debugger/debug/regress/regress-debug-code-recompilation.js
+++ b/src/v8/test/debugger/debug/regress/regress-debug-code-recompilation.js
@@ -34,6 +34,7 @@
   b=2;
 }
 
+%PrepareFunctionForOptimization(Debug.setBreakPoint);
 bp = Debug.setBreakPoint(f, 0, 0);
 Debug.clearBreakPoint(bp);
 %OptimizeFunctionOnNextCall(Debug.setBreakPoint);
@@ -41,6 +42,7 @@
 Debug.clearBreakPoint(bp);
 bp = Debug.setBreakPoint(f, 0, 0);
 Debug.clearBreakPoint(bp);
+%PrepareFunctionForOptimization(Debug.setBreakPoint);
 %OptimizeFunctionOnNextCall(Debug.setBreakPoint);
 bp = Debug.setBreakPoint(f, 0, 0);
 Debug.clearBreakPoint(bp);
diff --git a/src/v8/test/debugger/debug/regress/regress-debug-deopt-while-recompile.js b/src/v8/test/debugger/debug/regress/regress-debug-deopt-while-recompile.js
index e8336a8..c6b078b 100644
--- a/src/v8/test/debugger/debug/regress/regress-debug-deopt-while-recompile.js
+++ b/src/v8/test/debugger/debug/regress/regress-debug-deopt-while-recompile.js
@@ -45,13 +45,16 @@
   var bar = "foo";
   var baz = bar;  // Break point should be here.
   return bar;
-}
+};
 
 var g = function() {
   var bar = "foo";
   var baz = bar;  // Break point should be here.
   return bar;
-}
+};
+
+%PrepareFunctionForOptimization(f);
+%PrepareFunctionForOptimization(g);
 
 f();
 f();
diff --git a/src/v8/test/debugger/debug/regress/regress-opt-after-debug-deopt.js b/src/v8/test/debugger/debug/regress/regress-opt-after-debug-deopt.js
index 2b11357..b39c97b 100644
--- a/src/v8/test/debugger/debug/regress/regress-opt-after-debug-deopt.js
+++ b/src/v8/test/debugger/debug/regress/regress-opt-after-debug-deopt.js
@@ -53,8 +53,9 @@
   var b = a.substring("1");
   [a, b].sort();
   return a;
-}
+};
 
+%PrepareFunctionForOptimization(f);
 f();
 f();
 %OptimizeFunctionOnNextCall(f, "concurrent");  // Mark with builtin.
diff --git a/src/v8/test/debugger/debug/regress/regress-prepare-break-while-recompile.js b/src/v8/test/debugger/debug/regress/regress-prepare-break-while-recompile.js
index 3b56254..83d2181 100644
--- a/src/v8/test/debugger/debug/regress/regress-prepare-break-while-recompile.js
+++ b/src/v8/test/debugger/debug/regress/regress-prepare-break-while-recompile.js
@@ -45,6 +45,7 @@
   return x;
 }
 
+%PrepareFunctionForOptimization(foo);
 foo();
 foo();
 // Mark and kick off recompilation.
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-async.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-async.js
new file mode 100644
index 0000000..c7f55c1
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-async.js
@@ -0,0 +1,59 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Test that asynchronous features do not work with
+// side-effect free debug-evaluate.
+
+Debug = debug.Debug
+
+var exception = null;
+
+function* generator() {
+  yield 1;
+}
+
+async function async() {
+  return 1;
+}
+
+var g = generator();
+
+var p = new Promise(() => {});
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    function fail(source) {
+      assertThrows(() => exec_state.frame(0).evaluate(source, true),
+                   EvalError);
+    }
+    fail("new Promise()");
+    fail("generator()");
+    fail("g.next()");
+    fail("async()");
+    fail("Promise.resolve()");
+    fail("Promise.reject()");
+    fail("p.then(() => {})");
+    fail("p.catch(() => {})");
+    fail("p.finally(() => {})");
+    fail("Promise.all([p, p])");
+    fail("Promise.race([p, p])");
+    fail("(async function() {})()");
+    fail("(async function() { await 1; })()");
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+};
+
+f();
+
+assertNull(exception);
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-builtins-2.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-builtins-2.js
new file mode 100644
index 0000000..98cfdb1
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-builtins-2.js
@@ -0,0 +1,145 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug
+
+var exception = null;
+var date = new Date();
+var map = new Map().set("a", "b").set("c", "d");
+var set = new Set([1, 2]);
+var weak_key = [];
+var weak_map = new WeakMap().set(weak_key, "a").set({}, "b");
+var weak_set = new WeakSet([weak_key, {}]);
+var add = function (a, b) { return a + b; };
+var number_value = 13;
+function get_number() {
+  return typeof(number_value);
+};
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    function success(expectation, source) {
+      var result = exec_state.frame(0).evaluate(source, true).value();
+      if (expectation !== undefined) assertEquals(expectation, result);
+    }
+    function fail(source) {
+      assertThrows(() => exec_state.frame(0).evaluate(source, true),
+                   EvalError);
+    }
+
+    // Test Function-related functions.
+    success("func", `(function func(){}).prototype.constructor.name`);
+    success("[object Object]", `(function func(){}).prototype.toString()`);
+    success(12, `add.bind(null, 10)(2)`);
+    success(3, `add.call(null, 1, 2)`);
+    success(3, `add.apply(null, [1, 2])`);
+
+    // Test Date.prototype functions.
+    success(undefined, `Date()`);
+    success(undefined, `new Date()`);
+    success(undefined, `Date.now()`);
+    success(undefined, `Date.parse(1)`);
+    for (f of Object.getOwnPropertyNames(Date.prototype)) {
+      if (typeof Date.prototype[f] === "function") {
+        if (f.startsWith("set")) {
+          fail(`date.${f}(5);`, true);
+        } else if (f.startsWith("toLocale") && typeof Intl === "undefined") {
+          continue;
+        } else {
+          success(undefined, `date.${f}();`);
+        }
+      }
+    }
+
+    // Test Boolean.
+    success(true, `Boolean(1)`);
+    success(new Boolean(true), `new Boolean(1)`);
+    success("true", `true.toString()`);
+    success(true, `true.valueOf()`);
+
+    // Test global functions.
+    success(1, `parseInt("1")`);
+    success(1.3, `parseFloat("1.3")`);
+    success("abc", `decodeURI("abc")`);
+    success("abc", `encodeURI("abc")`);
+    success("abc", `decodeURIComponent("abc")`);
+    success("abc", `encodeURIComponent("abc")`);
+    success("abc", `escape("abc")`);
+    success("abc", `unescape("abc")`);
+    success(true, `isFinite(0)`);
+    success(true, `isNaN(0/0)`);
+    success("object", `typeof date`);
+    success("number", `get_number()`);
+
+    // Test Map functions.
+    success(undefined, `new Map()`);
+    success("[object Map]", `map.toString()`);
+    success("b", `map.get("a")`);
+    success(true, `map.get("x") === undefined`);
+    success(undefined, `map.entries()`);
+    success(undefined, `map.keys()`);
+    success(undefined, `map.values()`);
+    success(undefined, `map.forEach(()=>1)`);
+    success(true, `map.has("c")`);
+    success(2, `map.size`);
+    success(undefined, `new Map([[1, 2]])`);
+    fail(`map.delete("a")`);
+    fail(`map.clear()`);
+    fail(`map.set("x", "y")`);
+
+    // Test Set functions.
+    success(undefined, `new Set()`);
+    success("[object Set]", `set.toString()`);
+    success(undefined, `set.entries()`);
+    success(undefined, `set.keys()`);
+    success(undefined, `set.values()`);
+    success(undefined, `set.forEach(()=>1)`);
+    success(true, `set.has(1)`);
+    success(2, `set.size`);
+    success(1, `new Set([1]).size`);
+    fail(`set.add(2)`);
+    fail(`set.delete(1)`);
+    fail(`set.clear()`);
+
+    // Test WeakMap functions.
+    success(undefined, `new WeakMap()`);
+    success("[object WeakMap]", `weak_map.toString()`);
+    success("a", `weak_map.get(weak_key)`);
+    success(true, `weak_map.get([]) === undefined`);
+    success(true, `weak_map.has(weak_key)`);
+    fail(`new WeakMap([[[], {}]])`);
+    fail(`weak_map.delete("a")`);
+    fail(`weak_map.set("x", "y")`);
+
+    // Test WeakSet functions.
+    success(undefined, `new WeakSet()`);
+    success("[object WeakSet]", `weak_set.toString()`);
+    success(true, `weak_set.has(weak_key)`);
+    fail(`new WeakSet([[], {}])`);
+    fail(`weak_set.add([])`);
+    fail(`weak_set.delete("a")`);
+
+    // Test BigInt functions.
+    success(10n, `BigInt('10')`);
+    success(10n, `BigInt.asIntN(10, 10n)`);
+    success(10n, `BigInt.asUintN(10, 10n)`);
+    success("10", `10n.toString()`);
+    success(10n, `10n.valueOf()`);
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+};
+
+f();
+
+assertNull(exception);
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-builtins.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-builtins.js
new file mode 100644
index 0000000..29d8145
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-builtins.js
@@ -0,0 +1,234 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --no-enable-one-shot-optimization
+
+Debug = debug.Debug
+
+var exception = null;
+var object_with_symbol_key = {[Symbol("a")]: 1};
+var object_with_callbacks = { toString: () => "string", valueOf: () => 3};
+var symbol_for_a = Symbol.for("a");
+var typed_array = new Uint8Array([1, 2, 3]);
+var array_buffer = new ArrayBuffer(3);
+var data_view = new DataView(new ArrayBuffer(8), 0, 8);
+var array = [1,2,3];
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    function success(expectation, source) {
+      var result = exec_state.frame(0).evaluate(source, true).value();
+      if (expectation !== undefined) assertEquals(expectation, result);
+    }
+    function fail(source) {
+      assertThrows(() => exec_state.frame(0).evaluate(source, true),
+                   EvalError);
+    }
+
+    // Test some Object functions.
+    success({}, `new Object()`);
+    success({p : 3}, `Object.create({}, { p: { value: 3 } })`);
+    success("[[\"a\",1],[\"b\",2]]",
+            `JSON.stringify(Object.entries({a:1, b:2}))`);
+    success({value: 1, writable: true, enumerable: true, configurable: true},
+            `Object.getOwnPropertyDescriptor({a: 1}, "a")`);
+    success("{\"a\":{\"value\":1,\"writable\":true," +
+            "\"enumerable\":true,\"configurable\":true}}",
+            `JSON.stringify(Object.getOwnPropertyDescriptors({a: 1}))`);
+    success(["a"], `Object.getOwnPropertyNames({a: 1})`);
+    success(undefined, `Object.getOwnPropertySymbols(object_with_symbol_key)`);
+    success({}, `Object.getPrototypeOf(Object.create({}))`);
+    success(true, `Object.is(Object, Object)`);
+    success(true, `Object.isExtensible({})`);
+    success(false, `Object.isFrozen({})`);
+    success(false, `Object.isSealed({})`);
+    success([1, 2], `Object.values({a:1, b:2})`);
+
+    fail(`Object.assign({}, {})`);
+    fail(`Object.defineProperties({}, [{p:{value:3}}])`);
+    fail(`Object.defineProperty({}, {p:{value:3}})`);
+    fail(`Object.freeze({})`);
+    fail(`Object.preventExtensions({})`);
+    fail(`Object.seal({})`);
+    fail(`Object.setPrototypeOf({}, {})`);
+
+    // Test some Object.prototype functions.
+    success(true, `({a:1}).hasOwnProperty("a")`);
+    success(true, `Object.prototype.isPrototypeOf({})`);
+    success(true, `({a:1}).propertyIsEnumerable("a")`);
+    success("[object Object]", `({a:1}).toString()`);
+    success("[object Object]", `({a:1}).toLocaleString()`);
+    success("string", `(object_with_callbacks).toString()`);
+    success(3, `(object_with_callbacks).valueOf()`);
+
+    // Test Array functions.
+    success(true, `Array.isArray([1, 2, 3])`);
+    success([], `new Array()`);
+    success([undefined, undefined], `new Array(2)`);
+    success([1, 2], `new Array(1, 2)`);
+    fail(`Array.from([1, 2, 3])`);
+    fail(`Array.of(1, 2, 3)`);
+    var function_param = [
+      "flatMap", "forEach", "every", "some", "reduce", "reduceRight", "find",
+      "filter", "map", "findIndex"
+    ];
+    var fails = ["pop", "push", "reverse", "shift", "unshift", "splice",
+      "sort", "copyWithin", "fill"];
+    for (f of Object.getOwnPropertyNames(Array.prototype)) {
+      if (typeof Array.prototype[f] === "function") {
+        if (fails.includes(f)) {
+          if (function_param.includes(f)) {
+            fail(`array.${f}(()=>{});`);
+          } else {
+            fail(`array.${f}();`);
+          }
+        } else if (function_param.includes(f)) {
+          exec_state.frame(0).evaluate(`array.${f}(()=>{});`, true);
+        } else {
+          exec_state.frame(0).evaluate(`array.${f}();`, true);
+        }
+      }
+    }
+
+    // Test ArrayBuffer functions.
+    success(3, `array_buffer.byteLength`);
+    success(2, `array_buffer.slice(1, 3).byteLength`);
+    success(true, `ArrayBuffer.isView(typed_array)`);
+
+    // Test DataView functions.
+    success(undefined, `new DataView(array_buffer, 1, 2)`);
+    success(undefined, `data_view.buffer`);
+    success(undefined, `data_view.byteLength`);
+    success(undefined, `data_view.byteOffset`);
+    for (f of Object.getOwnPropertyNames(DataView.prototype)) {
+      if (typeof data_view[f] === 'function') {
+        if (f.startsWith('getBig')) {
+          success(0n, `data_view.${f}()`);
+        } else if (f.startsWith('get')) {
+          success(0, `data_view.${f}()`);
+        }
+      }
+    }
+
+    // Test TypedArray functions.
+    success({}, `new Uint8Array()`);
+    success({0: 0, 1: 0}, `new Uint8Array(2)`);
+    success({0: 1, 1: 2, 2: 3}, `new Uint8Array(typed_array)`);
+    success(true, `!!typed_array.buffer`);
+    success(0, `typed_array.byteOffset`);
+    success(3, `typed_array.byteLength`);
+    fail(`Uint8Array.of(1, 2)`);
+    function_param = [
+      "forEach", "every", "some", "reduce", "reduceRight", "find", "filter",
+      "map", "findIndex"
+    ];
+    fails = ["reverse", "sort", "copyWithin", "fill", "set"];
+    var typed_proto_proto = Object.getPrototypeOf(Object.getPrototypeOf(new Uint8Array()));
+    for (f of Object.getOwnPropertyNames(typed_proto_proto)) {
+      if (typeof typed_array[f] === "function" && f !== "constructor") {
+        if (fails.includes(f)) {
+          if (function_param.includes(f)) {
+            fail(`typed_array.${f}(()=>{});`);
+          } else {
+            fail(`typed_array.${f}();`);
+          }
+        } else if (function_param.includes(f)) {
+          exec_state.frame(0).evaluate(`typed_array.${f}(()=>{});`, true);
+        } else {
+          exec_state.frame(0).evaluate(`typed_array.${f}();`, true);
+        }
+      }
+    }
+
+    // Test Math functions.
+    for (f of Object.getOwnPropertyNames(Math)) {
+      if (typeof Math[f] === "function") {
+        var result = exec_state.frame(0).evaluate(
+                         `Math.${f}(0.5, -0.5);`, true).value();
+        if (f != "random") assertEquals(Math[f](0.5, -0.5), result);
+      }
+    }
+
+    // Test Number functions.
+    success(new Number(0), `new Number()`);
+    for (f of Object.getOwnPropertyNames(Number)) {
+      if (typeof Number[f] === "function") {
+        success(Number[f](0.5), `Number.${f}(0.5);`);
+      }
+    }
+    for (f of Object.getOwnPropertyNames(Number.prototype)) {
+      if (typeof Number.prototype[f] === "function") {
+        if (f == "toLocaleString" && typeof Intl === "undefined") continue;
+        success(Number(0.5)[f](5), `Number(0.5).${f}(5);`);
+      }
+    }
+
+    // Test String functions.
+    success(new String(), `new String()`);
+    success(" ", "String.fromCodePoint(0x20)");
+    success(" ", "String.fromCharCode(0x20)");
+    for (f of Object.getOwnPropertyNames(String.prototype)) {
+      if (typeof String.prototype[f] === "function") {
+        // Do not expect locale-specific or regexp-related functions to work.
+        // {Lower,Upper}Case (Locale-specific or not) do not work either
+        // if Intl is enabled.
+        if (f.indexOf("locale") >= 0) continue;
+        if (f.indexOf("Locale") >= 0) continue;
+        if (typeof Intl !== 'undefined') {
+          if (f == "toUpperCase") continue;
+          if (f == "toLowerCase") continue;
+        }
+        if (f == "normalize") continue;
+        if (f == "match") continue;
+        if (f == "matchAll") continue;
+        if (f == "search") continue;
+        if (f == "split" || f == "replace") {
+          fail(`'abcd'.${f}(2)`);
+          continue;
+        }
+        success("abcd"[f](2), `"abcd".${f}(2);`);
+      }
+    }
+    fail("'abCd'.toLocaleLowerCase()");
+    fail("'abcd'.toLocaleUpperCase()");
+    if (typeof Intl !== 'undefined') {
+      fail("'abCd'.toLowerCase()");
+      fail("'abcd'.toUpperCase()");
+    }
+    fail("'abcd'.match(/a/)");
+    fail("'abcd'.replace(/a/)");
+    fail("'abcd'.search(/a/)");
+
+    // Test RegExp functions.
+    fail(`/a/.compile()`);
+    success('a', `/a/.exec('abc')[0]`);
+    success(true, `/a/.test('abc')`);
+    fail(`/a/.toString()`);
+
+    // Test JSON functions.
+    success('{"abc":[1,2]}', "JSON.stringify(JSON.parse('{\"abc\":[1,2]}'))");
+
+    // Test Symbol functions.
+    success(undefined, `Symbol("a")`);
+    fail(`Symbol.for("a")`);  // Symbol.for can be observed via Symbol.keyFor.
+    success("a", `Symbol.keyFor(symbol_for_a)`);
+    success("Symbol(a)", `symbol_for_a.valueOf().toString()`);
+    success("Symbol(a)", `symbol_for_a[Symbol.toPrimitive]().toString()`);
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+};
+
+f();
+
+assertNull(exception);
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-control.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-control.js
new file mode 100644
index 0000000..06f41eb
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-control.js
@@ -0,0 +1,109 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug
+
+var exception = null;
+
+var o = { p : 1 };
+
+var successes = [
+  [45,
+   `(function() {
+      var sum = 0;
+      for (var i = 0; i < 10; i++) sum += i;
+      return sum;
+    })()`
+  ],
+  ["0012",
+   `(function() {
+      var sum = 0;
+      for (var i in [1, 2, 3]) sum += i;
+      return sum;
+    })()`
+  ],
+  [15,
+   `(function() {
+      var sum = 1;
+      while (sum < 12) sum += sum + 1;
+      return sum;
+    })()`
+  ],
+  [15,
+   `(function() {
+      var sum = 1;
+      do { sum += sum + 1; } while (sum < 12);
+      return sum;
+    })()`
+  ],
+  ["023",
+   `(function() {
+      var sum = "";
+      for (var i = 0; i < 4; i++) {
+        switch (i) {
+          case 0:
+          case 1:
+            if (i == 0) sum += i;
+            break;
+          default:
+          case 3:
+            sum += i;
+            break;
+        }
+      }
+      return sum;
+    })()`
+  ],
+  ["oups",
+   `(function() {
+      try {
+        if (Math.sin(1) < 1) throw new Error("oups");
+      } catch (e) {
+        return e.message;
+      }
+    })()`
+  ],
+  [6,
+   `(function() {  // Iterator.prototype.next performs stores.
+      var sum = 0;
+      for (let i of [1, 2, 3]) sum += i;
+      return sum;
+    })()`
+  ]
+];
+
+var fails = [
+  `(function() {  // Store to scope object.
+     with (o) {
+       p = 2;
+     }
+   })()`,
+];
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    successes.forEach(function ([expectation, source]) {
+      assertEquals(expectation,
+                   exec_state.frame(0).evaluate(source, true).value());
+    });
+    fails.forEach(function (test) {
+      assertThrows(() => exec_state.frame(0).evaluate(test, true), EvalError);
+    });
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+};
+
+f();
+
+assertNull(exception);
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-iife.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-iife.js
new file mode 100644
index 0000000..c8dc2a5
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-iife.js
@@ -0,0 +1,67 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Test that declaring local variables in IIFEs works with
+// side-effect free debug-evaluate.
+
+Debug = debug.Debug
+
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    function success(expectation, source) {
+      assertEquals(expectation,
+                   exec_state.frame(0).evaluate(source, true).value());
+    }
+    function fail(source) {
+      assertThrows(() => exec_state.frame(0).evaluate(source, true),
+                   EvalError);
+    }
+    // Declaring 'a' sets a property to the global object.
+    fail("var a = 3");
+    exec_state.frame(0).evaluate("var a = 2", false);
+    assertEquals(2, a);
+    // Wrapping into an IIFE would be fine, since 'a' is local.
+    success(100,
+            `(function(x) {
+                var a = 0;
+                for (var i = 0; i < x; i++) {
+                  a += x;
+                }
+                return a;
+              })(10);`);
+    success(100,
+            `(x => {
+                let a = 0;
+                for (var i = 0; i < x; i++) {
+                  a += x;
+                }
+                return a;
+              })(10);`);
+    // Not using 'var' to declare would make the access go to global object.
+    fail(   `(function(x) {
+                a = 0;
+                for (var i = 0; i < x; i++) {
+                  a += x;
+                }
+                return a;
+              })(10);`);
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+};
+
+f();
+
+assertNull(exception);
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-ops.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-ops.js
new file mode 100644
index 0000000..7f3675d
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-ops.js
@@ -0,0 +1,97 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug
+
+var exception = null;
+var date = new Date();
+var T = true;
+var F = false;
+var one = 1;
+var two = 2;
+var string = "s";
+var array = [1, 2, 3];
+function max(...rest) {
+  return Math.max(...rest);
+}
+
+function def(a = 1) {
+  return a;
+}
+
+function d1([a, b = 'b']) {
+  return a + b;
+}
+
+function d2({ x: c, y, z = 'z' } = {x: 'x', y: 'y' }) {
+  return c + y + z;
+}
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    function success(expectation, source) {
+      var result = exec_state.frame(0).evaluate(source, true).value();
+      if (expectation !== undefined) assertEquals(expectation, result);
+    }
+    function fail(source) {
+      assertThrows(() => exec_state.frame(0).evaluate(source, true),
+                   EvalError);
+    }
+    success(false, `Object == {}`);
+    success(false, `Object === {}`);
+    success(true, `Object != {}`);
+    success(true, `Object !== {}`);
+    success(true, `'s' == string`);
+    success(true, `'s' === string`);
+    success(true, `1 < Math.cos(0) * 2`);
+    success(false, `1 < string`);
+    success(true, `'a' < string`);
+    success("s", `string[0]`);
+    success(0, `[0][0]`);
+    success(1, `T^F`);
+    success(0, `T&F`);
+    success(1, `T|F`);
+    success(false, `T&&F`);
+    success(true, `T||F`);
+    success(false, `T?F:T`);
+    success(false, `!T`);
+    success(1, `+one`);
+    success(-1, `-one`);
+    success(-2, `~one`);
+    success(4, `one << two`);
+    success(1, `two >> one`);
+    success(1, `two >>> one`);
+    success(3, `two + one`);
+    success(2, `two * one`);
+    success(0.5, `one / two`);
+    success(0, `(one / two) | 0`);
+    success(1, `one ** two`);
+    success(NaN, `string * two`);
+    success("s2", `string + two`);
+    success("s2", `string + two`);
+    success([1,2,3], `[...array]`);
+    success(3, `max(...array)`);
+    success({s:1}, `({[string]:1})`);
+    fail(`[a, b] = [1, 2]`);
+    success(2, `def(2)`);
+    success(1, `def()`);
+    success('ab', `d1(['a'])`);
+    success("XYz", `d2({x:'X', y:'Y'})`);
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+};
+
+f();
+
+assertNull(exception);
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-regexp.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-regexp.js
new file mode 100644
index 0000000..1db5dbd
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-regexp.js
@@ -0,0 +1,28 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug;
+
+/(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)/.exec(">>>abcdefghij<<<");
+assertRegExp();
+Debug.evaluateGlobal(`/(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)(\\w)/.exec(">>>hklmnoprst<<<")`, true);
+assertRegExp();
+
+function assertRegExp() {
+  assertEquals("a", RegExp.$1);
+  assertEquals("b", RegExp.$2);
+  assertEquals("c", RegExp.$3);
+  assertEquals("d", RegExp.$4);
+  assertEquals("e", RegExp.$5);
+  assertEquals("f", RegExp.$6);
+  assertEquals("g", RegExp.$7);
+  assertEquals("h", RegExp.$8);
+  assertEquals("i", RegExp.$9);
+
+  assertEquals("abcdefghij", RegExp.lastMatch);
+  assertEquals("j", RegExp.lastParen);
+  assertEquals(">>>", RegExp.leftContext);
+  assertEquals("<<<", RegExp.rightContext);
+  assertEquals(">>>abcdefghij<<<", RegExp.input);
+}
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-runtime-check.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-runtime-check.js
new file mode 100644
index 0000000..7a0f373
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect-runtime-check.js
@@ -0,0 +1,201 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug;
+
+// StaCurrentContextSlot
+success(10, `(function(){
+  const x = 10;
+  function f1() {return x;}
+  return x;
+})()`);
+
+// StaNamedProperty
+var a = {name: 'foo'};
+function set_name(a) {
+  a.name = 'bar';
+  return a.name;
+}
+
+fail(`set_name(a)`);
+success('bar', `set_name({name: 'foo'})`);
+
+// StaNamedOwnProperty
+var name_value = 'value';
+function create_object_literal() {
+  var obj = {name: name_value};
+  return obj.name;
+};
+
+success('value', `create_object_literal()`);
+
+// StaKeyedProperty
+var arrayValue = 1;
+function create_array_literal() {
+  return [arrayValue];
+}
+var b = { 1: 2 };
+
+success([arrayValue], `create_array_literal()`)
+fail(`b[1] ^= 2`);
+
+// StaInArrayLiteral
+function return_array_use_spread(a) {
+  return [...a];
+}
+
+success([1], `return_array_use_spread([1])`);
+
+// CallAccessorSetter
+var array = [1,2,3];
+fail(`array.length = 2`);
+success(2, `[1,2,3].length = 2`);
+
+// StaDataPropertyInLiteral
+function return_literal_with_data_property(a) {
+  return {[a] : 1};
+}
+
+success({foo: 1}, `return_literal_with_data_property('foo')`);
+
+// Set builtins with temporary objects
+var set = new Set([1,2]);
+fail(`set.add(3).size`);
+success(1, `new Set().add(1).size`);
+
+success(0, `(() => { const s = new Set([1]); s.delete(1); return s.size; })()`);
+fail(`set.delete(1)`);
+
+success(0, `(() => { const s = new Set([1]); s.clear(); return s.size; })()`);
+fail(`set.clear()`);
+
+// new set
+success(3, `(() => {
+  let s = 0;
+  for (const a of new Set([1,2]))
+    s += a;
+  return s;
+})()`);
+// existing set
+success(3, `(() => {
+  let s = 0;
+  for (const a of set)
+    s += a;
+  return s;
+})()`);
+// existing iterator
+var setIterator = set.entries();
+fail(`(() => {
+  let s = 0;
+  for (const a of setIterator)
+    s += a;
+  return s;
+})()`);
+
+// Array builtins with temporary objects
+success([1,1,1], '[1,2,3].fill(1)');
+fail(`array.fill(1)`);
+
+success([1], `(() => { const a = []; a.push(1); return a; })()`);
+fail(`array.push(1)`);
+
+success([1], `(() => { const a = [1,2]; a.pop(); return a; })()`);
+fail(`array.pop()`);
+
+success([3,2,1], `[1,2,3].reverse()`);
+fail(`array.reverse()`);
+
+success([1,2,3], `[2,1,3].sort()`);
+fail(`array.sort()`);
+
+success([2,3], `[1,2,3].splice(1,2)`);
+fail(`array.splice(1,2)`);
+
+success([1,2], `(() => { const a = [2]; a.unshift(1); return a; })()`);
+fail(`array.unshift(1)`);
+success(1, `[1,2].shift()`);
+fail(`array.shift()`);
+
+// new array
+success(6, `(() => {
+  let s = 0;
+  for (const a of [1,2,3])
+    s += a;
+  return s;
+})()`);
+// existing array
+success(6, `(() => {
+  let s = 0;
+  for (const a of array)
+    s += a;
+  return s;
+})()`);
+// existing iterator
+var arrayIterator = array.entries();
+fail(`(() => {
+  let s = 0;
+  for (const a of arrayIterator)
+    s += a;
+  return s;
+})()`);
+
+success(6, `array.reduce((a,b) => a + b, 0)`);
+
+// Map builtins with temporary objects
+var map = new Map([[1,2]]);
+fail(`map.set(3, 4).size`);
+success(1, `new Map().set(1, 2).size`);
+
+success(0, `(() => {
+  const m = new Map([[1, 2]]);
+  m.delete(1);
+  return m.size;
+})()`);
+fail(`map.delete(1)`);
+
+success(0, `(() => {
+  const m = new Map([[1, 2]]);
+  m.clear();
+  return m.size;
+})()`);
+fail(`map.clear()`);
+
+// new set
+success(2, `(() => {
+  let s = 0;
+  for (const [a, b] of new Map([[1,2]]))
+    s += b;
+  return s;
+})()`);
+// existing set
+success(2, `(() => {
+  let s = 0;
+  for (const [a,b] of map)
+    s += b;
+  return s;
+})()`);
+// existing iterator
+var mapIterator = map.entries();
+fail(`(() => {
+  let s = 0;
+  for (const [a,b] of mapIterator)
+    s += a;
+  return s;
+})()`);
+
+// Regexps
+var regExp = /a/;
+success(true, `/a/.test('a')`);
+fail(`/a/.test({toString: () => {map.clear(); return 'a';}})`)
+fail(`regExp.test('a')`);
+
+function success(expectation, source) {
+  const result = Debug.evaluateGlobal(source, true).value();
+  if (expectation !== undefined) assertEquals(expectation, result);
+}
+
+function fail(source) {
+  assertThrows(() => Debug.evaluateGlobal(source, true),
+               EvalError);
+}
diff --git a/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect.js b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect.js
new file mode 100644
index 0000000..5504cef
--- /dev/null
+++ b/src/v8/test/debugger/debug/side-effect/debug-evaluate-no-side-effect.js
@@ -0,0 +1,131 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Debug = debug.Debug
+
+var exception = null;
+let a = 1;
+var object = { property : 2,
+               get getter() { return 3; }
+             };
+var string0 = new String("string");
+var string1 = { toString() { return "x"; } };
+var string2 = { toString() { print("x"); return "x"; } };
+var array = [4, 5];
+var error = new Error();
+
+function simple_return(x) { return x; }
+function set_a() { a = 2; }
+function get_a() { return a; }
+var bound = get_a.bind(0);
+
+function return_arg0() { return return_arg0.arguments[0]; }
+function return_caller_name() { return return_caller_name.caller.name; }
+
+var global_eval = eval;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    function success(expectation, source) {
+      assertEquals(expectation,
+                   exec_state.frame(0).evaluate(source, true).value());
+    }
+    function fail(source) {
+      assertThrows(() => exec_state.frame(0).evaluate(source, true),
+                   EvalError);
+    }
+
+    // Simple test.
+    success(3, "1 + 2");
+    // Dymanic load.
+    success(array, "array");
+    // Context load.
+    success(1, "a");
+    // Global and named property load.
+    success(2, "object.property");
+    // Load via read-only getter.
+    success(3, "object.getter");
+    // Implicit call to read-only toString.
+    success("xy", "string1 + 'y'");
+    // Keyed property load.
+    success(5, "array[1]");
+    // Call to read-only function.
+    success(1, "get_a()");
+    success(1, "bound()");
+    success({}, "new get_a()");
+    // Call to read-only function within try-catch.
+    success(1, "try { get_a() } catch (e) {}");
+    // Call to C++ built-in.
+    success(Math.sin(2), "Math.sin(2)");
+    // Call to whitelisted get accessors.
+    success(3, "'abc'.length");
+    success(2, "array.length");
+    success(1, "'x'.length");
+    success(0, "set_a.length");
+    success("set_a", "set_a.name");
+    success(0, "bound.length");
+    success("bound get_a", "bound.name");
+    success(1, "return_arg0(1)");
+    success("f", "(function f() { return return_caller_name() })()");
+    // Non-evaluated call.
+    // Constructed literals.
+    success([1], "[1]");
+    success({x: 1}, "({x: 1})");
+    success([1], "[a]");
+    success({x: 1}, "({x: a})");
+    // Test that template literal evaluation fails.
+    fail("simple_return`1`");
+    // Test that non-read-only code fails.
+    fail("exception = 1");
+    // Test that calling a non-read-only function fails.
+    fail("set_a()");
+    fail("new set_a()");
+    // Test that implicit call to a non-read-only function fails.
+    fail("string2 + 'y'");
+    // Test that try-catch does not catch the EvalError.
+    fail("try { set_a() } catch (e) {}");
+    // Test that call to set accessor fails.
+    fail("array.length = 4");
+    fail("set_a.name = 'set_b'");
+    fail("set_a.length = 1");
+    fail("bound.name = 'bound'");
+    fail("bound.length = 1");
+    fail("set_a.prototype = null");
+    // Test that call to non-whitelisted get accessor fails.
+    fail("error.stack");
+    // Call to set accessors with receiver check.
+    success(1, "[].length = 1");
+    success(1, "'x'.length = 1");
+    fail("string0.length = 1");
+    success(1, "(new String('abc')).length = 1");
+    success("g", "(function(){}).name = 'g'");
+    success(1, "(function(){}).length = 1");
+    success("g", "get_a.bind(0).name = 'g'");
+    success(1, "get_a.bind(0).length = 1");
+    success(null, "(function(){}).prototype = null");
+    success(true, "(new Error()).stack.length > 1");
+    success("a", "(new Error()).stack = 'a'");
+    // Eval is not allowed.
+    fail("eval('Math.sin(1)')");
+    fail("eval('exception = 1')");
+    fail("global_eval('1')");
+    success(1, "(() => { var a = 1; return a++; })()")
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function f() {
+  debugger;
+};
+
+f();
+
+assertNull(exception);
+assertEquals(1, a);
diff --git a/src/v8/test/debugger/debug/wasm/frame-inspection.js b/src/v8/test/debugger/debug/wasm/frame-inspection.js
index 45fa8a9..882b7e3 100644
--- a/src/v8/test/debugger/debug/wasm/frame-inspection.js
+++ b/src/v8/test/debugger/debug/wasm/frame-inspection.js
@@ -4,7 +4,6 @@
 
 // Flags: --expose-wasm
 
-load("test/mjsunit/wasm/wasm-constants.js");
 load("test/mjsunit/wasm/wasm-module-builder.js");
 
 Debug = debug.Debug
@@ -25,7 +24,6 @@
   if (event != Debug.DebugEvent.Break) return;
   ++break_count;
   try {
-    var break_id = exec_state.break_id;
     var frame_count = exec_state.frameCount();
     assertEquals(expected_frames.length, frame_count, 'frame count');