@@ -164,8 +164,10 @@ class DynamicDispatcher {
164
164
w.Instructions b = function.body;
165
165
w.Local addLocal (w.ValueType type) => function.addLocal (type);
166
166
167
- Iterable <SelectorInfo >? selectors =
168
- translator.dispatchTable.selectorsForDynamicNode (node);
167
+ // We make a copy of the list of selectors to avoid concurrent
168
+ // modification.
169
+ List <SelectorInfo > selectors =
170
+ translator.dispatchTable.selectorsForDynamicNode (node)? .toList () ?? [];
169
171
170
172
// Test the receiver's class ID against every class that implements a given
171
173
// selector. If there is a match then invoke the selector, otherwise calls
@@ -179,47 +181,43 @@ class DynamicDispatcher {
179
181
b.local_get (receiverVar);
180
182
b.struct_get (translator.topInfo.struct, FieldIndex .classId);
181
183
b.local_set (cidLocal);
182
- if (selectors != null ) {
183
- // We make a copy of the list of selectors to avoid concurrent
184
- // modification.
185
- for (SelectorInfo selector in selectors.toList ()) {
186
- if (! preSelector (selector)) {
187
- continue ;
188
- }
189
- translator.functions.activateSelector (selector);
190
- for (int classID in selector.classIds) {
191
- b.local_get (cidLocal);
192
- b.i32_const (classID);
193
- b.i32_eq ();
194
- b.if_ ();
195
-
196
- // TODO(joshualitt): We should be able to make this a direct
197
- // invocation. However, there appear to be corner cases today where we
198
- // still need to do the actual invocation as an indirect call, for
199
- // example if the procedure we are invoking is abstract.
200
- b.comment ("Dynamic invocation of '${selector .name }'" );
201
- b.local_get (receiverVar);
202
- translator.convertType (function, translator.topInfo.nullableType,
203
- selector.signature.inputs[0 ]);
204
-
205
- pushArguments (selector);
206
- b.local_get (cidLocal);
207
- int offset = selector.offset! ;
208
- if (offset != 0 ) {
209
- b.i32_const (offset);
210
- b.i32_add ();
211
- }
212
- b.call_indirect (selector.signature);
213
-
214
- w.ValueType result =
215
- translator.outputOrVoid (selector.signature.outputs);
216
- translator.convertType (
217
- function, result, translator.topInfo.nullableType);
218
- onCallSuccess ();
219
- b.end (); // end if
184
+ for (SelectorInfo selector in selectors) {
185
+ if (! preSelector (selector)) {
186
+ continue ;
187
+ }
188
+ translator.functions.activateSelector (selector);
189
+ for (int classID in selector.classIds) {
190
+ b.local_get (cidLocal);
191
+ b.i32_const (classID);
192
+ b.i32_eq ();
193
+ b.if_ ();
194
+
195
+ // TODO(joshualitt): We should be able to make this a direct
196
+ // invocation. However, there appear to be corner cases today where we
197
+ // still need to do the actual invocation as an indirect call, for
198
+ // example if the procedure we are invoking is abstract.
199
+ b.comment ("Dynamic invocation of '${selector .name }'" );
200
+ b.local_get (receiverVar);
201
+ translator.convertType (function, translator.topInfo.nullableType,
202
+ selector.signature.inputs[0 ]);
203
+
204
+ pushArguments (selector);
205
+ b.local_get (cidLocal);
206
+ int offset = selector.offset! ;
207
+ if (offset != 0 ) {
208
+ b.i32_const (offset);
209
+ b.i32_add ();
220
210
}
221
- postSelector ();
211
+ b.call_indirect (selector.signature);
212
+
213
+ w.ValueType result =
214
+ translator.outputOrVoid (selector.signature.outputs);
215
+ translator.convertType (
216
+ function, result, translator.topInfo.nullableType);
217
+ onCallSuccess ();
218
+ b.end (); // end if
222
219
}
220
+ postSelector ();
223
221
}
224
222
225
223
// Handle the case where no test succeeded.
0 commit comments