| // 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>"); |
| })(); |