@@ -524,25 +524,27 @@ private void generateStatement(Node node, int initialStackDepth) {
524524 updateLineNumber (node );
525525 var testOperands = new ArrayList <Operand >();
526526 var targets = new ArrayList <Node >();
527+ var lineNumbers = new ArrayList <Integer >();
527528 var shouldUseSimpleSwitch = true ;
528529
529530 // See comments in IRFactory.createSwitch() for description of SWITCH node
530- var valueOperand = getOperand (child , 0 , true );
531+ var valueOperand = getOperand (child , 0 , true , lineNumbers );
531532 for (Jump caseNode = (Jump ) child .getNext ();
532533 caseNode != null ;
533534 caseNode = (Jump ) caseNode .getNext ()) {
534535 if (caseNode .getType () != Token .CASE ) {
535536 throw badTree (caseNode );
536537 }
537538
538- updateLineNumber (caseNode );
539-
540539 Node test = caseNode .getFirstChild ();
541540 var lastInstruction = instructions .size ();
542- var testOperand = getOperand (test , 0 );
541+ var testOperand = getOperand (test , 0 , false , lineNumbers );
543542 var target = caseNode .target ;
544543 if (!shouldUseSimpleSwitch || !testOperand .isValidJumpTableKey ()) {
545544 shouldUseSimpleSwitch = false ;
545+
546+ updateLineNumbers (lineNumbers );
547+
546548 for (int i = 0 ; i < targets .size (); i ++) {
547549 addGoto (
548550 targets .get (i ),
@@ -552,6 +554,7 @@ private void generateStatement(Node node, int initialStackDepth) {
552554 }
553555 targets .clear ();
554556 testOperands .clear ();
557+ lineNumbers .clear ();
555558
556559 addGoto (target , new IfEqPop (valueOperand , testOperand ));
557560 } else {
@@ -561,6 +564,8 @@ private void generateStatement(Node node, int initialStackDepth) {
561564 }
562565
563566 if (shouldUseSimpleSwitch && !testOperands .isEmpty ()) {
567+ updateLineNumbers (lineNumbers );
568+
564569 for (var target : targets ) {
565570 addGoto (target );
566571 }
@@ -570,8 +575,8 @@ private void generateStatement(Node node, int initialStackDepth) {
570575
571576 var target = ((Jump ) next ).target ;
572577 addGoto (target , new SimpleSwitch (valueOperand , testOperands ));
573- } else {
574- addInstruction (new Cleanup ( valueOperand ) );
578+ } else if ( valueOperand instanceof PeekOperand ) {
579+ addInstruction (Pop . instance );
575580 }
576581 return ;
577582 }
@@ -1393,13 +1398,14 @@ private void visitExpression(Node node, int contextFlags) {
13931398 if (numberOfSpread > 0 ) {
13941399 var elements = new ArrayList <Operand >();
13951400 var spreadFlags = new ArrayList <Boolean >();
1401+ var lines = new ArrayList <Integer >();
13961402 while (child != null ) {
13971403 updateLineNumber (child );
13981404 if (child .getType () == Token .DOTDOTDOT ) {
1399- elements .add (getOperand (child .getFirstChild (), 0 ));
1405+ elements .add (getOperand (child .getFirstChild (), 0 , false , lines ));
14001406 spreadFlags .add (Boolean .TRUE );
14011407 } else {
1402- elements .add (getOperand (child , 0 ));
1408+ elements .add (getOperand (child , 0 , false , lines ));
14031409 spreadFlags .add (Boolean .FALSE );
14041410 }
14051411 child = child .getNext ();
@@ -1428,6 +1434,7 @@ private void visitExpression(Node node, int contextFlags) {
14281434 }
14291435
14301436 int nonSpreadCount = count - numberOfSpread ;
1437+ updateLineNumbers (lines );
14311438 addInstruction (
14321439 new ArrayLitWithSpread (
14331440 elements .toArray (Operand .EMPTY_ARRAY ),
@@ -1439,12 +1446,14 @@ private void visitExpression(Node node, int contextFlags) {
14391446 }
14401447
14411448 var elements = new ArrayList <Operand >();
1449+ var lines = new ArrayList <Integer >();
14421450 while (child != null ) {
1443- updateLineNumber (child );
1444- elements .add (getOperand (child , 0 ));
1451+ elements .add (getOperand (child , 0 , false , lines ));
14451452 child = child .getNext ();
14461453 }
14471454
1455+ updateLineNumbers (lines );
1456+ updateLineNumber (node );
14481457 addInstruction (
14491458 new ArrayLit (elements .toArray (Operand .EMPTY_ARRAY ), skipIndices ));
14501459 return ;
@@ -1465,15 +1474,13 @@ private void visitExpression(Node node, int contextFlags) {
14651474 && ((Node ) id ).getType ()
14661475 != Token .DOTDOTDOT );
14671476
1468- // dedup not supported in open-source
1469-
14701477 updateLineNumber (node );
14711478
14721479 if (hasSpread ) {
1473- emitObjectLiteralWithSpread (child , propertyIds , count , nonSpreadCount );
1480+ emitObjectLiteralWithSpread (node , child , propertyIds , count , nonSpreadCount );
14741481 } else {
14751482 emitObjectLiteralNoSpread (
1476- child , propertyIds , count , hasAnyComputedProperty );
1483+ node , child , propertyIds , count , hasAnyComputedProperty );
14771484 }
14781485 return ;
14791486 }
@@ -1578,11 +1585,14 @@ private void visitExpression(Node node, int contextFlags) {
15781585 {
15791586 int flags = node .getIntProp (Node .MEMBER_TYPE_PROP , 0 );
15801587 // generate possible target, possible namespace and member
1581- List <Operand > operands = new ArrayList <>();
1588+ var operands = new ArrayList <Operand >();
1589+ var lines = new ArrayList <Integer >();
15821590 do {
1583- operands .add (getOperand (child , 0 ));
1591+ operands .add (getOperand (child , 0 , false , lines ));
15841592 child = child .getNext ();
15851593 } while (child != null );
1594+ updateLineNumber (node );
1595+ updateLineNumbers (lines );
15861596 addInstruction (createRefInstruction (op , operands , flags ));
15871597 return ;
15881598 }
@@ -1866,10 +1876,11 @@ private static RuntimeException badTree(Node node) {
18661876 * index without touching the storage's sequential write pointer.
18671877 */
18681878 private void emitObjectLiteralNoSpread (
1869- Node child , Object [] propertyIds , int count , boolean hasAnyComputedProperty ) {
1879+ Node node , Node child , Object [] propertyIds , int count , boolean hasAnyComputedProperty ) {
18701880 Object [] keys = new Object [count ];
18711881 Operand [] literalValues = new Operand [count ];
18721882 boolean [] needsPass2 = new boolean [count ];
1883+ var lines = new ArrayList <Integer >();
18731884
18741885 // Pass 1: walk children once, capture static keys and literal-value operands.
18751886 // Literal operands are stack-neutral and emit no instructions, so their value slot can
@@ -1885,7 +1896,7 @@ private void emitObjectLiteralNoSpread(
18851896 boolean valueIsLiteral =
18861897 ct != Token .GET && ct != Token .SET && ct != Token .METHOD && isLiteralToken (ct );
18871898 if (valueIsLiteral ) {
1888- literalValues [i ] = getOperand (c , 0 );
1899+ literalValues [i ] = getOperand (c , 0 , false , lines );
18891900 }
18901901 // Need Pass 2 for: any computed key (must run the key expression), or any
18911902 // non-literal value (getter/setter/method/expression).
@@ -1895,6 +1906,8 @@ private void emitObjectLiteralNoSpread(
18951906 // If we do not have any computed properties, we can simply reuse the keys
18961907 // array as it won't be modified. If we do have computed properties, though,
18971908 // we'll fill some of the `null` holes, so we need to copy it.
1909+ updateLineNumber (node );
1910+ updateLineNumbers (lines );
18981911 addInstruction (NewObjectLiteral .create (keys , literalValues , hasAnyComputedProperty ));
18991912
19001913 // Pass 2: emit slots needing runtime work in source order with explicit slot indices.
@@ -1957,6 +1970,7 @@ private void emitObjectLiteralNoSpread(
19571970 addInstruction (LitSetAt .create (i , keyOp , valueOp , kind ));
19581971 }
19591972
1973+ updateLineNumber (node );
19601974 addInstruction (ObjectLit .ofPeekOperand );
19611975 }
19621976
@@ -1967,9 +1981,10 @@ private void emitObjectLiteralNoSpread(
19671981 * {@link LitPush} / {@link LitSpread} instructions fill the rest sequentially.
19681982 */
19691983 private void emitObjectLiteralWithSpread (
1970- Node child , Object [] propertyIds , int count , int nonSpreadCount ) {
1971- List <Operand > prefixValues = new ArrayList <>();
1972- List <Object > prefixKeys = new ArrayList <>();
1984+ Node node , Node child , Object [] propertyIds , int count , int nonSpreadCount ) {
1985+ var prefixValues = new ArrayList <Operand >();
1986+ var prefixKeys = new ArrayList <Object >();
1987+ var lines = new ArrayList <Integer >();
19731988 int prefixLen = 0 ;
19741989 Node c = child ;
19751990 while (prefixLen < count ) {
@@ -1984,12 +1999,14 @@ private void emitObjectLiteralWithSpread(
19841999 if (!isLiteralToken (ct )) {
19852000 break ;
19862001 }
1987- prefixValues .add (getOperand (c , 0 ));
2002+ prefixValues .add (getOperand (c , 0 , false , lines ));
19882003 prefixKeys .add (pid );
19892004 prefixLen ++;
19902005 c = c .getNext ();
19912006 }
19922007
2008+ updateLineNumber (child );
2009+ updateLineNumbers (lines );
19932010 addInstruction (
19942011 new NewObjectLiteralWithSpread (
19952012 prefixKeys .toArray (),
@@ -2041,12 +2058,13 @@ private void emitObjectLiteralWithSpread(
20412058 valueOp = PopOperand .instance ;
20422059 } else {
20432060 kind = 0 ;
2044- valueOp = getOperand (c , 0 );
2061+ valueOp = getOperand (c , 0 , false , lines );
20452062 }
20462063
20472064 addInstruction (new LitPush (keyOp , valueOp , kind ));
20482065 }
20492066
2067+ updateLineNumber (node );
20502068 addInstruction (ObjectLit .ofPeekOperand );
20512069 }
20522070
0 commit comments