OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.ir_builder_task; | 5 library dart2js.ir_builder_task; |
6 | 6 |
7 import '../closure.dart' as closure; | 7 import '../closure.dart' as closure; |
8 import '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/names.dart' show | 9 import '../common/names.dart' show Identifiers, Names, Selectors; |
10 Identifiers, | 10 import '../common/tasks.dart' show CompilerTask; |
11 Names, | 11 import '../compiler.dart' show Compiler; |
12 Selectors; | |
13 import '../common/tasks.dart' show | |
14 CompilerTask; | |
15 import '../compiler.dart' show | |
16 Compiler; | |
17 import '../constants/expressions.dart'; | 12 import '../constants/expressions.dart'; |
18 import '../dart_types.dart'; | 13 import '../dart_types.dart'; |
19 import '../elements/elements.dart'; | 14 import '../elements/elements.dart'; |
20 import '../elements/modelx.dart' show | 15 import '../elements/modelx.dart' |
21 SynthesizedConstructorElementX, | 16 show |
22 ConstructorBodyElementX, | 17 SynthesizedConstructorElementX, |
23 FunctionSignatureX; | 18 ConstructorBodyElementX, |
| 19 FunctionSignatureX; |
24 import '../io/source_information.dart'; | 20 import '../io/source_information.dart'; |
25 import '../js_backend/backend_helpers.dart' show | 21 import '../js_backend/backend_helpers.dart' show BackendHelpers; |
26 BackendHelpers; | 22 import '../js_backend/js_backend.dart' |
27 import '../js_backend/js_backend.dart' show | 23 show JavaScriptBackend, SyntheticConstantKind; |
28 JavaScriptBackend, | 24 import '../resolution/tree_elements.dart' show TreeElements; |
29 SyntheticConstantKind; | |
30 import '../resolution/tree_elements.dart' show | |
31 TreeElements; | |
32 import '../resolution/semantic_visitor.dart'; | 25 import '../resolution/semantic_visitor.dart'; |
33 import '../resolution/operators.dart' as op; | 26 import '../resolution/operators.dart' as op; |
34 import '../tree/tree.dart' as ast; | 27 import '../tree/tree.dart' as ast; |
35 import '../types/types.dart' show | 28 import '../types/types.dart' show TypeMask; |
36 TypeMask; | 29 import '../universe/call_structure.dart' show CallStructure; |
37 import '../universe/call_structure.dart' show | 30 import '../universe/selector.dart' show Selector; |
38 CallStructure; | 31 import '../constants/values.dart' show ConstantValue; |
39 import '../universe/selector.dart' show | |
40 Selector; | |
41 import '../constants/values.dart' show | |
42 ConstantValue; | |
43 import 'cps_ir_nodes.dart' as ir; | 32 import 'cps_ir_nodes.dart' as ir; |
44 import 'cps_ir_builder.dart'; | 33 import 'cps_ir_builder.dart'; |
45 import '../native/native.dart' show | 34 import '../native/native.dart' show NativeBehavior, HasCapturedPlaceholders; |
46 NativeBehavior, | |
47 HasCapturedPlaceholders; | |
48 | 35 |
49 // TODO(karlklose): remove. | 36 // TODO(karlklose): remove. |
50 import '../js/js.dart' as js show js, Template, Expression, Name; | 37 import '../js/js.dart' as js show js, Template, Expression, Name; |
51 import '../ssa/types.dart' show TypeMaskFactory; | 38 import '../ssa/types.dart' show TypeMaskFactory; |
52 import '../util/util.dart'; | 39 import '../util/util.dart'; |
53 | 40 |
54 import 'package:js_runtime/shared/embedded_names.dart' | 41 import 'package:js_runtime/shared/embedded_names.dart' |
55 show JsBuiltin, JsGetName; | 42 show JsBuiltin, JsGetName; |
56 import '../constants/values.dart'; | 43 import '../constants/values.dart'; |
57 import 'type_mask_system.dart' show | 44 import 'type_mask_system.dart' show TypeMaskSystem; |
58 TypeMaskSystem; | |
59 | 45 |
60 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); | 46 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); |
61 | 47 |
62 class ExplicitReceiverParameter implements Local { | 48 class ExplicitReceiverParameter implements Local { |
63 final ExecutableElement executableContext; | 49 final ExecutableElement executableContext; |
64 | 50 |
65 ExplicitReceiverParameter(this.executableContext); | 51 ExplicitReceiverParameter(this.executableContext); |
66 | 52 |
67 String get name => 'receiver'; | 53 String get name => 'receiver'; |
68 String toString() => 'ExplicitReceiverParameter($executableContext)'; | 54 String toString() => 'ExplicitReceiverParameter($executableContext)'; |
(...skipping 12 matching lines...) Expand all Loading... |
81 /// If not null, this function will be called with for each | 67 /// If not null, this function will be called with for each |
82 /// [ir.FunctionDefinition] node that has been built. | 68 /// [ir.FunctionDefinition] node that has been built. |
83 IrBuilderCallback builderCallback; | 69 IrBuilderCallback builderCallback; |
84 | 70 |
85 IrBuilderTask(Compiler compiler, this.sourceInformationStrategy, | 71 IrBuilderTask(Compiler compiler, this.sourceInformationStrategy, |
86 [this.builderCallback]) | 72 [this.builderCallback]) |
87 : super(compiler); | 73 : super(compiler); |
88 | 74 |
89 String get name => 'CPS builder'; | 75 String get name => 'CPS builder'; |
90 | 76 |
91 ir.FunctionDefinition buildNode(AstElement element, | 77 ir.FunctionDefinition buildNode( |
92 TypeMaskSystem typeMaskSystem) { | 78 AstElement element, TypeMaskSystem typeMaskSystem) { |
93 return measure(() { | 79 return measure(() { |
94 bailoutMessage = null; | 80 bailoutMessage = null; |
95 | 81 |
96 TreeElements elementsMapping = element.resolvedAst.elements; | 82 TreeElements elementsMapping = element.resolvedAst.elements; |
97 element = element.implementation; | 83 element = element.implementation; |
98 return reporter.withCurrentElement(element, () { | 84 return reporter.withCurrentElement(element, () { |
99 SourceInformationBuilder sourceInformationBuilder = | 85 SourceInformationBuilder sourceInformationBuilder = |
100 sourceInformationStrategy.createBuilderForContext(element); | 86 sourceInformationStrategy.createBuilderForContext(element); |
101 | 87 |
102 IrBuilderVisitor builder = | 88 IrBuilderVisitor builder = new IrBuilderVisitor(elementsMapping, |
103 new IrBuilderVisitor( | 89 compiler, sourceInformationBuilder, typeMaskSystem); |
104 elementsMapping, compiler, sourceInformationBuilder, | |
105 typeMaskSystem); | |
106 ir.FunctionDefinition irNode = builder.buildExecutable(element); | 90 ir.FunctionDefinition irNode = builder.buildExecutable(element); |
107 if (irNode == null) { | 91 if (irNode == null) { |
108 bailoutMessage = builder.bailoutMessage; | 92 bailoutMessage = builder.bailoutMessage; |
109 } else if (builderCallback != null) { | 93 } else if (builderCallback != null) { |
110 builderCallback(element, irNode); | 94 builderCallback(element, irNode); |
111 } | 95 } |
112 return irNode; | 96 return irNode; |
113 }); | 97 }); |
114 }); | 98 }); |
115 } | 99 } |
116 } | 100 } |
117 | 101 |
118 /// Translates the frontend AST of a method to its CPS IR. | 102 /// Translates the frontend AST of a method to its CPS IR. |
119 /// | 103 /// |
120 /// The visitor has an [IrBuilder] which contains an IR fragment to build upon | 104 /// The visitor has an [IrBuilder] which contains an IR fragment to build upon |
121 /// and the current reaching definition of local variables. | 105 /// and the current reaching definition of local variables. |
122 /// | 106 /// |
123 /// Visiting a statement or expression extends the IR builder's fragment. | 107 /// Visiting a statement or expression extends the IR builder's fragment. |
124 /// For expressions, the primitive holding the resulting value is returned. | 108 /// For expressions, the primitive holding the resulting value is returned. |
125 /// For statements, `null` is returned. | 109 /// For statements, `null` is returned. |
126 // TODO(johnniwinther): Implement [SemanticDeclVisitor]. | 110 // TODO(johnniwinther): Implement [SemanticDeclVisitor]. |
127 class IrBuilderVisitor extends ast.Visitor<ir.Primitive> | 111 class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
128 with IrBuilderMixin<ast.Node>, | 112 with |
129 SemanticSendResolvedMixin<ir.Primitive, dynamic>, | 113 IrBuilderMixin<ast.Node>, |
130 ErrorBulkMixin<ir.Primitive, dynamic>, | 114 SemanticSendResolvedMixin<ir.Primitive, dynamic>, |
131 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, | 115 ErrorBulkMixin<ir.Primitive, dynamic>, |
132 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, | 116 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, |
133 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, | 117 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, |
134 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, | 118 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, |
135 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, | 119 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
136 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, | 120 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, |
137 BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, | 121 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, |
138 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>, | 122 BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, |
139 BaseImplementationOfSuperIndexSetIfNullMixin<ir.Primitive, dynamic> | 123 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>, |
| 124 BaseImplementationOfSuperIndexSetIfNullMixin<ir.Primitive, dynamic> |
140 implements SemanticSendVisitor<ir.Primitive, dynamic> { | 125 implements SemanticSendVisitor<ir.Primitive, dynamic> { |
141 final TreeElements elements; | 126 final TreeElements elements; |
142 final Compiler compiler; | 127 final Compiler compiler; |
143 final SourceInformationBuilder sourceInformationBuilder; | 128 final SourceInformationBuilder sourceInformationBuilder; |
144 final TypeMaskSystem typeMaskSystem; | 129 final TypeMaskSystem typeMaskSystem; |
145 | 130 |
146 /// A map from try statements in the source to analysis information about | 131 /// A map from try statements in the source to analysis information about |
147 /// them. | 132 /// them. |
148 /// | 133 /// |
149 /// The analysis information includes the set of variables that must be | 134 /// The analysis information includes the set of variables that must be |
(...skipping 13 matching lines...) Expand all Loading... |
163 // surrounding context, the free occurrences can be captured or become free | 148 // surrounding context, the free occurrences can be captured or become free |
164 // occurrences in the next outer delimited subexpression. | 149 // occurrences in the next outer delimited subexpression. |
165 // | 150 // |
166 // Each nested visitor maintains a list that maps indexes of variables | 151 // Each nested visitor maintains a list that maps indexes of variables |
167 // assigned in the delimited subexpression to their reaching definition --- | 152 // assigned in the delimited subexpression to their reaching definition --- |
168 // that is, the definition in effect at the hole in 'current'. These are | 153 // that is, the definition in effect at the hole in 'current'. These are |
169 // used to determine if a join-point continuation needs to be passed | 154 // used to determine if a join-point continuation needs to be passed |
170 // arguments, and what the arguments are. | 155 // arguments, and what the arguments are. |
171 | 156 |
172 /// Construct a top-level visitor. | 157 /// Construct a top-level visitor. |
173 IrBuilderVisitor(this.elements, | 158 IrBuilderVisitor(this.elements, this.compiler, this.sourceInformationBuilder, |
174 this.compiler, | 159 this.typeMaskSystem); |
175 this.sourceInformationBuilder, | |
176 this.typeMaskSystem); | |
177 | 160 |
178 JavaScriptBackend get backend => compiler.backend; | 161 JavaScriptBackend get backend => compiler.backend; |
179 BackendHelpers get helpers => backend.helpers; | 162 BackendHelpers get helpers => backend.helpers; |
180 DiagnosticReporter get reporter => compiler.reporter; | 163 DiagnosticReporter get reporter => compiler.reporter; |
181 | 164 |
182 String bailoutMessage = null; | 165 String bailoutMessage = null; |
183 | 166 |
184 ir.Primitive visit(ast.Node node) => node.accept(this); | 167 ir.Primitive visit(ast.Node node) => node.accept(this); |
185 | 168 |
186 @override | 169 @override |
(...skipping 15 matching lines...) Expand all Loading... |
202 ClosureScope getClosureScopeForNode(ast.Node node) { | 185 ClosureScope getClosureScopeForNode(ast.Node node) { |
203 // We translate a ClosureScope from closure.dart into IR builder's variant | 186 // We translate a ClosureScope from closure.dart into IR builder's variant |
204 // because the IR builder should not depend on the synthetic elements | 187 // because the IR builder should not depend on the synthetic elements |
205 // created in closure.dart. | 188 // created in closure.dart. |
206 return new ClosureScope(closureClassMap.capturingScopes[node]); | 189 return new ClosureScope(closureClassMap.capturingScopes[node]); |
207 } | 190 } |
208 | 191 |
209 /// Returns the [ClosureScope] for any function, possibly different from the | 192 /// Returns the [ClosureScope] for any function, possibly different from the |
210 /// one currently being built. | 193 /// one currently being built. |
211 ClosureScope getClosureScopeForFunction(FunctionElement function) { | 194 ClosureScope getClosureScopeForFunction(FunctionElement function) { |
212 closure.ClosureClassMap map = | 195 closure.ClosureClassMap map = compiler.closureToClassMapper |
213 compiler.closureToClassMapper.computeClosureToClassMapping( | 196 .computeClosureToClassMapping(function, function.node, elements); |
214 function, | |
215 function.node, | |
216 elements); | |
217 return new ClosureScope(map.capturingScopes[function.node]); | 197 return new ClosureScope(map.capturingScopes[function.node]); |
218 } | 198 } |
219 | 199 |
220 /// If the current function is a nested function with free variables (or a | 200 /// If the current function is a nested function with free variables (or a |
221 /// captured reference to `this`), returns a [ClosureEnvironment] | 201 /// captured reference to `this`), returns a [ClosureEnvironment] |
222 /// indicating how to access these. | 202 /// indicating how to access these. |
223 ClosureEnvironment getClosureEnvironment() { | 203 ClosureEnvironment getClosureEnvironment() { |
224 return new ClosureEnvironment(closureClassMap); | 204 return new ClosureEnvironment(closureClassMap); |
225 } | 205 } |
226 | 206 |
227 IrBuilder getBuilderFor(Element element) { | 207 IrBuilder getBuilderFor(Element element) { |
228 return new IrBuilder( | 208 return new IrBuilder( |
229 new GlobalProgramInformation(compiler), | 209 new GlobalProgramInformation(compiler), backend.constants, element); |
230 backend.constants, | |
231 element); | |
232 } | 210 } |
233 | 211 |
234 /// Builds the [ir.FunctionDefinition] for an executable element. In case the | 212 /// Builds the [ir.FunctionDefinition] for an executable element. In case the |
235 /// function uses features that cannot be expressed in the IR, this element | 213 /// function uses features that cannot be expressed in the IR, this element |
236 /// returns `null`. | 214 /// returns `null`. |
237 ir.FunctionDefinition buildExecutable(ExecutableElement element) { | 215 ir.FunctionDefinition buildExecutable(ExecutableElement element) { |
238 return nullIfGiveup(() { | 216 return nullIfGiveup(() { |
239 ir.FunctionDefinition root; | 217 ir.FunctionDefinition root; |
240 switch (element.kind) { | 218 switch (element.kind) { |
241 case ElementKind.GENERATIVE_CONSTRUCTOR: | 219 case ElementKind.GENERATIVE_CONSTRUCTOR: |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 } | 268 } |
291 } | 269 } |
292 | 270 |
293 /// Loads all type variables for [type] and all of its super classes into | 271 /// Loads all type variables for [type] and all of its super classes into |
294 /// the environment. All type variables mentioned in [type] must already | 272 /// the environment. All type variables mentioned in [type] must already |
295 /// be in the environment. | 273 /// be in the environment. |
296 void loadTypeVariablesForType(InterfaceType type) { | 274 void loadTypeVariablesForType(InterfaceType type) { |
297 ClassElement clazz = type.element; | 275 ClassElement clazz = type.element; |
298 assert(clazz.typeVariables.length == type.typeArguments.length); | 276 assert(clazz.typeVariables.length == type.typeArguments.length); |
299 for (int i = 0; i < clazz.typeVariables.length; ++i) { | 277 for (int i = 0; i < clazz.typeVariables.length; ++i) { |
300 irBuilder.declareTypeVariable(clazz.typeVariables[i], | 278 irBuilder.declareTypeVariable( |
301 type.typeArguments[i]); | 279 clazz.typeVariables[i], type.typeArguments[i]); |
302 } | 280 } |
303 loadTypeVariablesForSuperClasses(clazz); | 281 loadTypeVariablesForSuperClasses(clazz); |
304 } | 282 } |
305 | 283 |
306 /// Returns the constructor body associated with the given constructor or | 284 /// Returns the constructor body associated with the given constructor or |
307 /// creates a new constructor body, if none can be found. | 285 /// creates a new constructor body, if none can be found. |
308 /// | 286 /// |
309 /// Returns `null` if the constructor does not have a body. | 287 /// Returns `null` if the constructor does not have a body. |
310 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { | 288 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { |
311 // TODO(asgerf): This is largely inherited from the SSA builder. | 289 // TODO(asgerf): This is largely inherited from the SSA builder. |
(...skipping 19 matching lines...) Expand all Loading... |
331 } | 309 } |
332 }); | 310 }); |
333 if (bodyElement == null) { | 311 if (bodyElement == null) { |
334 bodyElement = new ConstructorBodyElementX(constructor); | 312 bodyElement = new ConstructorBodyElementX(constructor); |
335 classElement.addBackendMember(bodyElement); | 313 classElement.addBackendMember(bodyElement); |
336 | 314 |
337 if (constructor.isPatch) { | 315 if (constructor.isPatch) { |
338 // Create origin body element for patched constructors. | 316 // Create origin body element for patched constructors. |
339 ConstructorBodyElementX patch = bodyElement; | 317 ConstructorBodyElementX patch = bodyElement; |
340 ConstructorBodyElementX origin = | 318 ConstructorBodyElementX origin = |
341 new ConstructorBodyElementX(constructor.origin); | 319 new ConstructorBodyElementX(constructor.origin); |
342 origin.applyPatch(patch); | 320 origin.applyPatch(patch); |
343 classElement.origin.addBackendMember(bodyElement.origin); | 321 classElement.origin.addBackendMember(bodyElement.origin); |
344 } | 322 } |
345 } | 323 } |
346 assert(bodyElement.isGenerativeConstructorBody); | 324 assert(bodyElement.isGenerativeConstructorBody); |
347 return bodyElement; | 325 return bodyElement; |
348 } | 326 } |
349 | 327 |
350 /// The list of parameters to send from the generative constructor | 328 /// The list of parameters to send from the generative constructor |
351 /// to the generative constructor body. | 329 /// to the generative constructor body. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 final bool requiresTypeInformation = | 373 final bool requiresTypeInformation = |
396 builder.program.requiresRuntimeTypesFor(classElement); | 374 builder.program.requiresRuntimeTypesFor(classElement); |
397 | 375 |
398 return withBuilder(builder, () { | 376 return withBuilder(builder, () { |
399 // Setup parameters and create a box if anything is captured. | 377 // Setup parameters and create a box if anything is captured. |
400 List<Local> parameters = <Local>[]; | 378 List<Local> parameters = <Local>[]; |
401 if (constructor.isGenerativeConstructor && | 379 if (constructor.isGenerativeConstructor && |
402 backend.isNativeOrExtendsNative(classElement)) { | 380 backend.isNativeOrExtendsNative(classElement)) { |
403 parameters.add(new ExplicitReceiverParameter(constructor)); | 381 parameters.add(new ExplicitReceiverParameter(constructor)); |
404 } | 382 } |
405 constructor.functionSignature.orderedForEachParameter( | 383 constructor.functionSignature |
406 (ParameterElement p) => parameters.add(p)); | 384 .orderedForEachParameter((ParameterElement p) => parameters.add(p)); |
407 | 385 |
408 int firstTypeArgumentParameterIndex; | 386 int firstTypeArgumentParameterIndex; |
409 | 387 |
410 // If instances of the class may need runtime type information, we add a | 388 // If instances of the class may need runtime type information, we add a |
411 // synthetic parameter for each type parameter. | 389 // synthetic parameter for each type parameter. |
412 if (requiresTypeInformation) { | 390 if (requiresTypeInformation) { |
413 firstTypeArgumentParameterIndex = parameters.length; | 391 firstTypeArgumentParameterIndex = parameters.length; |
414 classElement.typeVariables.forEach((TypeVariableType variable) { | 392 classElement.typeVariables.forEach((TypeVariableType variable) { |
415 parameters.add(new closure.TypeVariableLocal(variable, constructor)); | 393 parameters.add(new closure.TypeVariableLocal(variable, constructor)); |
416 }); | 394 }); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 instance.type = | 457 instance.type = |
480 new TypeMask.exact(classElement, typeMaskSystem.classWorld); | 458 new TypeMask.exact(classElement, typeMaskSystem.classWorld); |
481 irBuilder.addPrimitive(new ir.ReceiverCheck.nullCheck( | 459 irBuilder.addPrimitive(new ir.ReceiverCheck.nullCheck( |
482 instance, Selectors.toString_, null)); | 460 instance, Selectors.toString_, null)); |
483 for (int i = 0; i < fields.length; i++) { | 461 for (int i = 0; i < fields.length; i++) { |
484 irBuilder.addPrimitive( | 462 irBuilder.addPrimitive( |
485 new ir.SetField(instance, fields[i], instanceArguments[i])); | 463 new ir.SetField(instance, fields[i], instanceArguments[i])); |
486 } | 464 } |
487 } else { | 465 } else { |
488 instance = new ir.CreateInstance( | 466 instance = new ir.CreateInstance( |
489 classElement, | 467 classElement, |
490 instanceArguments, | 468 instanceArguments, |
491 typeInformation, | 469 typeInformation, |
492 constructor.hasNode | 470 constructor.hasNode |
493 ? sourceInformationBuilder.buildCreate(constructor.node) | 471 ? sourceInformationBuilder.buildCreate(constructor.node) |
494 // TODO(johnniwinther): Provide source information for creation | 472 // TODO(johnniwinther): Provide source information for creation |
495 // through synthetic constructors. | 473 // through synthetic constructors. |
496 : null); | 474 : null); |
497 irBuilder.add(new ir.LetPrim(instance)); | 475 irBuilder.add(new ir.LetPrim(instance)); |
498 } | 476 } |
499 | 477 |
500 // --- Call constructor bodies --- | 478 // --- Call constructor bodies --- |
501 for (ConstructorElement target in constructorList) { | 479 for (ConstructorElement target in constructorList) { |
502 ConstructorBodyElement bodyElement = getConstructorBody(target); | 480 ConstructorBodyElement bodyElement = getConstructorBody(target); |
503 if (bodyElement == null) continue; // Skip if constructor has no body. | 481 if (bodyElement == null) continue; // Skip if constructor has no body. |
504 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; | 482 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; |
505 for (Local param in getConstructorBodyParameters(bodyElement)) { | 483 for (Local param in getConstructorBodyParameters(bodyElement)) { |
506 bodyArguments.add(irBuilder.environment.lookup(param)); | 484 bodyArguments.add(irBuilder.environment.lookup(param)); |
507 } | 485 } |
508 Selector selector = new Selector.call(target.memberName, | 486 Selector selector = new Selector.call( |
509 new CallStructure(bodyArguments.length)); | 487 target.memberName, new CallStructure(bodyArguments.length)); |
510 irBuilder.addPrimitive(new ir.InvokeMethodDirectly( | 488 irBuilder.addPrimitive(new ir.InvokeMethodDirectly( |
511 instance, bodyElement, selector, bodyArguments, null)); | 489 instance, bodyElement, selector, bodyArguments, null)); |
512 } | 490 } |
513 | 491 |
514 // --- step 4: return the created object ---- | 492 // --- step 4: return the created object ---- |
515 irBuilder.buildReturn( | 493 irBuilder.buildReturn( |
516 value: instance, | 494 value: instance, |
517 sourceInformation: | 495 sourceInformation: |
518 sourceInformationBuilder.buildImplicitReturn(constructor)); | 496 sourceInformationBuilder.buildImplicitReturn(constructor)); |
519 | 497 |
520 return irBuilder.makeFunctionDefinition( | 498 return irBuilder.makeFunctionDefinition( |
521 sourceInformationBuilder.buildVariableDeclaration()); | 499 sourceInformationBuilder.buildVariableDeclaration()); |
522 }); | 500 }); |
523 } | 501 } |
524 | 502 |
525 /// Make a visitor suitable for translating ASTs taken from [context]. | 503 /// Make a visitor suitable for translating ASTs taken from [context]. |
526 /// | 504 /// |
527 /// Every visitor can only be applied to nodes in one context, because | 505 /// Every visitor can only be applied to nodes in one context, because |
528 /// the [elements] field is specific to that context. | 506 /// the [elements] field is specific to that context. |
529 IrBuilderVisitor makeVisitorForContext(AstElement context) { | 507 IrBuilderVisitor makeVisitorForContext(AstElement context) { |
530 return new IrBuilderVisitor( | 508 return new IrBuilderVisitor(context.resolvedAst.elements, compiler, |
531 context.resolvedAst.elements, | 509 sourceInformationBuilder.forContext(context), typeMaskSystem); |
532 compiler, | |
533 sourceInformationBuilder.forContext(context), | |
534 typeMaskSystem); | |
535 } | 510 } |
536 | 511 |
537 /// Builds the IR for an [expression] taken from a different [context]. | 512 /// Builds the IR for an [expression] taken from a different [context]. |
538 /// | 513 /// |
539 /// Such expressions need to be compiled with a different [sourceFile] and | 514 /// Such expressions need to be compiled with a different [sourceFile] and |
540 /// [elements] mapping. | 515 /// [elements] mapping. |
541 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { | 516 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { |
542 IrBuilderVisitor visitor = makeVisitorForContext(context); | 517 IrBuilderVisitor visitor = makeVisitorForContext(context); |
543 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); | 518 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); |
544 } | 519 } |
545 | 520 |
546 /// Evaluate the implicit super call in the given mixin constructor. | 521 /// Evaluate the implicit super call in the given mixin constructor. |
547 void forwardSynthesizedMixinConstructor( | 522 void forwardSynthesizedMixinConstructor( |
548 ConstructorElement constructor, | 523 ConstructorElement constructor, |
549 List<ConstructorElement> supers, | 524 List<ConstructorElement> supers, |
550 Map<FieldElement, ir.Primitive> fieldValues) { | 525 Map<FieldElement, ir.Primitive> fieldValues) { |
551 assert(constructor.enclosingClass.implementation.isMixinApplication); | 526 assert(constructor.enclosingClass.implementation.isMixinApplication); |
552 assert(constructor.isSynthesized); | 527 assert(constructor.isSynthesized); |
553 ConstructorElement target = | 528 ConstructorElement target = constructor.definingConstructor.implementation; |
554 constructor.definingConstructor.implementation; | |
555 // The resolver gives us the exact same FunctionSignature for the two | 529 // The resolver gives us the exact same FunctionSignature for the two |
556 // constructors. The parameters for the synthesized constructor | 530 // constructors. The parameters for the synthesized constructor |
557 // are already in the environment, so the target constructor's parameters | 531 // are already in the environment, so the target constructor's parameters |
558 // are also in the environment since their elements are the same. | 532 // are also in the environment since their elements are the same. |
559 assert(constructor.functionSignature == target.functionSignature); | 533 assert(constructor.functionSignature == target.functionSignature); |
560 IrBuilderVisitor visitor = makeVisitorForContext(target); | 534 IrBuilderVisitor visitor = makeVisitorForContext(target); |
561 visitor.withBuilder(irBuilder, () { | 535 visitor.withBuilder(irBuilder, () { |
562 visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues); | 536 visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues); |
563 }); | 537 }); |
564 } | 538 } |
565 | 539 |
566 /// In preparation of inlining (part of) [target], the [arguments] are moved | 540 /// In preparation of inlining (part of) [target], the [arguments] are moved |
567 /// into the environment bindings for the corresponding parameters. | 541 /// into the environment bindings for the corresponding parameters. |
568 /// | 542 /// |
569 /// Defaults for optional arguments are evaluated in order to ensure | 543 /// Defaults for optional arguments are evaluated in order to ensure |
570 /// all parameters are available in the environment. | 544 /// all parameters are available in the environment. |
571 void loadArguments(ConstructorElement target, | 545 void loadArguments(ConstructorElement target, CallStructure call, |
572 CallStructure call, | |
573 List<ir.Primitive> arguments) { | 546 List<ir.Primitive> arguments) { |
574 assert(target.isImplementation); | 547 assert(target.isImplementation); |
575 assert(target == elements.analyzedElement); | 548 assert(target == elements.analyzedElement); |
576 FunctionSignature signature = target.functionSignature; | 549 FunctionSignature signature = target.functionSignature; |
577 | 550 |
578 // Establish a scope in case parameters are captured. | 551 // Establish a scope in case parameters are captured. |
579 ClosureScope scope = getClosureScopeForFunction(target); | 552 ClosureScope scope = getClosureScopeForFunction(target); |
580 irBuilder.enterScope(scope); | 553 irBuilder.enterScope(scope); |
581 | 554 |
582 // Load required parameters | 555 // Load required parameters |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 } | 642 } |
670 // If this is a mixin constructor, it does not have its own parameter list | 643 // If this is a mixin constructor, it does not have its own parameter list |
671 // or initializer list. Directly forward to the super constructor. | 644 // or initializer list. Directly forward to the super constructor. |
672 // Note that the declaration-site initializers originating from the | 645 // Note that the declaration-site initializers originating from the |
673 // mixed-in class were handled above. | 646 // mixed-in class were handled above. |
674 if (enclosingClass.isMixinApplication) { | 647 if (enclosingClass.isMixinApplication) { |
675 forwardSynthesizedMixinConstructor(constructor, supers, fieldValues); | 648 forwardSynthesizedMixinConstructor(constructor, supers, fieldValues); |
676 return; | 649 return; |
677 } | 650 } |
678 // Evaluate initializing parameters, e.g. `Foo(this.x)`. | 651 // Evaluate initializing parameters, e.g. `Foo(this.x)`. |
679 constructor.functionSignature.orderedForEachParameter( | 652 constructor.functionSignature |
680 (ParameterElement parameter) { | 653 .orderedForEachParameter((ParameterElement parameter) { |
681 if (parameter.isInitializingFormal) { | 654 if (parameter.isInitializingFormal) { |
682 InitializingFormalElement fieldParameter = parameter; | 655 InitializingFormalElement fieldParameter = parameter; |
683 fieldValues[fieldParameter.fieldElement] = | 656 fieldValues[fieldParameter.fieldElement] = |
684 irBuilder.buildLocalGet(parameter); | 657 irBuilder.buildLocalGet(parameter); |
685 } | 658 } |
686 }); | 659 }); |
687 // Evaluate constructor initializers, e.g. `Foo() : x = 50`. | 660 // Evaluate constructor initializers, e.g. `Foo() : x = 50`. |
688 ast.FunctionExpression node = constructor.node; | 661 ast.FunctionExpression node = constructor.node; |
689 bool hasConstructorCall = false; // Has this() or super() initializer? | 662 bool hasConstructorCall = false; // Has this() or super() initializer? |
690 if (node != null && node.initializers != null) { | 663 if (node != null && node.initializers != null) { |
691 for(ast.Node initializer in node.initializers) { | 664 for (ast.Node initializer in node.initializers) { |
692 if (initializer is ast.SendSet) { | 665 if (initializer is ast.SendSet) { |
693 // Field initializer. | 666 // Field initializer. |
694 FieldElement field = elements[initializer]; | 667 FieldElement field = elements[initializer]; |
695 fieldValues[field] = visit(initializer.arguments.head); | 668 fieldValues[field] = visit(initializer.arguments.head); |
696 } else if (initializer is ast.Send) { | 669 } else if (initializer is ast.Send) { |
697 // Super or this initializer. | 670 // Super or this initializer. |
698 ConstructorElement target = elements[initializer].implementation; | 671 ConstructorElement target = elements[initializer].implementation; |
699 Selector selector = elements.getSelector(initializer); | 672 Selector selector = elements.getSelector(initializer); |
700 List<ir.Primitive> arguments = initializer.arguments.mapToList(visit); | 673 List<ir.Primitive> arguments = initializer.arguments.mapToList(visit); |
701 evaluateConstructorCallFromInitializer( | 674 evaluateConstructorCallFromInitializer( |
702 target, | 675 target, selector.callStructure, arguments, supers, fieldValues); |
703 selector.callStructure, | |
704 arguments, | |
705 supers, | |
706 fieldValues); | |
707 hasConstructorCall = true; | 676 hasConstructorCall = true; |
708 } else { | 677 } else { |
709 reporter.internalError(initializer, | 678 reporter.internalError( |
710 "Unexpected initializer type $initializer"); | 679 initializer, "Unexpected initializer type $initializer"); |
711 } | 680 } |
712 } | 681 } |
713 } | 682 } |
714 // If no super() or this() was found, also call default superconstructor. | 683 // If no super() or this() was found, also call default superconstructor. |
715 if (!hasConstructorCall && !enclosingClass.isObject) { | 684 if (!hasConstructorCall && !enclosingClass.isObject) { |
716 ClassElement superClass = enclosingClass.superclass; | 685 ClassElement superClass = enclosingClass.superclass; |
717 FunctionElement target = superClass.lookupDefaultConstructor(); | 686 FunctionElement target = superClass.lookupDefaultConstructor(); |
718 if (target == null) { | 687 if (target == null) { |
719 reporter.internalError(superClass, "No default constructor available."); | 688 reporter.internalError(superClass, "No default constructor available."); |
720 } | 689 } |
721 target = target.implementation; | 690 target = target.implementation; |
722 evaluateConstructorCallFromInitializer( | 691 evaluateConstructorCallFromInitializer( |
723 target, | 692 target, CallStructure.NO_ARGS, const [], supers, fieldValues); |
724 CallStructure.NO_ARGS, | |
725 const [], | |
726 supers, | |
727 fieldValues); | |
728 } | 693 } |
729 // Add this constructor after the superconstructors. | 694 // Add this constructor after the superconstructors. |
730 supers.add(constructor); | 695 supers.add(constructor); |
731 } | 696 } |
732 | 697 |
733 TryBoxedVariables _analyzeTryBoxedVariables(ast.Node node) { | 698 TryBoxedVariables _analyzeTryBoxedVariables(ast.Node node) { |
734 TryBoxedVariables variables = new TryBoxedVariables(elements); | 699 TryBoxedVariables variables = new TryBoxedVariables(elements); |
735 try { | 700 try { |
736 variables.analyze(node); | 701 variables.analyze(node); |
737 } catch (e) { | 702 } catch (e) { |
738 bailoutMessage = variables.bailoutMessage; | 703 bailoutMessage = variables.bailoutMessage; |
739 rethrow; | 704 rethrow; |
740 } | 705 } |
741 return variables; | 706 return variables; |
742 } | 707 } |
743 | 708 |
744 /// Builds the IR for the body of a constructor. | 709 /// Builds the IR for the body of a constructor. |
745 /// | 710 /// |
746 /// This function is invoked from one or more "factory" constructors built by | 711 /// This function is invoked from one or more "factory" constructors built by |
747 /// [buildConstructor]. | 712 /// [buildConstructor]. |
748 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { | 713 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { |
749 ConstructorElement constructor = body.constructor; | 714 ConstructorElement constructor = body.constructor; |
750 ast.FunctionExpression node = constructor.node; | 715 ast.FunctionExpression node = constructor.node; |
751 closureClassMap = | 716 closureClassMap = compiler.closureToClassMapper |
752 compiler.closureToClassMapper.computeClosureToClassMapping( | 717 .computeClosureToClassMapping(constructor, node, elements); |
753 constructor, | |
754 node, | |
755 elements); | |
756 | 718 |
757 // We compute variables boxed in mutable variables on entry to each try | 719 // We compute variables boxed in mutable variables on entry to each try |
758 // block, not including variables captured by a closure (which are boxed | 720 // block, not including variables captured by a closure (which are boxed |
759 // in the heap). This duplicates some of the work of closure conversion | 721 // in the heap). This duplicates some of the work of closure conversion |
760 // without directly using the results. This duplication is wasteful and | 722 // without directly using the results. This duplication is wasteful and |
761 // error-prone. | 723 // error-prone. |
762 // TODO(kmillikin): We should combine closure conversion and try/catch | 724 // TODO(kmillikin): We should combine closure conversion and try/catch |
763 // variable analysis in some way. | 725 // variable analysis in some way. |
764 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); | 726 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); |
765 tryStatements = variables.tryStatements; | 727 tryStatements = variables.tryStatements; |
766 IrBuilder builder = getBuilderFor(body); | 728 IrBuilder builder = getBuilderFor(body); |
767 | 729 |
768 return withBuilder(builder, () { | 730 return withBuilder(builder, () { |
769 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), | 731 irBuilder.buildConstructorBodyHeader( |
770 getClosureScopeForNode(node)); | 732 getConstructorBodyParameters(body), getClosureScopeForNode(node)); |
771 visit(node.body); | 733 visit(node.body); |
772 return irBuilder.makeFunctionDefinition( | 734 return irBuilder.makeFunctionDefinition( |
773 sourceInformationBuilder.buildVariableDeclaration()); | 735 sourceInformationBuilder.buildVariableDeclaration()); |
774 }); | 736 }); |
775 } | 737 } |
776 | 738 |
777 ir.FunctionDefinition buildFunction(FunctionElement element) { | 739 ir.FunctionDefinition buildFunction(FunctionElement element) { |
778 assert(invariant(element, element.isImplementation)); | 740 assert(invariant(element, element.isImplementation)); |
779 ast.FunctionExpression node = element.node; | 741 ast.FunctionExpression node = element.node; |
780 | 742 |
781 assert(!element.isSynthesized); | 743 assert(!element.isSynthesized); |
782 assert(node != null); | 744 assert(node != null); |
783 assert(elements[node] != null); | 745 assert(elements[node] != null); |
784 | 746 |
785 closureClassMap = | 747 closureClassMap = compiler.closureToClassMapper |
786 compiler.closureToClassMapper.computeClosureToClassMapping( | 748 .computeClosureToClassMapping(element, node, elements); |
787 element, | |
788 node, | |
789 elements); | |
790 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); | 749 TryBoxedVariables variables = _analyzeTryBoxedVariables(node); |
791 tryStatements = variables.tryStatements; | 750 tryStatements = variables.tryStatements; |
792 IrBuilder builder = getBuilderFor(element); | 751 IrBuilder builder = getBuilderFor(element); |
793 return withBuilder(builder, | 752 return withBuilder( |
794 () => _makeFunctionBody(builder, element, node)); | 753 builder, () => _makeFunctionBody(builder, element, node)); |
795 } | 754 } |
796 | 755 |
797 ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) { | 756 ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) { |
798 if (!backend.constants.lazyStatics.contains(element)) { | 757 if (!backend.constants.lazyStatics.contains(element)) { |
799 return null; // Nothing to do. | 758 return null; // Nothing to do. |
800 } | 759 } |
801 closureClassMap = | 760 closureClassMap = compiler.closureToClassMapper |
802 compiler.closureToClassMapper.computeClosureToClassMapping( | 761 .computeClosureToClassMapping(element, element.node, elements); |
803 element, | |
804 element.node, | |
805 elements); | |
806 IrBuilder builder = getBuilderFor(element); | 762 IrBuilder builder = getBuilderFor(element); |
807 return withBuilder(builder, () { | 763 return withBuilder(builder, () { |
808 irBuilder.buildFunctionHeader(<Local>[]); | 764 irBuilder.buildFunctionHeader(<Local>[]); |
809 ir.Primitive initialValue = visit(element.initializer); | 765 ir.Primitive initialValue = visit(element.initializer); |
810 ast.VariableDefinitions node = element.node; | 766 ast.VariableDefinitions node = element.node; |
811 ast.SendSet sendSet = node.definitions.nodes.head; | 767 ast.SendSet sendSet = node.definitions.nodes.head; |
812 irBuilder.buildReturn( | 768 irBuilder.buildReturn( |
813 value: initialValue, | 769 value: initialValue, |
814 sourceInformation: | 770 sourceInformation: |
815 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)); | 771 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)); |
816 return irBuilder.makeFunctionDefinition( | 772 return irBuilder.makeFunctionDefinition( |
817 sourceInformationBuilder.buildVariableDeclaration()); | 773 sourceInformationBuilder.buildVariableDeclaration()); |
818 }); | 774 }); |
819 } | 775 } |
820 | 776 |
821 /// Builds the IR for a constant taken from a different [context]. | 777 /// Builds the IR for a constant taken from a different [context]. |
822 /// | 778 /// |
823 /// Such constants need to be compiled with a different [sourceFile] and | 779 /// Such constants need to be compiled with a different [sourceFile] and |
824 /// [elements] mapping. | 780 /// [elements] mapping. |
825 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { | 781 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { |
(...skipping 14 matching lines...) Expand all Loading... |
840 } | 796 } |
841 | 797 |
842 /// Normalizes the argument list of a static invocation. | 798 /// Normalizes the argument list of a static invocation. |
843 /// | 799 /// |
844 /// A static invocation is one where the target is known. The argument list | 800 /// A static invocation is one where the target is known. The argument list |
845 /// [arguments] is normalized by adding default values for optional arguments | 801 /// [arguments] is normalized by adding default values for optional arguments |
846 /// that are not passed, and by sorting it in place so that named arguments | 802 /// that are not passed, and by sorting it in place so that named arguments |
847 /// appear in a canonical order. A [CallStructure] reflecting this order | 803 /// appear in a canonical order. A [CallStructure] reflecting this order |
848 /// is returned. | 804 /// is returned. |
849 CallStructure normalizeStaticArguments(CallStructure callStructure, | 805 CallStructure normalizeStaticArguments(CallStructure callStructure, |
850 FunctionElement target, | 806 FunctionElement target, List<ir.Primitive> arguments) { |
851 List<ir.Primitive> arguments) { | |
852 target = target.implementation; | 807 target = target.implementation; |
853 FunctionSignature signature = target.functionSignature; | 808 FunctionSignature signature = target.functionSignature; |
854 if (!signature.optionalParametersAreNamed && | 809 if (!signature.optionalParametersAreNamed && |
855 signature.parameterCount == arguments.length) { | 810 signature.parameterCount == arguments.length) { |
856 return callStructure; | 811 return callStructure; |
857 } | 812 } |
858 | 813 |
859 if (!signature.optionalParametersAreNamed) { | 814 if (!signature.optionalParametersAreNamed) { |
860 int i = signature.requiredParameterCount; | 815 int i = signature.requiredParameterCount; |
861 signature.forEachOptionalParameter((ParameterElement element) { | 816 signature.forEachOptionalParameter((ParameterElement element) { |
862 if (i < callStructure.positionalArgumentCount) { | 817 if (i < callStructure.positionalArgumentCount) { |
863 ++i; | 818 ++i; |
864 } else { | 819 } else { |
865 arguments.add(translateDefaultValue(element)); | 820 arguments.add(translateDefaultValue(element)); |
866 } | 821 } |
867 }); | 822 }); |
868 return new CallStructure(signature.parameterCount); | 823 return new CallStructure(signature.parameterCount); |
869 } | 824 } |
870 | 825 |
871 int offset = signature.requiredParameterCount; | 826 int offset = signature.requiredParameterCount; |
872 List<ir.Primitive> namedArguments = arguments.sublist(offset); | 827 List<ir.Primitive> namedArguments = arguments.sublist(offset); |
873 arguments.length = offset; | 828 arguments.length = offset; |
874 List<String> normalizedNames = <String>[]; | 829 List<String> normalizedNames = <String>[]; |
875 // Iterate over the optional parameters of the signature, and try to | 830 // Iterate over the optional parameters of the signature, and try to |
876 // find them in the callStructure's named arguments. If found, we use the | 831 // find them in the callStructure's named arguments. If found, we use the |
877 // value in the temporary list, otherwise the default value. | 832 // value in the temporary list, otherwise the default value. |
878 signature.orderedOptionalParameters.forEach((ParameterElement element) { | 833 signature.orderedOptionalParameters.forEach((ParameterElement element) { |
879 int nameIndex = callStructure.namedArguments.indexOf(element.name); | 834 int nameIndex = callStructure.namedArguments.indexOf(element.name); |
880 arguments.add(nameIndex == -1 ? translateDefaultValue(element) | 835 arguments.add(nameIndex == -1 |
| 836 ? translateDefaultValue(element) |
881 : namedArguments[nameIndex]); | 837 : namedArguments[nameIndex]); |
882 normalizedNames.add(element.name); | 838 normalizedNames.add(element.name); |
883 }); | 839 }); |
884 return new CallStructure(signature.parameterCount, normalizedNames); | 840 return new CallStructure(signature.parameterCount, normalizedNames); |
885 } | 841 } |
886 | 842 |
887 /// Normalizes the argument list of a dynamic invocation. | 843 /// Normalizes the argument list of a dynamic invocation. |
888 /// | 844 /// |
889 /// A dynamic invocation is one where the target is not known. The argument | 845 /// A dynamic invocation is one where the target is not known. The argument |
890 /// list [arguments] is normalized by sorting it in place so that the named | 846 /// list [arguments] is normalized by sorting it in place so that the named |
891 /// arguments appear in a canonical order. A [CallStructure] reflecting this | 847 /// arguments appear in a canonical order. A [CallStructure] reflecting this |
892 /// order is returned. | 848 /// order is returned. |
893 CallStructure normalizeDynamicArguments(CallStructure callStructure, | 849 CallStructure normalizeDynamicArguments( |
894 List<ir.Primitive> arguments) { | 850 CallStructure callStructure, List<ir.Primitive> arguments) { |
895 assert(arguments.length == callStructure.argumentCount); | 851 assert(arguments.length == callStructure.argumentCount); |
896 if (callStructure.namedArguments.isEmpty) return callStructure; | 852 if (callStructure.namedArguments.isEmpty) return callStructure; |
897 int destinationIndex = callStructure.positionalArgumentCount; | 853 int destinationIndex = callStructure.positionalArgumentCount; |
898 List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex); | 854 List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex); |
899 for (String argName in callStructure.getOrderedNamedArguments()) { | 855 for (String argName in callStructure.getOrderedNamedArguments()) { |
900 int sourceIndex = callStructure.namedArguments.indexOf(argName); | 856 int sourceIndex = callStructure.namedArguments.indexOf(argName); |
901 arguments[destinationIndex++] = namedArguments[sourceIndex]; | 857 arguments[destinationIndex++] = namedArguments[sourceIndex]; |
902 } | 858 } |
903 return new CallStructure(callStructure.argumentCount, | 859 return new CallStructure( |
904 callStructure.getOrderedNamedArguments()); | 860 callStructure.argumentCount, callStructure.getOrderedNamedArguments()); |
905 } | 861 } |
906 | 862 |
907 /// Read the value of [field]. | 863 /// Read the value of [field]. |
908 ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) { | 864 ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) { |
909 ConstantValue constant = getConstantForVariable(field); | 865 ConstantValue constant = getConstantForVariable(field); |
910 if (constant != null && !field.isAssignable) { | 866 if (constant != null && !field.isAssignable) { |
911 typeMaskSystem.associateConstantValueWithElement(constant, field); | 867 typeMaskSystem.associateConstantValueWithElement(constant, field); |
912 return irBuilder.buildConstant(constant, sourceInformation: src); | 868 return irBuilder.buildConstant(constant, sourceInformation: src); |
913 } else if (backend.constants.lazyStatics.contains(field)) { | 869 } else if (backend.constants.lazyStatics.contains(field)) { |
914 return irBuilder.addPrimitive(new ir.GetLazyStatic(field, | 870 return irBuilder.addPrimitive(new ir.GetLazyStatic(field, |
915 sourceInformation: src, | 871 sourceInformation: src, |
916 isFinal: compiler.world.fieldNeverChanges(field))); | 872 isFinal: compiler.world.fieldNeverChanges(field))); |
917 } else { | 873 } else { |
918 return irBuilder.addPrimitive(new ir.GetStatic(field, | 874 return irBuilder.addPrimitive(new ir.GetStatic(field, |
919 sourceInformation: src, | 875 sourceInformation: src, |
920 isFinal: compiler.world.fieldNeverChanges(field))); | 876 isFinal: compiler.world.fieldNeverChanges(field))); |
921 } | 877 } |
922 } | 878 } |
923 | 879 |
924 ir.FunctionDefinition _makeFunctionBody( | 880 ir.FunctionDefinition _makeFunctionBody( |
925 IrBuilder builder, | 881 IrBuilder builder, FunctionElement element, ast.FunctionExpression node) { |
926 FunctionElement element, | |
927 ast.FunctionExpression node) { | |
928 FunctionSignature signature = element.functionSignature; | 882 FunctionSignature signature = element.functionSignature; |
929 List<Local> parameters = <Local>[]; | 883 List<Local> parameters = <Local>[]; |
930 signature.orderedForEachParameter( | 884 signature.orderedForEachParameter( |
931 (LocalParameterElement e) => parameters.add(e)); | 885 (LocalParameterElement e) => parameters.add(e)); |
932 | 886 |
933 bool requiresRuntimeTypes = false; | 887 bool requiresRuntimeTypes = false; |
934 if (element.isFactoryConstructor) { | 888 if (element.isFactoryConstructor) { |
935 requiresRuntimeTypes = | 889 requiresRuntimeTypes = |
936 builder.program.requiresRuntimeTypesFor(element.enclosingElement); | 890 builder.program.requiresRuntimeTypesFor(element.enclosingElement); |
937 if (requiresRuntimeTypes) { | 891 if (requiresRuntimeTypes) { |
938 // Type arguments are passed in as extra parameters. | 892 // Type arguments are passed in as extra parameters. |
939 for (DartType typeVariable in element.enclosingClass.typeVariables) { | 893 for (DartType typeVariable in element.enclosingClass.typeVariables) { |
940 parameters.add(new closure.TypeVariableLocal(typeVariable, element)); | 894 parameters.add(new closure.TypeVariableLocal(typeVariable, element)); |
941 } | 895 } |
942 } | 896 } |
943 } | 897 } |
944 | 898 |
945 irBuilder.buildFunctionHeader(parameters, | 899 irBuilder.buildFunctionHeader(parameters, |
946 closureScope: getClosureScopeForNode(node), | 900 closureScope: getClosureScopeForNode(node), |
947 env: getClosureEnvironment()); | 901 env: getClosureEnvironment()); |
948 | 902 |
949 if (element == helpers.jsArrayTypedConstructor) { | 903 if (element == helpers.jsArrayTypedConstructor) { |
950 // Generate a body for JSArray<E>.typed(allocation): | 904 // Generate a body for JSArray<E>.typed(allocation): |
951 // | 905 // |
952 // t1 = setRuntimeTypeInfo(allocation, TypeExpression($E)); | 906 // t1 = setRuntimeTypeInfo(allocation, TypeExpression($E)); |
953 // return Refinement(t1, <JSArray>); | 907 // return Refinement(t1, <JSArray>); |
954 // | 908 // |
955 assert(parameters.length == 1 || parameters.length == 2); | 909 assert(parameters.length == 1 || parameters.length == 2); |
956 ir.Primitive allocation = irBuilder.buildLocalGet(parameters[0]); | 910 ir.Primitive allocation = irBuilder.buildLocalGet(parameters[0]); |
957 ClassElement classElement = element.enclosingElement; | 911 ClassElement classElement = element.enclosingElement; |
958 | 912 |
959 // Only call setRuntimeTypeInfo if JSArray requires the type parameter. | 913 // Only call setRuntimeTypeInfo if JSArray requires the type parameter. |
960 if (requiresRuntimeTypes) { | 914 if (requiresRuntimeTypes) { |
961 assert(parameters.length == 2); | 915 assert(parameters.length == 2); |
962 closure.TypeVariableLocal typeParameter = parameters[1]; | 916 closure.TypeVariableLocal typeParameter = parameters[1]; |
963 ir.Primitive typeArgument = | 917 ir.Primitive typeArgument = |
964 irBuilder.buildTypeVariableAccess(typeParameter.typeVariable); | 918 irBuilder.buildTypeVariableAccess(typeParameter.typeVariable); |
965 | 919 |
966 ir.Primitive typeInformation = irBuilder.addPrimitive( | 920 ir.Primitive typeInformation = irBuilder.addPrimitive( |
967 new ir.TypeExpression(ir.TypeExpressionKind.INSTANCE, | 921 new ir.TypeExpression(ir.TypeExpressionKind.INSTANCE, |
968 element.enclosingClass.thisType, | 922 element.enclosingClass.thisType, <ir.Primitive>[typeArgument])); |
969 <ir.Primitive>[typeArgument])); | |
970 | 923 |
971 MethodElement helper = helpers.setRuntimeTypeInfo; | 924 MethodElement helper = helpers.setRuntimeTypeInfo; |
972 CallStructure callStructure = CallStructure.TWO_ARGS; | 925 CallStructure callStructure = CallStructure.TWO_ARGS; |
973 Selector selector = new Selector.call(helper.memberName, callStructure); | 926 Selector selector = new Selector.call(helper.memberName, callStructure); |
974 allocation = irBuilder.buildInvokeStatic( | 927 allocation = irBuilder.buildInvokeStatic( |
975 helper, selector, <ir.Primitive>[allocation, typeInformation], | 928 helper, |
| 929 selector, |
| 930 <ir.Primitive>[allocation, typeInformation], |
976 sourceInformationBuilder.buildGeneric(node)); | 931 sourceInformationBuilder.buildGeneric(node)); |
977 } | 932 } |
978 | 933 |
979 ir.Primitive refinement = irBuilder.addPrimitive( | 934 ir.Primitive refinement = irBuilder.addPrimitive( |
980 new ir.Refinement(allocation, typeMaskSystem.arrayType)); | 935 new ir.Refinement(allocation, typeMaskSystem.arrayType)); |
981 | 936 |
982 irBuilder.buildReturn(value: refinement, | 937 irBuilder.buildReturn( |
| 938 value: refinement, |
983 sourceInformation: | 939 sourceInformation: |
984 sourceInformationBuilder.buildImplicitReturn(element)); | 940 sourceInformationBuilder.buildImplicitReturn(element)); |
985 } else { | 941 } else { |
986 visit(node.body); | 942 visit(node.body); |
987 } | 943 } |
988 return irBuilder.makeFunctionDefinition( | 944 return irBuilder.makeFunctionDefinition( |
989 sourceInformationBuilder.buildVariableDeclaration()); | 945 sourceInformationBuilder.buildVariableDeclaration()); |
990 } | 946 } |
991 | 947 |
992 /// Builds the IR for creating an instance of the closure class corresponding | 948 /// Builds the IR for creating an instance of the closure class corresponding |
993 /// to the given nested function. | 949 /// to the given nested function. |
994 closure.ClosureClassElement makeSubFunction(ast.FunctionExpression node) { | 950 closure.ClosureClassElement makeSubFunction(ast.FunctionExpression node) { |
995 closure.ClosureClassMap innerMap = | 951 closure.ClosureClassMap innerMap = |
996 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 952 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
997 closure.ClosureClassElement closureClass = innerMap.closureClassElement; | 953 closure.ClosureClassElement closureClass = innerMap.closureClassElement; |
998 return closureClass; | 954 return closureClass; |
999 } | 955 } |
1000 | 956 |
1001 ir.Primitive visitFunctionExpression(ast.FunctionExpression node) { | 957 ir.Primitive visitFunctionExpression(ast.FunctionExpression node) { |
1002 return irBuilder.buildFunctionExpression(makeSubFunction(node), | 958 return irBuilder.buildFunctionExpression( |
1003 sourceInformationBuilder.buildCreate(node)); | 959 makeSubFunction(node), sourceInformationBuilder.buildCreate(node)); |
1004 } | 960 } |
1005 | 961 |
1006 visitFunctionDeclaration(ast.FunctionDeclaration node) { | 962 visitFunctionDeclaration(ast.FunctionDeclaration node) { |
1007 LocalFunctionElement element = elements[node.function]; | 963 LocalFunctionElement element = elements[node.function]; |
1008 Object inner = makeSubFunction(node.function); | 964 Object inner = makeSubFunction(node.function); |
1009 irBuilder.declareLocalFunction(element, inner, | 965 irBuilder.declareLocalFunction( |
1010 sourceInformationBuilder.buildCreate(node.function)); | 966 element, inner, sourceInformationBuilder.buildCreate(node.function)); |
1011 } | 967 } |
1012 | 968 |
1013 // ## Statements ## | 969 // ## Statements ## |
1014 visitBlock(ast.Block node) { | 970 visitBlock(ast.Block node) { |
1015 irBuilder.buildBlock(node.statements.nodes, build); | 971 irBuilder.buildBlock(node.statements.nodes, build); |
1016 } | 972 } |
1017 | 973 |
1018 ir.Primitive visitBreakStatement(ast.BreakStatement node) { | 974 ir.Primitive visitBreakStatement(ast.BreakStatement node) { |
1019 if (!irBuilder.buildBreak(elements.getTargetOf(node))) { | 975 if (!irBuilder.buildBreak(elements.getTargetOf(node))) { |
1020 reporter.internalError(node, "'break' target not found"); | 976 reporter.internalError(node, "'break' target not found"); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 redirectingConstructor.functionSignature; | 1027 redirectingConstructor.functionSignature; |
1072 List<String> namedParameters = <String>[]; | 1028 List<String> namedParameters = <String>[]; |
1073 redirectingSignature.forEachParameter((ParameterElement parameter) { | 1029 redirectingSignature.forEachParameter((ParameterElement parameter) { |
1074 arguments.add(irBuilder.environment.lookup(parameter)); | 1030 arguments.add(irBuilder.environment.lookup(parameter)); |
1075 if (parameter.isNamed) { | 1031 if (parameter.isNamed) { |
1076 namedParameters.add(parameter.name); | 1032 namedParameters.add(parameter.name); |
1077 } | 1033 } |
1078 }); | 1034 }); |
1079 ClassElement cls = redirectingConstructor.enclosingClass; | 1035 ClassElement cls = redirectingConstructor.enclosingClass; |
1080 InterfaceType targetType = | 1036 InterfaceType targetType = |
1081 redirectingConstructor.computeEffectiveTargetType(cls.thisType); | 1037 redirectingConstructor.computeEffectiveTargetType(cls.thisType); |
1082 CallStructure callStructure = new CallStructure( | 1038 CallStructure callStructure = |
1083 redirectingSignature.parameterCount, | 1039 new CallStructure(redirectingSignature.parameterCount, namedParameters); |
1084 namedParameters); | |
1085 callStructure = | 1040 callStructure = |
1086 normalizeStaticArguments(callStructure, targetConstructor, arguments); | 1041 normalizeStaticArguments(callStructure, targetConstructor, arguments); |
1087 ir.Primitive instance = irBuilder.buildConstructorInvocation( | 1042 ir.Primitive instance = irBuilder.buildConstructorInvocation( |
1088 targetConstructor, | 1043 targetConstructor, |
1089 callStructure, | 1044 callStructure, |
1090 targetType, | 1045 targetType, |
1091 arguments, | 1046 arguments, |
1092 sourceInformationBuilder.buildNew(node)); | 1047 sourceInformationBuilder.buildNew(node)); |
1093 irBuilder.buildReturn( | 1048 irBuilder.buildReturn( |
1094 value: instance, | 1049 value: instance, |
(...skipping 15 matching lines...) Expand all Loading... |
1110 buildInitializer: subbuild(node.initializer), | 1065 buildInitializer: subbuild(node.initializer), |
1111 buildCondition: subbuild(node.condition), | 1066 buildCondition: subbuild(node.condition), |
1112 buildBody: subbuild(node.body), | 1067 buildBody: subbuild(node.body), |
1113 buildUpdate: subbuildSequence(node.update), | 1068 buildUpdate: subbuildSequence(node.update), |
1114 closureScope: getClosureScopeForNode(node), | 1069 closureScope: getClosureScopeForNode(node), |
1115 loopVariables: loopVariables, | 1070 loopVariables: loopVariables, |
1116 target: target); | 1071 target: target); |
1117 } | 1072 } |
1118 | 1073 |
1119 visitIf(ast.If node) { | 1074 visitIf(ast.If node) { |
1120 irBuilder.buildIf( | 1075 irBuilder.buildIf(build(node.condition), subbuild(node.thenPart), |
1121 build(node.condition), | 1076 subbuild(node.elsePart), sourceInformationBuilder.buildIf(node)); |
1122 subbuild(node.thenPart), | |
1123 subbuild(node.elsePart), | |
1124 sourceInformationBuilder.buildIf(node)); | |
1125 } | 1077 } |
1126 | 1078 |
1127 visitLabeledStatement(ast.LabeledStatement node) { | 1079 visitLabeledStatement(ast.LabeledStatement node) { |
1128 ast.Statement body = node.statement; | 1080 ast.Statement body = node.statement; |
1129 if (body is ast.Loop) { | 1081 if (body is ast.Loop) { |
1130 visit(body); | 1082 visit(body); |
1131 } else { | 1083 } else { |
1132 JumpTarget target = elements.getTargetDefinition(body); | 1084 JumpTarget target = elements.getTargetDefinition(body); |
1133 irBuilder.buildLabeledStatement( | 1085 irBuilder.buildLabeledStatement( |
1134 buildBody: subbuild(body), | 1086 buildBody: subbuild(body), target: target); |
1135 target: target); | |
1136 } | 1087 } |
1137 } | 1088 } |
1138 | 1089 |
1139 visitDoWhile(ast.DoWhile node) { | 1090 visitDoWhile(ast.DoWhile node) { |
1140 irBuilder.buildDoWhile( | 1091 irBuilder.buildDoWhile( |
1141 buildBody: subbuild(node.body), | 1092 buildBody: subbuild(node.body), |
1142 buildCondition: subbuild(node.condition), | 1093 buildCondition: subbuild(node.condition), |
1143 target: elements.getTargetDefinition(node), | 1094 target: elements.getTargetDefinition(node), |
1144 closureScope: getClosureScopeForNode(node)); | 1095 closureScope: getClosureScopeForNode(node)); |
1145 } | 1096 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 Element variable = elements.getForInVariable(node); | 1152 Element variable = elements.getForInVariable(node); |
1202 SourceInformation sourceInformation = | 1153 SourceInformation sourceInformation = |
1203 sourceInformationBuilder.buildForInSet(node); | 1154 sourceInformationBuilder.buildForInSet(node); |
1204 if (Elements.isLocal(variable)) { | 1155 if (Elements.isLocal(variable)) { |
1205 if (node.declaredIdentifier.asVariableDefinitions() != null) { | 1156 if (node.declaredIdentifier.asVariableDefinitions() != null) { |
1206 irBuilder.declareLocalVariable(variable); | 1157 irBuilder.declareLocalVariable(variable); |
1207 } | 1158 } |
1208 irBuilder.buildLocalVariableSet( | 1159 irBuilder.buildLocalVariableSet( |
1209 variable, current, sourceInformation); | 1160 variable, current, sourceInformation); |
1210 } else if (Elements.isError(variable) || | 1161 } else if (Elements.isError(variable) || |
1211 Elements.isMalformed(variable)) { | 1162 Elements.isMalformed(variable)) { |
1212 Selector selector = | 1163 Selector selector = |
1213 new Selector.setter(new Name(variable.name, variable.library)); | 1164 new Selector.setter(new Name(variable.name, variable.library)); |
1214 List<ir.Primitive> args = <ir.Primitive>[current]; | 1165 List<ir.Primitive> args = <ir.Primitive>[current]; |
1215 // Note the comparison below. It can be the case that an element | 1166 // Note the comparison below. It can be the case that an element |
1216 // isError and isMalformed. | 1167 // isError and isMalformed. |
1217 if (Elements.isError(variable)) { | 1168 if (Elements.isError(variable)) { |
1218 irBuilder.buildStaticNoSuchMethod( | 1169 irBuilder.buildStaticNoSuchMethod( |
1219 selector, args, sourceInformation); | 1170 selector, args, sourceInformation); |
1220 } else { | 1171 } else { |
1221 irBuilder.buildErroneousInvocation( | 1172 irBuilder.buildErroneousInvocation( |
(...skipping 30 matching lines...) Expand all Loading... |
1252 ir.Node buildFinallyBody(IrBuilder builder) { | 1203 ir.Node buildFinallyBody(IrBuilder builder) { |
1253 ir.Primitive cancellation = builder.buildDynamicInvocation( | 1204 ir.Primitive cancellation = builder.buildDynamicInvocation( |
1254 iterator, | 1205 iterator, |
1255 Selectors.cancel, | 1206 Selectors.cancel, |
1256 backend.dynamicType, | 1207 backend.dynamicType, |
1257 <ir.Primitive>[], | 1208 <ir.Primitive>[], |
1258 sourceInformationBuilder.buildGeneric(node)); | 1209 sourceInformationBuilder.buildGeneric(node)); |
1259 return builder.addPrimitive(new ir.Await(cancellation)); | 1210 return builder.addPrimitive(new ir.Await(cancellation)); |
1260 } | 1211 } |
1261 | 1212 |
1262 irBuilder.buildTryFinally(new TryStatementInfo(), buildTryBody, | 1213 irBuilder.buildTryFinally( |
1263 buildFinallyBody); | 1214 new TryStatementInfo(), buildTryBody, buildFinallyBody); |
1264 } | 1215 } |
1265 | 1216 |
1266 visitAwait(ast.Await node) { | 1217 visitAwait(ast.Await node) { |
1267 assert(irBuilder.isOpen); | 1218 assert(irBuilder.isOpen); |
1268 ir.Primitive value = visit(node.expression); | 1219 ir.Primitive value = visit(node.expression); |
1269 return irBuilder.addPrimitive(new ir.Await(value)); | 1220 return irBuilder.addPrimitive(new ir.Await(value)); |
1270 } | 1221 } |
1271 | 1222 |
1272 visitYield(ast.Yield node) { | 1223 visitYield(ast.Yield node) { |
1273 assert(irBuilder.isOpen); | 1224 assert(irBuilder.isOpen); |
(...skipping 11 matching lines...) Expand all Loading... |
1285 Element variableElement = elements.getForInVariable(node); | 1236 Element variableElement = elements.getForInVariable(node); |
1286 Selector selector = elements.getSelector(identifier); | 1237 Selector selector = elements.getSelector(identifier); |
1287 | 1238 |
1288 irBuilder.buildForIn( | 1239 irBuilder.buildForIn( |
1289 buildExpression: subbuild(node.expression), | 1240 buildExpression: subbuild(node.expression), |
1290 buildVariableDeclaration: subbuild(variableDeclaration), | 1241 buildVariableDeclaration: subbuild(variableDeclaration), |
1291 variableElement: variableElement, | 1242 variableElement: variableElement, |
1292 variableSelector: selector, | 1243 variableSelector: selector, |
1293 variableMask: elements.getTypeMask(identifier), | 1244 variableMask: elements.getTypeMask(identifier), |
1294 variableSetSourceInformation: | 1245 variableSetSourceInformation: |
1295 sourceInformationBuilder.buildForInSet(node), | 1246 sourceInformationBuilder.buildForInSet(node), |
1296 currentMask: elements.getCurrentTypeMask(node), | 1247 currentMask: elements.getCurrentTypeMask(node), |
1297 currentSourceInformation: | 1248 currentSourceInformation: |
1298 sourceInformationBuilder.buildForInCurrent(node), | 1249 sourceInformationBuilder.buildForInCurrent(node), |
1299 moveNextMask: elements.getMoveNextTypeMask(node), | 1250 moveNextMask: elements.getMoveNextTypeMask(node), |
1300 moveNextSourceInformation: | 1251 moveNextSourceInformation: |
1301 sourceInformationBuilder.buildForInMoveNext(node), | 1252 sourceInformationBuilder.buildForInMoveNext(node), |
1302 iteratorMask: elements.getIteratorTypeMask(node), | 1253 iteratorMask: elements.getIteratorTypeMask(node), |
1303 iteratorSourceInformation: | 1254 iteratorSourceInformation: |
1304 sourceInformationBuilder.buildForInIterator(node), | 1255 sourceInformationBuilder.buildForInIterator(node), |
1305 buildBody: subbuild(node.body), | 1256 buildBody: subbuild(node.body), |
1306 target: elements.getTargetDefinition(node), | 1257 target: elements.getTargetDefinition(node), |
1307 closureScope: getClosureScopeForNode(node)); | 1258 closureScope: getClosureScopeForNode(node)); |
1308 } | 1259 } |
1309 | 1260 |
1310 /// If compiling with trusted type annotations, assumes that [value] is | 1261 /// If compiling with trusted type annotations, assumes that [value] is |
1311 /// now known to be `null` or an instance of [type]. | 1262 /// now known to be `null` or an instance of [type]. |
1312 /// | 1263 /// |
1313 /// This is also where we should add type checks in checked mode, but this | 1264 /// This is also where we should add type checks in checked mode, but this |
1314 /// is not supported yet. | 1265 /// is not supported yet. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 visitReturn(ast.Return node) { | 1303 visitReturn(ast.Return node) { |
1353 assert(irBuilder.isOpen); | 1304 assert(irBuilder.isOpen); |
1354 SourceInformation source = sourceInformationBuilder.buildReturn(node); | 1305 SourceInformation source = sourceInformationBuilder.buildReturn(node); |
1355 if (node.beginToken.value == 'native') { | 1306 if (node.beginToken.value == 'native') { |
1356 FunctionElement function = irBuilder.state.currentElement; | 1307 FunctionElement function = irBuilder.state.currentElement; |
1357 assert(backend.isNative(function)); | 1308 assert(backend.isNative(function)); |
1358 ast.Node nativeBody = node.expression; | 1309 ast.Node nativeBody = node.expression; |
1359 if (nativeBody != null) { | 1310 if (nativeBody != null) { |
1360 ast.LiteralString jsCode = nativeBody.asLiteralString(); | 1311 ast.LiteralString jsCode = nativeBody.asLiteralString(); |
1361 String javaScriptCode = jsCode.dartString.slowToString(); | 1312 String javaScriptCode = jsCode.dartString.slowToString(); |
1362 assert(invariant(nativeBody, | 1313 assert(invariant( |
1363 !nativeRedirectionRegExp.hasMatch(javaScriptCode), | 1314 nativeBody, !nativeRedirectionRegExp.hasMatch(javaScriptCode), |
1364 message: "Deprecated syntax, use @JSName('name') instead.")); | 1315 message: "Deprecated syntax, use @JSName('name') instead.")); |
1365 assert(invariant(nativeBody, | 1316 assert(invariant( |
1366 function.functionSignature.parameterCount == 0, | 1317 nativeBody, function.functionSignature.parameterCount == 0, |
1367 message: 'native "..." syntax is restricted to ' | 1318 message: 'native "..." syntax is restricted to ' |
1368 'functions with zero parameters.')); | 1319 'functions with zero parameters.')); |
1369 irBuilder.buildNativeFunctionBody(function, javaScriptCode, | 1320 irBuilder.buildNativeFunctionBody(function, javaScriptCode, |
1370 sourceInformationBuilder.buildForeignCode(node)); | 1321 sourceInformationBuilder.buildForeignCode(node)); |
1371 } else { | 1322 } else { |
1372 String name = backend.nativeData.getFixedBackendName(function); | 1323 String name = backend.nativeData.getFixedBackendName(function); |
1373 irBuilder.buildRedirectingNativeFunctionBody(function, name, source); | 1324 irBuilder.buildRedirectingNativeFunctionBody(function, name, source); |
1374 } | 1325 } |
1375 } else { | 1326 } else { |
1376 irBuilder.buildReturn( | 1327 irBuilder.buildReturn( |
1377 value: build(node.expression), | 1328 value: build(node.expression), sourceInformation: source); |
1378 sourceInformation: source); | |
1379 } | 1329 } |
1380 } | 1330 } |
1381 | 1331 |
1382 visitSwitchStatement(ast.SwitchStatement node) { | 1332 visitSwitchStatement(ast.SwitchStatement node) { |
1383 // Dart switch cases can be labeled and be the target of continue from | 1333 // Dart switch cases can be labeled and be the target of continue from |
1384 // within the switch. Such cases are 'recursive'. If there are any | 1334 // within the switch. Such cases are 'recursive'. If there are any |
1385 // recursive cases, we implement the switch using a pair of switches with | 1335 // recursive cases, we implement the switch using a pair of switches with |
1386 // the second one switching over a state variable in a loop. The first | 1336 // the second one switching over a state variable in a loop. The first |
1387 // switch contains the non-recursive cases, and the second switch contains | 1337 // switch contains the non-recursive cases, and the second switch contains |
1388 // the recursive ones. | 1338 // the recursive ones. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 // Use a simple switch for the non-recursive cases. A break will go to the | 1414 // Use a simple switch for the non-recursive cases. A break will go to the |
1465 // join-point after the switch. A continue to a labeled case will assign | 1415 // join-point after the switch. A continue to a labeled case will assign |
1466 // to the state variable and go to the join-point. | 1416 // to the state variable and go to the join-point. |
1467 ir.Primitive value = visit(node.expression); | 1417 ir.Primitive value = visit(node.expression); |
1468 JumpCollector join = new ForwardJumpCollector(irBuilder.environment, | 1418 JumpCollector join = new ForwardJumpCollector(irBuilder.environment, |
1469 target: elements.getTargetDefinition(node)); | 1419 target: elements.getTargetDefinition(node)); |
1470 irBuilder.state.breakCollectors.add(join); | 1420 irBuilder.state.breakCollectors.add(join); |
1471 for (int i = 0; i < continueTargets.length; ++i) { | 1421 for (int i = 0; i < continueTargets.length; ++i) { |
1472 // The state value is i, the case's position in the list of recursive | 1422 // The state value is i, the case's position in the list of recursive |
1473 // cases. | 1423 // cases. |
1474 irBuilder.state.continueCollectors.add(new GotoJumpCollector( | 1424 irBuilder.state.continueCollectors |
1475 continueTargets[i], stateIndex, i, join)); | 1425 .add(new GotoJumpCollector(continueTargets[i], stateIndex, i, join)); |
1476 } | 1426 } |
1477 | 1427 |
1478 // For each non-default case use a pair of functions, one to translate the | 1428 // For each non-default case use a pair of functions, one to translate the |
1479 // condition and one to translate the body. For the default case use a | 1429 // condition and one to translate the body. For the default case use a |
1480 // function to translate the body. Use continueTargetIterator as a pointer | 1430 // function to translate the body. Use continueTargetIterator as a pointer |
1481 // to the next recursive case. | 1431 // to the next recursive case. |
1482 Iterator<JumpTarget> continueTargetIterator = continueTargets.iterator; | 1432 Iterator<JumpTarget> continueTargetIterator = continueTargets.iterator; |
1483 continueTargetIterator.moveNext(); | 1433 continueTargetIterator.moveNext(); |
1484 List<SwitchCaseInfo> cases = <SwitchCaseInfo>[]; | 1434 List<SwitchCaseInfo> cases = <SwitchCaseInfo>[]; |
1485 SubbuildFunction buildDefaultBody; | 1435 SubbuildFunction buildDefaultBody; |
(...skipping 30 matching lines...) Expand all Loading... |
1516 if (labelOrCase is ast.CaseMatch) { | 1466 if (labelOrCase is ast.CaseMatch) { |
1517 ir.Primitive buildComparison() { | 1467 ir.Primitive buildComparison() { |
1518 ir.Primitive constant = | 1468 ir.Primitive constant = |
1519 translateConstant(labelOrCase.expression); | 1469 translateConstant(labelOrCase.expression); |
1520 return irBuilder.buildIdentical(value, constant); | 1470 return irBuilder.buildIdentical(value, constant); |
1521 } | 1471 } |
1522 | 1472 |
1523 if (condition == null) { | 1473 if (condition == null) { |
1524 condition = buildComparison(); | 1474 condition = buildComparison(); |
1525 } else { | 1475 } else { |
1526 condition = irBuilder.buildLogicalOperator(condition, | 1476 condition = irBuilder.buildLogicalOperator( |
| 1477 condition, |
1527 nested(buildComparison), | 1478 nested(buildComparison), |
1528 sourceInformationBuilder.buildSwitchCase(switchCase), | 1479 sourceInformationBuilder.buildSwitchCase(switchCase), |
1529 isLazyOr: true); | 1480 isLazyOr: true); |
1530 } | 1481 } |
1531 } | 1482 } |
1532 } | 1483 } |
1533 return condition; | 1484 return condition; |
1534 }); | 1485 }); |
1535 } | 1486 } |
1536 | 1487 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1582 // has not been assigned. | 1533 // has not been assigned. |
1583 // | 1534 // |
1584 // 'loop' is the join-point of the exits from the inner switch which will | 1535 // 'loop' is the join-point of the exits from the inner switch which will |
1585 // perform another iteration of the loop. 'exit' is the join-point of the | 1536 // perform another iteration of the loop. 'exit' is the join-point of the |
1586 // breaks from the switch, outside the loop. | 1537 // breaks from the switch, outside the loop. |
1587 JumpCollector loop = new ForwardJumpCollector(irBuilder.environment); | 1538 JumpCollector loop = new ForwardJumpCollector(irBuilder.environment); |
1588 JumpCollector exit = new ForwardJumpCollector(irBuilder.environment, | 1539 JumpCollector exit = new ForwardJumpCollector(irBuilder.environment, |
1589 target: elements.getTargetDefinition(node)); | 1540 target: elements.getTargetDefinition(node)); |
1590 irBuilder.state.breakCollectors.add(exit); | 1541 irBuilder.state.breakCollectors.add(exit); |
1591 for (int i = 0; i < continueTargets.length; ++i) { | 1542 for (int i = 0; i < continueTargets.length; ++i) { |
1592 irBuilder.state.continueCollectors.add(new GotoJumpCollector( | 1543 irBuilder.state.continueCollectors |
1593 continueTargets[i], stateIndex, i, loop)); | 1544 .add(new GotoJumpCollector(continueTargets[i], stateIndex, i, loop)); |
1594 } | 1545 } |
1595 cases.clear(); | 1546 cases.clear(); |
1596 for (int i = 0; i < continueTargets.length; ++i) { | 1547 for (int i = 0; i < continueTargets.length; ++i) { |
1597 // The conditions compare to the recursive case index. | 1548 // The conditions compare to the recursive case index. |
1598 ir.Primitive buildCondition(IrBuilder builder) { | 1549 ir.Primitive buildCondition(IrBuilder builder) { |
1599 ir.Primitive constant = builder.buildIntegerConstant(i); | 1550 ir.Primitive constant = builder.buildIntegerConstant(i); |
1600 return builder.buildIdentical( | 1551 return builder.buildIdentical( |
1601 builder.environment.index2value[stateIndex], constant); | 1552 builder.environment.index2value[stateIndex], constant); |
1602 } | 1553 } |
1603 | 1554 |
(...skipping 17 matching lines...) Expand all Loading... |
1621 }); | 1572 }); |
1622 return null; | 1573 return null; |
1623 } | 1574 } |
1624 | 1575 |
1625 cases.add(new SwitchCaseInfo(buildCondition, buildBody, | 1576 cases.add(new SwitchCaseInfo(buildCondition, buildBody, |
1626 sourceInformationBuilder.buildSwitch(node))); | 1577 sourceInformationBuilder.buildSwitch(node))); |
1627 } | 1578 } |
1628 | 1579 |
1629 // A loop with a simple switch in the body. | 1580 // A loop with a simple switch in the body. |
1630 IrBuilder whileBuilder = irBuilder.makeDelimitedBuilder(); | 1581 IrBuilder whileBuilder = irBuilder.makeDelimitedBuilder(); |
1631 whileBuilder.buildWhile( | 1582 whileBuilder.buildWhile(buildCondition: (IrBuilder builder) { |
1632 buildCondition: (IrBuilder builder) { | 1583 ir.Primitive condition = builder.buildIdentical( |
1633 ir.Primitive condition = builder.buildIdentical( | 1584 builder.environment.index2value[stateIndex], initial); |
1634 builder.environment.index2value[stateIndex], initial); | 1585 return builder.buildNegation( |
1635 return builder.buildNegation(condition, | 1586 condition, sourceInformationBuilder.buildSwitch(node)); |
1636 sourceInformationBuilder.buildSwitch(node)); | 1587 }, buildBody: (IrBuilder builder) { |
1637 }, | 1588 builder.buildSimpleSwitch(loop, cases, null); |
1638 buildBody: (IrBuilder builder) { | 1589 }); |
1639 builder.buildSimpleSwitch(loop, cases, null); | |
1640 }); | |
1641 // Jump to the exit continuation. This jump is the body of the loop exit | 1590 // Jump to the exit continuation. This jump is the body of the loop exit |
1642 // continuation, so the loop exit continuation can be eta-reduced. The | 1591 // continuation, so the loop exit continuation can be eta-reduced. The |
1643 // jump is here for simplicity because `buildWhile` does not expose the | 1592 // jump is here for simplicity because `buildWhile` does not expose the |
1644 // loop's exit continuation directly and has already emitted all jumps | 1593 // loop's exit continuation directly and has already emitted all jumps |
1645 // to it anyway. | 1594 // to it anyway. |
1646 whileBuilder.jumpTo(exit); | 1595 whileBuilder.jumpTo(exit); |
1647 irBuilder.add(new ir.LetCont(exit.continuation, whileBuilder.root)); | 1596 irBuilder.add(new ir.LetCont(exit.continuation, whileBuilder.root)); |
1648 irBuilder.environment = exit.environment; | 1597 irBuilder.environment = exit.environment; |
1649 irBuilder.environment.discard(1); // Discard the state variable. | 1598 irBuilder.environment.discard(1); // Discard the state variable. |
1650 irBuilder.state.breakCollectors.removeLast(); | 1599 irBuilder.state.breakCollectors.removeLast(); |
1651 irBuilder.state.continueCollectors.length -= continueTargets.length; | 1600 irBuilder.state.continueCollectors.length -= continueTargets.length; |
1652 } | 1601 } |
1653 | 1602 |
1654 visitTryStatement(ast.TryStatement node) { | 1603 visitTryStatement(ast.TryStatement node) { |
1655 List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[]; | 1604 List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[]; |
1656 for (ast.CatchBlock catchClause in node.catchBlocks.nodes) { | 1605 for (ast.CatchBlock catchClause in node.catchBlocks.nodes) { |
1657 LocalVariableElement exceptionVariable; | 1606 LocalVariableElement exceptionVariable; |
1658 if (catchClause.exception != null) { | 1607 if (catchClause.exception != null) { |
1659 exceptionVariable = elements[catchClause.exception]; | 1608 exceptionVariable = elements[catchClause.exception]; |
(...skipping 16 matching lines...) Expand all Loading... |
1676 | 1625 |
1677 assert(!node.catchBlocks.isEmpty || node.finallyBlock != null); | 1626 assert(!node.catchBlocks.isEmpty || node.finallyBlock != null); |
1678 if (!node.catchBlocks.isEmpty && node.finallyBlock != null) { | 1627 if (!node.catchBlocks.isEmpty && node.finallyBlock != null) { |
1679 // Try/catch/finally is encoded in terms of try/catch and try/finally: | 1628 // Try/catch/finally is encoded in terms of try/catch and try/finally: |
1680 // | 1629 // |
1681 // try tryBlock catch (ex, st) catchBlock finally finallyBlock | 1630 // try tryBlock catch (ex, st) catchBlock finally finallyBlock |
1682 // ==> | 1631 // ==> |
1683 // try { try tryBlock catch (ex, st) catchBlock } finally finallyBlock | 1632 // try { try tryBlock catch (ex, st) catchBlock } finally finallyBlock |
1684 irBuilder.buildTryFinally(tryStatements[node.finallyBlock], | 1633 irBuilder.buildTryFinally(tryStatements[node.finallyBlock], |
1685 (IrBuilder inner) { | 1634 (IrBuilder inner) { |
1686 inner.buildTryCatch(tryStatements[node.catchBlocks], | 1635 inner.buildTryCatch(tryStatements[node.catchBlocks], |
1687 subbuild(node.tryBlock), | 1636 subbuild(node.tryBlock), catchClauseInfos); |
1688 catchClauseInfos); | 1637 }, subbuild(node.finallyBlock)); |
1689 }, | |
1690 subbuild(node.finallyBlock)); | |
1691 } else if (!node.catchBlocks.isEmpty) { | 1638 } else if (!node.catchBlocks.isEmpty) { |
1692 irBuilder.buildTryCatch(tryStatements[node.catchBlocks], | 1639 irBuilder.buildTryCatch(tryStatements[node.catchBlocks], |
1693 subbuild(node.tryBlock), | 1640 subbuild(node.tryBlock), catchClauseInfos); |
1694 catchClauseInfos); | |
1695 } else { | 1641 } else { |
1696 irBuilder.buildTryFinally(tryStatements[node.finallyBlock], | 1642 irBuilder.buildTryFinally(tryStatements[node.finallyBlock], |
1697 subbuild(node.tryBlock), | 1643 subbuild(node.tryBlock), subbuild(node.finallyBlock)); |
1698 subbuild(node.finallyBlock)); | |
1699 } | 1644 } |
1700 } | 1645 } |
1701 | 1646 |
1702 // ## Expressions ## | 1647 // ## Expressions ## |
1703 ir.Primitive visitConditional(ast.Conditional node) { | 1648 ir.Primitive visitConditional(ast.Conditional node) { |
1704 return irBuilder.buildConditional( | 1649 return irBuilder.buildConditional( |
1705 build(node.condition), | 1650 build(node.condition), |
1706 subbuild(node.thenExpression), | 1651 subbuild(node.thenExpression), |
1707 subbuild(node.elseExpression), | 1652 subbuild(node.elseExpression), |
1708 sourceInformationBuilder.buildIf(node)); | 1653 sourceInformationBuilder.buildIf(node)); |
(...skipping 27 matching lines...) Expand all Loading... |
1736 } | 1681 } |
1737 | 1682 |
1738 ConstantValue getConstantForNode(ast.Node node) { | 1683 ConstantValue getConstantForNode(ast.Node node) { |
1739 return irBuilder.state.constants.getConstantValueForNode(node, elements); | 1684 return irBuilder.state.constants.getConstantValueForNode(node, elements); |
1740 } | 1685 } |
1741 | 1686 |
1742 ConstantValue getConstantForVariable(VariableElement element) { | 1687 ConstantValue getConstantForVariable(VariableElement element) { |
1743 return irBuilder.state.constants.getConstantValueForVariable(element); | 1688 return irBuilder.state.constants.getConstantValueForVariable(element); |
1744 } | 1689 } |
1745 | 1690 |
1746 ir.Primitive buildConstantExpression(ConstantExpression expression, | 1691 ir.Primitive buildConstantExpression( |
1747 SourceInformation sourceInformation) { | 1692 ConstantExpression expression, SourceInformation sourceInformation) { |
1748 return irBuilder.buildConstant( | 1693 return irBuilder.buildConstant( |
1749 irBuilder.state.constants.getConstantValue(expression), | 1694 irBuilder.state.constants.getConstantValue(expression), |
1750 sourceInformation: sourceInformation); | 1695 sourceInformation: sourceInformation); |
1751 } | 1696 } |
1752 | 1697 |
1753 /// Returns the allocation site-specific type for a given allocation. | 1698 /// Returns the allocation site-specific type for a given allocation. |
1754 /// | 1699 /// |
1755 /// Currently, it is an error to call this with anything that is not the | 1700 /// Currently, it is an error to call this with anything that is not the |
1756 /// allocation site for a List object (a literal list or a call to one | 1701 /// allocation site for a List object (a literal list or a call to one |
1757 /// of the List constructors). | 1702 /// of the List constructors). |
1758 TypeMask getAllocationSiteType(ast.Node node) { | 1703 TypeMask getAllocationSiteType(ast.Node node) { |
1759 return compiler.typesTask.getGuaranteedTypeOfNode( | 1704 return compiler.typesTask |
1760 elements.analyzedElement, node); | 1705 .getGuaranteedTypeOfNode(elements.analyzedElement, node); |
1761 } | 1706 } |
1762 | 1707 |
1763 ir.Primitive visitLiteralList(ast.LiteralList node) { | 1708 ir.Primitive visitLiteralList(ast.LiteralList node) { |
1764 if (node.isConst) { | 1709 if (node.isConst) { |
1765 return translateConstant(node); | 1710 return translateConstant(node); |
1766 } | 1711 } |
1767 List<ir.Primitive> values = node.elements.nodes.mapToList(visit); | 1712 List<ir.Primitive> values = node.elements.nodes.mapToList(visit); |
1768 InterfaceType type = elements.getType(node); | 1713 InterfaceType type = elements.getType(node); |
1769 TypeMask allocationSiteType = getAllocationSiteType(node); | 1714 TypeMask allocationSiteType = getAllocationSiteType(node); |
1770 // TODO(sra): In checked mode, the elements must be checked as though | 1715 // TODO(sra): In checked mode, the elements must be checked as though |
1771 // operator[]= is called. | 1716 // operator[]= is called. |
1772 ir.Primitive list = irBuilder.buildListLiteral(type, values, | 1717 ir.Primitive list = irBuilder.buildListLiteral(type, values, |
1773 allocationSiteType: allocationSiteType); | 1718 allocationSiteType: allocationSiteType); |
1774 if (type.treatAsRaw) return list; | 1719 if (type.treatAsRaw) return list; |
1775 // Call JSArray<E>.typed(allocation) to install the reified type. | 1720 // Call JSArray<E>.typed(allocation) to install the reified type. |
1776 ConstructorElement constructor = helpers.jsArrayTypedConstructor; | 1721 ConstructorElement constructor = helpers.jsArrayTypedConstructor; |
1777 ir.Primitive tagged = irBuilder.buildConstructorInvocation( | 1722 ir.Primitive tagged = irBuilder.buildConstructorInvocation( |
1778 constructor.effectiveTarget, | 1723 constructor.effectiveTarget, |
1779 CallStructure.ONE_ARG, | 1724 CallStructure.ONE_ARG, |
1780 constructor.computeEffectiveTargetType(type), | 1725 constructor.computeEffectiveTargetType(type), |
1781 <ir.Primitive>[list], | 1726 <ir.Primitive>[list], |
1782 sourceInformationBuilder.buildNew(node)); | 1727 sourceInformationBuilder.buildNew(node)); |
1783 | 1728 |
1784 if (allocationSiteType == null) return tagged; | 1729 if (allocationSiteType == null) return tagged; |
1785 | 1730 |
1786 return irBuilder.addPrimitive( | 1731 return irBuilder |
1787 new ir.Refinement(tagged, allocationSiteType)); | 1732 .addPrimitive(new ir.Refinement(tagged, allocationSiteType)); |
1788 } | 1733 } |
1789 | 1734 |
1790 ir.Primitive visitLiteralMap(ast.LiteralMap node) { | 1735 ir.Primitive visitLiteralMap(ast.LiteralMap node) { |
1791 assert(irBuilder.isOpen); | 1736 assert(irBuilder.isOpen); |
1792 if (node.isConst) { | 1737 if (node.isConst) { |
1793 return translateConstant(node); | 1738 return translateConstant(node); |
1794 } | 1739 } |
1795 | 1740 |
1796 InterfaceType type = elements.getType(node); | 1741 InterfaceType type = elements.getType(node); |
1797 | 1742 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 <ir.Primitive>[keysAndValuesList], | 1779 <ir.Primitive>[keysAndValuesList], |
1835 sourceInformationBuilder.buildNew(node)); | 1780 sourceInformationBuilder.buildNew(node)); |
1836 } | 1781 } |
1837 } | 1782 } |
1838 | 1783 |
1839 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) { | 1784 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) { |
1840 assert(irBuilder.isOpen); | 1785 assert(irBuilder.isOpen); |
1841 return translateConstant(node); | 1786 return translateConstant(node); |
1842 } | 1787 } |
1843 | 1788 |
1844 ir.Primitive visitParenthesizedExpression( | 1789 ir.Primitive visitParenthesizedExpression(ast.ParenthesizedExpression node) { |
1845 ast.ParenthesizedExpression node) { | |
1846 assert(irBuilder.isOpen); | 1790 assert(irBuilder.isOpen); |
1847 return visit(node.expression); | 1791 return visit(node.expression); |
1848 } | 1792 } |
1849 | 1793 |
1850 // Stores the result of visiting a CascadeReceiver, so we can return it from | 1794 // Stores the result of visiting a CascadeReceiver, so we can return it from |
1851 // its enclosing Cascade. | 1795 // its enclosing Cascade. |
1852 ir.Primitive _currentCascadeReceiver; | 1796 ir.Primitive _currentCascadeReceiver; |
1853 | 1797 |
1854 ir.Primitive visitCascadeReceiver(ast.CascadeReceiver node) { | 1798 ir.Primitive visitCascadeReceiver(ast.CascadeReceiver node) { |
1855 assert(irBuilder.isOpen); | 1799 assert(irBuilder.isOpen); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 <ir.Primitive>[name, uri], | 1844 <ir.Primitive>[name, uri], |
1901 sourceInformation); | 1845 sourceInformation); |
1902 } | 1846 } |
1903 | 1847 |
1904 ir.Primitive visitNamedArgument(ast.NamedArgument node) { | 1848 ir.Primitive visitNamedArgument(ast.NamedArgument node) { |
1905 assert(irBuilder.isOpen); | 1849 assert(irBuilder.isOpen); |
1906 return visit(node.expression); | 1850 return visit(node.expression); |
1907 } | 1851 } |
1908 | 1852 |
1909 @override | 1853 @override |
1910 ir.Primitive visitExpressionInvoke(ast.Send node, | 1854 ir.Primitive visitExpressionInvoke(ast.Send node, ast.Node expression, |
1911 ast.Node expression, | 1855 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
1912 ast.NodeList argumentsNode, | |
1913 CallStructure callStructure, _) { | |
1914 ir.Primitive receiver = visit(expression); | 1856 ir.Primitive receiver = visit(expression); |
1915 List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit); | 1857 List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit); |
1916 callStructure = normalizeDynamicArguments(callStructure, arguments); | 1858 callStructure = normalizeDynamicArguments(callStructure, arguments); |
1917 return irBuilder.buildCallInvocation(receiver, callStructure, arguments, | 1859 return irBuilder.buildCallInvocation(receiver, callStructure, arguments, |
1918 sourceInformationBuilder.buildCall(node, argumentsNode)); | 1860 sourceInformationBuilder.buildCall(node, argumentsNode)); |
1919 } | 1861 } |
1920 | 1862 |
1921 /// Returns `true` if [node] is a super call. | 1863 /// Returns `true` if [node] is a super call. |
1922 // TODO(johnniwinther): Remove the need for this. | 1864 // TODO(johnniwinther): Remove the need for this. |
1923 bool isSuperCall(ast.Send node) { | 1865 bool isSuperCall(ast.Send node) { |
1924 return node != null && node.receiver != null && node.receiver.isSuper(); | 1866 return node != null && node.receiver != null && node.receiver.isSuper(); |
1925 } | 1867 } |
1926 | 1868 |
1927 @override | 1869 @override |
1928 ir.Primitive handleConstantGet( | 1870 ir.Primitive handleConstantGet( |
1929 ast.Node node, | 1871 ast.Node node, ConstantExpression constant, _) { |
1930 ConstantExpression constant, _) { | 1872 return buildConstantExpression( |
1931 return buildConstantExpression(constant, | 1873 constant, sourceInformationBuilder.buildGet(node)); |
1932 sourceInformationBuilder.buildGet(node)); | |
1933 } | 1874 } |
1934 | 1875 |
1935 /// If [node] is null, returns this. | 1876 /// If [node] is null, returns this. |
1936 /// Otherwise visits [node] and returns the result. | 1877 /// Otherwise visits [node] and returns the result. |
1937 ir.Primitive translateReceiver(ast.Expression node) { | 1878 ir.Primitive translateReceiver(ast.Expression node) { |
1938 return node != null ? visit(node) : irBuilder.buildThis(); | 1879 return node != null ? visit(node) : irBuilder.buildThis(); |
1939 } | 1880 } |
1940 | 1881 |
1941 @override | 1882 @override |
1942 ir.Primitive handleDynamicGet( | 1883 ir.Primitive handleDynamicGet( |
1943 ast.Send node, | 1884 ast.Send node, ast.Node receiver, Name name, _) { |
1944 ast.Node receiver, | |
1945 Name name, | |
1946 _) { | |
1947 return irBuilder.buildDynamicGet( | 1885 return irBuilder.buildDynamicGet( |
1948 translateReceiver(receiver), | 1886 translateReceiver(receiver), |
1949 new Selector.getter(name), | 1887 new Selector.getter(name), |
1950 elements.getTypeMask(node), | 1888 elements.getTypeMask(node), |
1951 sourceInformationBuilder.buildGet(node)); | 1889 sourceInformationBuilder.buildGet(node)); |
1952 } | 1890 } |
1953 | 1891 |
1954 @override | 1892 @override |
1955 ir.Primitive visitIfNotNullDynamicPropertyGet( | 1893 ir.Primitive visitIfNotNullDynamicPropertyGet( |
1956 ast.Send node, | 1894 ast.Send node, ast.Node receiver, Name name, _) { |
1957 ast.Node receiver, | |
1958 Name name, | |
1959 _) { | |
1960 ir.Primitive target = visit(receiver); | 1895 ir.Primitive target = visit(receiver); |
1961 return irBuilder.buildIfNotNullSend( | 1896 return irBuilder.buildIfNotNullSend( |
1962 target, | 1897 target, |
1963 nested(() => irBuilder.buildDynamicGet( | 1898 nested(() => irBuilder.buildDynamicGet( |
1964 target, | 1899 target, |
1965 new Selector.getter(name), | 1900 new Selector.getter(name), |
1966 elements.getTypeMask(node), | 1901 elements.getTypeMask(node), |
1967 sourceInformationBuilder.buildGet(node))), | 1902 sourceInformationBuilder.buildGet(node))), |
1968 sourceInformationBuilder.buildIf(node)); | 1903 sourceInformationBuilder.buildIf(node)); |
1969 } | 1904 } |
1970 | 1905 |
1971 @override | 1906 @override |
1972 ir.Primitive visitDynamicTypeLiteralGet( | 1907 ir.Primitive visitDynamicTypeLiteralGet( |
1973 ast.Send node, | 1908 ast.Send node, ConstantExpression constant, _) { |
1974 ConstantExpression constant, | 1909 return buildConstantExpression( |
1975 _) { | 1910 constant, sourceInformationBuilder.buildGet(node)); |
1976 return buildConstantExpression(constant, | |
1977 sourceInformationBuilder.buildGet(node)); | |
1978 } | 1911 } |
1979 | 1912 |
1980 @override | 1913 @override |
1981 ir.Primitive visitLocalVariableGet( | 1914 ir.Primitive visitLocalVariableGet( |
1982 ast.Send node, | 1915 ast.Send node, LocalVariableElement element, _) { |
1983 LocalVariableElement element, | |
1984 _) { | |
1985 return element.isConst | 1916 return element.isConst |
1986 ? irBuilder.buildConstant(getConstantForVariable(element), | 1917 ? irBuilder.buildConstant(getConstantForVariable(element), |
1987 sourceInformation: sourceInformationBuilder.buildGet(node)) | 1918 sourceInformation: sourceInformationBuilder.buildGet(node)) |
1988 : irBuilder.buildLocalGet(element); | 1919 : irBuilder.buildLocalGet(element); |
1989 } | 1920 } |
1990 | 1921 |
1991 ir.Primitive handleLocalGet( | 1922 ir.Primitive handleLocalGet(ast.Send node, LocalElement element, _) { |
1992 ast.Send node, | |
1993 LocalElement element, | |
1994 _) { | |
1995 return irBuilder.buildLocalGet(element); | 1923 return irBuilder.buildLocalGet(element); |
1996 } | 1924 } |
1997 | 1925 |
1998 @override | 1926 @override |
1999 ir.Primitive handleStaticFunctionGet( | 1927 ir.Primitive handleStaticFunctionGet( |
2000 ast.Send node, | 1928 ast.Send node, MethodElement function, _) { |
2001 MethodElement function, | |
2002 _) { | |
2003 return irBuilder.addPrimitive(new ir.GetStatic(function, isFinal: true)); | 1929 return irBuilder.addPrimitive(new ir.GetStatic(function, isFinal: true)); |
2004 } | 1930 } |
2005 | 1931 |
2006 @override | 1932 @override |
2007 ir.Primitive handleStaticGetterGet( | 1933 ir.Primitive handleStaticGetterGet(ast.Send node, FunctionElement getter, _) { |
2008 ast.Send node, | 1934 return buildStaticGetterGet( |
2009 FunctionElement getter, | 1935 getter, node, sourceInformationBuilder.buildGet(node)); |
2010 _) { | |
2011 return buildStaticGetterGet( | |
2012 getter, node, sourceInformationBuilder.buildGet(node)); | |
2013 } | 1936 } |
2014 | 1937 |
2015 /// Create a getter invocation of the static getter [getter]. This also | 1938 /// Create a getter invocation of the static getter [getter]. This also |
2016 /// handles the special case where [getter] is the `loadLibrary` | 1939 /// handles the special case where [getter] is the `loadLibrary` |
2017 /// pseudo-function on library prefixes of deferred imports. | 1940 /// pseudo-function on library prefixes of deferred imports. |
2018 ir.Primitive buildStaticGetterGet( | 1941 ir.Primitive buildStaticGetterGet(MethodElement getter, ast.Send node, |
2019 MethodElement getter, | |
2020 ast.Send node, | |
2021 SourceInformation sourceInformation) { | 1942 SourceInformation sourceInformation) { |
2022 if (getter.isDeferredLoaderGetter) { | 1943 if (getter.isDeferredLoaderGetter) { |
2023 PrefixElement prefix = getter.enclosingElement; | 1944 PrefixElement prefix = getter.enclosingElement; |
2024 ir.Primitive loadId = irBuilder.buildStringConstant( | 1945 ir.Primitive loadId = irBuilder.buildStringConstant( |
2025 compiler.deferredLoadTask.getImportDeferName(node, prefix)); | 1946 compiler.deferredLoadTask.getImportDeferName(node, prefix)); |
2026 return irBuilder.buildStaticFunctionInvocation( | 1947 return irBuilder.buildStaticFunctionInvocation( |
2027 compiler.loadLibraryFunction, | 1948 compiler.loadLibraryFunction, |
2028 <ir.Primitive>[loadId], | 1949 <ir.Primitive>[loadId], |
2029 sourceInformation); | 1950 sourceInformation); |
2030 } else { | 1951 } else { |
2031 return irBuilder.buildStaticGetterGet(getter, sourceInformation); | 1952 return irBuilder.buildStaticGetterGet(getter, sourceInformation); |
2032 } | 1953 } |
2033 } | 1954 } |
2034 | 1955 |
2035 @override | 1956 @override |
2036 ir.Primitive visitSuperFieldGet( | 1957 ir.Primitive visitSuperFieldGet(ast.Send node, FieldElement field, _) { |
2037 ast.Send node, | |
2038 FieldElement field, | |
2039 _) { | |
2040 return irBuilder.buildSuperFieldGet( | 1958 return irBuilder.buildSuperFieldGet( |
2041 field, sourceInformationBuilder.buildGet(node)); | 1959 field, sourceInformationBuilder.buildGet(node)); |
2042 } | 1960 } |
2043 | 1961 |
2044 @override | 1962 @override |
2045 ir.Primitive visitSuperGetterGet( | 1963 ir.Primitive visitSuperGetterGet(ast.Send node, FunctionElement getter, _) { |
2046 ast.Send node, | |
2047 FunctionElement getter, | |
2048 _) { | |
2049 return irBuilder.buildSuperGetterGet( | 1964 return irBuilder.buildSuperGetterGet( |
2050 getter, sourceInformationBuilder.buildGet(node)); | 1965 getter, sourceInformationBuilder.buildGet(node)); |
2051 } | 1966 } |
2052 | 1967 |
2053 @override | 1968 @override |
2054 ir.Primitive visitSuperMethodGet( | 1969 ir.Primitive visitSuperMethodGet(ast.Send node, MethodElement method, _) { |
2055 ast.Send node, | |
2056 MethodElement method, | |
2057 _) { | |
2058 return irBuilder.buildSuperMethodGet( | 1970 return irBuilder.buildSuperMethodGet( |
2059 method, sourceInformationBuilder.buildGet(node)); | 1971 method, sourceInformationBuilder.buildGet(node)); |
2060 } | 1972 } |
2061 | 1973 |
2062 @override | 1974 @override |
2063 ir.Primitive visitUnresolvedSuperGet( | 1975 ir.Primitive visitUnresolvedSuperGet(ast.Send node, Element element, _) { |
2064 ast.Send node, | |
2065 Element element, _) { | |
2066 return buildSuperNoSuchMethod( | 1976 return buildSuperNoSuchMethod( |
2067 elements.getSelector(node), elements.getTypeMask(node), [], | 1977 elements.getSelector(node), |
| 1978 elements.getTypeMask(node), |
| 1979 [], |
2068 sourceInformationBuilder.buildGet(node)); | 1980 sourceInformationBuilder.buildGet(node)); |
2069 } | 1981 } |
2070 | 1982 |
2071 @override | 1983 @override |
2072 ir.Primitive visitUnresolvedSuperSet( | 1984 ir.Primitive visitUnresolvedSuperSet( |
2073 ast.Send node, | 1985 ast.Send node, Element element, ast.Node rhs, _) { |
2074 Element element, | |
2075 ast.Node rhs, _) { | |
2076 return buildSuperNoSuchMethod( | 1986 return buildSuperNoSuchMethod( |
2077 elements.getSelector(node), elements.getTypeMask(node), [visit(rhs)], | 1987 elements.getSelector(node), |
| 1988 elements.getTypeMask(node), |
| 1989 [visit(rhs)], |
2078 sourceInformationBuilder.buildAssignment(node)); | 1990 sourceInformationBuilder.buildAssignment(node)); |
2079 } | 1991 } |
2080 | 1992 |
2081 @override | 1993 @override |
2082 ir.Primitive visitThisGet(ast.Identifier node, _) { | 1994 ir.Primitive visitThisGet(ast.Identifier node, _) { |
2083 if (irBuilder.state.thisParameter == null) { | 1995 if (irBuilder.state.thisParameter == null) { |
2084 // TODO(asgerf,johnniwinther): Should be in a visitInvalidThis method. | 1996 // TODO(asgerf,johnniwinther): Should be in a visitInvalidThis method. |
2085 // 'this' in static context. Just translate to null. | 1997 // 'this' in static context. Just translate to null. |
2086 assert(compiler.compilationFailed); | 1998 assert(compiler.compilationFailed); |
2087 return irBuilder.buildNullConstant(); | 1999 return irBuilder.buildNullConstant(); |
2088 } | 2000 } |
2089 return irBuilder.buildThis(); | 2001 return irBuilder.buildThis(); |
2090 } | 2002 } |
2091 | 2003 |
2092 ir.Primitive translateTypeVariableTypeLiteral( | 2004 ir.Primitive translateTypeVariableTypeLiteral( |
2093 TypeVariableElement element, | 2005 TypeVariableElement element, SourceInformation sourceInformation) { |
2094 SourceInformation sourceInformation) { | |
2095 return irBuilder.buildReifyTypeVariable(element.type, sourceInformation); | 2006 return irBuilder.buildReifyTypeVariable(element.type, sourceInformation); |
2096 } | 2007 } |
2097 | 2008 |
2098 @override | 2009 @override |
2099 ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node, | 2010 ir.Primitive visitTypeVariableTypeLiteralGet( |
2100 TypeVariableElement element, _) { | 2011 ast.Send node, TypeVariableElement element, _) { |
2101 return translateTypeVariableTypeLiteral(element, | 2012 return translateTypeVariableTypeLiteral( |
2102 sourceInformationBuilder.buildGet(node)); | 2013 element, sourceInformationBuilder.buildGet(node)); |
2103 } | 2014 } |
2104 | 2015 |
2105 ir.Primitive translateLogicalOperator(ast.Expression left, | 2016 ir.Primitive translateLogicalOperator(ast.Expression left, |
2106 ast.Expression right, | 2017 ast.Expression right, SourceInformation sourceInformation, |
2107 SourceInformation sourceInformation, | 2018 {bool isLazyOr}) { |
2108 {bool isLazyOr}) { | |
2109 ir.Primitive leftValue = visit(left); | 2019 ir.Primitive leftValue = visit(left); |
2110 | 2020 |
2111 ir.Primitive buildRightValue(IrBuilder rightBuilder) { | 2021 ir.Primitive buildRightValue(IrBuilder rightBuilder) { |
2112 return withBuilder(rightBuilder, () => visit(right)); | 2022 return withBuilder(rightBuilder, () => visit(right)); |
2113 } | 2023 } |
2114 | 2024 |
2115 return irBuilder.buildLogicalOperator( | 2025 return irBuilder.buildLogicalOperator( |
2116 leftValue, buildRightValue, sourceInformation, isLazyOr: isLazyOr); | 2026 leftValue, buildRightValue, sourceInformation, |
| 2027 isLazyOr: isLazyOr); |
2117 } | 2028 } |
2118 | 2029 |
2119 @override | 2030 @override |
2120 ir.Primitive visitIfNull( | 2031 ir.Primitive visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) { |
2121 ast.Send node, ast.Node left, ast.Node right, _) { | 2032 return irBuilder.buildIfNull( |
2122 return irBuilder.buildIfNull(build(left), subbuild(right), | 2033 build(left), subbuild(right), sourceInformationBuilder.buildIf(node)); |
2123 sourceInformationBuilder.buildIf(node)); | |
2124 } | 2034 } |
2125 | 2035 |
2126 @override | 2036 @override |
2127 ir.Primitive visitLogicalAnd( | 2037 ir.Primitive visitLogicalAnd( |
2128 ast.Send node, ast.Node left, ast.Node right, _) { | 2038 ast.Send node, ast.Node left, ast.Node right, _) { |
2129 return translateLogicalOperator(left, right, | 2039 return translateLogicalOperator( |
2130 sourceInformationBuilder.buildIf(node), isLazyOr: false); | 2040 left, right, sourceInformationBuilder.buildIf(node), |
| 2041 isLazyOr: false); |
2131 } | 2042 } |
2132 | 2043 |
2133 @override | 2044 @override |
2134 ir.Primitive visitLogicalOr( | 2045 ir.Primitive visitLogicalOr(ast.Send node, ast.Node left, ast.Node right, _) { |
2135 ast.Send node, ast.Node left, ast.Node right, _) { | 2046 return translateLogicalOperator( |
2136 return translateLogicalOperator(left, right, | 2047 left, right, sourceInformationBuilder.buildIf(node), |
2137 sourceInformationBuilder.buildIf(node), isLazyOr: true); | 2048 isLazyOr: true); |
2138 } | 2049 } |
2139 | 2050 |
2140 @override | 2051 @override |
2141 ir.Primitive visitAs( | 2052 ir.Primitive visitAs(ast.Send node, ast.Node expression, DartType type, _) { |
2142 ast.Send node, | |
2143 ast.Node expression, | |
2144 DartType type, | |
2145 _) { | |
2146 ir.Primitive receiver = visit(expression); | 2053 ir.Primitive receiver = visit(expression); |
2147 return irBuilder.buildTypeOperator( | 2054 return irBuilder.buildTypeOperator( |
2148 receiver, | 2055 receiver, type, sourceInformationBuilder.buildAs(node), |
2149 type, | |
2150 sourceInformationBuilder.buildAs(node), | |
2151 isTypeTest: false); | 2056 isTypeTest: false); |
2152 } | 2057 } |
2153 | 2058 |
2154 @override | 2059 @override |
2155 ir.Primitive visitIs( | 2060 ir.Primitive visitIs(ast.Send node, ast.Node expression, DartType type, _) { |
2156 ast.Send node, | |
2157 ast.Node expression, | |
2158 DartType type, | |
2159 _) { | |
2160 ir.Primitive value = visit(expression); | 2061 ir.Primitive value = visit(expression); |
2161 return irBuilder.buildTypeOperator( | 2062 return irBuilder.buildTypeOperator( |
2162 value, | 2063 value, type, sourceInformationBuilder.buildIs(node), |
2163 type, | |
2164 sourceInformationBuilder.buildIs(node), | |
2165 isTypeTest: true); | 2064 isTypeTest: true); |
2166 } | 2065 } |
2167 | 2066 |
2168 @override | 2067 @override |
2169 ir.Primitive visitIsNot(ast.Send node, | 2068 ir.Primitive visitIsNot( |
2170 ast.Node expression, DartType type, _) { | 2069 ast.Send node, ast.Node expression, DartType type, _) { |
2171 ir.Primitive value = visit(expression); | 2070 ir.Primitive value = visit(expression); |
2172 ir.Primitive check = irBuilder.buildTypeOperator( | 2071 ir.Primitive check = irBuilder.buildTypeOperator( |
2173 value, | 2072 value, type, sourceInformationBuilder.buildIs(node), |
2174 type, | |
2175 sourceInformationBuilder.buildIs(node), | |
2176 isTypeTest: true); | 2073 isTypeTest: true); |
2177 return irBuilder.buildNegation(check, | 2074 return irBuilder.buildNegation( |
2178 sourceInformationBuilder.buildIf(node)); | 2075 check, sourceInformationBuilder.buildIf(node)); |
2179 } | 2076 } |
2180 | 2077 |
2181 ir.Primitive translateBinary(ast.Send node, | 2078 ir.Primitive translateBinary(ast.Send node, ast.Node left, |
2182 ast.Node left, | 2079 op.BinaryOperator operator, ast.Node right) { |
2183 op.BinaryOperator operator, | |
2184 ast.Node right) { | |
2185 ir.Primitive receiver = visit(left); | 2080 ir.Primitive receiver = visit(left); |
2186 Selector selector = new Selector.binaryOperator(operator.selectorName); | 2081 Selector selector = new Selector.binaryOperator(operator.selectorName); |
2187 List<ir.Primitive> arguments = <ir.Primitive>[visit(right)]; | 2082 List<ir.Primitive> arguments = <ir.Primitive>[visit(right)]; |
2188 CallStructure callStructure = | 2083 CallStructure callStructure = |
2189 normalizeDynamicArguments(selector.callStructure, arguments); | 2084 normalizeDynamicArguments(selector.callStructure, arguments); |
2190 return irBuilder.buildDynamicInvocation( | 2085 return irBuilder.buildDynamicInvocation( |
2191 receiver, | 2086 receiver, |
2192 new Selector(selector.kind, selector.memberName, callStructure), | 2087 new Selector(selector.kind, selector.memberName, callStructure), |
2193 elements.getTypeMask(node), | 2088 elements.getTypeMask(node), |
2194 arguments, | 2089 arguments, |
2195 sourceInformationBuilder.buildCall(node, node.selector)); | 2090 sourceInformationBuilder.buildCall(node, node.selector)); |
2196 } | 2091 } |
2197 | 2092 |
2198 @override | 2093 @override |
2199 ir.Primitive visitBinary(ast.Send node, | 2094 ir.Primitive visitBinary(ast.Send node, ast.Node left, |
2200 ast.Node left, | 2095 op.BinaryOperator operator, ast.Node right, _) { |
2201 op.BinaryOperator operator, | |
2202 ast.Node right, _) { | |
2203 return translateBinary(node, left, operator, right); | 2096 return translateBinary(node, left, operator, right); |
2204 } | 2097 } |
2205 | 2098 |
2206 @override | 2099 @override |
2207 ir.Primitive visitIndex(ast.Send node, | 2100 ir.Primitive visitIndex(ast.Send node, ast.Node receiver, ast.Node index, _) { |
2208 ast.Node receiver, | |
2209 ast.Node index, _) { | |
2210 ir.Primitive target = visit(receiver); | 2101 ir.Primitive target = visit(receiver); |
2211 Selector selector = new Selector.index(); | 2102 Selector selector = new Selector.index(); |
2212 List<ir.Primitive> arguments = <ir.Primitive>[visit(index)]; | 2103 List<ir.Primitive> arguments = <ir.Primitive>[visit(index)]; |
2213 CallStructure callStructure = | 2104 CallStructure callStructure = |
2214 normalizeDynamicArguments(selector.callStructure, arguments); | 2105 normalizeDynamicArguments(selector.callStructure, arguments); |
2215 return irBuilder.buildDynamicInvocation( | 2106 return irBuilder.buildDynamicInvocation( |
2216 target, | 2107 target, |
2217 new Selector(selector.kind, selector.memberName, callStructure), | 2108 new Selector(selector.kind, selector.memberName, callStructure), |
2218 elements.getTypeMask(node), | 2109 elements.getTypeMask(node), |
2219 arguments, | 2110 arguments, |
2220 sourceInformationBuilder.buildCall(receiver, node.selector)); | 2111 sourceInformationBuilder.buildCall(receiver, node.selector)); |
2221 } | 2112 } |
2222 | 2113 |
2223 ir.Primitive translateSuperBinary(FunctionElement function, | 2114 ir.Primitive translateSuperBinary( |
2224 op.BinaryOperator operator, | 2115 FunctionElement function, |
2225 ast.Node argument, | 2116 op.BinaryOperator operator, |
2226 SourceInformation sourceInformation) { | 2117 ast.Node argument, |
| 2118 SourceInformation sourceInformation) { |
2227 List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)]; | 2119 List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)]; |
2228 return irBuilder.buildSuperMethodInvocation(function, | 2120 return irBuilder.buildSuperMethodInvocation( |
2229 CallStructure.ONE_ARG, arguments, sourceInformation); | 2121 function, CallStructure.ONE_ARG, arguments, sourceInformation); |
2230 } | 2122 } |
2231 | 2123 |
2232 @override | 2124 @override |
2233 ir.Primitive visitSuperBinary( | 2125 ir.Primitive visitSuperBinary(ast.Send node, FunctionElement function, |
2234 ast.Send node, | 2126 op.BinaryOperator operator, ast.Node argument, _) { |
2235 FunctionElement function, | |
2236 op.BinaryOperator operator, | |
2237 ast.Node argument, | |
2238 _) { | |
2239 return translateSuperBinary(function, operator, argument, | 2127 return translateSuperBinary(function, operator, argument, |
2240 sourceInformationBuilder.buildBinary(node)); | 2128 sourceInformationBuilder.buildBinary(node)); |
2241 } | 2129 } |
2242 | 2130 |
2243 @override | 2131 @override |
2244 ir.Primitive visitSuperIndex( | 2132 ir.Primitive visitSuperIndex( |
2245 ast.Send node, | 2133 ast.Send node, FunctionElement function, ast.Node index, _) { |
2246 FunctionElement function, | 2134 return irBuilder.buildSuperIndex( |
2247 ast.Node index, | 2135 function, visit(index), sourceInformationBuilder.buildIndex(node)); |
2248 _) { | |
2249 return irBuilder.buildSuperIndex(function, visit(index), | |
2250 sourceInformationBuilder.buildIndex(node)); | |
2251 } | 2136 } |
2252 | 2137 |
2253 @override | 2138 @override |
2254 ir.Primitive visitEquals( | 2139 ir.Primitive visitEquals(ast.Send node, ast.Node left, ast.Node right, _) { |
2255 ast.Send node, | |
2256 ast.Node left, | |
2257 ast.Node right, | |
2258 _) { | |
2259 return translateBinary(node, left, op.BinaryOperator.EQ, right); | 2140 return translateBinary(node, left, op.BinaryOperator.EQ, right); |
2260 } | 2141 } |
2261 | 2142 |
2262 @override | 2143 @override |
2263 ir.Primitive visitSuperEquals( | 2144 ir.Primitive visitSuperEquals( |
2264 ast.Send node, | 2145 ast.Send node, FunctionElement function, ast.Node argument, _) { |
2265 FunctionElement function, | |
2266 ast.Node argument, | |
2267 _) { | |
2268 return translateSuperBinary(function, op.BinaryOperator.EQ, argument, | 2146 return translateSuperBinary(function, op.BinaryOperator.EQ, argument, |
2269 sourceInformationBuilder.buildBinary(node)); | 2147 sourceInformationBuilder.buildBinary(node)); |
2270 } | 2148 } |
2271 | 2149 |
2272 @override | 2150 @override |
2273 ir.Primitive visitNot( | 2151 ir.Primitive visitNot(ast.Send node, ast.Node expression, _) { |
2274 ast.Send node, | 2152 return irBuilder.buildNegation( |
2275 ast.Node expression, | 2153 visit(expression), sourceInformationBuilder.buildIf(node)); |
2276 _) { | |
2277 return irBuilder.buildNegation(visit(expression), | |
2278 sourceInformationBuilder.buildIf(node)); | |
2279 } | 2154 } |
2280 | 2155 |
2281 @override | 2156 @override |
2282 ir.Primitive visitNotEquals( | 2157 ir.Primitive visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) { |
2283 ast.Send node, | |
2284 ast.Node left, | |
2285 ast.Node right, | |
2286 _) { | |
2287 return irBuilder.buildNegation( | 2158 return irBuilder.buildNegation( |
2288 translateBinary(node, left, op.BinaryOperator.NOT_EQ, right), | 2159 translateBinary(node, left, op.BinaryOperator.NOT_EQ, right), |
2289 sourceInformationBuilder.buildIf(node)); | 2160 sourceInformationBuilder.buildIf(node)); |
2290 } | 2161 } |
2291 | 2162 |
2292 @override | 2163 @override |
2293 ir.Primitive visitSuperNotEquals( | 2164 ir.Primitive visitSuperNotEquals( |
2294 ast.Send node, | 2165 ast.Send node, FunctionElement function, ast.Node argument, _) { |
2295 FunctionElement function, | |
2296 ast.Node argument, | |
2297 _) { | |
2298 return irBuilder.buildNegation( | 2166 return irBuilder.buildNegation( |
2299 translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument, | 2167 translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument, |
2300 sourceInformationBuilder.buildBinary(node)), | 2168 sourceInformationBuilder.buildBinary(node)), |
2301 sourceInformationBuilder.buildIf(node)); | 2169 sourceInformationBuilder.buildIf(node)); |
2302 } | 2170 } |
2303 | 2171 |
2304 @override | 2172 @override |
2305 ir.Primitive visitUnary(ast.Send node, | 2173 ir.Primitive visitUnary( |
2306 op.UnaryOperator operator, ast.Node expression, _) { | 2174 ast.Send node, op.UnaryOperator operator, ast.Node expression, _) { |
2307 // TODO(johnniwinther): Clean up the creation of selectors. | 2175 // TODO(johnniwinther): Clean up the creation of selectors. |
2308 Selector selector = operator.selector; | 2176 Selector selector = operator.selector; |
2309 ir.Primitive receiver = translateReceiver(expression); | 2177 ir.Primitive receiver = translateReceiver(expression); |
2310 return irBuilder.buildDynamicInvocation( | 2178 return irBuilder.buildDynamicInvocation( |
2311 receiver, selector, elements.getTypeMask(node), const [], | 2179 receiver, |
| 2180 selector, |
| 2181 elements.getTypeMask(node), |
| 2182 const [], |
2312 sourceInformationBuilder.buildCall(expression, node)); | 2183 sourceInformationBuilder.buildCall(expression, node)); |
2313 } | 2184 } |
2314 | 2185 |
2315 @override | 2186 @override |
2316 ir.Primitive visitSuperUnary( | 2187 ir.Primitive visitSuperUnary( |
2317 ast.Send node, | 2188 ast.Send node, op.UnaryOperator operator, FunctionElement function, _) { |
2318 op.UnaryOperator operator, | 2189 return irBuilder.buildSuperMethodInvocation(function, CallStructure.NO_ARGS, |
2319 FunctionElement function, | 2190 const [], sourceInformationBuilder.buildCall(node, node)); |
2320 _) { | |
2321 return irBuilder.buildSuperMethodInvocation( | |
2322 function, CallStructure.NO_ARGS, const [], | |
2323 sourceInformationBuilder.buildCall(node, node)); | |
2324 } | 2191 } |
2325 | 2192 |
2326 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct | 2193 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct |
2327 // semantic correlation between arguments and invocation. | 2194 // semantic correlation between arguments and invocation. |
2328 CallStructure translateDynamicArguments(ast.NodeList nodeList, | 2195 CallStructure translateDynamicArguments(ast.NodeList nodeList, |
2329 CallStructure callStructure, | 2196 CallStructure callStructure, List<ir.Primitive> arguments) { |
2330 List<ir.Primitive> arguments) { | |
2331 assert(arguments.isEmpty); | 2197 assert(arguments.isEmpty); |
2332 for (ast.Node node in nodeList) arguments.add(visit(node)); | 2198 for (ast.Node node in nodeList) arguments.add(visit(node)); |
2333 return normalizeDynamicArguments(callStructure, arguments); | 2199 return normalizeDynamicArguments(callStructure, arguments); |
2334 } | 2200 } |
2335 | 2201 |
2336 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct | 2202 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct |
2337 // semantic correlation between arguments and invocation. | 2203 // semantic correlation between arguments and invocation. |
2338 CallStructure translateStaticArguments(ast.NodeList nodeList, | 2204 CallStructure translateStaticArguments(ast.NodeList nodeList, Element element, |
2339 Element element, | 2205 CallStructure callStructure, List<ir.Primitive> arguments) { |
2340 CallStructure callStructure, | |
2341 List<ir.Primitive> arguments) { | |
2342 assert(arguments.isEmpty); | 2206 assert(arguments.isEmpty); |
2343 for (ast.Node node in nodeList) arguments.add(visit(node)); | 2207 for (ast.Node node in nodeList) arguments.add(visit(node)); |
2344 return normalizeStaticArguments(callStructure, element, arguments); | 2208 return normalizeStaticArguments(callStructure, element, arguments); |
2345 } | 2209 } |
2346 | 2210 |
2347 ir.Primitive translateCallInvoke(ir.Primitive target, | 2211 ir.Primitive translateCallInvoke( |
2348 ast.NodeList argumentsNode, | 2212 ir.Primitive target, |
2349 CallStructure callStructure, | 2213 ast.NodeList argumentsNode, |
2350 SourceInformation sourceInformation) { | 2214 CallStructure callStructure, |
| 2215 SourceInformation sourceInformation) { |
2351 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2216 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2352 callStructure = | 2217 callStructure = |
2353 translateDynamicArguments(argumentsNode, callStructure, arguments); | 2218 translateDynamicArguments(argumentsNode, callStructure, arguments); |
2354 return irBuilder.buildCallInvocation( | 2219 return irBuilder.buildCallInvocation( |
2355 target, callStructure, arguments, sourceInformation); | 2220 target, callStructure, arguments, sourceInformation); |
2356 } | 2221 } |
2357 | 2222 |
2358 @override | 2223 @override |
2359 ir.Primitive handleConstantInvoke( | 2224 ir.Primitive handleConstantInvoke(ast.Send node, ConstantExpression constant, |
2360 ast.Send node, | 2225 ast.NodeList arguments, CallStructure callStructure, _) { |
2361 ConstantExpression constant, | 2226 ir.Primitive target = buildConstantExpression( |
2362 ast.NodeList arguments, | 2227 constant, sourceInformationBuilder.buildGet(node)); |
2363 CallStructure callStructure, | |
2364 _) { | |
2365 ir.Primitive target = buildConstantExpression(constant, | |
2366 sourceInformationBuilder.buildGet(node)); | |
2367 return translateCallInvoke(target, arguments, callStructure, | 2228 return translateCallInvoke(target, arguments, callStructure, |
2368 sourceInformationBuilder.buildCall(node, arguments)); | 2229 sourceInformationBuilder.buildCall(node, arguments)); |
2369 } | 2230 } |
2370 | 2231 |
2371 @override | 2232 @override |
2372 ir.Primitive handleConstructorInvoke( | 2233 ir.Primitive handleConstructorInvoke( |
2373 ast.NewExpression node, | 2234 ast.NewExpression node, |
2374 ConstructorElement constructor, | 2235 ConstructorElement constructor, |
2375 DartType type, | 2236 DartType type, |
2376 ast.NodeList argumentsNode, | 2237 ast.NodeList argumentsNode, |
2377 CallStructure callStructure, | 2238 CallStructure callStructure, |
2378 _) { | 2239 _) { |
2379 | |
2380 // TODO(sigmund): move these checks down after visiting arguments | 2240 // TODO(sigmund): move these checks down after visiting arguments |
2381 // (see issue #25355) | 2241 // (see issue #25355) |
2382 ast.Send send = node.send; | 2242 ast.Send send = node.send; |
2383 // If an allocation refers to a type using a deferred import prefix (e.g. | 2243 // If an allocation refers to a type using a deferred import prefix (e.g. |
2384 // `new lib.A()`), we must ensure that the deferred import has already been | 2244 // `new lib.A()`), we must ensure that the deferred import has already been |
2385 // loaded. | 2245 // loaded. |
2386 var prefix = compiler.deferredLoadTask.deferredPrefixElement( | 2246 var prefix = |
2387 send, elements); | 2247 compiler.deferredLoadTask.deferredPrefixElement(send, elements); |
2388 if (prefix != null) buildCheckDeferredIsLoaded(prefix, send); | 2248 if (prefix != null) buildCheckDeferredIsLoaded(prefix, send); |
2389 | 2249 |
2390 // We also emit deferred import checks when using redirecting factories that | 2250 // We also emit deferred import checks when using redirecting factories that |
2391 // refer to deferred prefixes. | 2251 // refer to deferred prefixes. |
2392 if (constructor.isRedirectingFactory && !constructor.isCyclicRedirection) { | 2252 if (constructor.isRedirectingFactory && !constructor.isCyclicRedirection) { |
2393 ConstructorElement current = constructor; | 2253 ConstructorElement current = constructor; |
2394 while (current.isRedirectingFactory) { | 2254 while (current.isRedirectingFactory) { |
2395 var prefix = current.redirectionDeferredPrefix; | 2255 var prefix = current.redirectionDeferredPrefix; |
2396 if (prefix != null) buildCheckDeferredIsLoaded(prefix, send); | 2256 if (prefix != null) buildCheckDeferredIsLoaded(prefix, send); |
2397 current = current.immediateRedirectionTarget; | 2257 current = current.immediateRedirectionTarget; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2432 return irBuilder.buildConstructorInvocation( | 2292 return irBuilder.buildConstructorInvocation( |
2433 target, | 2293 target, |
2434 callStructure, | 2294 callStructure, |
2435 constructorImplementation.computeEffectiveTargetType(type), | 2295 constructorImplementation.computeEffectiveTargetType(type), |
2436 arguments, | 2296 arguments, |
2437 sourceInformationBuilder.buildNew(node), | 2297 sourceInformationBuilder.buildNew(node), |
2438 allocationSiteType: allocationSiteType); | 2298 allocationSiteType: allocationSiteType); |
2439 } | 2299 } |
2440 | 2300 |
2441 @override | 2301 @override |
2442 ir.Primitive handleDynamicInvoke( | 2302 ir.Primitive handleDynamicInvoke(ast.Send node, ast.Node receiver, |
2443 ast.Send node, | 2303 ast.NodeList argumentsNode, Selector selector, _) { |
2444 ast.Node receiver, | |
2445 ast.NodeList argumentsNode, | |
2446 Selector selector, | |
2447 _) { | |
2448 ir.Primitive target = translateReceiver(receiver); | 2304 ir.Primitive target = translateReceiver(receiver); |
2449 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2305 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2450 CallStructure callStructure = translateDynamicArguments( | 2306 CallStructure callStructure = translateDynamicArguments( |
2451 argumentsNode, selector.callStructure, arguments); | 2307 argumentsNode, selector.callStructure, arguments); |
2452 return irBuilder.buildDynamicInvocation( | 2308 return irBuilder.buildDynamicInvocation( |
2453 target, | 2309 target, |
2454 new Selector(selector.kind, selector.memberName, callStructure), | 2310 new Selector(selector.kind, selector.memberName, callStructure), |
2455 elements.getTypeMask(node), | 2311 elements.getTypeMask(node), |
2456 arguments, | 2312 arguments, |
2457 sourceInformationBuilder.buildCall(node, node.selector)); | 2313 sourceInformationBuilder.buildCall(node, node.selector)); |
2458 } | 2314 } |
2459 | 2315 |
2460 @override | 2316 @override |
2461 ir.Primitive visitIfNotNullDynamicPropertyInvoke( | 2317 ir.Primitive visitIfNotNullDynamicPropertyInvoke(ast.Send node, |
2462 ast.Send node, | 2318 ast.Node receiver, ast.NodeList argumentsNode, Selector selector, _) { |
2463 ast.Node receiver, | |
2464 ast.NodeList argumentsNode, | |
2465 Selector selector, | |
2466 _) { | |
2467 ir.Primitive target = visit(receiver); | 2319 ir.Primitive target = visit(receiver); |
2468 return irBuilder.buildIfNotNullSend( | 2320 return irBuilder.buildIfNotNullSend(target, nested(() { |
2469 target, | 2321 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2470 nested(() { | 2322 CallStructure callStructure = translateDynamicArguments( |
2471 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2323 argumentsNode, selector.callStructure, arguments); |
2472 CallStructure callStructure = translateDynamicArguments( | 2324 return irBuilder.buildDynamicInvocation( |
2473 argumentsNode, selector.callStructure, arguments); | 2325 target, |
2474 return irBuilder.buildDynamicInvocation( | 2326 new Selector(selector.kind, selector.memberName, callStructure), |
2475 target, | 2327 elements.getTypeMask(node), |
2476 new Selector(selector.kind, selector.memberName, callStructure), | 2328 arguments, |
2477 elements.getTypeMask(node), | 2329 sourceInformationBuilder.buildCall(node, node.selector)); |
2478 arguments, | 2330 }), sourceInformationBuilder.buildIf(node)); |
2479 sourceInformationBuilder.buildCall(node, node.selector)); | |
2480 }), | |
2481 sourceInformationBuilder.buildIf(node)); | |
2482 } | 2331 } |
2483 | 2332 |
2484 ir.Primitive handleLocalInvoke( | 2333 ir.Primitive handleLocalInvoke(ast.Send node, LocalElement element, |
2485 ast.Send node, | 2334 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
2486 LocalElement element, | |
2487 ast.NodeList argumentsNode, | |
2488 CallStructure callStructure, | |
2489 _) { | |
2490 ir.Primitive function = irBuilder.buildLocalGet(element); | 2335 ir.Primitive function = irBuilder.buildLocalGet(element); |
2491 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2336 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2492 callStructure = | 2337 callStructure = |
2493 translateDynamicArguments(argumentsNode, callStructure, arguments); | 2338 translateDynamicArguments(argumentsNode, callStructure, arguments); |
2494 return irBuilder.buildCallInvocation(function, callStructure, arguments, | 2339 return irBuilder.buildCallInvocation(function, callStructure, arguments, |
2495 sourceInformationBuilder.buildCall(node, argumentsNode)); | 2340 sourceInformationBuilder.buildCall(node, argumentsNode)); |
2496 } | 2341 } |
2497 | 2342 |
2498 @override | 2343 @override |
2499 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) { | 2344 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) { |
2500 return buildStaticFieldGet(field, sourceInformationBuilder.buildGet(node)); | 2345 return buildStaticFieldGet(field, sourceInformationBuilder.buildGet(node)); |
2501 } | 2346 } |
2502 | 2347 |
2503 @override | 2348 @override |
2504 ir.Primitive handleStaticFieldInvoke( | 2349 ir.Primitive handleStaticFieldInvoke(ast.Send node, FieldElement field, |
2505 ast.Send node, | 2350 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
2506 FieldElement field, | |
2507 ast.NodeList argumentsNode, | |
2508 CallStructure callStructure, | |
2509 _) { | |
2510 SourceInformation src = sourceInformationBuilder.buildGet(node); | 2351 SourceInformation src = sourceInformationBuilder.buildGet(node); |
2511 ir.Primitive target = buildStaticFieldGet(field, src); | 2352 ir.Primitive target = buildStaticFieldGet(field, src); |
2512 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2353 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2513 callStructure = | 2354 callStructure = |
2514 translateDynamicArguments(argumentsNode, callStructure, arguments); | 2355 translateDynamicArguments(argumentsNode, callStructure, arguments); |
2515 return irBuilder.buildCallInvocation( | 2356 return irBuilder.buildCallInvocation(target, callStructure, arguments, |
2516 target, | |
2517 callStructure, | |
2518 arguments, | |
2519 sourceInformationBuilder.buildCall(node, argumentsNode)); | 2357 sourceInformationBuilder.buildCall(node, argumentsNode)); |
2520 } | 2358 } |
2521 | 2359 |
2522 @override | 2360 @override |
2523 ir.Primitive handleStaticFunctionInvoke(ast.Send node, | 2361 ir.Primitive handleStaticFunctionInvoke(ast.Send node, MethodElement function, |
2524 MethodElement function, | 2362 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
2525 ast.NodeList argumentsNode, | |
2526 CallStructure callStructure, | |
2527 _) { | |
2528 if (compiler.backend.isForeign(function)) { | 2363 if (compiler.backend.isForeign(function)) { |
2529 return handleForeignCode( | 2364 return handleForeignCode(node, function, argumentsNode, callStructure); |
2530 node, | |
2531 function, | |
2532 argumentsNode, | |
2533 callStructure); | |
2534 } else { | 2365 } else { |
2535 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2366 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2536 callStructure = translateStaticArguments(argumentsNode, function, | 2367 callStructure = translateStaticArguments( |
2537 callStructure, arguments); | 2368 argumentsNode, function, callStructure, arguments); |
2538 Selector selector = new Selector.call(function.memberName, callStructure); | 2369 Selector selector = new Selector.call(function.memberName, callStructure); |
2539 return irBuilder.buildInvokeStatic(function, selector, arguments, | 2370 return irBuilder.buildInvokeStatic(function, selector, arguments, |
2540 sourceInformationBuilder.buildCall(node, node.selector)); | 2371 sourceInformationBuilder.buildCall(node, node.selector)); |
2541 } | 2372 } |
2542 } | 2373 } |
2543 | 2374 |
2544 @override | 2375 @override |
2545 ir.Primitive handleStaticFunctionIncompatibleInvoke( | 2376 ir.Primitive handleStaticFunctionIncompatibleInvoke( |
2546 ast.Send node, | 2377 ast.Send node, |
2547 MethodElement function, | 2378 MethodElement function, |
2548 ast.NodeList arguments, | 2379 ast.NodeList arguments, |
2549 CallStructure callStructure, _) { | 2380 CallStructure callStructure, |
| 2381 _) { |
2550 return irBuilder.buildStaticNoSuchMethod( | 2382 return irBuilder.buildStaticNoSuchMethod( |
2551 elements.getSelector(node), | 2383 elements.getSelector(node), |
2552 arguments.nodes.mapToList(visit), | 2384 arguments.nodes.mapToList(visit), |
2553 sourceInformationBuilder.buildCall(node, node.selector)); | 2385 sourceInformationBuilder.buildCall(node, node.selector)); |
2554 } | 2386 } |
2555 | 2387 |
2556 @override | 2388 @override |
2557 ir.Primitive handleStaticGetterInvoke( | 2389 ir.Primitive handleStaticGetterInvoke(ast.Send node, FunctionElement getter, |
2558 ast.Send node, | 2390 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
2559 FunctionElement getter, | |
2560 ast.NodeList argumentsNode, | |
2561 CallStructure callStructure, | |
2562 _) { | |
2563 ir.Primitive target = buildStaticGetterGet( | 2391 ir.Primitive target = buildStaticGetterGet( |
2564 getter, node, sourceInformationBuilder.buildGet(node)); | 2392 getter, node, sourceInformationBuilder.buildGet(node)); |
2565 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2393 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2566 callStructure = | 2394 callStructure = |
2567 translateDynamicArguments(argumentsNode, callStructure, arguments); | 2395 translateDynamicArguments(argumentsNode, callStructure, arguments); |
2568 return irBuilder.buildCallInvocation( | 2396 return irBuilder.buildCallInvocation(target, callStructure, arguments, |
2569 target, | |
2570 callStructure, | |
2571 arguments, | |
2572 sourceInformationBuilder.buildCall(node, argumentsNode)); | 2397 sourceInformationBuilder.buildCall(node, argumentsNode)); |
2573 } | 2398 } |
2574 | 2399 |
2575 @override | 2400 @override |
2576 ir.Primitive visitSuperFieldInvoke( | 2401 ir.Primitive visitSuperFieldInvoke(ast.Send node, FieldElement field, |
2577 ast.Send node, | 2402 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
2578 FieldElement field, | |
2579 ast.NodeList argumentsNode, | |
2580 CallStructure callStructure, | |
2581 _) { | |
2582 ir.Primitive target = irBuilder.buildSuperFieldGet( | 2403 ir.Primitive target = irBuilder.buildSuperFieldGet( |
2583 field, sourceInformationBuilder.buildGet(node)); | 2404 field, sourceInformationBuilder.buildGet(node)); |
2584 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2405 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2585 callStructure = | 2406 callStructure = |
2586 translateDynamicArguments(argumentsNode, callStructure, arguments); | 2407 translateDynamicArguments(argumentsNode, callStructure, arguments); |
2587 return irBuilder.buildCallInvocation( | 2408 return irBuilder.buildCallInvocation(target, callStructure, arguments, |
2588 target, | |
2589 callStructure, | |
2590 arguments, | |
2591 sourceInformationBuilder.buildCall(node, argumentsNode)); | 2409 sourceInformationBuilder.buildCall(node, argumentsNode)); |
2592 } | 2410 } |
2593 | 2411 |
2594 @override | 2412 @override |
2595 ir.Primitive visitSuperGetterInvoke( | 2413 ir.Primitive visitSuperGetterInvoke(ast.Send node, FunctionElement getter, |
2596 ast.Send node, | 2414 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
2597 FunctionElement getter, | 2415 ir.Primitive target = irBuilder.buildSuperGetterGet( |
2598 ast.NodeList argumentsNode, | 2416 getter, sourceInformationBuilder.buildGet(node)); |
2599 CallStructure callStructure, | |
2600 _) { | |
2601 ir.Primitive target = irBuilder.buildSuperGetterGet(getter, | |
2602 sourceInformationBuilder.buildGet(node)); | |
2603 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2417 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2604 callStructure = | 2418 callStructure = |
2605 translateDynamicArguments(argumentsNode, callStructure, arguments); | 2419 translateDynamicArguments(argumentsNode, callStructure, arguments); |
2606 return irBuilder.buildCallInvocation( | 2420 return irBuilder.buildCallInvocation(target, callStructure, arguments, |
2607 target, | |
2608 callStructure, | |
2609 arguments, | |
2610 sourceInformationBuilder.buildCall(node, argumentsNode)); | 2421 sourceInformationBuilder.buildCall(node, argumentsNode)); |
2611 } | 2422 } |
2612 | 2423 |
2613 @override | 2424 @override |
2614 ir.Primitive visitSuperMethodInvoke( | 2425 ir.Primitive visitSuperMethodInvoke(ast.Send node, MethodElement method, |
2615 ast.Send node, | 2426 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
2616 MethodElement method, | |
2617 ast.NodeList argumentsNode, | |
2618 CallStructure callStructure, | |
2619 _) { | |
2620 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2427 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2621 callStructure = translateStaticArguments(argumentsNode, method, | 2428 callStructure = translateStaticArguments( |
2622 callStructure, arguments); | 2429 argumentsNode, method, callStructure, arguments); |
2623 return irBuilder.buildSuperMethodInvocation( | 2430 return irBuilder.buildSuperMethodInvocation(method, callStructure, |
2624 method, | 2431 arguments, sourceInformationBuilder.buildCall(node, node.selector)); |
2625 callStructure, | |
2626 arguments, | |
2627 sourceInformationBuilder.buildCall(node, node.selector)); | |
2628 } | 2432 } |
2629 | 2433 |
2630 @override | 2434 @override |
2631 ir.Primitive visitSuperMethodIncompatibleInvoke( | 2435 ir.Primitive visitSuperMethodIncompatibleInvoke( |
2632 ast.Send node, | 2436 ast.Send node, |
2633 MethodElement method, | 2437 MethodElement method, |
2634 ast.NodeList arguments, | 2438 ast.NodeList arguments, |
2635 CallStructure callStructure, _) { | 2439 CallStructure callStructure, |
| 2440 _) { |
2636 List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; | 2441 List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
2637 CallStructure normalizedCallStructure = | 2442 CallStructure normalizedCallStructure = translateDynamicArguments( |
2638 translateDynamicArguments(arguments, callStructure, normalizedArguments); | 2443 arguments, callStructure, normalizedArguments); |
2639 return buildSuperNoSuchMethod( | 2444 return buildSuperNoSuchMethod( |
2640 new Selector.call(method.memberName, normalizedCallStructure), | 2445 new Selector.call(method.memberName, normalizedCallStructure), |
2641 elements.getTypeMask(node), | 2446 elements.getTypeMask(node), |
2642 normalizedArguments, | 2447 normalizedArguments, |
2643 sourceInformationBuilder.buildCall(node, arguments)); | 2448 sourceInformationBuilder.buildCall(node, arguments)); |
2644 } | 2449 } |
2645 | 2450 |
2646 @override | 2451 @override |
2647 ir.Primitive visitUnresolvedSuperInvoke( | 2452 ir.Primitive visitUnresolvedSuperInvoke(ast.Send node, Element element, |
2648 ast.Send node, | 2453 ast.NodeList argumentsNode, Selector selector, _) { |
2649 Element element, | |
2650 ast.NodeList argumentsNode, | |
2651 Selector selector, _) { | |
2652 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2454 List<ir.Primitive> arguments = <ir.Primitive>[]; |
2653 CallStructure callStructure = translateDynamicArguments( | 2455 CallStructure callStructure = translateDynamicArguments( |
2654 argumentsNode, selector.callStructure, arguments); | 2456 argumentsNode, selector.callStructure, arguments); |
2655 // TODO(johnniwinther): Supply a member name to the visit function instead | 2457 // TODO(johnniwinther): Supply a member name to the visit function instead |
2656 // of looking it up in elements. | 2458 // of looking it up in elements. |
2657 return buildSuperNoSuchMethod( | 2459 return buildSuperNoSuchMethod( |
2658 new Selector.call(elements.getSelector(node).memberName, callStructure), | 2460 new Selector.call(elements.getSelector(node).memberName, callStructure), |
2659 elements.getTypeMask(node), | 2461 elements.getTypeMask(node), |
2660 arguments, | 2462 arguments, |
2661 sourceInformationBuilder.buildCall(node, argumentsNode)); | 2463 sourceInformationBuilder.buildCall(node, argumentsNode)); |
2662 } | 2464 } |
2663 | 2465 |
2664 @override | 2466 @override |
2665 ir.Primitive visitThisInvoke( | 2467 ir.Primitive visitThisInvoke( |
2666 ast.Send node, | 2468 ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) { |
2667 ast.NodeList arguments, | 2469 return translateCallInvoke(irBuilder.buildThis(), arguments, callStructure, |
2668 CallStructure callStructure, | |
2669 _) { | |
2670 return translateCallInvoke( | |
2671 irBuilder.buildThis(), | |
2672 arguments, | |
2673 callStructure, | |
2674 sourceInformationBuilder.buildCall(node, arguments)); | 2470 sourceInformationBuilder.buildCall(node, arguments)); |
2675 } | 2471 } |
2676 | 2472 |
2677 @override | 2473 @override |
2678 ir.Primitive visitTypeVariableTypeLiteralInvoke( | 2474 ir.Primitive visitTypeVariableTypeLiteralInvoke( |
2679 ast.Send node, | 2475 ast.Send node, |
2680 TypeVariableElement element, | 2476 TypeVariableElement element, |
2681 ast.NodeList arguments, | 2477 ast.NodeList arguments, |
2682 CallStructure callStructure, | 2478 CallStructure callStructure, |
2683 _) { | 2479 _) { |
2684 return translateCallInvoke( | 2480 return translateCallInvoke( |
2685 translateTypeVariableTypeLiteral( | 2481 translateTypeVariableTypeLiteral( |
2686 element, sourceInformationBuilder.buildGet(node)), | 2482 element, sourceInformationBuilder.buildGet(node)), |
2687 arguments, | 2483 arguments, |
2688 callStructure, | 2484 callStructure, |
2689 sourceInformationBuilder.buildCall(node, arguments)); | 2485 sourceInformationBuilder.buildCall(node, arguments)); |
2690 } | 2486 } |
2691 | 2487 |
2692 @override | 2488 @override |
2693 ir.Primitive visitIndexSet( | 2489 ir.Primitive visitIndexSet( |
2694 ast.SendSet node, | 2490 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) { |
2695 ast.Node receiver, | |
2696 ast.Node index, | |
2697 ast.Node rhs, | |
2698 _) { | |
2699 return irBuilder.buildDynamicIndexSet( | 2491 return irBuilder.buildDynamicIndexSet( |
2700 visit(receiver), | 2492 visit(receiver), |
2701 elements.getTypeMask(node), | 2493 elements.getTypeMask(node), |
2702 visit(index), | 2494 visit(index), |
2703 visit(rhs), | 2495 visit(rhs), |
2704 sourceInformationBuilder.buildIndexSet(node)); | 2496 sourceInformationBuilder.buildIndexSet(node)); |
2705 } | 2497 } |
2706 | 2498 |
2707 @override | 2499 @override |
2708 ir.Primitive visitSuperIndexSet( | 2500 ir.Primitive visitSuperIndexSet(ast.SendSet node, FunctionElement function, |
2709 ast.SendSet node, | 2501 ast.Node index, ast.Node rhs, _) { |
2710 FunctionElement function, | 2502 return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs), |
2711 ast.Node index, | |
2712 ast.Node rhs, | |
2713 _) { | |
2714 return irBuilder.buildSuperIndexSet( | |
2715 function, | |
2716 visit(index), | |
2717 visit(rhs), | |
2718 sourceInformationBuilder.buildIndexSet(node)); | 2503 sourceInformationBuilder.buildIndexSet(node)); |
2719 } | 2504 } |
2720 | 2505 |
2721 ir.Primitive translateIfNull( | 2506 ir.Primitive translateIfNull(ast.SendSet node, ir.Primitive getValue(), |
2722 ast.SendSet node, | 2507 ast.Node rhs, void setValue(ir.Primitive value)) { |
2723 ir.Primitive getValue(), | |
2724 ast.Node rhs, | |
2725 void setValue(ir.Primitive value)) { | |
2726 ir.Primitive value = getValue(); | 2508 ir.Primitive value = getValue(); |
2727 // Unlike other compound operators if-null conditionally will not do the | 2509 // Unlike other compound operators if-null conditionally will not do the |
2728 // assignment operation. | 2510 // assignment operation. |
2729 return irBuilder.buildIfNull(value, nested(() { | 2511 return irBuilder.buildIfNull(value, nested(() { |
2730 ir.Primitive newValue = build(rhs); | 2512 ir.Primitive newValue = build(rhs); |
2731 setValue(newValue); | 2513 setValue(newValue); |
2732 return newValue; | 2514 return newValue; |
2733 }), | 2515 }), sourceInformationBuilder.buildIf(node)); |
2734 sourceInformationBuilder.buildIf(node)); | |
2735 } | 2516 } |
2736 | 2517 |
2737 ir.Primitive translateCompounds( | 2518 ir.Primitive translateCompounds(ast.SendSet node, ir.Primitive getValue(), |
2738 ast.SendSet node, | 2519 CompoundRhs rhs, void setValue(ir.Primitive value)) { |
2739 ir.Primitive getValue(), | |
2740 CompoundRhs rhs, | |
2741 void setValue(ir.Primitive value)) { | |
2742 ir.Primitive value = getValue(); | 2520 ir.Primitive value = getValue(); |
2743 op.BinaryOperator operator = rhs.operator; | 2521 op.BinaryOperator operator = rhs.operator; |
2744 assert(operator.kind != op.BinaryOperatorKind.IF_NULL); | 2522 assert(operator.kind != op.BinaryOperatorKind.IF_NULL); |
2745 | 2523 |
2746 Selector operatorSelector = | 2524 Selector operatorSelector = |
2747 new Selector.binaryOperator(operator.selectorName); | 2525 new Selector.binaryOperator(operator.selectorName); |
2748 ir.Primitive rhsValue; | 2526 ir.Primitive rhsValue; |
2749 if (rhs.kind == CompoundKind.ASSIGNMENT) { | 2527 if (rhs.kind == CompoundKind.ASSIGNMENT) { |
2750 rhsValue = visit(rhs.rhs); | 2528 rhsValue = visit(rhs.rhs); |
2751 } else { | 2529 } else { |
2752 rhsValue = irBuilder.buildIntegerConstant(1); | 2530 rhsValue = irBuilder.buildIntegerConstant(1); |
2753 } | 2531 } |
2754 List<ir.Primitive> arguments = <ir.Primitive>[rhsValue]; | 2532 List<ir.Primitive> arguments = <ir.Primitive>[rhsValue]; |
2755 CallStructure callStructure = | 2533 CallStructure callStructure = |
2756 normalizeDynamicArguments(operatorSelector.callStructure, arguments); | 2534 normalizeDynamicArguments(operatorSelector.callStructure, arguments); |
2757 TypeMask operatorTypeMask = | 2535 TypeMask operatorTypeMask = |
2758 elements.getOperatorTypeMaskInComplexSendSet(node); | 2536 elements.getOperatorTypeMaskInComplexSendSet(node); |
2759 SourceInformation operatorSourceInformation = | 2537 SourceInformation operatorSourceInformation = |
2760 sourceInformationBuilder.buildCall(node, node.assignmentOperator); | 2538 sourceInformationBuilder.buildCall(node, node.assignmentOperator); |
2761 ir.Primitive result = irBuilder.buildDynamicInvocation( | 2539 ir.Primitive result = irBuilder.buildDynamicInvocation( |
2762 value, | 2540 value, |
2763 new Selector(operatorSelector.kind, operatorSelector.memberName, | 2541 new Selector( |
2764 callStructure), | 2542 operatorSelector.kind, operatorSelector.memberName, callStructure), |
2765 operatorTypeMask, | 2543 operatorTypeMask, |
2766 arguments, | 2544 arguments, |
2767 operatorSourceInformation); | 2545 operatorSourceInformation); |
2768 setValue(result); | 2546 setValue(result); |
2769 return rhs.kind == CompoundKind.POSTFIX ? value : result; | 2547 return rhs.kind == CompoundKind.POSTFIX ? value : result; |
2770 } | 2548 } |
2771 | 2549 |
2772 ir.Primitive translateSetIfNull( | 2550 ir.Primitive translateSetIfNull(ast.SendSet node, ir.Primitive getValue(), |
2773 ast.SendSet node, | 2551 ast.Node rhs, void setValue(ir.Primitive value)) { |
2774 ir.Primitive getValue(), | |
2775 ast.Node rhs, | |
2776 void setValue(ir.Primitive value)) { | |
2777 ir.Primitive value = getValue(); | 2552 ir.Primitive value = getValue(); |
2778 // Unlike other compound operators if-null conditionally will not do the | 2553 // Unlike other compound operators if-null conditionally will not do the |
2779 // assignment operation. | 2554 // assignment operation. |
2780 return irBuilder.buildIfNull(value, nested(() { | 2555 return irBuilder.buildIfNull(value, nested(() { |
2781 ir.Primitive newValue = build(rhs); | 2556 ir.Primitive newValue = build(rhs); |
2782 setValue(newValue); | 2557 setValue(newValue); |
2783 return newValue; | 2558 return newValue; |
2784 }), | 2559 }), sourceInformationBuilder.buildIf(node)); |
2785 sourceInformationBuilder.buildIf(node)); | |
2786 } | 2560 } |
2787 | 2561 |
2788 @override | 2562 @override |
2789 ir.Primitive handleSuperIndexSetIfNull( | 2563 ir.Primitive handleSuperIndexSetIfNull( |
2790 ast.SendSet node, | 2564 ast.SendSet node, |
2791 Element indexFunction, | 2565 Element indexFunction, |
2792 Element indexSetFunction, | 2566 Element indexSetFunction, |
2793 ast.Node index, | 2567 ast.Node index, |
2794 ast.Node rhs, | 2568 ast.Node rhs, |
2795 arg, | 2569 arg, |
2796 {bool isGetterValid, | 2570 {bool isGetterValid, |
2797 bool isSetterValid}) { | 2571 bool isSetterValid}) { |
2798 return translateSetIfNull(node, () { | 2572 return translateSetIfNull( |
2799 if (isGetterValid) { | 2573 node, |
2800 return irBuilder.buildSuperMethodGet( | 2574 () { |
2801 indexFunction, sourceInformationBuilder.buildIndex(node)); | 2575 if (isGetterValid) { |
2802 } else { | 2576 return irBuilder.buildSuperMethodGet( |
2803 return buildSuperNoSuchGetter( | 2577 indexFunction, sourceInformationBuilder.buildIndex(node)); |
2804 indexFunction, | 2578 } else { |
2805 elements.getGetterTypeMaskInComplexSendSet(node), | 2579 return buildSuperNoSuchGetter( |
2806 sourceInformationBuilder.buildIndex(node)); | 2580 indexFunction, |
2807 } | 2581 elements.getGetterTypeMaskInComplexSendSet(node), |
2808 }, rhs, (ir.Primitive result) { | 2582 sourceInformationBuilder.buildIndex(node)); |
2809 if (isSetterValid) { | 2583 } |
2810 return irBuilder.buildSuperMethodGet( | 2584 }, |
2811 indexSetFunction, sourceInformationBuilder.buildIndexSet(node)); | 2585 rhs, |
2812 } else { | 2586 (ir.Primitive result) { |
2813 return buildSuperNoSuchSetter( | 2587 if (isSetterValid) { |
2814 indexSetFunction, elements.getTypeMask(node), result, | 2588 return irBuilder.buildSuperMethodGet( |
2815 sourceInformationBuilder.buildIndexSet(node)); | 2589 indexSetFunction, sourceInformationBuilder.buildIndexSet(node)); |
2816 } | 2590 } else { |
2817 }); | 2591 return buildSuperNoSuchSetter( |
| 2592 indexSetFunction, |
| 2593 elements.getTypeMask(node), |
| 2594 result, |
| 2595 sourceInformationBuilder.buildIndexSet(node)); |
| 2596 } |
| 2597 }); |
2818 } | 2598 } |
2819 | 2599 |
2820 @override | 2600 @override |
2821 ir.Primitive visitIndexSetIfNull( | 2601 ir.Primitive visitIndexSetIfNull( |
2822 ast.SendSet node, | 2602 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, arg) { |
2823 ast.Node receiver, | |
2824 ast.Node index, | |
2825 ast.Node rhs, | |
2826 arg) { | |
2827 ir.Primitive target = visit(receiver); | 2603 ir.Primitive target = visit(receiver); |
2828 ir.Primitive indexValue = visit(index); | 2604 ir.Primitive indexValue = visit(index); |
2829 return translateSetIfNull(node, () { | 2605 return translateSetIfNull( |
2830 Selector selector = new Selector.index(); | 2606 node, |
2831 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; | 2607 () { |
2832 CallStructure callStructure = | 2608 Selector selector = new Selector.index(); |
2833 normalizeDynamicArguments(selector.callStructure, arguments); | 2609 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
2834 return irBuilder.buildDynamicInvocation( | 2610 CallStructure callStructure = |
2835 target, | 2611 normalizeDynamicArguments(selector.callStructure, arguments); |
2836 new Selector(selector.kind, selector.memberName, callStructure), | 2612 return irBuilder.buildDynamicInvocation( |
2837 elements.getGetterTypeMaskInComplexSendSet(node), | 2613 target, |
2838 arguments, | 2614 new Selector(selector.kind, selector.memberName, callStructure), |
2839 sourceInformationBuilder.buildCall(receiver, node)); | 2615 elements.getGetterTypeMaskInComplexSendSet(node), |
2840 }, rhs, (ir.Primitive result) { | 2616 arguments, |
2841 irBuilder.buildDynamicIndexSet( | 2617 sourceInformationBuilder.buildCall(receiver, node)); |
2842 target, | 2618 }, |
2843 elements.getTypeMask(node), | 2619 rhs, |
2844 indexValue, | 2620 (ir.Primitive result) { |
2845 result, | 2621 irBuilder.buildDynamicIndexSet(target, elements.getTypeMask(node), |
2846 sourceInformationBuilder.buildIndexSet(node)); | 2622 indexValue, result, sourceInformationBuilder.buildIndexSet(node)); |
2847 }); | 2623 }); |
2848 } | 2624 } |
2849 | 2625 |
2850 @override | 2626 @override |
2851 ir.Primitive handleDynamicSet( | 2627 ir.Primitive handleDynamicSet( |
2852 ast.SendSet node, | 2628 ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) { |
2853 ast.Node receiver, | |
2854 Name name, | |
2855 ast.Node rhs, | |
2856 _) { | |
2857 return irBuilder.buildDynamicSet( | 2629 return irBuilder.buildDynamicSet( |
2858 translateReceiver(receiver), | 2630 translateReceiver(receiver), |
2859 new Selector.setter(name), | 2631 new Selector.setter(name), |
2860 elements.getTypeMask(node), | 2632 elements.getTypeMask(node), |
2861 visit(rhs), | 2633 visit(rhs), |
2862 sourceInformationBuilder.buildAssignment(node)); | 2634 sourceInformationBuilder.buildAssignment(node)); |
2863 } | 2635 } |
2864 | 2636 |
2865 @override | 2637 @override |
2866 ir.Primitive visitIfNotNullDynamicPropertySet( | 2638 ir.Primitive visitIfNotNullDynamicPropertySet( |
2867 ast.SendSet node, | 2639 ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) { |
2868 ast.Node receiver, | |
2869 Name name, | |
2870 ast.Node rhs, | |
2871 _) { | |
2872 ir.Primitive target = visit(receiver); | 2640 ir.Primitive target = visit(receiver); |
2873 return irBuilder.buildIfNotNullSend( | 2641 return irBuilder.buildIfNotNullSend( |
2874 target, | 2642 target, |
2875 nested(() => irBuilder.buildDynamicSet( | 2643 nested(() => irBuilder.buildDynamicSet( |
2876 target, | 2644 target, |
2877 new Selector.setter(name), | 2645 new Selector.setter(name), |
2878 elements.getTypeMask(node), | 2646 elements.getTypeMask(node), |
2879 visit(rhs), | 2647 visit(rhs), |
2880 sourceInformationBuilder.buildAssignment(node))), | 2648 sourceInformationBuilder.buildAssignment(node))), |
2881 sourceInformationBuilder.buildIf(node)); | 2649 sourceInformationBuilder.buildIf(node)); |
2882 } | 2650 } |
2883 | 2651 |
2884 @override | 2652 @override |
2885 ir.Primitive handleLocalSet( | 2653 ir.Primitive handleLocalSet( |
2886 ast.SendSet node, | 2654 ast.SendSet node, LocalElement element, ast.Node rhs, _) { |
2887 LocalElement element, | |
2888 ast.Node rhs, | |
2889 _) { | |
2890 ir.Primitive value = visit(rhs); | 2655 ir.Primitive value = visit(rhs); |
2891 value = checkTypeVsElement(value, element); | 2656 value = checkTypeVsElement(value, element); |
2892 return irBuilder.buildLocalVariableSet(element, value, | 2657 return irBuilder.buildLocalVariableSet( |
2893 sourceInformationBuilder.buildAssignment(node)); | 2658 element, value, sourceInformationBuilder.buildAssignment(node)); |
2894 } | 2659 } |
2895 | 2660 |
2896 @override | 2661 @override |
2897 ir.Primitive handleStaticFieldSet( | 2662 ir.Primitive handleStaticFieldSet( |
2898 ast.SendSet node, | 2663 ast.SendSet node, FieldElement field, ast.Node rhs, _) { |
2899 FieldElement field, | |
2900 ast.Node rhs, | |
2901 _) { | |
2902 ir.Primitive value = visit(rhs); | 2664 ir.Primitive value = visit(rhs); |
2903 irBuilder.addPrimitive(new ir.SetStatic(field, value, | 2665 irBuilder.addPrimitive(new ir.SetStatic( |
2904 sourceInformationBuilder.buildAssignment(node))); | 2666 field, value, sourceInformationBuilder.buildAssignment(node))); |
2905 return value; | 2667 return value; |
2906 } | 2668 } |
2907 | 2669 |
2908 @override | 2670 @override |
2909 ir.Primitive visitSuperFieldSet( | 2671 ir.Primitive visitSuperFieldSet( |
2910 ast.SendSet node, | 2672 ast.SendSet node, FieldElement field, ast.Node rhs, _) { |
2911 FieldElement field, | 2673 return irBuilder.buildSuperFieldSet( |
2912 ast.Node rhs, | 2674 field, visit(rhs), sourceInformationBuilder.buildAssignment(node)); |
2913 _) { | |
2914 return irBuilder.buildSuperFieldSet(field, visit(rhs), | |
2915 sourceInformationBuilder.buildAssignment(node)); | |
2916 } | 2675 } |
2917 | 2676 |
2918 @override | 2677 @override |
2919 ir.Primitive visitSuperSetterSet( | 2678 ir.Primitive visitSuperSetterSet( |
2920 ast.SendSet node, | 2679 ast.SendSet node, FunctionElement setter, ast.Node rhs, _) { |
2921 FunctionElement setter, | 2680 return irBuilder.buildSuperSetterSet( |
2922 ast.Node rhs, | 2681 setter, visit(rhs), sourceInformationBuilder.buildAssignment(node)); |
2923 _) { | |
2924 return irBuilder.buildSuperSetterSet(setter, visit(rhs), | |
2925 sourceInformationBuilder.buildAssignment(node)); | |
2926 } | 2682 } |
2927 | 2683 |
2928 @override | 2684 @override |
2929 ir.Primitive visitUnresolvedSuperIndexSet( | 2685 ir.Primitive visitUnresolvedSuperIndexSet( |
2930 ast.Send node, | 2686 ast.Send node, Element element, ast.Node index, ast.Node rhs, arg) { |
2931 Element element, | |
2932 ast.Node index, | |
2933 ast.Node rhs, | |
2934 arg) { | |
2935 return giveup(node, 'visitUnresolvedSuperIndexSet'); | 2687 return giveup(node, 'visitUnresolvedSuperIndexSet'); |
2936 } | 2688 } |
2937 | 2689 |
2938 @override | 2690 @override |
2939 ir.Primitive handleStaticSetterSet( | 2691 ir.Primitive handleStaticSetterSet( |
2940 ast.SendSet node, | 2692 ast.SendSet node, FunctionElement setter, ast.Node rhs, _) { |
2941 FunctionElement setter, | 2693 return irBuilder.buildStaticSetterSet( |
2942 ast.Node rhs, | 2694 setter, visit(rhs), sourceInformationBuilder.buildAssignment(node)); |
2943 _) { | |
2944 return irBuilder.buildStaticSetterSet(setter, visit(rhs), | |
2945 sourceInformationBuilder.buildAssignment(node)); | |
2946 } | 2695 } |
2947 | 2696 |
2948 @override | 2697 @override |
2949 ir.Primitive handleTypeLiteralConstantCompounds( | 2698 ir.Primitive handleTypeLiteralConstantCompounds( |
2950 ast.SendSet node, | 2699 ast.SendSet node, ConstantExpression constant, CompoundRhs rhs, arg) { |
2951 ConstantExpression constant, | |
2952 CompoundRhs rhs, | |
2953 arg) { | |
2954 SourceInformation src = sourceInformationBuilder.buildGet(node); | 2700 SourceInformation src = sourceInformationBuilder.buildGet(node); |
2955 return translateCompounds(node, () { | 2701 return translateCompounds( |
2956 return buildConstantExpression(constant, src); | 2702 node, |
2957 }, rhs, (ir.Primitive value) { | 2703 () { |
2958 // The binary operator will throw before this. | 2704 return buildConstantExpression(constant, src); |
2959 }); | 2705 }, |
| 2706 rhs, |
| 2707 (ir.Primitive value) { |
| 2708 // The binary operator will throw before this. |
| 2709 }); |
2960 } | 2710 } |
2961 | 2711 |
2962 @override | 2712 @override |
2963 ir.Primitive handleTypeLiteralConstantSetIfNulls( | 2713 ir.Primitive handleTypeLiteralConstantSetIfNulls( |
2964 ast.SendSet node, | 2714 ast.SendSet node, ConstantExpression constant, ast.Node rhs, _) { |
2965 ConstantExpression constant, | |
2966 ast.Node rhs, | |
2967 _) { | |
2968 // The type literal is never `null`. | 2715 // The type literal is never `null`. |
2969 return buildConstantExpression(constant, | 2716 return buildConstantExpression( |
2970 sourceInformationBuilder.buildGet(node)); | 2717 constant, sourceInformationBuilder.buildGet(node)); |
2971 } | 2718 } |
2972 | 2719 |
2973 @override | 2720 @override |
2974 ir.Primitive handleDynamicCompounds( | 2721 ir.Primitive handleDynamicCompounds( |
2975 ast.SendSet node, | 2722 ast.SendSet node, ast.Node receiver, Name name, CompoundRhs rhs, arg) { |
2976 ast.Node receiver, | |
2977 Name name, | |
2978 CompoundRhs rhs, | |
2979 arg) { | |
2980 ir.Primitive target = translateReceiver(receiver); | 2723 ir.Primitive target = translateReceiver(receiver); |
2981 ir.Primitive helper() { | 2724 ir.Primitive helper() { |
2982 return translateCompounds(node, () { | 2725 return translateCompounds( |
2983 return irBuilder.buildDynamicGet( | 2726 node, |
2984 target, | 2727 () { |
2985 new Selector.getter(name), | 2728 return irBuilder.buildDynamicGet( |
2986 elements.getGetterTypeMaskInComplexSendSet(node), | 2729 target, |
2987 sourceInformationBuilder.buildGet(node)); | 2730 new Selector.getter(name), |
2988 }, rhs, (ir.Primitive result) { | 2731 elements.getGetterTypeMaskInComplexSendSet(node), |
2989 irBuilder.buildDynamicSet( | 2732 sourceInformationBuilder.buildGet(node)); |
2990 target, | 2733 }, |
2991 new Selector.setter(name), | 2734 rhs, |
2992 elements.getTypeMask(node), | 2735 (ir.Primitive result) { |
2993 result, | 2736 irBuilder.buildDynamicSet( |
2994 sourceInformationBuilder.buildAssignment(node)); | 2737 target, |
2995 }); | 2738 new Selector.setter(name), |
| 2739 elements.getTypeMask(node), |
| 2740 result, |
| 2741 sourceInformationBuilder.buildAssignment(node)); |
| 2742 }); |
2996 } | 2743 } |
2997 return node.isConditional | 2744 return node.isConditional |
2998 ? irBuilder.buildIfNotNullSend( | 2745 ? irBuilder.buildIfNotNullSend( |
2999 target, nested(helper), sourceInformationBuilder.buildIf(node)) | 2746 target, nested(helper), sourceInformationBuilder.buildIf(node)) |
3000 : helper(); | 2747 : helper(); |
3001 } | 2748 } |
3002 | 2749 |
3003 @override | 2750 @override |
3004 ir.Primitive handleDynamicSetIfNulls( | 2751 ir.Primitive handleDynamicSetIfNulls( |
3005 ast.Send node, | 2752 ast.Send node, ast.Node receiver, Name name, ast.Node rhs, _) { |
3006 ast.Node receiver, | |
3007 Name name, | |
3008 ast.Node rhs, | |
3009 _) { | |
3010 ir.Primitive target = translateReceiver(receiver); | 2753 ir.Primitive target = translateReceiver(receiver); |
3011 ir.Primitive helper() { | 2754 ir.Primitive helper() { |
3012 return translateSetIfNull(node, () { | 2755 return translateSetIfNull( |
3013 return irBuilder.buildDynamicGet( | 2756 node, |
3014 target, | 2757 () { |
3015 new Selector.getter(name), | 2758 return irBuilder.buildDynamicGet( |
3016 elements.getGetterTypeMaskInComplexSendSet(node), | 2759 target, |
3017 sourceInformationBuilder.buildGet(node)); | 2760 new Selector.getter(name), |
3018 }, rhs, (ir.Primitive result) { | 2761 elements.getGetterTypeMaskInComplexSendSet(node), |
3019 irBuilder.buildDynamicSet( | 2762 sourceInformationBuilder.buildGet(node)); |
3020 target, | 2763 }, |
3021 new Selector.setter(name), | 2764 rhs, |
3022 elements.getTypeMask(node), | 2765 (ir.Primitive result) { |
3023 result, | 2766 irBuilder.buildDynamicSet( |
3024 sourceInformationBuilder.buildAssignment(node)); | 2767 target, |
3025 }); | 2768 new Selector.setter(name), |
| 2769 elements.getTypeMask(node), |
| 2770 result, |
| 2771 sourceInformationBuilder.buildAssignment(node)); |
| 2772 }); |
3026 } | 2773 } |
3027 return node.isConditional | 2774 return node.isConditional |
3028 ? irBuilder.buildIfNotNullSend( | 2775 ? irBuilder.buildIfNotNullSend( |
3029 target, nested(helper), sourceInformationBuilder.buildIf(node)) | 2776 target, nested(helper), sourceInformationBuilder.buildIf(node)) |
3030 : helper(); | 2777 : helper(); |
3031 } | 2778 } |
3032 | 2779 |
3033 ir.Primitive buildLocalNoSuchSetter( | 2780 ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value, |
3034 LocalElement local, | |
3035 ir.Primitive value, | |
3036 SourceInformation sourceInformation) { | 2781 SourceInformation sourceInformation) { |
3037 Selector selector = new Selector.setter( | 2782 Selector selector = new Selector.setter( |
3038 new Name(local.name, local.library, isSetter: true)); | 2783 new Name(local.name, local.library, isSetter: true)); |
3039 return irBuilder.buildStaticNoSuchMethod( | 2784 return irBuilder.buildStaticNoSuchMethod( |
3040 selector, [value], sourceInformation); | 2785 selector, [value], sourceInformation); |
3041 } | 2786 } |
3042 | 2787 |
3043 @override | 2788 @override |
3044 ir.Primitive handleLocalCompounds( | 2789 ir.Primitive handleLocalCompounds( |
3045 ast.SendSet node, | 2790 ast.SendSet node, LocalElement local, CompoundRhs rhs, arg, |
3046 LocalElement local, | |
3047 CompoundRhs rhs, | |
3048 arg, | |
3049 {bool isSetterValid}) { | 2791 {bool isSetterValid}) { |
3050 return translateCompounds(node, () { | 2792 return translateCompounds( |
3051 return irBuilder.buildLocalGet(local); | 2793 node, |
3052 }, rhs, (ir.Primitive result) { | 2794 () { |
3053 if (isSetterValid) { | 2795 return irBuilder.buildLocalGet(local); |
3054 irBuilder.buildLocalVariableSet( | 2796 }, |
3055 local, result, | 2797 rhs, |
3056 sourceInformationBuilder.buildAssignment(node)); | 2798 (ir.Primitive result) { |
3057 } else { | 2799 if (isSetterValid) { |
3058 Selector selector = new Selector.setter( | 2800 irBuilder.buildLocalVariableSet( |
3059 new Name(local.name, local.library, isSetter: true)); | 2801 local, result, sourceInformationBuilder.buildAssignment(node)); |
3060 irBuilder.buildStaticNoSuchMethod( | 2802 } else { |
3061 selector, <ir.Primitive>[result], | 2803 Selector selector = new Selector.setter( |
3062 sourceInformationBuilder.buildAssignment(node)); | 2804 new Name(local.name, local.library, isSetter: true)); |
3063 } | 2805 irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result], |
3064 }); | 2806 sourceInformationBuilder.buildAssignment(node)); |
| 2807 } |
| 2808 }); |
3065 } | 2809 } |
3066 | 2810 |
3067 @override | 2811 @override |
3068 ir.Primitive handleLocalSetIfNulls( | 2812 ir.Primitive handleLocalSetIfNulls( |
3069 ast.SendSet node, | 2813 ast.SendSet node, LocalElement local, ast.Node rhs, _, |
3070 LocalElement local, | |
3071 ast.Node rhs, | |
3072 _, | |
3073 {bool isSetterValid}) { | 2814 {bool isSetterValid}) { |
3074 return translateSetIfNull(node, () { | 2815 return translateSetIfNull( |
3075 return irBuilder.buildLocalGet( | 2816 node, |
3076 local, sourceInformation: sourceInformationBuilder.buildGet(node)); | 2817 () { |
3077 }, rhs, (ir.Primitive result) { | 2818 return irBuilder.buildLocalGet(local, |
3078 SourceInformation sourceInformation = | 2819 sourceInformation: sourceInformationBuilder.buildGet(node)); |
3079 sourceInformationBuilder.buildAssignment(node); | 2820 }, |
3080 if (isSetterValid) { | 2821 rhs, |
3081 irBuilder.buildLocalVariableSet( | 2822 (ir.Primitive result) { |
3082 local, result, sourceInformation); | 2823 SourceInformation sourceInformation = |
3083 } else { | 2824 sourceInformationBuilder.buildAssignment(node); |
3084 Selector selector = new Selector.setter( | 2825 if (isSetterValid) { |
3085 new Name(local.name, local.library, isSetter: true)); | 2826 irBuilder.buildLocalVariableSet(local, result, sourceInformation); |
3086 irBuilder.buildStaticNoSuchMethod( | 2827 } else { |
3087 selector, <ir.Primitive>[result], sourceInformation); | 2828 Selector selector = new Selector.setter( |
3088 } | 2829 new Name(local.name, local.library, isSetter: true)); |
3089 }); | 2830 irBuilder.buildStaticNoSuchMethod( |
| 2831 selector, <ir.Primitive>[result], sourceInformation); |
| 2832 } |
| 2833 }); |
3090 } | 2834 } |
3091 | 2835 |
3092 @override | 2836 @override |
3093 ir.Primitive handleStaticCompounds( | 2837 ir.Primitive handleStaticCompounds( |
3094 ast.SendSet node, | 2838 ast.SendSet node, |
3095 Element getter, | 2839 Element getter, |
3096 CompoundGetter getterKind, | 2840 CompoundGetter getterKind, |
3097 Element setter, | 2841 Element setter, |
3098 CompoundSetter setterKind, | 2842 CompoundSetter setterKind, |
3099 CompoundRhs rhs, | 2843 CompoundRhs rhs, |
3100 arg) { | 2844 arg) { |
3101 return translateCompounds(node, () { | 2845 return translateCompounds( |
3102 SourceInformation sourceInformation = | 2846 node, |
3103 sourceInformationBuilder.buildGet(node); | 2847 () { |
3104 switch (getterKind) { | 2848 SourceInformation sourceInformation = |
3105 case CompoundGetter.FIELD: | 2849 sourceInformationBuilder.buildGet(node); |
3106 return buildStaticFieldGet(getter, sourceInformation); | 2850 switch (getterKind) { |
3107 case CompoundGetter.GETTER: | 2851 case CompoundGetter.FIELD: |
3108 return buildStaticGetterGet(getter, node, sourceInformation); | 2852 return buildStaticFieldGet(getter, sourceInformation); |
3109 case CompoundGetter.METHOD: | 2853 case CompoundGetter.GETTER: |
3110 return irBuilder.addPrimitive(new ir.GetStatic(getter, | 2854 return buildStaticGetterGet(getter, node, sourceInformation); |
3111 sourceInformation: sourceInformation, isFinal: true)); | 2855 case CompoundGetter.METHOD: |
3112 case CompoundGetter.UNRESOLVED: | 2856 return irBuilder.addPrimitive(new ir.GetStatic(getter, |
3113 return irBuilder.buildStaticNoSuchMethod( | 2857 sourceInformation: sourceInformation, isFinal: true)); |
3114 new Selector.getter(new Name(getter.name, getter.library)), | 2858 case CompoundGetter.UNRESOLVED: |
3115 <ir.Primitive>[], | 2859 return irBuilder.buildStaticNoSuchMethod( |
3116 sourceInformation); | 2860 new Selector.getter(new Name(getter.name, getter.library)), |
3117 } | 2861 <ir.Primitive>[], |
3118 }, rhs, (ir.Primitive result) { | 2862 sourceInformation); |
3119 SourceInformation sourceInformation = | 2863 } |
3120 sourceInformationBuilder.buildAssignment(node); | 2864 }, |
3121 switch (setterKind) { | 2865 rhs, |
3122 case CompoundSetter.FIELD: | 2866 (ir.Primitive result) { |
3123 irBuilder.addPrimitive( | 2867 SourceInformation sourceInformation = |
3124 new ir.SetStatic(setter, result, sourceInformation)); | 2868 sourceInformationBuilder.buildAssignment(node); |
3125 return; | 2869 switch (setterKind) { |
3126 case CompoundSetter.SETTER: | 2870 case CompoundSetter.FIELD: |
3127 irBuilder.buildStaticSetterSet(setter, result, sourceInformation); | 2871 irBuilder.addPrimitive( |
3128 return; | 2872 new ir.SetStatic(setter, result, sourceInformation)); |
3129 case CompoundSetter.INVALID: | 2873 return; |
3130 irBuilder.buildStaticNoSuchMethod( | 2874 case CompoundSetter.SETTER: |
3131 new Selector.setter(new Name(setter.name, setter.library)), | 2875 irBuilder.buildStaticSetterSet(setter, result, sourceInformation); |
3132 <ir.Primitive>[result], | 2876 return; |
3133 sourceInformation); | 2877 case CompoundSetter.INVALID: |
3134 return; | 2878 irBuilder.buildStaticNoSuchMethod( |
3135 } | 2879 new Selector.setter(new Name(setter.name, setter.library)), |
3136 }); | 2880 <ir.Primitive>[result], |
| 2881 sourceInformation); |
| 2882 return; |
| 2883 } |
| 2884 }); |
3137 } | 2885 } |
3138 | 2886 |
3139 @override | 2887 @override |
3140 ir.Primitive handleStaticSetIfNulls( | 2888 ir.Primitive handleStaticSetIfNulls( |
3141 ast.SendSet node, | 2889 ast.SendSet node, |
3142 Element getter, | 2890 Element getter, |
3143 CompoundGetter getterKind, | 2891 CompoundGetter getterKind, |
3144 Element setter, | 2892 Element setter, |
3145 CompoundSetter setterKind, | 2893 CompoundSetter setterKind, |
3146 ast.Node rhs, | 2894 ast.Node rhs, |
3147 _) { | 2895 _) { |
3148 return translateSetIfNull(node, () { | 2896 return translateSetIfNull( |
3149 SourceInformation sourceInformation = | 2897 node, |
3150 sourceInformationBuilder.buildGet(node); | 2898 () { |
3151 switch (getterKind) { | 2899 SourceInformation sourceInformation = |
3152 case CompoundGetter.FIELD: | 2900 sourceInformationBuilder.buildGet(node); |
3153 return buildStaticFieldGet(getter, sourceInformation); | 2901 switch (getterKind) { |
3154 case CompoundGetter.GETTER: | 2902 case CompoundGetter.FIELD: |
3155 return buildStaticGetterGet(getter, node, sourceInformation); | 2903 return buildStaticFieldGet(getter, sourceInformation); |
3156 case CompoundGetter.METHOD: | 2904 case CompoundGetter.GETTER: |
3157 return irBuilder.addPrimitive(new ir.GetStatic(getter, | 2905 return buildStaticGetterGet(getter, node, sourceInformation); |
3158 sourceInformation: sourceInformation, | 2906 case CompoundGetter.METHOD: |
3159 isFinal: true)); | 2907 return irBuilder.addPrimitive(new ir.GetStatic(getter, |
3160 case CompoundGetter.UNRESOLVED: | 2908 sourceInformation: sourceInformation, isFinal: true)); |
3161 return irBuilder.buildStaticNoSuchMethod( | 2909 case CompoundGetter.UNRESOLVED: |
3162 new Selector.getter(new Name(getter.name, getter.library)), | 2910 return irBuilder.buildStaticNoSuchMethod( |
3163 <ir.Primitive>[], | 2911 new Selector.getter(new Name(getter.name, getter.library)), |
3164 sourceInformation); | 2912 <ir.Primitive>[], |
3165 } | 2913 sourceInformation); |
3166 }, rhs, (ir.Primitive result) { | 2914 } |
3167 SourceInformation sourceInformation = | 2915 }, |
3168 sourceInformationBuilder.buildAssignment(node); | 2916 rhs, |
3169 switch (setterKind) { | 2917 (ir.Primitive result) { |
3170 case CompoundSetter.FIELD: | 2918 SourceInformation sourceInformation = |
3171 irBuilder.addPrimitive(new ir.SetStatic( | 2919 sourceInformationBuilder.buildAssignment(node); |
3172 setter, result, sourceInformation)); | 2920 switch (setterKind) { |
3173 return; | 2921 case CompoundSetter.FIELD: |
3174 case CompoundSetter.SETTER: | 2922 irBuilder.addPrimitive( |
3175 irBuilder.buildStaticSetterSet(setter, result, sourceInformation); | 2923 new ir.SetStatic(setter, result, sourceInformation)); |
3176 return; | 2924 return; |
3177 case CompoundSetter.INVALID: | 2925 case CompoundSetter.SETTER: |
3178 irBuilder.buildStaticNoSuchMethod( | 2926 irBuilder.buildStaticSetterSet(setter, result, sourceInformation); |
3179 new Selector.setter(new Name(setter.name, setter.library)), | 2927 return; |
3180 <ir.Primitive>[result], | 2928 case CompoundSetter.INVALID: |
3181 sourceInformation); | 2929 irBuilder.buildStaticNoSuchMethod( |
3182 return; | 2930 new Selector.setter(new Name(setter.name, setter.library)), |
3183 } | 2931 <ir.Primitive>[result], |
3184 }); | 2932 sourceInformation); |
| 2933 return; |
| 2934 } |
| 2935 }); |
3185 } | 2936 } |
3186 | 2937 |
3187 ir.Primitive buildSuperNoSuchGetter( | 2938 ir.Primitive buildSuperNoSuchGetter( |
3188 Element element, | 2939 Element element, TypeMask mask, SourceInformation sourceInformation) { |
3189 TypeMask mask, | |
3190 SourceInformation sourceInformation) { | |
3191 return buildSuperNoSuchMethod( | 2940 return buildSuperNoSuchMethod( |
3192 new Selector.getter(new Name(element.name, element.library)), | 2941 new Selector.getter(new Name(element.name, element.library)), |
3193 mask, | 2942 mask, |
3194 const <ir.Primitive>[], | 2943 const <ir.Primitive>[], |
3195 sourceInformation); | 2944 sourceInformation); |
3196 } | 2945 } |
3197 | 2946 |
3198 ir.Primitive buildSuperNoSuchSetter( | 2947 ir.Primitive buildSuperNoSuchSetter(Element element, TypeMask mask, |
3199 Element element, | 2948 ir.Primitive value, SourceInformation sourceInformation) { |
3200 TypeMask mask, | |
3201 ir.Primitive value, | |
3202 SourceInformation sourceInformation) { | |
3203 return buildSuperNoSuchMethod( | 2949 return buildSuperNoSuchMethod( |
3204 new Selector.setter(new Name(element.name, element.library)), | 2950 new Selector.setter(new Name(element.name, element.library)), |
3205 mask, | 2951 mask, |
3206 <ir.Primitive>[value], | 2952 <ir.Primitive>[value], |
3207 sourceInformation); | 2953 sourceInformation); |
3208 } | 2954 } |
3209 | 2955 |
3210 @override | 2956 @override |
3211 ir.Primitive handleSuperCompounds( | 2957 ir.Primitive handleSuperCompounds( |
3212 ast.SendSet node, | 2958 ast.SendSet node, |
3213 Element getter, | 2959 Element getter, |
3214 CompoundGetter getterKind, | 2960 CompoundGetter getterKind, |
3215 Element setter, | 2961 Element setter, |
3216 CompoundSetter setterKind, | 2962 CompoundSetter setterKind, |
3217 CompoundRhs rhs, | 2963 CompoundRhs rhs, |
3218 arg) { | 2964 arg) { |
3219 return translateCompounds(node, () { | 2965 return translateCompounds( |
3220 switch (getterKind) { | 2966 node, |
3221 case CompoundGetter.FIELD: | 2967 () { |
3222 return irBuilder.buildSuperFieldGet( | 2968 switch (getterKind) { |
3223 getter, sourceInformationBuilder.buildGet(node)); | 2969 case CompoundGetter.FIELD: |
3224 case CompoundGetter.GETTER: | 2970 return irBuilder.buildSuperFieldGet( |
3225 return irBuilder.buildSuperGetterGet( | 2971 getter, sourceInformationBuilder.buildGet(node)); |
3226 getter, sourceInformationBuilder.buildGet(node)); | 2972 case CompoundGetter.GETTER: |
3227 case CompoundGetter.METHOD: | 2973 return irBuilder.buildSuperGetterGet( |
3228 return irBuilder.buildSuperMethodGet( | 2974 getter, sourceInformationBuilder.buildGet(node)); |
3229 getter, sourceInformationBuilder.buildGet(node)); | 2975 case CompoundGetter.METHOD: |
3230 case CompoundGetter.UNRESOLVED: | 2976 return irBuilder.buildSuperMethodGet( |
3231 return buildSuperNoSuchGetter( | 2977 getter, sourceInformationBuilder.buildGet(node)); |
3232 getter, elements.getGetterTypeMaskInComplexSendSet(node), | 2978 case CompoundGetter.UNRESOLVED: |
3233 sourceInformationBuilder.buildGet(node)); | 2979 return buildSuperNoSuchGetter( |
3234 } | 2980 getter, |
3235 }, rhs, (ir.Primitive result) { | 2981 elements.getGetterTypeMaskInComplexSendSet(node), |
3236 switch (setterKind) { | 2982 sourceInformationBuilder.buildGet(node)); |
3237 case CompoundSetter.FIELD: | 2983 } |
3238 irBuilder.buildSuperFieldSet(setter, result, | 2984 }, |
3239 sourceInformationBuilder.buildAssignment(node)); | 2985 rhs, |
3240 return; | 2986 (ir.Primitive result) { |
3241 case CompoundSetter.SETTER: | 2987 switch (setterKind) { |
3242 irBuilder.buildSuperSetterSet(setter, result, | 2988 case CompoundSetter.FIELD: |
3243 sourceInformationBuilder.buildAssignment(node)); | 2989 irBuilder.buildSuperFieldSet(setter, result, |
3244 return; | 2990 sourceInformationBuilder.buildAssignment(node)); |
3245 case CompoundSetter.INVALID: | 2991 return; |
3246 buildSuperNoSuchSetter( | 2992 case CompoundSetter.SETTER: |
3247 setter, elements.getTypeMask(node), result, | 2993 irBuilder.buildSuperSetterSet(setter, result, |
3248 sourceInformationBuilder.buildAssignment(node)); | 2994 sourceInformationBuilder.buildAssignment(node)); |
3249 return; | 2995 return; |
3250 } | 2996 case CompoundSetter.INVALID: |
3251 }); | 2997 buildSuperNoSuchSetter(setter, elements.getTypeMask(node), result, |
| 2998 sourceInformationBuilder.buildAssignment(node)); |
| 2999 return; |
| 3000 } |
| 3001 }); |
3252 } | 3002 } |
3253 | 3003 |
3254 @override | 3004 @override |
3255 ir.Primitive handleSuperSetIfNulls( | 3005 ir.Primitive handleSuperSetIfNulls( |
3256 ast.SendSet node, | 3006 ast.SendSet node, |
3257 Element getter, | 3007 Element getter, |
3258 CompoundGetter getterKind, | 3008 CompoundGetter getterKind, |
3259 Element setter, | 3009 Element setter, |
3260 CompoundSetter setterKind, | 3010 CompoundSetter setterKind, |
3261 ast.Node rhs, | 3011 ast.Node rhs, |
3262 _) { | 3012 _) { |
3263 return translateSetIfNull(node, () { | 3013 return translateSetIfNull( |
3264 switch (getterKind) { | 3014 node, |
3265 case CompoundGetter.FIELD: | 3015 () { |
3266 return irBuilder.buildSuperFieldGet( | 3016 switch (getterKind) { |
3267 getter, sourceInformationBuilder.buildGet(node)); | 3017 case CompoundGetter.FIELD: |
3268 case CompoundGetter.GETTER: | 3018 return irBuilder.buildSuperFieldGet( |
3269 return irBuilder.buildSuperGetterGet( | 3019 getter, sourceInformationBuilder.buildGet(node)); |
3270 getter, sourceInformationBuilder.buildGet(node)); | 3020 case CompoundGetter.GETTER: |
3271 case CompoundGetter.METHOD: | 3021 return irBuilder.buildSuperGetterGet( |
3272 return irBuilder.buildSuperMethodGet( | 3022 getter, sourceInformationBuilder.buildGet(node)); |
3273 getter, sourceInformationBuilder.buildGet(node)); | 3023 case CompoundGetter.METHOD: |
3274 case CompoundGetter.UNRESOLVED: | 3024 return irBuilder.buildSuperMethodGet( |
3275 return buildSuperNoSuchGetter( | 3025 getter, sourceInformationBuilder.buildGet(node)); |
3276 getter, | 3026 case CompoundGetter.UNRESOLVED: |
3277 elements.getGetterTypeMaskInComplexSendSet(node), | 3027 return buildSuperNoSuchGetter( |
3278 sourceInformationBuilder.buildGet(node)); | 3028 getter, |
3279 } | 3029 elements.getGetterTypeMaskInComplexSendSet(node), |
3280 }, rhs, (ir.Primitive result) { | 3030 sourceInformationBuilder.buildGet(node)); |
3281 switch (setterKind) { | 3031 } |
3282 case CompoundSetter.FIELD: | 3032 }, |
3283 irBuilder.buildSuperFieldSet( | 3033 rhs, |
3284 setter, result, | 3034 (ir.Primitive result) { |
3285 sourceInformationBuilder.buildAssignment(node)); | 3035 switch (setterKind) { |
3286 return; | 3036 case CompoundSetter.FIELD: |
3287 case CompoundSetter.SETTER: | 3037 irBuilder.buildSuperFieldSet(setter, result, |
3288 irBuilder.buildSuperSetterSet( | 3038 sourceInformationBuilder.buildAssignment(node)); |
3289 setter, result, | 3039 return; |
3290 sourceInformationBuilder.buildAssignment(node)); | 3040 case CompoundSetter.SETTER: |
3291 return; | 3041 irBuilder.buildSuperSetterSet(setter, result, |
3292 case CompoundSetter.INVALID: | 3042 sourceInformationBuilder.buildAssignment(node)); |
3293 buildSuperNoSuchSetter( | 3043 return; |
3294 setter, elements.getTypeMask(node), result, | 3044 case CompoundSetter.INVALID: |
3295 sourceInformationBuilder.buildAssignment(node)); | 3045 buildSuperNoSuchSetter(setter, elements.getTypeMask(node), result, |
3296 return; | 3046 sourceInformationBuilder.buildAssignment(node)); |
3297 } | 3047 return; |
3298 }); | 3048 } |
| 3049 }); |
3299 } | 3050 } |
3300 | 3051 |
3301 @override | 3052 @override |
3302 ir.Primitive handleTypeVariableTypeLiteralCompounds( | 3053 ir.Primitive handleTypeVariableTypeLiteralCompounds(ast.SendSet node, |
3303 ast.SendSet node, | 3054 TypeVariableElement typeVariable, CompoundRhs rhs, arg) { |
3304 TypeVariableElement typeVariable, | 3055 return translateCompounds( |
3305 CompoundRhs rhs, | 3056 node, |
3306 arg) { | 3057 () { |
3307 return translateCompounds(node, () { | 3058 return irBuilder.buildReifyTypeVariable( |
3308 return irBuilder.buildReifyTypeVariable( | 3059 typeVariable.type, sourceInformationBuilder.buildGet(node)); |
3309 typeVariable.type, | 3060 }, |
3310 sourceInformationBuilder.buildGet(node)); | 3061 rhs, |
3311 }, rhs, (ir.Primitive value) { | 3062 (ir.Primitive value) { |
3312 // The binary operator will throw before this. | 3063 // The binary operator will throw before this. |
3313 }); | 3064 }); |
3314 } | 3065 } |
3315 | 3066 |
3316 @override | 3067 @override |
3317 ir.Primitive visitTypeVariableTypeLiteralSetIfNull( | 3068 ir.Primitive visitTypeVariableTypeLiteralSetIfNull( |
3318 ast.Send node, | 3069 ast.Send node, TypeVariableElement element, ast.Node rhs, _) { |
3319 TypeVariableElement element, | |
3320 ast.Node rhs, | |
3321 _) { | |
3322 // The type variable is never `null`. | 3070 // The type variable is never `null`. |
3323 return translateTypeVariableTypeLiteral(element, | 3071 return translateTypeVariableTypeLiteral( |
3324 sourceInformationBuilder.buildGet(node)); | 3072 element, sourceInformationBuilder.buildGet(node)); |
3325 } | 3073 } |
3326 | 3074 |
3327 @override | 3075 @override |
3328 ir.Primitive handleIndexCompounds( | 3076 ir.Primitive handleIndexCompounds(ast.SendSet node, ast.Node receiver, |
3329 ast.SendSet node, | 3077 ast.Node index, CompoundRhs rhs, arg) { |
3330 ast.Node receiver, | |
3331 ast.Node index, | |
3332 CompoundRhs rhs, | |
3333 arg) { | |
3334 ir.Primitive target = visit(receiver); | 3078 ir.Primitive target = visit(receiver); |
3335 ir.Primitive indexValue = visit(index); | 3079 ir.Primitive indexValue = visit(index); |
3336 return translateCompounds(node, () { | 3080 return translateCompounds( |
3337 Selector selector = new Selector.index(); | 3081 node, |
3338 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; | 3082 () { |
3339 CallStructure callStructure = | 3083 Selector selector = new Selector.index(); |
3340 normalizeDynamicArguments(selector.callStructure, arguments); | 3084 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
3341 return irBuilder.buildDynamicInvocation( | 3085 CallStructure callStructure = |
3342 target, | 3086 normalizeDynamicArguments(selector.callStructure, arguments); |
3343 new Selector(selector.kind, selector.memberName, callStructure), | 3087 return irBuilder.buildDynamicInvocation( |
3344 elements.getGetterTypeMaskInComplexSendSet(node), | 3088 target, |
3345 arguments, | 3089 new Selector(selector.kind, selector.memberName, callStructure), |
3346 sourceInformationBuilder.buildCall(receiver, node)); | 3090 elements.getGetterTypeMaskInComplexSendSet(node), |
3347 }, rhs, (ir.Primitive result) { | 3091 arguments, |
3348 irBuilder.buildDynamicIndexSet( | 3092 sourceInformationBuilder.buildCall(receiver, node)); |
3349 target, | 3093 }, |
3350 elements.getTypeMask(node), | 3094 rhs, |
3351 indexValue, | 3095 (ir.Primitive result) { |
3352 result, | 3096 irBuilder.buildDynamicIndexSet(target, elements.getTypeMask(node), |
3353 sourceInformationBuilder.buildIndexSet(node)); | 3097 indexValue, result, sourceInformationBuilder.buildIndexSet(node)); |
3354 }); | 3098 }); |
3355 } | 3099 } |
3356 | 3100 |
3357 @override | 3101 @override |
3358 ir.Primitive handleSuperIndexCompounds( | 3102 ir.Primitive handleSuperIndexCompounds( |
3359 ast.SendSet node, | 3103 ast.SendSet node, |
3360 Element indexFunction, | 3104 Element indexFunction, |
3361 Element indexSetFunction, | 3105 Element indexSetFunction, |
3362 ast.Node index, | 3106 ast.Node index, |
3363 CompoundRhs rhs, | 3107 CompoundRhs rhs, |
3364 arg, | 3108 arg, |
3365 {bool isGetterValid, | 3109 {bool isGetterValid, |
3366 bool isSetterValid}) { | 3110 bool isSetterValid}) { |
3367 ir.Primitive indexValue = visit(index); | 3111 ir.Primitive indexValue = visit(index); |
3368 return translateCompounds(node, () { | 3112 return translateCompounds( |
3369 if (isGetterValid) { | 3113 node, |
3370 return irBuilder.buildSuperIndex( | 3114 () { |
3371 indexFunction, | 3115 if (isGetterValid) { |
3372 indexValue, | 3116 return irBuilder.buildSuperIndex(indexFunction, indexValue, |
3373 sourceInformationBuilder.buildIndex(node)); | 3117 sourceInformationBuilder.buildIndex(node)); |
3374 } else { | 3118 } else { |
3375 return buildSuperNoSuchMethod( | 3119 return buildSuperNoSuchMethod( |
3376 new Selector.index(), | 3120 new Selector.index(), |
3377 elements.getGetterTypeMaskInComplexSendSet(node), | 3121 elements.getGetterTypeMaskInComplexSendSet(node), |
3378 <ir.Primitive>[indexValue], | 3122 <ir.Primitive>[indexValue], |
3379 sourceInformationBuilder.buildIndex(node)); | 3123 sourceInformationBuilder.buildIndex(node)); |
3380 } | 3124 } |
3381 }, rhs, (ir.Primitive result) { | 3125 }, |
3382 if (isSetterValid) { | 3126 rhs, |
3383 irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result, | 3127 (ir.Primitive result) { |
3384 sourceInformationBuilder.buildIndexSet(node)); | 3128 if (isSetterValid) { |
3385 } else { | 3129 irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result, |
3386 buildSuperNoSuchMethod( | 3130 sourceInformationBuilder.buildIndexSet(node)); |
3387 new Selector.indexSet(), | 3131 } else { |
3388 elements.getTypeMask(node), | 3132 buildSuperNoSuchMethod( |
3389 <ir.Primitive>[indexValue, result], | 3133 new Selector.indexSet(), |
3390 sourceInformationBuilder.buildIndexSet(node)); | 3134 elements.getTypeMask(node), |
3391 } | 3135 <ir.Primitive>[indexValue, result], |
3392 }); | 3136 sourceInformationBuilder.buildIndexSet(node)); |
| 3137 } |
| 3138 }); |
3393 } | 3139 } |
3394 | 3140 |
3395 /// Build code to handle foreign code, that is, native JavaScript code, or | 3141 /// Build code to handle foreign code, that is, native JavaScript code, or |
3396 /// builtin values and operations of the backend. | 3142 /// builtin values and operations of the backend. |
3397 ir.Primitive handleForeignCode(ast.Send node, | 3143 ir.Primitive handleForeignCode(ast.Send node, MethodElement function, |
3398 MethodElement function, | 3144 ast.NodeList argumentList, CallStructure callStructure) { |
3399 ast.NodeList argumentList, | |
3400 CallStructure callStructure) { | |
3401 | |
3402 void validateArgumentCount({int minimum, int exactly}) { | 3145 void validateArgumentCount({int minimum, int exactly}) { |
3403 assert((minimum == null) != (exactly == null)); | 3146 assert((minimum == null) != (exactly == null)); |
3404 int count = 0; | 3147 int count = 0; |
3405 int maximum; | 3148 int maximum; |
3406 if (exactly != null) { | 3149 if (exactly != null) { |
3407 minimum = exactly; | 3150 minimum = exactly; |
3408 maximum = exactly; | 3151 maximum = exactly; |
3409 } | 3152 } |
3410 for (ast.Node argument in argumentList) { | 3153 for (ast.Node argument in argumentList) { |
3411 count++; | 3154 count++; |
3412 if (maximum != null && count > maximum) { | 3155 if (maximum != null && count > maximum) { |
3413 internalError(argument, 'Additional argument.'); | 3156 internalError(argument, 'Additional argument.'); |
3414 } | 3157 } |
3415 } | 3158 } |
3416 if (count < minimum) { | 3159 if (count < minimum) { |
3417 internalError(node, 'Expected at least $minimum arguments.'); | 3160 internalError(node, 'Expected at least $minimum arguments.'); |
3418 } | 3161 } |
3419 } | 3162 } |
3420 | 3163 |
3421 /// Call a helper method from the isolate library. The isolate library uses | 3164 /// Call a helper method from the isolate library. The isolate library uses |
3422 /// its own isolate structure, that encapsulates dart2js's isolate. | 3165 /// its own isolate structure, that encapsulates dart2js's isolate. |
3423 ir.Primitive buildIsolateHelperInvocation(MethodElement element, | 3166 ir.Primitive buildIsolateHelperInvocation( |
3424 CallStructure callStructure) { | 3167 MethodElement element, CallStructure callStructure) { |
3425 if (element == null) { | 3168 if (element == null) { |
3426 reporter.internalError(node, | 3169 reporter.internalError(node, 'Isolate library and compiler mismatch.'); |
3427 'Isolate library and compiler mismatch.'); | |
3428 } | 3170 } |
3429 List<ir.Primitive> arguments = <ir.Primitive>[]; | 3171 List<ir.Primitive> arguments = <ir.Primitive>[]; |
3430 callStructure = translateStaticArguments(argumentList, element, | 3172 callStructure = translateStaticArguments( |
3431 callStructure, arguments); | 3173 argumentList, element, callStructure, arguments); |
3432 Selector selector = new Selector.call(element.memberName, callStructure); | 3174 Selector selector = new Selector.call(element.memberName, callStructure); |
3433 return irBuilder.buildInvokeStatic(element, selector, arguments, | 3175 return irBuilder.buildInvokeStatic(element, selector, arguments, |
3434 sourceInformationBuilder.buildCall(node, node.selector)); | 3176 sourceInformationBuilder.buildCall(node, node.selector)); |
3435 } | 3177 } |
3436 | 3178 |
3437 /// Lookup the value of the enum described by [node]. | 3179 /// Lookup the value of the enum described by [node]. |
3438 getEnumValue(ast.Node node, EnumClassElement enumClass, List values) { | 3180 getEnumValue(ast.Node node, EnumClassElement enumClass, List values) { |
3439 Element element = elements[node]; | 3181 Element element = elements[node]; |
3440 if (element is! FieldElement || element.enclosingClass != enumClass) { | 3182 if (element is! FieldElement || element.enclosingClass != enumClass) { |
3441 internalError(node, 'expected a JsBuiltin enum value'); | 3183 internalError(node, 'expected a JsBuiltin enum value'); |
3442 } | 3184 } |
3443 | 3185 |
3444 int index = enumClass.enumValues.indexOf(element); | 3186 int index = enumClass.enumValues.indexOf(element); |
3445 return values[index]; | 3187 return values[index]; |
3446 } | 3188 } |
3447 | 3189 |
3448 /// Returns the String the node evaluates to, or throws an error if the | 3190 /// Returns the String the node evaluates to, or throws an error if the |
3449 /// result is not a string constant. | 3191 /// result is not a string constant. |
3450 String expectStringConstant(ast.Node node) { | 3192 String expectStringConstant(ast.Node node) { |
3451 ir.Primitive nameValue = visit(node); | 3193 ir.Primitive nameValue = visit(node); |
3452 if (nameValue is ir.Constant && nameValue.value.isString) { | 3194 if (nameValue is ir.Constant && nameValue.value.isString) { |
3453 StringConstantValue constantValue = nameValue.value; | 3195 StringConstantValue constantValue = nameValue.value; |
3454 return constantValue.primitiveValue.slowToString(); | 3196 return constantValue.primitiveValue.slowToString(); |
3455 } else { | 3197 } else { |
3456 return internalError(node, 'expected a literal string'); | 3198 return internalError(node, 'expected a literal string'); |
3457 } | 3199 } |
3458 } | 3200 } |
3459 | 3201 |
3460 Link<ast.Node> argumentNodes = argumentList.nodes; | 3202 Link<ast.Node> argumentNodes = argumentList.nodes; |
3461 NativeBehavior behavior = | 3203 NativeBehavior behavior = |
3462 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); | 3204 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
3463 switch (function.name) { | 3205 switch (function.name) { |
3464 case 'JS': | 3206 case 'JS': |
3465 validateArgumentCount(minimum: 2); | 3207 validateArgumentCount(minimum: 2); |
3466 // The first two arguments are the type and the foreign code template, | 3208 // The first two arguments are the type and the foreign code template, |
3467 // which already have been analyzed by the resolver and can be retrieved | 3209 // which already have been analyzed by the resolver and can be retrieved |
3468 // using [NativeBehavior]. We can ignore these arguments in the backend. | 3210 // using [NativeBehavior]. We can ignore these arguments in the backend. |
3469 List<ir.Primitive> arguments = | 3211 List<ir.Primitive> arguments = |
3470 argumentNodes.skip(2).mapToList(visit, growable: false); | 3212 argumentNodes.skip(2).mapToList(visit, growable: false); |
3471 if (behavior.codeTemplate.positionalArgumentCount != arguments.length) { | 3213 if (behavior.codeTemplate.positionalArgumentCount != arguments.length) { |
3472 reporter.reportErrorMessage( | 3214 reporter.reportErrorMessage(node, MessageKind.GENERIC, { |
3473 node, MessageKind.GENERIC, | 3215 'text': 'Mismatch between number of placeholders' |
3474 {'text': | 3216 ' and number of arguments.' |
3475 'Mismatch between number of placeholders' | 3217 }); |
3476 ' and number of arguments.'}); | |
3477 return irBuilder.buildNullConstant(); | 3218 return irBuilder.buildNullConstant(); |
3478 } | 3219 } |
3479 | 3220 |
3480 if (HasCapturedPlaceholders.check(behavior.codeTemplate.ast)) { | 3221 if (HasCapturedPlaceholders.check(behavior.codeTemplate.ast)) { |
3481 reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE); | 3222 reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE); |
3482 return irBuilder.buildNullConstant(); | 3223 return irBuilder.buildNullConstant(); |
3483 } | 3224 } |
3484 | 3225 |
3485 return irBuilder.buildForeignCode(behavior.codeTemplate, arguments, | 3226 return irBuilder.buildForeignCode(behavior.codeTemplate, arguments, |
3486 behavior, sourceInformationBuilder.buildForeignCode(node)); | 3227 behavior, sourceInformationBuilder.buildForeignCode(node)); |
3487 | 3228 |
3488 case 'DART_CLOSURE_TO_JS': | 3229 case 'DART_CLOSURE_TO_JS': |
3489 // TODO(ahe): This should probably take care to wrap the closure in | 3230 // TODO(ahe): This should probably take care to wrap the closure in |
3490 // another closure that saves the current isolate. | 3231 // another closure that saves the current isolate. |
3491 case 'RAW_DART_FUNCTION_REF': | 3232 case 'RAW_DART_FUNCTION_REF': |
3492 validateArgumentCount(exactly: 1); | 3233 validateArgumentCount(exactly: 1); |
3493 | 3234 |
3494 ast.Node argument = node.arguments.single; | 3235 ast.Node argument = node.arguments.single; |
3495 FunctionElement closure = elements[argument].implementation; | 3236 FunctionElement closure = elements[argument].implementation; |
3496 if (!Elements.isStaticOrTopLevelFunction(closure)) { | 3237 if (!Elements.isStaticOrTopLevelFunction(closure)) { |
3497 internalError(argument, | 3238 internalError(argument, 'only static or toplevel function supported'); |
3498 'only static or toplevel function supported'); | |
3499 } | 3239 } |
3500 if (closure.functionSignature.hasOptionalParameters) { | 3240 if (closure.functionSignature.hasOptionalParameters) { |
3501 internalError(argument, | 3241 internalError( |
3502 'closures with optional parameters not supported'); | 3242 argument, 'closures with optional parameters not supported'); |
3503 } | 3243 } |
3504 return irBuilder.buildForeignCode( | 3244 return irBuilder.buildForeignCode( |
3505 js.js.expressionTemplateYielding( | 3245 js.js.expressionTemplateYielding( |
3506 backend.emitter.staticFunctionAccess(closure)), | 3246 backend.emitter.staticFunctionAccess(closure)), |
3507 <ir.Primitive>[], | 3247 <ir.Primitive>[], |
3508 NativeBehavior.PURE, | 3248 NativeBehavior.PURE, |
3509 sourceInformationBuilder.buildForeignCode(node), | 3249 sourceInformationBuilder.buildForeignCode(node), |
3510 dependency: closure); | 3250 dependency: closure); |
3511 | 3251 |
3512 case 'JS_BUILTIN': | 3252 case 'JS_BUILTIN': |
3513 // The first argument is a description of the type and effect of the | 3253 // The first argument is a description of the type and effect of the |
3514 // builtin, which has already been analyzed in the frontend. The second | 3254 // builtin, which has already been analyzed in the frontend. The second |
3515 // argument must be a [JsBuiltin] value. All other arguments are | 3255 // argument must be a [JsBuiltin] value. All other arguments are |
3516 // values used by the JavaScript template that is associated with the | 3256 // values used by the JavaScript template that is associated with the |
3517 // builtin. | 3257 // builtin. |
3518 validateArgumentCount(minimum: 2); | 3258 validateArgumentCount(minimum: 2); |
3519 | 3259 |
3520 ast.Node builtin = argumentNodes.tail.head; | 3260 ast.Node builtin = argumentNodes.tail.head; |
3521 JsBuiltin value = getEnumValue(builtin, helpers.jsBuiltinEnum, | 3261 JsBuiltin value = |
3522 JsBuiltin.values); | 3262 getEnumValue(builtin, helpers.jsBuiltinEnum, JsBuiltin.values); |
3523 js.Template template = backend.emitter.builtinTemplateFor(value); | 3263 js.Template template = backend.emitter.builtinTemplateFor(value); |
3524 List<ir.Primitive> arguments = | 3264 List<ir.Primitive> arguments = |
3525 argumentNodes.skip(2).mapToList(visit, growable: false); | 3265 argumentNodes.skip(2).mapToList(visit, growable: false); |
3526 return irBuilder.buildForeignCode(template, arguments, behavior, | 3266 return irBuilder.buildForeignCode(template, arguments, behavior, |
3527 sourceInformationBuilder.buildForeignCode(node)); | 3267 sourceInformationBuilder.buildForeignCode(node)); |
3528 | 3268 |
3529 case 'JS_EMBEDDED_GLOBAL': | 3269 case 'JS_EMBEDDED_GLOBAL': |
3530 validateArgumentCount(exactly: 2); | 3270 validateArgumentCount(exactly: 2); |
3531 | 3271 |
3532 String name = expectStringConstant(argumentNodes.tail.head); | 3272 String name = expectStringConstant(argumentNodes.tail.head); |
3533 js.Expression access = | 3273 js.Expression access = |
3534 backend.emitter.generateEmbeddedGlobalAccess(name); | 3274 backend.emitter.generateEmbeddedGlobalAccess(name); |
3535 js.Template template = js.js.expressionTemplateYielding(access); | 3275 js.Template template = js.js.expressionTemplateYielding(access); |
3536 return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior, | 3276 return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior, |
3537 sourceInformationBuilder.buildForeignCode(node)); | 3277 sourceInformationBuilder.buildForeignCode(node)); |
3538 | 3278 |
3539 case 'JS_INTERCEPTOR_CONSTANT': | 3279 case 'JS_INTERCEPTOR_CONSTANT': |
3540 validateArgumentCount(exactly: 1); | 3280 validateArgumentCount(exactly: 1); |
3541 | 3281 |
3542 ast.Node argument = argumentNodes.head; | 3282 ast.Node argument = argumentNodes.head; |
3543 ir.Primitive argumentValue = visit(argument); | 3283 ir.Primitive argumentValue = visit(argument); |
3544 if (argumentValue is ir.Constant && argumentValue.value.isType) { | 3284 if (argumentValue is ir.Constant && argumentValue.value.isType) { |
3545 TypeConstantValue constant = argumentValue.value; | 3285 TypeConstantValue constant = argumentValue.value; |
3546 ConstantValue interceptorValue = | 3286 ConstantValue interceptorValue = |
3547 new InterceptorConstantValue(constant.representedType); | 3287 new InterceptorConstantValue(constant.representedType); |
3548 return irBuilder.buildConstant(interceptorValue); | 3288 return irBuilder.buildConstant(interceptorValue); |
3549 } | 3289 } |
3550 return internalError(argument, 'expected Type as argument'); | 3290 return internalError(argument, 'expected Type as argument'); |
3551 | 3291 |
3552 case 'JS_EFFECT': | 3292 case 'JS_EFFECT': |
3553 return irBuilder.buildNullConstant(); | 3293 return irBuilder.buildNullConstant(); |
3554 | 3294 |
3555 case 'JS_GET_NAME': | 3295 case 'JS_GET_NAME': |
3556 validateArgumentCount(exactly: 1); | 3296 validateArgumentCount(exactly: 1); |
3557 | 3297 |
3558 ast.Node argument = argumentNodes.head; | 3298 ast.Node argument = argumentNodes.head; |
3559 JsGetName id = getEnumValue(argument, helpers.jsGetNameEnum, | 3299 JsGetName id = |
3560 JsGetName.values); | 3300 getEnumValue(argument, helpers.jsGetNameEnum, JsGetName.values); |
3561 js.Name name = backend.namer.getNameForJsGetName(argument, id); | 3301 js.Name name = backend.namer.getNameForJsGetName(argument, id); |
3562 ConstantValue nameConstant = | 3302 ConstantValue nameConstant = new SyntheticConstantValue( |
3563 new SyntheticConstantValue(SyntheticConstantKind.NAME, | 3303 SyntheticConstantKind.NAME, js.js.quoteName(name)); |
3564 js.js.quoteName(name)); | |
3565 | 3304 |
3566 return irBuilder.buildConstant(nameConstant); | 3305 return irBuilder.buildConstant(nameConstant); |
3567 | 3306 |
3568 case 'JS_GET_FLAG': | 3307 case 'JS_GET_FLAG': |
3569 validateArgumentCount(exactly: 1); | 3308 validateArgumentCount(exactly: 1); |
3570 | 3309 |
3571 String name = expectStringConstant(argumentNodes.first); | 3310 String name = expectStringConstant(argumentNodes.first); |
3572 bool value = false; | 3311 bool value = false; |
3573 switch (name) { | 3312 switch (name) { |
3574 case 'MUST_RETAIN_METADATA': | 3313 case 'MUST_RETAIN_METADATA': |
3575 value = backend.mustRetainMetadata; | 3314 value = backend.mustRetainMetadata; |
3576 break; | 3315 break; |
3577 case 'USE_CONTENT_SECURITY_POLICY': | 3316 case 'USE_CONTENT_SECURITY_POLICY': |
3578 value = compiler.options.useContentSecurityPolicy; | 3317 value = compiler.options.useContentSecurityPolicy; |
3579 break; | 3318 break; |
3580 default: | 3319 default: |
3581 internalError(node, 'Unknown internal flag "$name".'); | 3320 internalError(node, 'Unknown internal flag "$name".'); |
3582 } | 3321 } |
3583 return irBuilder.buildBooleanConstant(value); | 3322 return irBuilder.buildBooleanConstant(value); |
3584 | 3323 |
3585 case 'JS_STRING_CONCAT': | 3324 case 'JS_STRING_CONCAT': |
3586 validateArgumentCount(exactly: 2); | 3325 validateArgumentCount(exactly: 2); |
3587 List<ir.Primitive> arguments = argumentNodes.mapToList(visit); | 3326 List<ir.Primitive> arguments = argumentNodes.mapToList(visit); |
3588 return irBuilder.buildStringConcatenation(arguments, | 3327 return irBuilder.buildStringConcatenation( |
3589 sourceInformationBuilder.buildForeignCode(node)); | 3328 arguments, sourceInformationBuilder.buildForeignCode(node)); |
3590 | 3329 |
3591 case 'JS_CURRENT_ISOLATE_CONTEXT': | 3330 case 'JS_CURRENT_ISOLATE_CONTEXT': |
3592 validateArgumentCount(exactly: 0); | 3331 validateArgumentCount(exactly: 0); |
3593 | 3332 |
3594 if (!compiler.hasIsolateSupport) { | 3333 if (!compiler.hasIsolateSupport) { |
3595 // If the isolate library is not used, we just generate code | 3334 // If the isolate library is not used, we just generate code |
3596 // to fetch the current isolate. | 3335 // to fetch the current isolate. |
3597 continue getStaticState; | 3336 continue getStaticState; |
3598 } | 3337 } |
3599 return buildIsolateHelperInvocation(helpers.currentIsolate, | 3338 return buildIsolateHelperInvocation( |
3600 CallStructure.NO_ARGS); | 3339 helpers.currentIsolate, CallStructure.NO_ARGS); |
3601 | 3340 |
3602 getStaticState: case 'JS_GET_STATIC_STATE': | 3341 getStaticState: case 'JS_GET_STATIC_STATE': |
3603 validateArgumentCount(exactly: 0); | 3342 validateArgumentCount(exactly: 0); |
3604 | 3343 |
3605 return irBuilder.buildForeignCode( | 3344 return irBuilder.buildForeignCode( |
3606 js.js.parseForeignJS(backend.namer.staticStateHolder), | 3345 js.js.parseForeignJS(backend.namer.staticStateHolder), |
3607 const <ir.Primitive>[], | 3346 const <ir.Primitive>[], |
3608 NativeBehavior.DEPENDS_OTHER, | 3347 NativeBehavior.DEPENDS_OTHER, |
3609 sourceInformationBuilder.buildForeignCode(node)); | 3348 sourceInformationBuilder.buildForeignCode(node)); |
3610 | 3349 |
3611 case 'JS_SET_STATIC_STATE': | 3350 case 'JS_SET_STATIC_STATE': |
3612 validateArgumentCount(exactly: 1); | 3351 validateArgumentCount(exactly: 1); |
3613 | 3352 |
3614 ir.Primitive value = visit(argumentNodes.single); | 3353 ir.Primitive value = visit(argumentNodes.single); |
3615 String isolateName = backend.namer.staticStateHolder; | 3354 String isolateName = backend.namer.staticStateHolder; |
3616 return irBuilder.buildForeignCode( | 3355 return irBuilder.buildForeignCode( |
3617 js.js.parseForeignJS("$isolateName = #"), | 3356 js.js.parseForeignJS("$isolateName = #"), |
3618 <ir.Primitive>[value], | 3357 <ir.Primitive>[value], |
3619 NativeBehavior.CHANGES_OTHER, | 3358 NativeBehavior.CHANGES_OTHER, |
3620 sourceInformationBuilder.buildForeignCode(node)); | 3359 sourceInformationBuilder.buildForeignCode(node)); |
3621 | 3360 |
3622 case 'JS_CALL_IN_ISOLATE': | 3361 case 'JS_CALL_IN_ISOLATE': |
3623 validateArgumentCount(exactly: 2); | 3362 validateArgumentCount(exactly: 2); |
3624 | 3363 |
3625 if (!compiler.hasIsolateSupport) { | 3364 if (!compiler.hasIsolateSupport) { |
3626 ir.Primitive closure = visit(argumentNodes.tail.head); | 3365 ir.Primitive closure = visit(argumentNodes.tail.head); |
3627 return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS, | 3366 return irBuilder.buildCallInvocation( |
| 3367 closure, |
| 3368 CallStructure.NO_ARGS, |
3628 const <ir.Primitive>[], | 3369 const <ir.Primitive>[], |
3629 sourceInformationBuilder.buildForeignCode(node)); | 3370 sourceInformationBuilder.buildForeignCode(node)); |
3630 } | 3371 } |
3631 return buildIsolateHelperInvocation(helpers.callInIsolate, | 3372 return buildIsolateHelperInvocation( |
3632 CallStructure.TWO_ARGS); | 3373 helpers.callInIsolate, CallStructure.TWO_ARGS); |
3633 | 3374 |
3634 default: | 3375 default: |
3635 return giveup(node, 'unplemented native construct: ${function.name}'); | 3376 return giveup(node, 'unplemented native construct: ${function.name}'); |
3636 } | 3377 } |
3637 } | 3378 } |
3638 | 3379 |
3639 /// Evaluates a string interpolation and appends each part to [accumulator] | 3380 /// Evaluates a string interpolation and appends each part to [accumulator] |
3640 /// (after stringify conversion). | 3381 /// (after stringify conversion). |
3641 void buildStringParts(ast.Node node, List<ir.Primitive> accumulator) { | 3382 void buildStringParts(ast.Node node, List<ir.Primitive> accumulator) { |
3642 if (node is ast.StringJuxtaposition) { | 3383 if (node is ast.StringJuxtaposition) { |
(...skipping 19 matching lines...) Expand all Loading... |
3662 helpers.stringInterpolationHelper, | 3403 helpers.stringInterpolationHelper, |
3663 <ir.Primitive>[value], | 3404 <ir.Primitive>[value], |
3664 sourceInformationBuilder.buildStringInterpolation(node))); | 3405 sourceInformationBuilder.buildStringInterpolation(node))); |
3665 } | 3406 } |
3666 } | 3407 } |
3667 | 3408 |
3668 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { | 3409 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { |
3669 assert(irBuilder.isOpen); | 3410 assert(irBuilder.isOpen); |
3670 List<ir.Primitive> parts = <ir.Primitive>[]; | 3411 List<ir.Primitive> parts = <ir.Primitive>[]; |
3671 buildStringParts(node, parts); | 3412 buildStringParts(node, parts); |
3672 return irBuilder.buildStringConcatenation(parts, | 3413 return irBuilder.buildStringConcatenation( |
3673 sourceInformationBuilder.buildStringInterpolation(node)); | 3414 parts, sourceInformationBuilder.buildStringInterpolation(node)); |
3674 } | 3415 } |
3675 | 3416 |
3676 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { | 3417 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { |
3677 assert(irBuilder.isOpen); | 3418 assert(irBuilder.isOpen); |
3678 List<ir.Primitive> parts = <ir.Primitive>[]; | 3419 List<ir.Primitive> parts = <ir.Primitive>[]; |
3679 buildStringParts(node, parts); | 3420 buildStringParts(node, parts); |
3680 return irBuilder.buildStringConcatenation(parts, | 3421 return irBuilder.buildStringConcatenation( |
3681 sourceInformationBuilder.buildStringInterpolation(node)); | 3422 parts, sourceInformationBuilder.buildStringInterpolation(node)); |
3682 } | 3423 } |
3683 | 3424 |
3684 ir.Primitive translateConstant(ast.Node node) { | 3425 ir.Primitive translateConstant(ast.Node node) { |
3685 assert(irBuilder.isOpen); | 3426 assert(irBuilder.isOpen); |
3686 return irBuilder.buildConstant( | 3427 return irBuilder.buildConstant(getConstantForNode(node), |
3687 getConstantForNode(node), | |
3688 sourceInformation: sourceInformationBuilder.buildGet(node)); | 3428 sourceInformation: sourceInformationBuilder.buildGet(node)); |
3689 } | 3429 } |
3690 | 3430 |
3691 ir.Primitive visitThrow(ast.Throw node) { | 3431 ir.Primitive visitThrow(ast.Throw node) { |
3692 assert(irBuilder.isOpen); | 3432 assert(irBuilder.isOpen); |
3693 // This function is not called for throw expressions occurring as | 3433 // This function is not called for throw expressions occurring as |
3694 // statements. | 3434 // statements. |
3695 return irBuilder.buildNonTailThrow(visit(node.expression)); | 3435 return irBuilder.buildNonTailThrow(visit(node.expression)); |
3696 } | 3436 } |
3697 | 3437 |
3698 ir.Primitive buildSuperNoSuchMethod( | 3438 ir.Primitive buildSuperNoSuchMethod(Selector selector, TypeMask mask, |
3699 Selector selector, | 3439 List<ir.Primitive> arguments, SourceInformation sourceInformation) { |
3700 TypeMask mask, | |
3701 List<ir.Primitive> arguments, | |
3702 SourceInformation sourceInformation) { | |
3703 ClassElement cls = elements.analyzedElement.enclosingClass; | 3440 ClassElement cls = elements.analyzedElement.enclosingClass; |
3704 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 3441 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
3705 if (!Selectors.noSuchMethod_.signatureApplies(element)) { | 3442 if (!Selectors.noSuchMethod_.signatureApplies(element)) { |
3706 element = compiler.coreClasses.objectClass.lookupMember( | 3443 element = compiler.coreClasses.objectClass |
3707 Identifiers.noSuchMethod_); | 3444 .lookupMember(Identifiers.noSuchMethod_); |
3708 } | 3445 } |
3709 return irBuilder.buildSuperMethodInvocation( | 3446 return irBuilder.buildSuperMethodInvocation( |
3710 element, | 3447 element, |
3711 Selectors.noSuchMethod_.callStructure, | 3448 Selectors.noSuchMethod_.callStructure, |
3712 [irBuilder.buildInvocationMirror(selector, arguments)], | 3449 [irBuilder.buildInvocationMirror(selector, arguments)], |
3713 sourceInformation); | 3450 sourceInformation); |
3714 } | 3451 } |
3715 | 3452 |
3716 @override | 3453 @override |
3717 ir.Primitive visitUnresolvedCompound( | 3454 ir.Primitive visitUnresolvedCompound(ast.Send node, Element element, |
3718 ast.Send node, | 3455 op.AssignmentOperator operator, ast.Node rhs, _) { |
3719 Element element, | |
3720 op.AssignmentOperator operator, | |
3721 ast.Node rhs, _) { | |
3722 return irBuilder.buildStaticNoSuchMethod( | 3456 return irBuilder.buildStaticNoSuchMethod( |
3723 new Selector.getter(new Name(element.name, element.library)), | 3457 new Selector.getter(new Name(element.name, element.library)), |
3724 [], | 3458 [], |
3725 sourceInformationBuilder.buildGet(node)); | 3459 sourceInformationBuilder.buildGet(node)); |
3726 } | 3460 } |
3727 | 3461 |
3728 @override | 3462 @override |
3729 ir.Primitive visitUnresolvedClassConstructorInvoke( | 3463 ir.Primitive visitUnresolvedClassConstructorInvoke( |
3730 ast.NewExpression node, | 3464 ast.NewExpression node, |
3731 Element element, | 3465 Element element, |
3732 DartType type, | 3466 DartType type, |
3733 ast.NodeList arguments, | 3467 ast.NodeList arguments, |
3734 Selector selector, _) { | 3468 Selector selector, |
| 3469 _) { |
3735 // If the class is missing it's a runtime error. | 3470 // If the class is missing it's a runtime error. |
3736 ir.Primitive message = | 3471 ir.Primitive message = |
3737 irBuilder.buildStringConstant("Unresolved class: '${element.name}'"); | 3472 irBuilder.buildStringConstant("Unresolved class: '${element.name}'"); |
3738 return irBuilder.buildStaticFunctionInvocation( | 3473 return irBuilder.buildStaticFunctionInvocation(helpers.throwRuntimeError, |
3739 helpers.throwRuntimeError, | 3474 <ir.Primitive>[message], sourceInformationBuilder.buildNew(node)); |
3740 <ir.Primitive>[message], | |
3741 sourceInformationBuilder.buildNew(node)); | |
3742 } | 3475 } |
3743 | 3476 |
3744 @override | 3477 @override |
3745 ir.Primitive visitUnresolvedConstructorInvoke( | 3478 ir.Primitive visitUnresolvedConstructorInvoke( |
3746 ast.NewExpression node, | 3479 ast.NewExpression node, |
3747 Element constructor, | 3480 Element constructor, |
3748 DartType type, | 3481 DartType type, |
3749 ast.NodeList argumentsNode, | 3482 ast.NodeList argumentsNode, |
3750 Selector selector, _) { | 3483 Selector selector, |
| 3484 _) { |
3751 // If the class is there but the constructor is missing, it's an NSM error. | 3485 // If the class is there but the constructor is missing, it's an NSM error. |
3752 List<ir.Primitive> arguments = <ir.Primitive>[]; | 3486 List<ir.Primitive> arguments = <ir.Primitive>[]; |
3753 CallStructure callStructure = translateDynamicArguments( | 3487 CallStructure callStructure = translateDynamicArguments( |
3754 argumentsNode, selector.callStructure, arguments); | 3488 argumentsNode, selector.callStructure, arguments); |
3755 return irBuilder.buildStaticNoSuchMethod( | 3489 return irBuilder.buildStaticNoSuchMethod( |
3756 new Selector(selector.kind, selector.memberName, callStructure), | 3490 new Selector(selector.kind, selector.memberName, callStructure), |
3757 arguments, | 3491 arguments, |
3758 sourceInformationBuilder.buildNew(node)); | 3492 sourceInformationBuilder.buildNew(node)); |
3759 } | 3493 } |
3760 | 3494 |
3761 @override | 3495 @override |
3762 ir.Primitive visitConstructorIncompatibleInvoke( | 3496 ir.Primitive visitConstructorIncompatibleInvoke( |
3763 ast.NewExpression node, | 3497 ast.NewExpression node, |
3764 ConstructorElement constructor, | 3498 ConstructorElement constructor, |
3765 DartType type, | 3499 DartType type, |
3766 ast.NodeList argumentsNode, | 3500 ast.NodeList argumentsNode, |
3767 CallStructure callStructure, _) { | 3501 CallStructure callStructure, |
| 3502 _) { |
3768 List<ir.Primitive> arguments = <ir.Primitive>[]; | 3503 List<ir.Primitive> arguments = <ir.Primitive>[]; |
3769 callStructure = | 3504 callStructure = |
3770 translateDynamicArguments(argumentsNode, callStructure, arguments); | 3505 translateDynamicArguments(argumentsNode, callStructure, arguments); |
3771 return irBuilder.buildStaticNoSuchMethod( | 3506 return irBuilder.buildStaticNoSuchMethod( |
3772 new Selector.call(constructor.memberName, callStructure), arguments, | 3507 new Selector.call(constructor.memberName, callStructure), |
| 3508 arguments, |
3773 sourceInformationBuilder.buildNew(node)); | 3509 sourceInformationBuilder.buildNew(node)); |
3774 } | 3510 } |
3775 | 3511 |
3776 @override | 3512 @override |
3777 ir.Primitive visitUnresolvedGet( | 3513 ir.Primitive visitUnresolvedGet(ast.Send node, Element element, _) { |
3778 ast.Send node, | 3514 return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), [], |
3779 Element element, _) { | |
3780 return irBuilder.buildStaticNoSuchMethod( | |
3781 elements.getSelector(node), [], | |
3782 sourceInformationBuilder.buildGet(node)); | 3515 sourceInformationBuilder.buildGet(node)); |
3783 } | 3516 } |
3784 | 3517 |
3785 @override | 3518 @override |
3786 ir.Primitive visitUnresolvedInvoke( | 3519 ir.Primitive visitUnresolvedInvoke(ast.Send node, Element element, |
3787 ast.Send node, | 3520 ast.NodeList arguments, Selector selector, _) { |
3788 Element element, | |
3789 ast.NodeList arguments, | |
3790 Selector selector, _) { | |
3791 return irBuilder.buildStaticNoSuchMethod( | 3521 return irBuilder.buildStaticNoSuchMethod( |
3792 elements.getSelector(node), | 3522 elements.getSelector(node), |
3793 arguments.nodes.mapToList(visit), | 3523 arguments.nodes.mapToList(visit), |
3794 sourceInformationBuilder.buildCall(node, node.selector)); | 3524 sourceInformationBuilder.buildCall(node, node.selector)); |
3795 } | 3525 } |
3796 | 3526 |
3797 @override | 3527 @override |
3798 ir.Primitive visitUnresolvedRedirectingFactoryConstructorInvoke( | 3528 ir.Primitive visitUnresolvedRedirectingFactoryConstructorInvoke( |
3799 ast.NewExpression node, | 3529 ast.NewExpression node, |
3800 ConstructorElement constructor, | 3530 ConstructorElement constructor, |
3801 InterfaceType type, | 3531 InterfaceType type, |
3802 ast.NodeList argumentsNode, | 3532 ast.NodeList argumentsNode, |
3803 CallStructure callStructure, _) { | 3533 CallStructure callStructure, |
| 3534 _) { |
3804 String nameString = Elements.reconstructConstructorName(constructor); | 3535 String nameString = Elements.reconstructConstructorName(constructor); |
3805 Name name = new Name(nameString, constructor.library); | 3536 Name name = new Name(nameString, constructor.library); |
3806 List<ir.Primitive> arguments = <ir.Primitive>[]; | 3537 List<ir.Primitive> arguments = <ir.Primitive>[]; |
3807 callStructure = | 3538 callStructure = |
3808 translateDynamicArguments(argumentsNode, callStructure, arguments); | 3539 translateDynamicArguments(argumentsNode, callStructure, arguments); |
3809 return irBuilder.buildStaticNoSuchMethod( | 3540 return irBuilder.buildStaticNoSuchMethod( |
3810 new Selector.call(name, callStructure), | 3541 new Selector.call(name, callStructure), |
3811 arguments, | 3542 arguments, |
3812 sourceInformationBuilder.buildNew(node)); | 3543 sourceInformationBuilder.buildNew(node)); |
3813 } | 3544 } |
3814 | 3545 |
3815 @override | 3546 @override |
3816 ir.Primitive visitUnresolvedSet( | 3547 ir.Primitive visitUnresolvedSet( |
3817 ast.Send node, | 3548 ast.Send node, Element element, ast.Node rhs, _) { |
3818 Element element, | |
3819 ast.Node rhs, _) { | |
3820 return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), | 3549 return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), |
3821 [visit(rhs)], | 3550 [visit(rhs)], sourceInformationBuilder.buildAssignment(node)); |
3822 sourceInformationBuilder.buildAssignment(node)); | |
3823 } | 3551 } |
3824 | 3552 |
3825 @override | 3553 @override |
3826 ir.Primitive visitUnresolvedSuperIndex( | 3554 ir.Primitive visitUnresolvedSuperIndex( |
3827 ast.Send node, | 3555 ast.Send node, Element function, ast.Node index, _) { |
3828 Element function, | |
3829 ast.Node index, _) { | |
3830 // Assume the index getter is missing. | 3556 // Assume the index getter is missing. |
3831 return buildSuperNoSuchMethod( | 3557 return buildSuperNoSuchMethod( |
3832 new Selector.index(), elements.getTypeMask(node), [visit(index)], | 3558 new Selector.index(), |
| 3559 elements.getTypeMask(node), |
| 3560 [visit(index)], |
3833 sourceInformationBuilder.buildIndex(node)); | 3561 sourceInformationBuilder.buildIndex(node)); |
3834 } | 3562 } |
3835 | 3563 |
3836 @override | 3564 @override |
3837 ir.Primitive visitUnresolvedSuperBinary( | 3565 ir.Primitive visitUnresolvedSuperBinary(ast.Send node, Element element, |
3838 ast.Send node, | 3566 op.BinaryOperator operator, ast.Node argument, _) { |
3839 Element element, | |
3840 op.BinaryOperator operator, | |
3841 ast.Node argument, _) { | |
3842 return buildSuperNoSuchMethod( | 3567 return buildSuperNoSuchMethod( |
3843 elements.getSelector(node), | 3568 elements.getSelector(node), |
3844 elements.getTypeMask(node), | 3569 elements.getTypeMask(node), |
3845 [visit(argument)], | 3570 [visit(argument)], |
3846 sourceInformationBuilder.buildCall(node, node.selector)); | 3571 sourceInformationBuilder.buildCall(node, node.selector)); |
3847 } | 3572 } |
3848 | 3573 |
3849 @override | 3574 @override |
3850 ir.Primitive visitUnresolvedSuperUnary( | 3575 ir.Primitive visitUnresolvedSuperUnary( |
3851 ast.Send node, | 3576 ast.Send node, op.UnaryOperator operator, Element element, _) { |
3852 op.UnaryOperator operator, | |
3853 Element element, _) { | |
3854 return buildSuperNoSuchMethod( | 3577 return buildSuperNoSuchMethod( |
3855 elements.getSelector(node), elements.getTypeMask(node), [], | 3578 elements.getSelector(node), |
| 3579 elements.getTypeMask(node), |
| 3580 [], |
3856 sourceInformationBuilder.buildCall(node, node.selector)); | 3581 sourceInformationBuilder.buildCall(node, node.selector)); |
3857 } | 3582 } |
3858 | 3583 |
3859 @override | 3584 @override |
3860 ir.Primitive bulkHandleNode(ast.Node node, String message, _) { | 3585 ir.Primitive bulkHandleNode(ast.Node node, String message, _) { |
3861 return giveup(node, "Unhandled node: ${message.replaceAll('#', '$node')}"); | 3586 return giveup(node, "Unhandled node: ${message.replaceAll('#', '$node')}"); |
3862 } | 3587 } |
3863 | 3588 |
3864 @override | 3589 @override |
3865 ir.Primitive bulkHandleError(ast.Node node, ErroneousElement error, _) { | 3590 ir.Primitive bulkHandleError(ast.Node node, ErroneousElement error, _) { |
3866 return irBuilder.buildNullConstant(); | 3591 return irBuilder.buildNullConstant(); |
3867 } | 3592 } |
3868 | 3593 |
3869 @override | 3594 @override |
3870 ir.Primitive visitClassTypeLiteralSet( | 3595 ir.Primitive visitClassTypeLiteralSet( |
3871 ast.SendSet node, | 3596 ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) { |
3872 TypeConstantExpression constant, | |
3873 ast.Node rhs, _) { | |
3874 InterfaceType type = constant.type; | 3597 InterfaceType type = constant.type; |
3875 ClassElement element = type.element; | 3598 ClassElement element = type.element; |
3876 return irBuilder.buildStaticNoSuchMethod( | 3599 return irBuilder.buildStaticNoSuchMethod( |
3877 new Selector.setter(element.memberName), | 3600 new Selector.setter(element.memberName), |
3878 [visit(rhs)], | 3601 [visit(rhs)], |
3879 sourceInformationBuilder.buildAssignment(node)); | 3602 sourceInformationBuilder.buildAssignment(node)); |
3880 } | 3603 } |
3881 | 3604 |
3882 @override | 3605 @override |
3883 ir.Primitive visitTypedefTypeLiteralSet( | 3606 ir.Primitive visitTypedefTypeLiteralSet( |
3884 ast.SendSet node, | 3607 ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) { |
3885 TypeConstantExpression constant, | |
3886 ast.Node rhs, _) { | |
3887 TypedefType type = constant.type; | 3608 TypedefType type = constant.type; |
3888 TypedefElement element = type.element; | 3609 TypedefElement element = type.element; |
3889 return irBuilder.buildStaticNoSuchMethod( | 3610 return irBuilder.buildStaticNoSuchMethod( |
3890 new Selector.setter(element.memberName), | 3611 new Selector.setter(element.memberName), |
3891 [visit(rhs)], | 3612 [visit(rhs)], |
3892 sourceInformationBuilder.buildAssignment(node)); | 3613 sourceInformationBuilder.buildAssignment(node)); |
3893 } | 3614 } |
3894 | 3615 |
3895 @override | 3616 @override |
3896 ir.Primitive visitTypeVariableTypeLiteralSet( | 3617 ir.Primitive visitTypeVariableTypeLiteralSet( |
3897 ast.SendSet node, | 3618 ast.SendSet node, TypeVariableElement element, ast.Node rhs, _) { |
3898 TypeVariableElement element, | |
3899 ast.Node rhs, _) { | |
3900 return irBuilder.buildStaticNoSuchMethod( | 3619 return irBuilder.buildStaticNoSuchMethod( |
3901 new Selector.setter(element.memberName), [visit(rhs)], | 3620 new Selector.setter(element.memberName), |
| 3621 [visit(rhs)], |
3902 sourceInformationBuilder.buildAssignment(node)); | 3622 sourceInformationBuilder.buildAssignment(node)); |
3903 } | 3623 } |
3904 | 3624 |
3905 @override | 3625 @override |
3906 ir.Primitive visitDynamicTypeLiteralSet( | 3626 ir.Primitive visitDynamicTypeLiteralSet( |
3907 ast.SendSet node, | 3627 ast.SendSet node, ConstantExpression constant, ast.Node rhs, _) { |
3908 ConstantExpression constant, | |
3909 ast.Node rhs, _) { | |
3910 return irBuilder.buildStaticNoSuchMethod( | 3628 return irBuilder.buildStaticNoSuchMethod( |
3911 new Selector.setter(Names.dynamic_), [visit(rhs)], | 3629 new Selector.setter(Names.dynamic_), |
| 3630 [visit(rhs)], |
3912 sourceInformationBuilder.buildAssignment(node)); | 3631 sourceInformationBuilder.buildAssignment(node)); |
3913 } | 3632 } |
3914 | 3633 |
3915 @override | 3634 @override |
3916 ir.Primitive visitAbstractClassConstructorInvoke( | 3635 ir.Primitive visitAbstractClassConstructorInvoke( |
3917 ast.NewExpression node, | 3636 ast.NewExpression node, |
3918 ConstructorElement element, | 3637 ConstructorElement element, |
3919 InterfaceType type, | 3638 InterfaceType type, |
3920 ast.NodeList arguments, | 3639 ast.NodeList arguments, |
3921 CallStructure callStructure, _) { | 3640 CallStructure callStructure, |
| 3641 _) { |
3922 for (ast.Node argument in arguments) visit(argument); | 3642 for (ast.Node argument in arguments) visit(argument); |
3923 ir.Primitive name = | 3643 ir.Primitive name = |
3924 irBuilder.buildStringConstant(element.enclosingClass.name); | 3644 irBuilder.buildStringConstant(element.enclosingClass.name); |
3925 return irBuilder.buildStaticFunctionInvocation( | 3645 return irBuilder.buildStaticFunctionInvocation( |
3926 helpers.throwAbstractClassInstantiationError, | 3646 helpers.throwAbstractClassInstantiationError, |
3927 <ir.Primitive>[name], | 3647 <ir.Primitive>[name], |
3928 sourceInformationBuilder.buildNew(node)); | 3648 sourceInformationBuilder.buildNew(node)); |
3929 } | 3649 } |
3930 | 3650 |
3931 @override | 3651 @override |
3932 ir.Primitive handleFinalStaticFieldSet( | 3652 ir.Primitive handleFinalStaticFieldSet( |
3933 ast.SendSet node, | 3653 ast.SendSet node, FieldElement field, ast.Node rhs, _) { |
3934 FieldElement field, | |
3935 ast.Node rhs, _) { | |
3936 // TODO(asgerf): Include class name somehow for static class members? | 3654 // TODO(asgerf): Include class name somehow for static class members? |
3937 return irBuilder.buildStaticNoSuchMethod( | 3655 return irBuilder.buildStaticNoSuchMethod( |
3938 new Selector.setter(field.memberName), | 3656 new Selector.setter(field.memberName), |
3939 [visit(rhs)], | 3657 [visit(rhs)], |
3940 sourceInformationBuilder.buildAssignment(node)); | 3658 sourceInformationBuilder.buildAssignment(node)); |
3941 } | 3659 } |
3942 | 3660 |
3943 @override | 3661 @override |
3944 ir.Primitive visitFinalSuperFieldSet( | 3662 ir.Primitive visitFinalSuperFieldSet( |
3945 ast.SendSet node, | 3663 ast.SendSet node, FieldElement field, ast.Node rhs, _) { |
3946 FieldElement field, | |
3947 ast.Node rhs, _) { | |
3948 return buildSuperNoSuchMethod( | 3664 return buildSuperNoSuchMethod( |
3949 new Selector.setter(field.memberName), | 3665 new Selector.setter(field.memberName), |
3950 elements.getTypeMask(node), | 3666 elements.getTypeMask(node), |
3951 [visit(rhs)], | 3667 [visit(rhs)], |
3952 sourceInformationBuilder.buildAssignment(node)); | 3668 sourceInformationBuilder.buildAssignment(node)); |
3953 } | 3669 } |
3954 | 3670 |
3955 @override | 3671 @override |
3956 ir.Primitive handleImmutableLocalSet( | 3672 ir.Primitive handleImmutableLocalSet( |
3957 ast.SendSet node, | 3673 ast.SendSet node, LocalElement local, ast.Node rhs, _) { |
3958 LocalElement local, | |
3959 ast.Node rhs, _) { | |
3960 return irBuilder.buildStaticNoSuchMethod( | 3674 return irBuilder.buildStaticNoSuchMethod( |
3961 new Selector.setter(new Name(local.name, local.library)), | 3675 new Selector.setter(new Name(local.name, local.library)), |
3962 [visit(rhs)], | 3676 [visit(rhs)], |
3963 sourceInformationBuilder.buildAssignment(node)); | 3677 sourceInformationBuilder.buildAssignment(node)); |
3964 } | 3678 } |
3965 | 3679 |
3966 @override | 3680 @override |
3967 ir.Primitive handleStaticFunctionSet( | 3681 ir.Primitive handleStaticFunctionSet( |
3968 ast.Send node, | 3682 ast.Send node, MethodElement function, ast.Node rhs, _) { |
3969 MethodElement function, | |
3970 ast.Node rhs, | |
3971 _) { | |
3972 return irBuilder.buildStaticNoSuchMethod( | 3683 return irBuilder.buildStaticNoSuchMethod( |
3973 new Selector.setter(function.memberName), | 3684 new Selector.setter(function.memberName), |
3974 [visit(rhs)], | 3685 [visit(rhs)], |
3975 sourceInformationBuilder.buildAssignment(node)); | 3686 sourceInformationBuilder.buildAssignment(node)); |
3976 } | 3687 } |
3977 | 3688 |
3978 @override | 3689 @override |
3979 ir.Primitive handleStaticGetterSet( | 3690 ir.Primitive handleStaticGetterSet( |
3980 ast.SendSet node, | 3691 ast.SendSet node, GetterElement getter, ast.Node rhs, _) { |
3981 GetterElement getter, | |
3982 ast.Node rhs, | |
3983 _) { | |
3984 return irBuilder.buildStaticNoSuchMethod( | 3692 return irBuilder.buildStaticNoSuchMethod( |
3985 new Selector.setter(getter.memberName), | 3693 new Selector.setter(getter.memberName), |
3986 [visit(rhs)], | 3694 [visit(rhs)], |
3987 sourceInformationBuilder.buildAssignment(node)); | 3695 sourceInformationBuilder.buildAssignment(node)); |
3988 } | 3696 } |
3989 | 3697 |
3990 @override | 3698 @override |
3991 ir.Primitive handleStaticSetterGet( | 3699 ir.Primitive handleStaticSetterGet(ast.Send node, SetterElement setter, _) { |
3992 ast.Send node, | |
3993 SetterElement setter, | |
3994 _) { | |
3995 return irBuilder.buildStaticNoSuchMethod( | 3700 return irBuilder.buildStaticNoSuchMethod( |
3996 new Selector.getter(setter.memberName), | 3701 new Selector.getter(setter.memberName), |
3997 [], | 3702 [], |
3998 sourceInformationBuilder.buildGet(node)); | 3703 sourceInformationBuilder.buildGet(node)); |
3999 } | 3704 } |
4000 | 3705 |
4001 @override | 3706 @override |
4002 ir.Primitive handleStaticSetterInvoke( | 3707 ir.Primitive handleStaticSetterInvoke(ast.Send node, SetterElement setter, |
4003 ast.Send node, | 3708 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
4004 SetterElement setter, | |
4005 ast.NodeList argumentsNode, | |
4006 CallStructure callStructure, _) { | |
4007 // Translate as a method call. | 3709 // Translate as a method call. |
4008 List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit); | 3710 List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit); |
4009 return irBuilder.buildStaticNoSuchMethod( | 3711 return irBuilder.buildStaticNoSuchMethod( |
4010 new Selector.call(setter.memberName, callStructure), | 3712 new Selector.call(setter.memberName, callStructure), |
4011 arguments, | 3713 arguments, |
4012 sourceInformationBuilder.buildCall(node, argumentsNode)); | 3714 sourceInformationBuilder.buildCall(node, argumentsNode)); |
4013 } | 3715 } |
4014 | 3716 |
4015 @override | 3717 @override |
4016 ir.Primitive visitSuperGetterSet( | 3718 ir.Primitive visitSuperGetterSet( |
4017 ast.SendSet node, | 3719 ast.SendSet node, GetterElement getter, ast.Node rhs, _) { |
4018 GetterElement getter, | |
4019 ast.Node rhs, | |
4020 _) { | |
4021 return buildSuperNoSuchMethod( | 3720 return buildSuperNoSuchMethod( |
4022 new Selector.setter(getter.memberName), | 3721 new Selector.setter(getter.memberName), |
4023 elements.getTypeMask(node), | 3722 elements.getTypeMask(node), |
4024 [visit(rhs)], | 3723 [visit(rhs)], |
4025 sourceInformationBuilder.buildAssignment(node)); | 3724 sourceInformationBuilder.buildAssignment(node)); |
4026 } | 3725 } |
4027 | 3726 |
4028 @override | 3727 @override |
4029 ir.Primitive visitSuperMethodSet( | 3728 ir.Primitive visitSuperMethodSet( |
4030 ast.Send node, | 3729 ast.Send node, MethodElement method, ast.Node rhs, _) { |
4031 MethodElement method, | |
4032 ast.Node rhs, | |
4033 _) { | |
4034 return buildSuperNoSuchMethod( | 3730 return buildSuperNoSuchMethod( |
4035 new Selector.setter(method.memberName), | 3731 new Selector.setter(method.memberName), |
4036 elements.getTypeMask(node), | 3732 elements.getTypeMask(node), |
4037 [visit(rhs)], | 3733 [visit(rhs)], |
4038 sourceInformationBuilder.buildAssignment(node)); | 3734 sourceInformationBuilder.buildAssignment(node)); |
4039 } | 3735 } |
4040 | 3736 |
4041 @override | 3737 @override |
4042 ir.Primitive visitSuperSetterGet( | 3738 ir.Primitive visitSuperSetterGet(ast.Send node, SetterElement setter, _) { |
4043 ast.Send node, | |
4044 SetterElement setter, _) { | |
4045 return buildSuperNoSuchMethod( | 3739 return buildSuperNoSuchMethod( |
4046 new Selector.getter(setter.memberName), | 3740 new Selector.getter(setter.memberName), |
4047 elements.getTypeMask(node), | 3741 elements.getTypeMask(node), |
4048 [], | 3742 [], |
4049 sourceInformationBuilder.buildGet(node)); | 3743 sourceInformationBuilder.buildGet(node)); |
4050 } | 3744 } |
4051 | 3745 |
4052 @override | 3746 @override |
4053 ir.Primitive visitSuperSetterInvoke( | 3747 ir.Primitive visitSuperSetterInvoke(ast.Send node, SetterElement setter, |
4054 ast.Send node, | 3748 ast.NodeList argumentsNode, CallStructure callStructure, _) { |
4055 SetterElement setter, | |
4056 ast.NodeList argumentsNode, | |
4057 CallStructure callStructure, _) { | |
4058 List<ir.Primitive> arguments = <ir.Primitive>[]; | 3749 List<ir.Primitive> arguments = <ir.Primitive>[]; |
4059 callStructure = | 3750 callStructure = |
4060 translateDynamicArguments(argumentsNode, callStructure, arguments); | 3751 translateDynamicArguments(argumentsNode, callStructure, arguments); |
4061 return buildSuperNoSuchMethod( | 3752 return buildSuperNoSuchMethod( |
4062 new Selector.call(setter.memberName, callStructure), | 3753 new Selector.call(setter.memberName, callStructure), |
4063 elements.getTypeMask(node), | 3754 elements.getTypeMask(node), |
4064 arguments, | 3755 arguments, |
4065 sourceInformationBuilder.buildCall(node, argumentsNode)); | 3756 sourceInformationBuilder.buildCall(node, argumentsNode)); |
4066 } | 3757 } |
4067 | 3758 |
4068 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { | 3759 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { |
4069 try { | 3760 try { |
4070 return action(); | 3761 return action(); |
4071 } catch(e) { | 3762 } catch (e) { |
4072 if (e == ABORT_IRNODE_BUILDER) { | 3763 if (e == ABORT_IRNODE_BUILDER) { |
4073 return null; | 3764 return null; |
4074 } | 3765 } |
4075 rethrow; | 3766 rethrow; |
4076 } | 3767 } |
4077 } | 3768 } |
4078 | 3769 |
4079 internalError(ast.Node node, String message) { | 3770 internalError(ast.Node node, String message) { |
4080 reporter.internalError(node, message); | 3771 reporter.internalError(node, message); |
4081 } | 3772 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4290 return _backend.dynamicType; | 3981 return _backend.dynamicType; |
4291 } | 3982 } |
4292 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); | 3983 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); |
4293 } | 3984 } |
4294 | 3985 |
4295 bool isArrayType(TypeMask type) { | 3986 bool isArrayType(TypeMask type) { |
4296 return type.satisfies(_backend.helpers.jsArrayClass, _compiler.world); | 3987 return type.satisfies(_backend.helpers.jsArrayClass, _compiler.world); |
4297 } | 3988 } |
4298 | 3989 |
4299 TypeMask getTypeMaskForNativeFunction(FunctionElement function) { | 3990 TypeMask getTypeMaskForNativeFunction(FunctionElement function) { |
4300 return _compiler.typesTask.getGuaranteedReturnTypeOfElement(function); | 3991 return _compiler.typesTask.getGuaranteedReturnTypeOfElement(function); |
4301 } | 3992 } |
4302 | 3993 |
4303 FieldElement locateSingleField(Selector selector, TypeMask type) { | 3994 FieldElement locateSingleField(Selector selector, TypeMask type) { |
4304 return _compiler.world.locateSingleField(selector, type); | 3995 return _compiler.world.locateSingleField(selector, type); |
4305 } | 3996 } |
4306 | 3997 |
4307 bool fieldNeverChanges(FieldElement field) { | 3998 bool fieldNeverChanges(FieldElement field) { |
4308 return _compiler.world.fieldNeverChanges(field); | 3999 return _compiler.world.fieldNeverChanges(field); |
4309 } | 4000 } |
4310 | 4001 |
4311 Element get closureConverter { | 4002 Element get closureConverter { |
4312 return _backend.helpers.closureConverter; | 4003 return _backend.helpers.closureConverter; |
4313 } | 4004 } |
4314 | 4005 |
4315 void addNativeMethod(FunctionElement function) { | 4006 void addNativeMethod(FunctionElement function) { |
4316 _backend.emitter.nativeEmitter.nativeMethods.add(function); | 4007 _backend.emitter.nativeEmitter.nativeMethods.add(function); |
4317 } | 4008 } |
4318 | 4009 |
4319 bool get trustJSInteropTypeAnnotations => | 4010 bool get trustJSInteropTypeAnnotations => |
4320 _compiler.options.trustJSInteropTypeAnnotations; | 4011 _compiler.options.trustJSInteropTypeAnnotations; |
4321 | 4012 |
4322 bool isNative(ClassElement element) => _backend.isNative(element); | 4013 bool isNative(ClassElement element) => _backend.isNative(element); |
4323 | 4014 |
4324 bool isJsInterop(FunctionElement element) => _backend.isJsInterop(element); | 4015 bool isJsInterop(FunctionElement element) => _backend.isJsInterop(element); |
4325 | 4016 |
4326 bool isJsInteropAnonymous(FunctionElement element) => | 4017 bool isJsInteropAnonymous(FunctionElement element) => |
4327 _backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass); | 4018 _backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass); |
4328 | 4019 |
4329 String getJsInteropTargetPath(FunctionElement element) { | 4020 String getJsInteropTargetPath(FunctionElement element) { |
4330 return '${_backend.namer.fixedBackendPath(element)}.' | 4021 return '${_backend.namer.fixedBackendPath(element)}.' |
4331 '${_backend.nativeData.getFixedBackendName(element)}'; | 4022 '${_backend.nativeData.getFixedBackendName(element)}'; |
4332 } | 4023 } |
4333 | 4024 |
4334 DartType get jsJavascriptObjectType => | 4025 DartType get jsJavascriptObjectType => |
4335 _backend.helpers.jsJavaScriptObjectClass.thisType; | 4026 _backend.helpers.jsJavaScriptObjectClass.thisType; |
4336 } | 4027 } |
OLD | NEW |