// 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. // Test that live-editing a frame above one that uses new.target succeeds. // Flags: --allow-natives-syntax Debug = debug.Debug; var wrapper_calls = 0; var construct_calls = 0; var exceptions = 0; var results = []; var replace_again; eval(` function LogNewTarget(arg) { construct_calls++; results.push(new.target); } function Wrapper() { wrapper_calls++; ReplaceOnce(); new LogNewTarget(true); } `); function ExecuteInDebugContext(f) { var result; var exception = null; Debug.setListener(function(event) { if (event == Debug.DebugEvent.Break) { try { result = f(); } catch (e) { // Rethrow this exception later. exception = e; } } }); debugger; Debug.setListener(null); if (exception !== null) throw exception; return result; } function Replace(fun, original, patch) { ExecuteInDebugContext(function() { var change_log = []; try { %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch)); } catch (e) { exceptions++; } }); } function ReplaceOnce(x) { if (replace_again) { replace_again = false; Replace(Wrapper, "true", "false"); } } function Revert() { Replace(Wrapper, "false", "true"); } replace_again = true; ReplaceOnce(); Wrapper(); Revert(); assertEquals(1, construct_calls); assertEquals(1, wrapper_calls); assertEquals(0, exceptions); // Replace succeeds assertEquals([LogNewTarget], results); Wrapper(); assertEquals(2, construct_calls); assertEquals(2, wrapper_calls); assertEquals(0, exceptions); // Replace succeeds assertEquals([LogNewTarget, LogNewTarget], results); replace_again = true; Wrapper(); assertEquals(3, construct_calls); assertEquals(3, wrapper_calls); assertEquals(1, exceptions); // Replace failed assertEquals([LogNewTarget, LogNewTarget, LogNewTarget], results);