| // 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: --allow-natives-syntax | 
 |  | 
 | (function TestErrorObjectsRetainMap() { | 
 |   const error1 = new Error("foo"); | 
 |   const error2 = new Error("bar"); | 
 |  | 
 |   assertTrue(%HaveSameMap(error1, error2)); | 
 |  | 
 |   // Trigger serialization of the stack-trace. | 
 |   error1.stack; | 
 |   assertTrue(%HaveSameMap(error1, error2)); | 
 |  | 
 |   error2.stack; | 
 |   assertTrue(%HaveSameMap(error1, error2)); | 
 | })(); | 
 |  | 
 | (function TestPrepareStackTraceCallback() { | 
 |   Error.prepareStackTrace = (error, frame) => { | 
 |     return "custom stack trace No. 42"; | 
 |   }; | 
 |  | 
 |   const error = new Error("foo"); | 
 |  | 
 |   // Check it twice, so both code paths in the accessor are exercised. | 
 |   assertEquals(error.stack, "custom stack trace No. 42"); | 
 |   assertEquals(error.stack, "custom stack trace No. 42"); | 
 | })(); | 
 |  | 
 | (function TestPrepareStackTraceCallbackMessesWithProperty() { | 
 |   Error.prepareStackTrace = (error, frames) => { | 
 |     error.stack = "Yes, we can write to this!"; | 
 |     return 42; | 
 |   }; | 
 |  | 
 |   const error = new Error("foo"); | 
 |  | 
 |   // Check it twice. The first returns the formatting result, | 
 |   // the second the value of the private symbol. | 
 |   assertEquals(error.stack, 42); | 
 |   assertEquals(error.stack, 42); | 
 | })(); | 
 |  | 
 | (function TestPrepareStackTraceCallbackInstallsGetter() { | 
 |   Error.prepareStackTrace = (error, frames) => { | 
 |     Object.defineProperty(error, "stack", { get: () => 42 }); | 
 |     return "<formatted stack trace>"; | 
 |   }; | 
 |  | 
 |   const error = new Error("foo"); | 
 |  | 
 |   // Check it twice. The second time the accessor should be used. | 
 |   assertEquals(error.stack, "<formatted stack trace>"); | 
 |   assertEquals(error.stack, 42); | 
 | })(); | 
 |  | 
 | (function TestPrepareStackTraceCallbackInstallsSetter() { | 
 |   Error.prepareStackTrace = (error, frames) => { | 
 |     Object.defineProperty(error, "stack", { set: (x) => { | 
 |       error[42] = x; | 
 |     }}); | 
 |     return "<formatted stack trace>"; | 
 |   }; | 
 |  | 
 |   const error = new Error("foo"); | 
 |   // Cause the accessor to get installed. | 
 |   error.stack; | 
 |  | 
 |   error.stack = "Who needs stack traces anyway?"; | 
 |   assertEquals(error[42], "Who needs stack traces anyway?"); | 
 |   assertEquals(error.stack, undefined); // No getter. | 
 | })(); | 
 |  | 
 | (function TestFormatStackPropertyInDictionaryMode() { | 
 |   Error.prepareStackTrace = (error, frames) => { | 
 |     return "<formatted stack trace>"; | 
 |   }; | 
 |   const error = new Error("foo"); | 
 |   error[%MaxSmi()] = 42; | 
 |  | 
 |   assertTrue(%HasDictionaryElements(error)); | 
 |  | 
 |   // Check it twice. | 
 |   assertEquals(error.stack, "<formatted stack trace>"); | 
 |   assertEquals(error.stack, "<formatted stack trace>"); | 
 | })(); | 
 |  | 
 | (function TestTransitionToDictionaryModeAfterFormatting() { | 
 |   Error.prepareStackTrace = (error, frames) => { | 
 |     return "<formatted stack trace>"; | 
 |   }; | 
 |   const error = new Error("foo"); | 
 |   assertFalse(%HasDictionaryElements(error)); | 
 |  | 
 |   assertEquals(error.stack, "<formatted stack trace>"); | 
 |  | 
 |   error[%MaxSmi()] = 42; | 
 |   assertTrue(%HasDictionaryElements(error)); | 
 |   assertEquals(error.stack, "<formatted stack trace>"); | 
 | })(); |