119119import com .oracle .truffle .js .nodes .access .DeclareEvalVariableNode ;
120120import com .oracle .truffle .js .nodes .access .DeclareGlobalNode ;
121121import com .oracle .truffle .js .nodes .access .GetIteratorUnaryNode ;
122+ import com .oracle .truffle .js .nodes .access .GetMethodNode ;
122123import com .oracle .truffle .js .nodes .access .GlobalPropertyNode ;
124+ import com .oracle .truffle .js .nodes .access .IteratorToArrayNode ;
123125import com .oracle .truffle .js .nodes .access .JSConstantNode ;
124126import com .oracle .truffle .js .nodes .access .JSReadFrameSlotNode ;
125127import com .oracle .truffle .js .nodes .access .JSWriteFrameSlotNode ;
151153import com .oracle .truffle .js .nodes .control .SequenceNode ;
152154import com .oracle .truffle .js .nodes .control .StatementNode ;
153155import com .oracle .truffle .js .nodes .control .SuspendNode ;
156+ import com .oracle .truffle .js .nodes .extractor .InvokeCustomMatcherOrThrowNode ;
154157import com .oracle .truffle .js .nodes .function .AbstractFunctionArgumentsNode ;
155158import com .oracle .truffle .js .nodes .function .BlockScopeNode ;
156159import com .oracle .truffle .js .nodes .function .EvalNode ;
@@ -2846,7 +2849,12 @@ private JavaScriptNode transformAssignmentImpl(Expression assignmentExpression,
28462849 }
28472850 // fall through
28482851 case IDENT :
2849- assignedNode = transformAssignmentIdent ((IdentNode ) lhsExpression , assignedValue , binaryOp , returnOldValue , convertLHSToNumeric , initializationAssignment );
2852+ // todo-lw: call node :(
2853+ if (lhsExpression instanceof CallNode ) {
2854+ assignedNode = transformAssignmentExtractor ((CallNode ) lhsExpression , assignedValue , binaryOp , returnOldValue , convertLHSToNumeric , initializationAssignment );
2855+ } else {
2856+ assignedNode = transformAssignmentIdent ((IdentNode ) lhsExpression , assignedValue , binaryOp , returnOldValue , convertLHSToNumeric , initializationAssignment );
2857+ }
28502858 break ;
28512859 case LBRACKET :
28522860 // target[element]
@@ -2891,40 +2899,38 @@ private JavaScriptNode transformAssignmentIdent(IdentNode identNode, JavaScriptN
28912899 rhs = checkMutableBinding (rhs , scopeVar .getName ());
28922900 }
28932901 return scopeVar .createWriteNode (rhs );
2902+ } else if (isLogicalOp (binaryOp )) {
2903+ assert !convertLHSToNumeric && !returnOldValue && assignedValue != null ;
2904+ if (constAssignment ) {
2905+ rhs = checkMutableBinding (rhs , scopeVar .getName ());
2906+ }
2907+ JavaScriptNode readNode = tagExpression (scopeVar .createReadNode (), identNode );
2908+ JavaScriptNode writeNode = scopeVar .createWriteNode (rhs );
2909+ return factory .createBinary (context , binaryOp , readNode , writeNode );
28942910 } else {
2895- if (isLogicalOp (binaryOp )) {
2896- assert !convertLHSToNumeric && !returnOldValue && assignedValue != null ;
2897- if (constAssignment ) {
2898- rhs = checkMutableBinding (rhs , scopeVar .getName ());
2899- }
2900- JavaScriptNode readNode = tagExpression (scopeVar .createReadNode (), identNode );
2901- JavaScriptNode writeNode = scopeVar .createWriteNode (rhs );
2902- return factory .createBinary (context , binaryOp , readNode , writeNode );
2911+ // e.g.: lhs *= rhs => lhs = lhs * rhs
2912+ // If lhs is a side-effecting getter that deletes lhs, we must not throw a
2913+ // ReferenceError at the lhs assignment since the lhs reference is already resolved.
2914+ // We also need to ensure that HasBinding is idempotent or evaluated at most once.
2915+ Pair <Supplier <JavaScriptNode >, UnaryOperator <JavaScriptNode >> pair = scopeVar .createCompoundAssignNode ();
2916+ JavaScriptNode readNode = tagExpression (pair .getFirst ().get (), identNode );
2917+ if (convertLHSToNumeric ) {
2918+ readNode = factory .createToNumericOperand (readNode );
2919+ }
2920+ VarRef prevValueTemp = null ;
2921+ if (returnOldValue ) {
2922+ prevValueTemp = environment .createTempVar ();
2923+ readNode = prevValueTemp .createWriteNode (readNode );
2924+ }
2925+ JavaScriptNode binOpNode = tagExpression (factory .createBinary (context , binaryOp , readNode , rhs ), identNode );
2926+ if (constAssignment ) {
2927+ binOpNode = checkMutableBinding (binOpNode , scopeVar .getName ());
2928+ }
2929+ JavaScriptNode writeNode = pair .getSecond ().apply (binOpNode );
2930+ if (returnOldValue ) {
2931+ return factory .createDual (context , writeNode , prevValueTemp .createReadNode ());
29032932 } else {
2904- // e.g.: lhs *= rhs => lhs = lhs * rhs
2905- // If lhs is a side-effecting getter that deletes lhs, we must not throw a
2906- // ReferenceError at the lhs assignment since the lhs reference is already resolved.
2907- // We also need to ensure that HasBinding is idempotent or evaluated at most once.
2908- Pair <Supplier <JavaScriptNode >, UnaryOperator <JavaScriptNode >> pair = scopeVar .createCompoundAssignNode ();
2909- JavaScriptNode readNode = tagExpression (pair .getFirst ().get (), identNode );
2910- if (convertLHSToNumeric ) {
2911- readNode = factory .createToNumericOperand (readNode );
2912- }
2913- VarRef prevValueTemp = null ;
2914- if (returnOldValue ) {
2915- prevValueTemp = environment .createTempVar ();
2916- readNode = prevValueTemp .createWriteNode (readNode );
2917- }
2918- JavaScriptNode binOpNode = tagExpression (factory .createBinary (context , binaryOp , readNode , rhs ), identNode );
2919- if (constAssignment ) {
2920- binOpNode = checkMutableBinding (binOpNode , scopeVar .getName ());
2921- }
2922- JavaScriptNode writeNode = pair .getSecond ().apply (binOpNode );
2923- if (returnOldValue ) {
2924- return factory .createDual (context , writeNode , prevValueTemp .createReadNode ());
2925- } else {
2926- return writeNode ;
2927- }
2933+ return writeNode ;
29282934 }
29292935 }
29302936 }
@@ -3054,14 +3060,19 @@ private JavaScriptNode transformIndexAssignment(IndexNode indexNode, JavaScriptN
30543060 }
30553061
30563062 private JavaScriptNode transformDestructuringArrayAssignment (Expression lhsExpression , JavaScriptNode assignedValue , boolean initializationAssignment ) {
3063+ VarRef valueTempVar = environment .createTempVar ();
3064+ JavaScriptNode initValue = valueTempVar .createWriteNode (assignedValue );
3065+ JavaScriptNode getIterator = factory .createGetIterator (initValue );
30573066 LiteralNode .ArrayLiteralNode arrayLiteralNode = (LiteralNode .ArrayLiteralNode ) lhsExpression ;
30583067 List <Expression > elementExpressions = arrayLiteralNode .getElementExpressions ();
3068+
3069+ return this .transformDestructuringArrayAssignment (elementExpressions , getIterator , valueTempVar , initializationAssignment );
3070+ }
3071+
3072+ private JavaScriptNode transformDestructuringArrayAssignment (List <Expression > elementExpressions , JavaScriptNode getIterator , VarRef valueTempVar , boolean initializationAssignment ) {
30593073 JavaScriptNode [] initElements = javaScriptNodeArray (elementExpressions .size ());
30603074 VarRef iteratorTempVar = environment .createTempVar ();
3061- VarRef valueTempVar = environment .createTempVar ();
3062- JavaScriptNode initValue = valueTempVar .createWriteNode (assignedValue );
30633075 // By default, we use the hint to track the type of iterator.
3064- JavaScriptNode getIterator = factory .createGetIterator (initValue );
30653076 JavaScriptNode initIteratorTempVar = iteratorTempVar .createWriteNode (getIterator );
30663077
30673078 for (int i = 0 ; i < elementExpressions .size (); i ++) {
@@ -3083,7 +3094,8 @@ private JavaScriptNode transformDestructuringArrayAssignment(Expression lhsExpre
30833094 if (init != null ) {
30843095 rhsNode = factory .createNotUndefinedOr (rhsNode , transform (init ));
30853096 }
3086- if (lhsExpr != null && lhsExpr .isTokenType (TokenType .SPREAD_ARRAY )) {
3097+ // todo-lw: this change is kind of sus
3098+ if (lhsExpr != null && (lhsExpr .isTokenType (TokenType .SPREAD_ARRAY ) || lhsExpr .isTokenType (TokenType .SPREAD_ARGUMENT ))) {
30873099 rhsNode = factory .createIteratorToArray (context , iteratorTempVar .createReadNode ());
30883100 lhsExpr = ((UnaryNode ) lhsExpr ).getExpression ();
30893101 }
@@ -3097,6 +3109,25 @@ private JavaScriptNode transformDestructuringArrayAssignment(Expression lhsExpre
30973109 return factory .createExprBlock (initIteratorTempVar , closeIfNotDone , valueTempVar .createReadNode ());
30983110 }
30993111
3112+ private JavaScriptNode transformAssignmentExtractor (CallNode fakeCallNode , JavaScriptNode assignedValue , BinaryOperation binaryOp , boolean returnOldValue , boolean convertToNumeric , boolean initializationAssignment ) {
3113+ // todo-lw: call node :(
3114+
3115+ final var functionExpr = fakeCallNode .getFunction ();
3116+ final var function = transform (functionExpr );
3117+
3118+ var receiver = function ;
3119+ if (functionExpr instanceof AccessNode ) {
3120+ final AccessNode accessNode = (AccessNode ) functionExpr ;
3121+ receiver = transform (accessNode .getBase ());
3122+ }
3123+
3124+ final var invokeCustomMatcherOrThrowNode = InvokeCustomMatcherOrThrowNode .create (context , function , assignedValue , receiver );
3125+
3126+ final var args = fakeCallNode .getArgs ();
3127+ VarRef valueTempVar = environment .createTempVar ();
3128+ return this .transformDestructuringArrayAssignment (args , invokeCustomMatcherOrThrowNode , valueTempVar , initializationAssignment );
3129+ }
3130+
31003131 private JavaScriptNode transformDestructuringObjectAssignment (Expression lhsExpression , JavaScriptNode assignedValue , boolean initializationAssignment ) {
31013132 ObjectNode objectLiteralNode = (ObjectNode ) lhsExpression ;
31023133 List <PropertyNode > propertyExpressions = objectLiteralNode .getElements ();
0 commit comments