| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 js_backend.backend; | 5 library js_backend.backend; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| 10 | 10 |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 enum SyntheticConstantKind { | 298 enum SyntheticConstantKind { |
| 299 DUMMY_INTERCEPTOR, | 299 DUMMY_INTERCEPTOR, |
| 300 EMPTY_VALUE, | 300 EMPTY_VALUE, |
| 301 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. | 301 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. |
| 302 NAME | 302 NAME |
| 303 } | 303 } |
| 304 | 304 |
| 305 class JavaScriptBackend extends Backend { | 305 class JavaScriptBackend extends Backend { |
| 306 String get patchVersion => emitter.patchVersion; | 306 String get patchVersion => emitter.patchVersion; |
| 307 | 307 |
| 308 bool get supportsReflection => emitter.emitter.supportsReflection; | 308 bool get supportsReflection => emitter.supportsReflection; |
| 309 | 309 |
| 310 final Annotations annotations; | 310 final Annotations annotations; |
| 311 | 311 |
| 312 /// Set of classes that need to be considered for reflection although not | 312 /// Set of classes that need to be considered for reflection although not |
| 313 /// otherwise visible during resolution. | 313 /// otherwise visible during resolution. |
| 314 Iterable<ClassElement> get classesRequiredForReflection { | 314 Iterable<ClassElement> get classesRequiredForReflection { |
| 315 // TODO(herhut): Clean this up when classes needed for rti are tracked. | 315 // TODO(herhut): Clean this up when classes needed for rti are tracked. |
| 316 return [helpers.closureClass, helpers.jsIndexableClass]; | 316 return [helpers.closureClass, helpers.jsIndexableClass]; |
| 317 } | 317 } |
| 318 | 318 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 336 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); | 336 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); |
| 337 static const bool TRACE_CALLS = | 337 static const bool TRACE_CALLS = |
| 338 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; | 338 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; |
| 339 | 339 |
| 340 /// Maps special classes to their implementation (JSXxx) class. | 340 /// Maps special classes to their implementation (JSXxx) class. |
| 341 Map<ClassElement, ClassElement> implementationClasses; | 341 Map<ClassElement, ClassElement> implementationClasses; |
| 342 | 342 |
| 343 bool needToInitializeIsolateAffinityTag = false; | 343 bool needToInitializeIsolateAffinityTag = false; |
| 344 bool needToInitializeDispatchProperty = false; | 344 bool needToInitializeDispatchProperty = false; |
| 345 | 345 |
| 346 final Namer namer; | 346 Namer _namer; |
| 347 |
| 348 Namer get namer { |
| 349 assert(invariant(NO_LOCATION_SPANNABLE, _namer != null, |
| 350 message: "Namer has not been created yet.")); |
| 351 return _namer; |
| 352 } |
| 347 | 353 |
| 348 /** | 354 /** |
| 349 * A collection of selectors that must have a one shot interceptor | 355 * A collection of selectors that must have a one shot interceptor |
| 350 * generated. | 356 * generated. |
| 351 */ | 357 */ |
| 352 final Map<jsAst.Name, Selector> oneShotInterceptors; | 358 final Map<jsAst.Name, Selector> oneShotInterceptors; |
| 353 | 359 |
| 354 /** | 360 /** |
| 355 * The members of instantiated interceptor classes: maps a member name to the | 361 * The members of instantiated interceptor classes: maps a member name to the |
| 356 * list of members that have that name. This map is used by the codegen to | 362 * list of members that have that name. This map is used by the codegen to |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 final BackendImpacts impacts; | 557 final BackendImpacts impacts; |
| 552 BackendClasses backendClasses; | 558 BackendClasses backendClasses; |
| 553 | 559 |
| 554 final JSFrontendAccess frontend; | 560 final JSFrontendAccess frontend; |
| 555 | 561 |
| 556 JavaScriptBackend(Compiler compiler, | 562 JavaScriptBackend(Compiler compiler, |
| 557 {bool generateSourceMap: true, | 563 {bool generateSourceMap: true, |
| 558 bool useStartupEmitter: false, | 564 bool useStartupEmitter: false, |
| 559 bool useNewSourceInfo: false, | 565 bool useNewSourceInfo: false, |
| 560 bool useKernel: false}) | 566 bool useKernel: false}) |
| 561 : namer = determineNamer(compiler), | 567 : oneShotInterceptors = new Map<jsAst.Name, Selector>(), |
| 562 oneShotInterceptors = new Map<jsAst.Name, Selector>(), | |
| 563 interceptedElements = new Map<String, Set<Element>>(), | 568 interceptedElements = new Map<String, Set<Element>>(), |
| 564 rti = new _RuntimeTypes(compiler), | 569 rti = new _RuntimeTypes(compiler), |
| 565 rtiEncoder = new _RuntimeTypesEncoder(compiler), | 570 rtiEncoder = new _RuntimeTypesEncoder(compiler), |
| 566 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), | 571 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), |
| 567 annotations = new Annotations(compiler), | 572 annotations = new Annotations(compiler), |
| 568 this.sourceInformationStrategy = generateSourceMap | 573 this.sourceInformationStrategy = generateSourceMap |
| 569 ? (useNewSourceInfo | 574 ? (useNewSourceInfo |
| 570 ? new PositionSourceInformationStrategy() | 575 ? new PositionSourceInformationStrategy() |
| 571 : const StartEndSourceInformationStrategy()) | 576 : const StartEndSourceInformationStrategy()) |
| 572 : const JavaScriptSourceInformationStrategy(), | 577 : const JavaScriptSourceInformationStrategy(), |
| 573 helpers = new BackendHelpers(compiler), | 578 helpers = new BackendHelpers(compiler), |
| 574 impacts = new BackendImpacts(compiler), | 579 impacts = new BackendImpacts(compiler), |
| 575 frontend = new JSFrontendAccess(compiler), | 580 frontend = new JSFrontendAccess(compiler), |
| 576 super(compiler) { | 581 super(compiler) { |
| 577 emitter = new CodeEmitterTask( | 582 emitter = |
| 578 compiler, namer, generateSourceMap, useStartupEmitter); | 583 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); |
| 579 typeVariableHandler = new TypeVariableHandler(compiler); | 584 typeVariableHandler = new TypeVariableHandler(compiler); |
| 580 customElementsAnalysis = new CustomElementsAnalysis(this); | 585 customElementsAnalysis = new CustomElementsAnalysis(this); |
| 581 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); | 586 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); |
| 582 jsInteropAnalysis = new JsInteropAnalysis(this); | 587 jsInteropAnalysis = new JsInteropAnalysis(this); |
| 583 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); | 588 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); |
| 584 | 589 |
| 585 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 590 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
| 586 kernelTask = new KernelTask(compiler); | 591 kernelTask = new KernelTask(compiler); |
| 587 constantCompilerTask = new JavaScriptConstantTask(compiler); | 592 constantCompilerTask = new JavaScriptConstantTask(compiler); |
| 588 impactTransformer = new JavaScriptImpactTransformer(this); | 593 impactTransformer = new JavaScriptImpactTransformer(this); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 }); | 638 }); |
| 634 } | 639 } |
| 635 | 640 |
| 636 bool isForeign(Element element) => element.library == helpers.foreignLibrary; | 641 bool isForeign(Element element) => element.library == helpers.foreignLibrary; |
| 637 | 642 |
| 638 bool isBackendLibrary(LibraryElement library) { | 643 bool isBackendLibrary(LibraryElement library) { |
| 639 return library == helpers.interceptorsLibrary || | 644 return library == helpers.interceptorsLibrary || |
| 640 library == helpers.jsHelperLibrary; | 645 library == helpers.jsHelperLibrary; |
| 641 } | 646 } |
| 642 | 647 |
| 643 static Namer determineNamer(Compiler compiler) { | 648 Namer determineNamer(ClosedWorld closedWorld) { |
| 644 return compiler.options.enableMinification | 649 return compiler.options.enableMinification |
| 645 ? compiler.options.useFrequencyNamer | 650 ? compiler.options.useFrequencyNamer |
| 646 ? new FrequencyBasedNamer(compiler) | 651 ? new FrequencyBasedNamer(this, closedWorld) |
| 647 : new MinifyNamer(compiler) | 652 : new MinifyNamer(this, closedWorld) |
| 648 : new Namer(compiler); | 653 : new Namer(this, closedWorld); |
| 649 } | 654 } |
| 650 | 655 |
| 651 /// The backend must *always* call this method when enqueuing an | 656 /// The backend must *always* call this method when enqueuing an |
| 652 /// element. Calls done by the backend are not seen by global | 657 /// element. Calls done by the backend are not seen by global |
| 653 /// optimizations, so they would make these optimizations unsound. | 658 /// optimizations, so they would make these optimizations unsound. |
| 654 /// Therefore we need to collect the list of helpers the backend may | 659 /// Therefore we need to collect the list of helpers the backend may |
| 655 /// use. | 660 /// use. |
| 656 // TODO(johnniwinther): Replace this with a more precise modelling; type | 661 // TODO(johnniwinther): Replace this with a more precise modelling; type |
| 657 // inference of these elements is disabled. | 662 // inference of these elements is disabled. |
| 658 Element registerBackendUse(Element element) { | 663 Element registerBackendUse(Element element) { |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 /** | 1532 /** |
| 1528 * Unit test hook that returns code of an element as a String. | 1533 * Unit test hook that returns code of an element as a String. |
| 1529 * | 1534 * |
| 1530 * Invariant: [element] must be a declaration element. | 1535 * Invariant: [element] must be a declaration element. |
| 1531 */ | 1536 */ |
| 1532 String getGeneratedCode(Element element) { | 1537 String getGeneratedCode(Element element) { |
| 1533 assert(invariant(element, element.isDeclaration)); | 1538 assert(invariant(element, element.isDeclaration)); |
| 1534 return jsAst.prettyPrint(generatedCode[element], compiler); | 1539 return jsAst.prettyPrint(generatedCode[element], compiler); |
| 1535 } | 1540 } |
| 1536 | 1541 |
| 1537 int assembleProgram() { | 1542 int assembleProgram(ClosedWorld closedWorld) { |
| 1538 int programSize = emitter.assembleProgram(); | 1543 int programSize = emitter.assembleProgram(namer, closedWorld); |
| 1539 noSuchMethodRegistry.emitDiagnostic(); | 1544 noSuchMethodRegistry.emitDiagnostic(); |
| 1540 int totalMethodCount = generatedCode.length; | 1545 int totalMethodCount = generatedCode.length; |
| 1541 if (totalMethodCount != preMirrorsMethodCount) { | 1546 if (totalMethodCount != preMirrorsMethodCount) { |
| 1542 int mirrorCount = totalMethodCount - preMirrorsMethodCount; | 1547 int mirrorCount = totalMethodCount - preMirrorsMethodCount; |
| 1543 double percentage = (mirrorCount / totalMethodCount) * 100; | 1548 double percentage = (mirrorCount / totalMethodCount) * 100; |
| 1544 DiagnosticMessage hint = | 1549 DiagnosticMessage hint = |
| 1545 reporter.createMessage(compiler.mainApp, MessageKind.MIRROR_BLOAT, { | 1550 reporter.createMessage(compiler.mainApp, MessageKind.MIRROR_BLOAT, { |
| 1546 'count': mirrorCount, | 1551 'count': mirrorCount, |
| 1547 'total': totalMethodCount, | 1552 'total': totalMethodCount, |
| 1548 'percentage': percentage.round() | 1553 'percentage': percentage.round() |
| (...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2350 } | 2355 } |
| 2351 | 2356 |
| 2352 entities.forEach(processElementMetadata); | 2357 entities.forEach(processElementMetadata); |
| 2353 } | 2358 } |
| 2354 | 2359 |
| 2355 void onQueueClosed() { | 2360 void onQueueClosed() { |
| 2356 lookupMapAnalysis.onQueueClosed(); | 2361 lookupMapAnalysis.onQueueClosed(); |
| 2357 jsInteropAnalysis.onQueueClosed(); | 2362 jsInteropAnalysis.onQueueClosed(); |
| 2358 } | 2363 } |
| 2359 | 2364 |
| 2360 WorldImpact onCodegenStart() { | 2365 WorldImpact onCodegenStart(ClosedWorld closedWorld) { |
| 2366 _namer = determineNamer(closedWorld); |
| 2367 emitter.createEmitter(_namer, closedWorld); |
| 2361 lookupMapAnalysis.onCodegenStart(); | 2368 lookupMapAnalysis.onCodegenStart(); |
| 2362 if (hasIsolateSupport) { | 2369 if (hasIsolateSupport) { |
| 2363 return enableIsolateSupport(forResolution: false); | 2370 return enableIsolateSupport(forResolution: false); |
| 2364 } | 2371 } |
| 2365 return const WorldImpact(); | 2372 return const WorldImpact(); |
| 2366 } | 2373 } |
| 2367 | 2374 |
| 2368 /// Process backend specific annotations. | 2375 /// Process backend specific annotations. |
| 2369 void processAnnotations( | 2376 void processAnnotations( |
| 2370 Element element, ClosedWorldRefiner closedWorldRefiner) { | 2377 Element element, ClosedWorldRefiner closedWorldRefiner) { |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3218 @override | 3225 @override |
| 3219 bool isInterceptorClass(ClassElement cls) { | 3226 bool isInterceptorClass(ClassElement cls) { |
| 3220 return helpers.backend.isInterceptorClass(cls); | 3227 return helpers.backend.isInterceptorClass(cls); |
| 3221 } | 3228 } |
| 3222 | 3229 |
| 3223 @override | 3230 @override |
| 3224 bool isNative(Element element) { | 3231 bool isNative(Element element) { |
| 3225 return helpers.backend.isNative(element); | 3232 return helpers.backend.isNative(element); |
| 3226 } | 3233 } |
| 3227 } | 3234 } |
| OLD | NEW |