@@ -139,9 +139,12 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
139139 js.VariableUse get returnValue => js.VariableUse (returnValueName);
140140 late final String returnValueName;
141141
142- /// Stores the current error when we are in the process of handling an error.
143- js.VariableUse get currentError => js.VariableUse (currentErrorName);
144- late final String currentErrorName;
142+ /// Stores a stack of the current set of errors when we are in the process of
143+ /// handling an error. Errors are pushed onto this stack when error handling
144+ /// begins and the current error is popped off when error handling ends. This
145+ /// prevents nested error handling from overwriting state.
146+ js.VariableUse get errorStack => js.VariableUse (errorStackName);
147+ late final String errorStackName;
145148
146149 /// The label of the outer loop.
147150 ///
@@ -199,7 +202,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
199202 handlerName = freshName ("handler" );
200203 nextName = freshName ("next" );
201204 returnValueName = freshName ("returnValue" );
202- currentErrorName = freshName ("currentError " );
205+ errorStackName = freshName ("errorStack " );
203206 outerLabelName = freshName ("outer" );
204207 selfName = freshName ("self" );
205208 // Initialize names specific to the subclass.
@@ -742,8 +745,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
742745 if (hasHandlerLabels) {
743746 variables.add (_makeVariableInitializer (
744747 handler, js.number (rethrowLabel), bodySourceInformation));
745- variables.add (
746- _makeVariableInitializer (currentError, null , bodySourceInformation));
748+ variables.add (_makeVariableInitializer (
749+ errorStack, js. ArrayInitializer ( const []) , bodySourceInformation));
747750 }
748751 if (analysis.hasFinally || (isAsyncStar && analysis.hasYield)) {
749752 variables.add (_makeVariableInitializer (
@@ -1615,7 +1618,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
16151618 String errorRename = freshName (catchPart.declaration.name);
16161619 localVariables.add (js.VariableDeclaration (errorRename));
16171620 variableRenamings.add ((catchPart.declaration.name, errorRename));
1618- addStatement (js.js.statement ("# = #;" , [errorRename, currentError]));
1621+ addStatement (
1622+ js.js.statement ("# = #.pop();" , [errorRename, errorStack]));
16191623 visitStatement (catchPart.body);
16201624 variableRenamings.removeLast ();
16211625 if (finallyPart != null ) {
@@ -1837,10 +1841,10 @@ class AsyncRewriter extends AsyncRewriterBase {
18371841 void addErrorExit (js.JavaScriptNodeSourceInformation ? sourceInformation) {
18381842 if (! hasHandlerLabels) return ; // rethrow handled in method boilerplate.
18391843 beginLabel (rethrowLabel);
1840- js.Expression thenHelperCall = js. js (
1841- "#thenHelper(#currentError , #completer)" , {
1844+ js.Expression thenHelperCall =
1845+ js. js ( "#thenHelper(#errorStack.at(-1) , #completer)" , {
18421846 "thenHelper" : asyncRethrow,
1843- "currentError " : currentError ,
1847+ "errorStack " : errorStack ,
18441848 "completer" : completer
18451849 }).withSourceInformation (sourceInformation);
18461850 addStatement (
@@ -1917,12 +1921,12 @@ class AsyncRewriter extends AsyncRewriterBase {
19171921 if (hasHandlerLabels) {
19181922 errorCheck = js.js.statement ("""
19191923 if (#errorCode === #ERROR) {
1920- #currentError = #result;
1924+ #errorStack.push( #result) ;
19211925 #goto = #handler;
19221926 }""" , {
19231927 "errorCode" : errorCodeName,
19241928 "ERROR" : js.number (status_codes.ERROR ),
1925- "currentError " : currentError ,
1929+ "errorStack " : errorStack ,
19261930 "result" : resultName,
19271931 "goto" : goto,
19281932 "handler" : handler,
@@ -2066,22 +2070,22 @@ class SyncStarRewriter extends AsyncRewriterBase {
20662070 js.VariableDeclarationList copyParameters =
20672071 js.VariableDeclarationList (declarations);
20682072
2069- js.Expression setCurrentError = js.js ("#currentError = #result" , {
2073+ js.Expression pushError = js.js ("#errorStack.push( #result) " , {
20702074 "result" : resultName,
2071- "currentError " : currentErrorName ,
2075+ "errorStack " : errorStackName ,
20722076 }).withSourceInformation (bodySourceInformation);
20732077 js.Expression setGoto = js.js ("#goto = #handler" , {
20742078 "goto" : goto,
20752079 "handler" : handler,
20762080 }).withSourceInformation (bodySourceInformation);
20772081 js.Statement checkErrorCode = js.js.statement ("""
20782082 if (#errorCode === #ERROR) {
2079- #setCurrentError ;
2083+ #pushError ;
20802084 #setGoto;
20812085 }""" , {
20822086 "errorCode" : errorCodeName,
20832087 "ERROR" : js.number (status_codes.ERROR ),
2084- "setCurrentError " : setCurrentError ,
2088+ "pushError " : pushError ,
20852089 "setGoto" : setGoto,
20862090 }).withSourceInformation (bodySourceInformation);
20872091 js.Expression innerInnerFunction = js.js ("""
@@ -2140,7 +2144,7 @@ class SyncStarRewriter extends AsyncRewriterBase {
21402144 // SYNC_STAR_UNCAUGHT_EXCEPTION status code.
21412145 final store = js.Assignment (
21422146 js.PropertyAccess (js.VariableUse (iteratorName), iteratorDatumProperty),
2143- currentError );
2147+ js. js ( '#.at(-1)' , [errorStack]) );
21442148 addStatement (js.Return (js.Binary (
21452149 ',' , store, js.number (status_codes.SYNC_STAR_UNCAUGHT_EXCEPTION )))
21462150 .withSourceInformation (sourceInformation));
@@ -2303,8 +2307,8 @@ class AsyncStarRewriter extends AsyncRewriterBase {
23032307 "goto" : goto,
23042308 "callPop" : callPop,
23052309 }).withSourceInformation (bodySourceInformation);
2306- js.Expression updateError = js.js ("#currentError = #result" , {
2307- "currentError " : currentError ,
2310+ js.Expression pushError = js.js ("#errorStack.push( #result) " , {
2311+ "errorStack " : errorStack ,
23082312 "result" : resultName,
23092313 }).withSourceInformation (bodySourceInformation);
23102314 js.Expression gotoError = js.js ("#goto = #handler" , {
@@ -2320,7 +2324,7 @@ class AsyncStarRewriter extends AsyncRewriterBase {
23202324 #gotoCancelled;
23212325 #break;
23222326 case #ERROR:
2323- #updateError ;
2327+ #pushError ;
23242328 #gotoError;
23252329 }""" , {
23262330 "errorCode" : errorCodeName,
@@ -2329,17 +2333,17 @@ class AsyncStarRewriter extends AsyncRewriterBase {
23292333 "gotoCancelled" : gotoCancelled,
23302334 "break" : breakStatement,
23312335 "ERROR" : js.number (status_codes.ERROR ),
2332- "updateError " : updateError ,
2336+ "pushError " : pushError ,
23332337 "gotoError" : gotoError,
23342338 }).withSourceInformation (bodySourceInformation);
23352339 js.Statement ifError = js.js.statement ("""
23362340 if (#errorCode === #ERROR) {
2337- #updateError ;
2341+ #pushError ;
23382342 #gotoError;
23392343 }""" , {
23402344 "errorCode" : errorCodeName,
23412345 "ERROR" : js.number (status_codes.ERROR ),
2342- "updateError " : updateError ,
2346+ "pushError " : pushError ,
23432347 "gotoError" : gotoError,
23442348 }).withSourceInformation (bodySourceInformation);
23452349 js.Statement ifHasYield = js.js.statement ("""
@@ -2399,10 +2403,10 @@ class AsyncStarRewriter extends AsyncRewriterBase {
23992403 hasHandlerLabels = true ;
24002404 beginLabel (rethrowLabel);
24012405 js.Expression asyncHelperCall =
2402- js.js ("#asyncHelper(#currentError , #errorCode, #controller)" , {
2406+ js.js ("#asyncHelper(#errorStack.at(-1) , #errorCode, #controller)" , {
24032407 "asyncHelper" : asyncStarHelper,
24042408 "errorCode" : js.number (status_codes.ERROR ),
2405- "currentError " : currentError ,
2409+ "errorStack " : errorStack ,
24062410 "controller" : controllerName
24072411 }).withSourceInformation (sourceInformation);
24082412 addStatement (
0 commit comments