Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1110)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2607013003: Some constructor fixes: implement redirecting constructors, work with finding default constructors … (Closed)
Patch Set: . Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | sdk/bin/dart2js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../closure.dart'; 7 import '../closure.dart';
8 import '../common.dart'; 8 import '../common.dart';
9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
10 import '../common/names.dart'; 10 import '../common/names.dart';
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 fieldValues[field] = pop(); 301 fieldValues[field] = pop();
302 } 302 }
303 } 303 }
304 304
305 return fieldValues; 305 return fieldValues;
306 } 306 }
307 307
308 /// Collects field initializers all the way up the inheritance chain. 308 /// Collects field initializers all the way up the inheritance chain.
309 void _buildInitializers( 309 void _buildInitializers(
310 ir.Constructor constructor, Map<ir.Field, HInstruction> fieldValues) { 310 ir.Constructor constructor, Map<ir.Field, HInstruction> fieldValues) {
311 var foundSuperCall = false; 311 var foundSuperOrRedirectCall = false;
312 for (var initializer in constructor.initializers) { 312 for (var initializer in constructor.initializers) {
313 if (initializer is ir.SuperInitializer) { 313 if (initializer is ir.SuperInitializer ||
314 foundSuperCall = true; 314 initializer is ir.RedirectingInitializer) {
315 var superConstructor = initializer.target; 315 foundSuperOrRedirectCall = true;
316 var superOrRedirectConstructor = initializer.target;
316 var arguments = _normalizeAndBuildArguments( 317 var arguments = _normalizeAndBuildArguments(
317 superConstructor.function, initializer.arguments); 318 superOrRedirectConstructor.function, initializer.arguments);
318 _buildInlinedSuperInitializers( 319 _buildInlinedInitializers(
319 superConstructor, arguments, fieldValues); 320 superOrRedirectConstructor, arguments, fieldValues);
320 } else if (initializer is ir.FieldInitializer) { 321 } else if (initializer is ir.FieldInitializer) {
321 initializer.value.accept(this); 322 initializer.value.accept(this);
322 fieldValues[initializer.field] = pop(); 323 fieldValues[initializer.field] = pop();
323 } 324 }
324 } 325 }
325 326
326 // TODO(het): does kernel always set the super initializer at the end? 327 // Kernel always set the super initializer at the end, so if there was no
327 // If there was no super-call initializer, then call the default constructor 328 // super-call initializer, then the default constructor is called in the
328 // in the superclass. 329 // superclass.
329 if (!foundSuperCall) { 330 if (!foundSuperOrRedirectCall) {
330 if (constructor.enclosingClass != astAdapter.objectClass) { 331 if (constructor.enclosingClass != astAdapter.objectClass) {
331 var superclass = constructor.enclosingClass.superclass; 332 var superclass = constructor.enclosingClass.superclass;
332 var defaultConstructor = superclass.constructors 333 var defaultConstructor = superclass.constructors
333 .firstWhere((c) => c.name == '', orElse: () => null); 334 .firstWhere((c) => c.name.name == '', orElse: () => null);
334 if (defaultConstructor == null) { 335 if (defaultConstructor == null) {
335 compiler.reporter.internalError( 336 compiler.reporter.internalError(
336 NO_LOCATION_SPANNABLE, 'Could not find default constructor.'); 337 NO_LOCATION_SPANNABLE, 'Could not find default constructor.');
337 } 338 }
338 _buildInlinedSuperInitializers( 339 _buildInlinedInitializers(
339 defaultConstructor, <HInstruction>[], fieldValues); 340 defaultConstructor, <HInstruction>[], fieldValues);
340 } 341 }
341 } 342 }
342 } 343 }
343 344
344 List<HInstruction> _normalizeAndBuildArguments( 345 List<HInstruction> _normalizeAndBuildArguments(
345 ir.FunctionNode function, ir.Arguments arguments) { 346 ir.FunctionNode function, ir.Arguments arguments) {
346 var signature = astAdapter.getFunctionSignature(function); 347 var signature = astAdapter.getFunctionSignature(function);
347 var builtArguments = <HInstruction>[]; 348 var builtArguments = <HInstruction>[];
348 var positionalIndex = 0; 349 var positionalIndex = 0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 } 381 }
381 }); 382 });
382 } 383 }
383 384
384 return builtArguments; 385 return builtArguments;
385 } 386 }
386 387
387 /// Inlines the given super [constructor]'s initializers by collecting it's 388 /// Inlines the given super [constructor]'s initializers by collecting it's
388 /// field values and building its constructor initializers. We visit super 389 /// field values and building its constructor initializers. We visit super
389 /// constructors all the way up to the [Object] constructor. 390 /// constructors all the way up to the [Object] constructor.
390 void _buildInlinedSuperInitializers(ir.Constructor constructor, 391 void _buildInlinedInitializers(ir.Constructor constructor,
391 List<HInstruction> arguments, Map<ir.Field, HInstruction> fieldValues) { 392 List<HInstruction> arguments, Map<ir.Field, HInstruction> fieldValues) {
392 // TODO(het): Handle RTI if class needs it 393 // TODO(het): Handle RTI if class needs it
393 fieldValues.addAll(_collectFieldValues(constructor.enclosingClass)); 394 fieldValues.addAll(_collectFieldValues(constructor.enclosingClass));
394 395
395 var signature = astAdapter.getFunctionSignature(constructor.function); 396 var signature = astAdapter.getFunctionSignature(constructor.function);
396 var index = 0; 397 var index = 0;
397 signature.orderedForEachParameter((ParameterElement parameter) { 398 signature.orderedForEachParameter((ParameterElement parameter) {
398 HInstruction argument = arguments[index++]; 399 HInstruction argument = arguments[index++];
399 // Because we are inlining the initializer, we must update 400 // Because we are inlining the initializer, we must update
400 // what was given as parameter. This will be used in case 401 // what was given as parameter. This will be used in case
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 constructor = astAdapter.mapLiteralUntypedMaker; 1192 constructor = astAdapter.mapLiteralUntypedMaker;
1192 } 1193 }
1193 } else { 1194 } else {
1194 inputs.addAll(typeInputs); 1195 inputs.addAll(typeInputs);
1195 } 1196 }
1196 } 1197 }
1197 1198
1198 // If runtime type information is needed and the map literal has no type 1199 // If runtime type information is needed and the map literal has no type
1199 // parameters, 'constructor' is a static function that forwards the call to 1200 // parameters, 'constructor' is a static function that forwards the call to
1200 // the factory constructor without type parameters. 1201 // the factory constructor without type parameters.
1201 assert(constructor.kind == ir.ProcedureKind.Factory); 1202 assert(constructor.kind == ir.ProcedureKind.Method
1203 || constructor.kind == ir.ProcedureKind.Factory);
1202 1204
1203 // The instruction type will always be a subtype of the mapLiteralClass, but 1205 // The instruction type will always be a subtype of the mapLiteralClass, but
1204 // type inference might discover a more specific type, or find nothing (in 1206 // type inference might discover a more specific type, or find nothing (in
1205 // dart2js unit tests). 1207 // dart2js unit tests).
1206 TypeMask mapType = new TypeMask.nonNullSubtype( 1208 TypeMask mapType = new TypeMask.nonNullSubtype(
1207 astAdapter.getElement(astAdapter.mapLiteralClass), closedWorld); 1209 astAdapter.getElement(astAdapter.mapLiteralClass), closedWorld);
1208 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( 1210 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
1209 astAdapter.getElement(constructor), globalInferenceResults); 1211 astAdapter.getElement(constructor), globalInferenceResults);
1210 TypeMask instructionType = 1212 TypeMask instructionType =
1211 mapType.intersection(returnTypeMask, closedWorld); 1213 mapType.intersection(returnTypeMask, closedWorld);
(...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 kernelBuilder.open(exitBlock); 2479 kernelBuilder.open(exitBlock);
2478 enterBlock.setBlockFlow( 2480 enterBlock.setBlockFlow(
2479 new HTryBlockInformation( 2481 new HTryBlockInformation(
2480 kernelBuilder.wrapStatementGraph(bodyGraph), 2482 kernelBuilder.wrapStatementGraph(bodyGraph),
2481 exception, 2483 exception,
2482 kernelBuilder.wrapStatementGraph(catchGraph), 2484 kernelBuilder.wrapStatementGraph(catchGraph),
2483 kernelBuilder.wrapStatementGraph(finallyGraph)), 2485 kernelBuilder.wrapStatementGraph(finallyGraph)),
2484 exitBlock); 2486 exitBlock);
2485 } 2487 }
2486 } 2488 }
OLDNEW
« no previous file with comments | « no previous file | sdk/bin/dart2js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698