@@ -6,10 +6,118 @@ const marshallSourceTextInStrictMode = `
66(function(){
77 'use strict';
88 (${ function initializeShadowRealm ( ) {
9- if ( typeof Error . stackTraceLimit === 'number' ) {
10- // The default stack trace limit is 10.
11- // Increasing to 20 as a baby step.
12- Error . stackTraceLimit *= 2 ;
9+ // Hook into V8 stack trace API
10+ // https://v8.dev/docs/stack-trace-api
11+ if ( typeof Error . prepareStackTrace !== 'function' ) {
12+ const CallSite = ( ( ) : Function | undefined => {
13+ Error . prepareStackTrace = ( _error : Error , callSites : NodeJS . CallSite [ ] ) =>
14+ callSites ;
15+ const callSites = new Error ( ) . stack as string | NodeJS . CallSite [ ] ;
16+ delete Error . prepareStackTrace ;
17+ return Array . isArray ( callSites ) && callSites . length > 0
18+ ? callSites [ 0 ] ?. constructor
19+ : undefined ;
20+ } ) ( ) ;
21+ if ( typeof CallSite === 'function' ) {
22+ // @rollup /plugin-replace replaces `DEV_MODE` references.
23+ const DEV_MODE = true ;
24+ const ZERO_WIDTH_JOINER = '\u200D' ;
25+ const LOCKER_IDENTIFIER_MARKER = `$LWS${ ZERO_WIDTH_JOINER } ` ;
26+
27+ const { toString : ErrorProtoToString } = Error . prototype ;
28+ const { apply : ReflectApply , defineProperty : ReflectDefineProperty } = Reflect ;
29+ const { endsWith : StringProtoEndsWith , includes : StringProtoIncludes } =
30+ String . prototype ;
31+ const {
32+ getEvalOrigin : CallSiteProtoGetEvalOrigin ,
33+ getFunctionName : CallSiteProtoGetFunctionName ,
34+ toString : CallSiteProtoToString ,
35+ } = CallSite . prototype ;
36+
37+ const formatStackTrace = function formatStackTrace (
38+ error : Error ,
39+ callSites : NodeJS . CallSite [ ]
40+ ) : string {
41+ // Based on V8's default stack trace formatting:
42+ // https://chromium.googlesource.com/v8/v8.git/+/refs/heads/main/src/execution/messages.cc#371
43+ let stackTrace = '' ;
44+ try {
45+ stackTrace = ReflectApply ( ErrorProtoToString , error , [ ] ) ;
46+ } catch {
47+ stackTrace = '<error>' ;
48+ }
49+ let consecutive = false ;
50+ for ( let i = 0 , { length } = callSites ; i < length ; i += 1 ) {
51+ const callSite = callSites [ i ] ;
52+ const funcName = ReflectApply ( CallSiteProtoGetFunctionName , callSite , [ ] ) ;
53+ let isMarked = false ;
54+ if (
55+ typeof funcName === 'string' &&
56+ funcName !== 'eval' &&
57+ ReflectApply ( StringProtoEndsWith , funcName , [ LOCKER_IDENTIFIER_MARKER ] )
58+ ) {
59+ isMarked = true ;
60+ }
61+ if ( ! isMarked ) {
62+ const evalOrigin = ReflectApply (
63+ CallSiteProtoGetEvalOrigin ,
64+ callSite ,
65+ [ ]
66+ ) ;
67+ if (
68+ typeof evalOrigin === 'string' &&
69+ ReflectApply ( StringProtoIncludes , evalOrigin , [
70+ LOCKER_IDENTIFIER_MARKER ,
71+ ] )
72+ ) {
73+ isMarked = true ;
74+ }
75+ }
76+ // Only write a single LWS entry per consecutive LWS stacks.
77+ if ( isMarked ) {
78+ if ( ! consecutive ) {
79+ consecutive = true ;
80+ stackTrace += '\n at LWS' ;
81+ }
82+ continue ;
83+ } else {
84+ consecutive = false ;
85+ }
86+ try {
87+ stackTrace += `\n at ${ ReflectApply (
88+ CallSiteProtoToString ,
89+ callSite ,
90+ [ ]
91+ ) } `;
92+ // eslint-disable-next-line no-empty
93+ } catch { }
94+ }
95+ return stackTrace ;
96+ } ;
97+ // Make Error.prepareStackTrace non-configurable and non-writable.
98+ ReflectDefineProperty ( Error , 'prepareStackTrace' , {
99+ // @ts -ignore: TS doesn't like __proto__ on property descriptors.
100+ __proto__ : null ,
101+ enumerable : true ,
102+ // Error.prepareStackTrace cannot be a bound or proxy wrapped
103+ // function, so to obscure its source we wrap the call to
104+ // formatStackTrace().
105+ value : function prepareStackTrace ( error : Error , callSites : NodeJS . CallSite [ ] ) {
106+ return formatStackTrace ( error , callSites ) ;
107+ } ,
108+ } ) ;
109+ // Make Error.stackTraceLimit configurable and writable in DEV_MODE.
110+ ReflectDefineProperty ( Error , 'stackTraceLimit' , {
111+ // @ts -ignore: TS doesn't like __proto__ on property descriptors.
112+ __proto__ : null ,
113+ configurable : DEV_MODE ,
114+ enumerable : true ,
115+ // The default stack trace limit is 10.
116+ // Increasing to 20 for wiggle room of filtered results.
117+ value : 20 ,
118+ writable : DEV_MODE ,
119+ } ) ;
120+ }
13121 }
14122 } . toString ( ) } )();
15123 return (${ createMembraneMarshall . toString ( ) } )
0 commit comments