@@ -160,32 +160,54 @@ class QAST::OperationsJS {
160
160
161
161
add_simple_op(' setcontspec' , $ T_OBJ , [$ T_OBJ , $ T_STR , $ T_OBJ ], : side_effects, : decont(0 ));
162
162
163
+ sub do_assign ($ comp , $ node , $ op_name , $ value_kind ) {
164
+ my $ cont := $ comp . as_js($ node [0 ], : want($ T_OBJ ));
165
+ my $ value := $ comp . as_js($ node [1 ], : want($ value_kind ));
166
+
167
+ my $ deconted := $ value_kind == $ T_OBJ ?? $ comp . await(" { $ value . expr} .\$\$decont($ * CTX )" ) !! $ value . expr;
168
+ Chunk. new ($ T_OBJ , $ cont . expr, [
169
+ $ cont ,
170
+ $ value ,
171
+ $ comp . await ~ $ cont . expr ~ ' .$$' ~ $ op_name ~ ' (' ~ $ * CTX ~ ' , ' ~ $ deconted ~ " );\n "
172
+ ]);
173
+ }
174
+
163
175
sub add_assign_op ($ op_name , $ value_kind ) {
164
176
# TODO If possible lower it to a bind instead just like on the moarvm backend
165
177
# POTENTIAL OPTIMALIZATION
166
178
167
179
add_op($ op_name , sub ($ comp , $ node , : $ want ) {
168
- my $ cont := $ comp . as_js($ node [0 ], : want($ T_OBJ ));
169
- my $ value := $ comp . as_js($ node [1 ], : want($ value_kind ));
170
-
171
- my $ deconted := $ value_kind == $ T_OBJ ?? $ comp . await(" { $ value . expr} .\$\$decont($ * CTX )" ) !! $ value . expr;
172
- Chunk. new ($ T_OBJ , $ cont . expr, [
173
- $ cont ,
174
- $ value ,
175
- $ comp . await ~ $ cont . expr ~ ' .$$' ~ $ op_name ~ ' (' ~ $ * CTX ~ ' , ' ~ $ deconted ~ " );\n "
176
- ]);
180
+ do_assign($ comp , $ node , $ op_name , $ value_kind );
181
+ });
182
+ }
183
+
184
+ sub add_native_assign_op ($ op_name , $ value_kind ) {
185
+ add_op($ op_name , sub ($ comp , $ node , : $ want ) {
186
+ unless + $ node . list == 2 {
187
+ nqp ::die(" The '$ op_name ' op needs 2 arguments, got " ~ + $ node . list);
188
+ }
189
+ if $ * BLOCK . try_get_bind_scope($ node [0 ]) -> $ bind_scope {
190
+ # Can lower it to a bind instead.
191
+ my $ target := nqp :: clone ($ node [0 ]);
192
+ $ target . scope($ bind_scope );
193
+ $ comp . as_js(QAST ::Op. new (: op(' bind' ), $ target , $ node [1 ]), : $ want );
194
+ }
195
+ else {
196
+ do_assign($ comp , $ node , $ op_name , $ value_kind );
197
+ }
177
198
});
178
199
}
179
200
180
201
add_assign_op(' assignunchecked' , $ T_OBJ );
181
202
add_assign_op(' assign' , $ T_OBJ );
182
203
183
- add_assign_op(' assign_i' , $ T_INT );
184
- add_assign_op(' assign_n' , $ T_NUM );
185
- add_assign_op(' assign_s' , $ T_STR );
204
+ add_native_assign_op(' assign_i' , $ T_INT );
205
+ add_native_assign_op(' assign_n' , $ T_NUM );
206
+ add_native_assign_op(' assign_s' , $ T_STR );
207
+
208
+ add_native_assign_op(' assign_i64' , $ T_INT64 );
209
+ add_native_assign_op(' assign_u64' , $ T_UINT64 );
186
210
187
- add_assign_op(' assign_i64' , $ T_INT64 );
188
- add_assign_op(' assign_u64' , $ T_UINT64 );
189
211
190
212
add_simple_op(' decont' , $ T_OBJ , [$ T_OBJ ], : method_call, : ctx, : await);
191
213
0 commit comments