| 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 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 // constant emitter will generate a call to the createRuntimeType | 859 // constant emitter will generate a call to the createRuntimeType |
| 860 // helper so we register a use of that. | 860 // helper so we register a use of that. |
| 861 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 861 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 862 // TODO(johnniwinther): Find the right [CallStructure]. | 862 // TODO(johnniwinther): Find the right [CallStructure]. |
| 863 helpers.createRuntimeType, | 863 helpers.createRuntimeType, |
| 864 null)); | 864 null)); |
| 865 } | 865 } |
| 866 } | 866 } |
| 867 } | 867 } |
| 868 | 868 |
| 869 // TODO(johnniwinther): Avoid the need for this. | |
| 870 WorldImpact computeHelpersImpact() => | |
| 871 _resolutionEnqueuerListener.computeHelpersImpact(); | |
| 872 | |
| 873 void onResolutionComplete( | 869 void onResolutionComplete( |
| 874 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { | 870 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { |
| 875 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { | 871 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { |
| 876 processAnnotations(entity, closedWorldRefiner); | 872 processAnnotations(entity, closedWorldRefiner); |
| 877 } | 873 } |
| 878 mirrorsData.computeMembersNeededForReflection(closedWorld); | 874 mirrorsData.computeMembersNeededForReflection(closedWorld); |
| 879 _backendUsage = _backendUsageBuilder.close(); | 875 _backendUsage = _backendUsageBuilder.close(); |
| 880 _rtiNeed = rtiNeedBuilder.computeRuntimeTypesNeed( | 876 _rtiNeed = rtiNeedBuilder.computeRuntimeTypesNeed( |
| 881 compiler.enqueuer.resolution.worldBuilder, | 877 compiler.enqueuer.resolution.worldBuilder, |
| 882 closedWorld, | 878 closedWorld, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 } | 933 } |
| 938 } | 934 } |
| 939 } | 935 } |
| 940 reporter.reportErrorMessage( | 936 reporter.reportErrorMessage( |
| 941 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 937 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
| 942 } | 938 } |
| 943 // No native behavior for this call. | 939 // No native behavior for this call. |
| 944 return null; | 940 return null; |
| 945 } | 941 } |
| 946 | 942 |
| 947 /// Called to enable support for isolates. Any backend specific [WorldImpact] | |
| 948 /// of this is returned. | |
| 949 WorldImpact enableIsolateSupport({bool forResolution}) { | |
| 950 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | |
| 951 // TODO(floitsch): We should also ensure that the class IsolateMessage is | |
| 952 // instantiated. Currently, just enabling isolate support works. | |
| 953 if (compiler.mainFunction != null) { | |
| 954 // The JavaScript backend implements [Isolate.spawn] by looking up | |
| 955 // top-level functions by name. So all top-level function tear-off | |
| 956 // closures have a private name field. | |
| 957 // | |
| 958 // The JavaScript backend of [Isolate.spawnUri] uses the same internal | |
| 959 // implementation as [Isolate.spawn], and fails if it cannot look main up | |
| 960 // by name. | |
| 961 impactBuilder.registerStaticUse( | |
| 962 new StaticUse.staticTearOff(compiler.mainFunction)); | |
| 963 } | |
| 964 impacts.isolateSupport | |
| 965 .registerImpact(impactBuilder, compiler.elementEnvironment); | |
| 966 if (forResolution) { | |
| 967 backendUsageBuilder.processBackendImpact(impacts.isolateSupport); | |
| 968 impacts.isolateSupportForResolution | |
| 969 .registerImpact(impactBuilder, compiler.elementEnvironment); | |
| 970 backendUsageBuilder | |
| 971 .processBackendImpact(impacts.isolateSupportForResolution); | |
| 972 } | |
| 973 return impactBuilder; | |
| 974 } | |
| 975 | |
| 976 bool isComplexNoSuchMethod(FunctionElement element) => | 943 bool isComplexNoSuchMethod(FunctionElement element) => |
| 977 noSuchMethodRegistry.isComplex(element); | 944 noSuchMethodRegistry.isComplex(element); |
| 978 | 945 |
| 979 bool methodNeedsRti(FunctionElement function) { | 946 bool methodNeedsRti(FunctionElement function) { |
| 980 return rtiNeed.methodNeedsRti(function); | 947 return rtiNeed.methodNeedsRti(function); |
| 981 } | 948 } |
| 982 | 949 |
| 983 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; | 950 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; |
| 984 | 951 |
| 985 /// Creates an [Enqueuer] for code generation specific to this backend. | 952 /// Creates an [Enqueuer] for code generation specific to this backend. |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 // chance of making the dispatch record access monomorphic. | 1224 // chance of making the dispatch record access monomorphic. |
| 1258 jsAst.PropertyAccess record = | 1225 jsAst.PropertyAccess record = |
| 1259 new jsAst.PropertyAccess(use2, dispatchProperty); | 1226 new jsAst.PropertyAccess(use2, dispatchProperty); |
| 1260 | 1227 |
| 1261 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; | 1228 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; |
| 1262 MethodElement helper = helpers.isJsIndexable; | 1229 MethodElement helper = helpers.isJsIndexable; |
| 1263 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); | 1230 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); |
| 1264 return new jsAst.Call(helperExpression, arguments); | 1231 return new jsAst.Call(helperExpression, arguments); |
| 1265 } | 1232 } |
| 1266 | 1233 |
| 1267 void _onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) { | |
| 1268 if (compiler.options.useKernel && compiler.mainApp != null) { | |
| 1269 kernelTask.buildKernelIr(); | |
| 1270 } | |
| 1271 } | |
| 1272 | |
| 1273 /// Called after the queue is closed. [onQueueEmpty] may be called multiple | 1234 /// Called after the queue is closed. [onQueueEmpty] may be called multiple |
| 1274 /// times, but [onQueueClosed] is only called once. | 1235 /// times, but [onQueueClosed] is only called once. |
| 1275 void onQueueClosed() { | 1236 void onQueueClosed() { |
| 1276 lookupMapAnalysis.onQueueClosed(); | 1237 lookupMapAnalysis.onQueueClosed(); |
| 1277 jsInteropAnalysis.onQueueClosed(); | 1238 jsInteropAnalysis.onQueueClosed(); |
| 1278 } | 1239 } |
| 1279 | 1240 |
| 1280 // TODO(johnniwinther): Create a CodegenPhase object for the backend to hold | 1241 // TODO(johnniwinther): Create a CodegenPhase object for the backend to hold |
| 1281 // data only available during code generation. | 1242 // data only available during code generation. |
| 1282 ClosedWorld _closedWorldCache; | 1243 ClosedWorld _closedWorldCache; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1294 /// [WorldImpact] of enabled backend features is returned. | 1255 /// [WorldImpact] of enabled backend features is returned. |
| 1295 WorldImpact onCodegenStart(ClosedWorld closedWorld) { | 1256 WorldImpact onCodegenStart(ClosedWorld closedWorld) { |
| 1296 _closedWorld = closedWorld; | 1257 _closedWorld = closedWorld; |
| 1297 _namer = determineNamer(_closedWorld, compiler.codegenWorldBuilder); | 1258 _namer = determineNamer(_closedWorld, compiler.codegenWorldBuilder); |
| 1298 tracer = new Tracer(_closedWorld, namer, compiler); | 1259 tracer = new Tracer(_closedWorld, namer, compiler); |
| 1299 emitter.createEmitter(_namer, _closedWorld); | 1260 emitter.createEmitter(_namer, _closedWorld); |
| 1300 _rtiEncoder = | 1261 _rtiEncoder = |
| 1301 _namer.rtiEncoder = new _RuntimeTypesEncoder(_namer, emitter, helpers); | 1262 _namer.rtiEncoder = new _RuntimeTypesEncoder(_namer, emitter, helpers); |
| 1302 | 1263 |
| 1303 lookupMapAnalysis.onCodegenStart(); | 1264 lookupMapAnalysis.onCodegenStart(); |
| 1304 if (backendUsage.isIsolateInUse) { | |
| 1305 return enableIsolateSupport(forResolution: false); | |
| 1306 } | |
| 1307 return const WorldImpact(); | 1265 return const WorldImpact(); |
| 1308 } | 1266 } |
| 1309 | 1267 |
| 1310 /// Called when code generation has been completed. | 1268 /// Called when code generation has been completed. |
| 1311 void onCodegenEnd() { | 1269 void onCodegenEnd() { |
| 1312 sourceInformationStrategy.onComplete(); | 1270 sourceInformationStrategy.onComplete(); |
| 1313 tracer.close(); | 1271 tracer.close(); |
| 1314 } | 1272 } |
| 1315 | 1273 |
| 1316 // Does this element belong in the output | 1274 // Does this element belong in the output |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 "@NoSideEffects() should always be combined with @NoInline."); | 1368 "@NoSideEffects() should always be combined with @NoInline."); |
| 1411 } | 1369 } |
| 1412 } | 1370 } |
| 1413 | 1371 |
| 1414 MethodElement helperForBadMain() => helpers.badMain; | 1372 MethodElement helperForBadMain() => helpers.badMain; |
| 1415 | 1373 |
| 1416 MethodElement helperForMissingMain() => helpers.missingMain; | 1374 MethodElement helperForMissingMain() => helpers.missingMain; |
| 1417 | 1375 |
| 1418 MethodElement helperForMainArity() => helpers.mainHasTooManyParameters; | 1376 MethodElement helperForMainArity() => helpers.mainHasTooManyParameters; |
| 1419 | 1377 |
| 1420 /// Computes the [WorldImpact] of calling [mainMethod] as the entry point. | |
| 1421 WorldImpact computeMainImpact(MethodElement mainMethod, | |
| 1422 {bool forResolution}) { | |
| 1423 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); | |
| 1424 if (mainMethod.parameters.isNotEmpty) { | |
| 1425 impacts.mainWithArguments | |
| 1426 .registerImpact(mainImpact, compiler.elementEnvironment); | |
| 1427 if (forResolution) { | |
| 1428 backendUsageBuilder.processBackendImpact(impacts.mainWithArguments); | |
| 1429 } | |
| 1430 mainImpact.registerStaticUse( | |
| 1431 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); | |
| 1432 // If the main method takes arguments, this compilation could be the | |
| 1433 // target of Isolate.spawnUri. Strictly speaking, that can happen also if | |
| 1434 // main takes no arguments, but in this case the spawned isolate can't | |
| 1435 // communicate with the spawning isolate. | |
| 1436 mainImpact.addImpact(enableIsolateSupport(forResolution: forResolution)); | |
| 1437 } | |
| 1438 mainImpact.registerStaticUse( | |
| 1439 new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS)); | |
| 1440 return mainImpact; | |
| 1441 } | |
| 1442 | |
| 1443 /// Returns the filename for the output-unit named [name]. | 1378 /// Returns the filename for the output-unit named [name]. |
| 1444 /// | 1379 /// |
| 1445 /// The filename is of the form "<main output file>_<name>.part.js". | 1380 /// The filename is of the form "<main output file>_<name>.part.js". |
| 1446 /// If [addExtension] is false, the ".part.js" suffix is left out. | 1381 /// If [addExtension] is false, the ".part.js" suffix is left out. |
| 1447 String deferredPartFileName(String name, {bool addExtension: true}) { | 1382 String deferredPartFileName(String name, {bool addExtension: true}) { |
| 1448 assert(name != ""); | 1383 assert(name != ""); |
| 1449 String outPath = compiler.options.outputUri != null | 1384 String outPath = compiler.options.outputUri != null |
| 1450 ? compiler.options.outputUri.path | 1385 ? compiler.options.outputUri.path |
| 1451 : "out"; | 1386 : "out"; |
| 1452 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); | 1387 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 } | 1613 } |
| 1679 | 1614 |
| 1680 @override | 1615 @override |
| 1681 FieldEntity get symbolField => helpers.symbolImplementationField; | 1616 FieldEntity get symbolField => helpers.symbolImplementationField; |
| 1682 | 1617 |
| 1683 @override | 1618 @override |
| 1684 InterfaceType get symbolType { | 1619 InterfaceType get symbolType { |
| 1685 return _env.getRawType(helpers.symbolImplementationClass); | 1620 return _env.getRawType(helpers.symbolImplementationClass); |
| 1686 } | 1621 } |
| 1687 } | 1622 } |
| OLD | NEW |