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 '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/backend_api.dart' | 8 import '../common/backend_api.dart' |
9 show ForeignResolver, NativeRegistry, ImpactTransformer; | 9 show ForeignResolver, NativeRegistry, ImpactTransformer; |
10 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; | 10 import '../common/codegen.dart' show CodegenWorkItem; |
11 import '../common/names.dart' show Uris; | 11 import '../common/names.dart' show Uris; |
12 import '../common/resolution.dart' show Resolution, Target; | 12 import '../common/resolution.dart' show Resolution, Target; |
13 import '../common/tasks.dart' show CompilerTask; | 13 import '../common/tasks.dart' show CompilerTask; |
14 import '../compiler.dart' show Compiler; | 14 import '../compiler.dart' show Compiler; |
15 import '../constants/constant_system.dart'; | 15 import '../constants/constant_system.dart'; |
16 import '../constants/expressions.dart'; | 16 import '../constants/expressions.dart'; |
17 import '../constants/values.dart'; | 17 import '../constants/values.dart'; |
18 import '../common_elements.dart' show CommonElements; | 18 import '../common_elements.dart' show CommonElements; |
19 import '../deferred_load.dart' show DeferredLoadTask; | 19 import '../deferred_load.dart' show DeferredLoadTask; |
20 import '../dump_info.dart' show DumpInfoTask; | 20 import '../dump_info.dart' show DumpInfoTask; |
(...skipping 23 matching lines...) Expand all Loading... |
44 import '../library_loader.dart' show LoadedLibraries; | 44 import '../library_loader.dart' show LoadedLibraries; |
45 import '../native/native.dart' as native; | 45 import '../native/native.dart' as native; |
46 import '../native/resolver.dart'; | 46 import '../native/resolver.dart'; |
47 import '../ssa/ssa.dart' show SsaFunctionCompiler; | 47 import '../ssa/ssa.dart' show SsaFunctionCompiler; |
48 import '../tracer.dart'; | 48 import '../tracer.dart'; |
49 import '../tree/tree.dart'; | 49 import '../tree/tree.dart'; |
50 import '../types/types.dart'; | 50 import '../types/types.dart'; |
51 import '../universe/call_structure.dart' show CallStructure; | 51 import '../universe/call_structure.dart' show CallStructure; |
52 import '../universe/selector.dart' show Selector; | 52 import '../universe/selector.dart' show Selector; |
53 import '../universe/world_builder.dart'; | 53 import '../universe/world_builder.dart'; |
54 import '../universe/use.dart' show ConstantUse, StaticUse; | |
55 import '../universe/world_impact.dart' | 54 import '../universe/world_impact.dart' |
56 show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor; | 55 show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor; |
57 import '../util/util.dart'; | 56 import '../util/util.dart'; |
58 import '../world.dart' show ClosedWorld, ClosedWorldRefiner; | 57 import '../world.dart' show ClosedWorld, ClosedWorldRefiner; |
59 import 'annotations.dart'; | 58 import 'annotations.dart'; |
60 import 'backend_impact.dart'; | 59 import 'backend_impact.dart'; |
61 import 'backend_serialization.dart' show JavaScriptBackendSerialization; | 60 import 'backend_serialization.dart' show JavaScriptBackendSerialization; |
62 import 'backend_usage.dart'; | 61 import 'backend_usage.dart'; |
63 import 'checked_mode_helpers.dart'; | 62 import 'checked_mode_helpers.dart'; |
64 import 'codegen_listener.dart'; | 63 import 'codegen_listener.dart'; |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 return [commonElements.closureClass, commonElements.jsIndexableClass]; | 330 return [commonElements.closureClass, commonElements.jsIndexableClass]; |
332 } | 331 } |
333 | 332 |
334 FunctionCompiler functionCompiler; | 333 FunctionCompiler functionCompiler; |
335 | 334 |
336 CodeEmitterTask emitter; | 335 CodeEmitterTask emitter; |
337 | 336 |
338 /** | 337 /** |
339 * The generated code as a js AST for compiled methods. | 338 * The generated code as a js AST for compiled methods. |
340 */ | 339 */ |
341 final Map<MemberElement, jsAst.Expression> generatedCode = | 340 final Map<MemberEntity, jsAst.Expression> generatedCode = |
342 <MemberElement, jsAst.Expression>{}; | 341 <MemberEntity, jsAst.Expression>{}; |
343 | 342 |
344 FunctionInlineCache inlineCache = new FunctionInlineCache(); | 343 FunctionInlineCache inlineCache = new FunctionInlineCache(); |
345 | 344 |
346 /// If [true], the compiler will emit code that logs whenever a method is | 345 /// If [true], the compiler will emit code that logs whenever a method is |
347 /// called. When TRACE_METHOD is 'console' this will be logged | 346 /// called. When TRACE_METHOD is 'console' this will be logged |
348 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the | 347 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the |
349 /// information will be sent to a server via a POST request. | 348 /// information will be sent to a server via a POST request. |
350 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); | 349 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); |
351 static const bool TRACE_CALLS = | 350 static const bool TRACE_CALLS = |
352 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; | 351 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 closedWorld.backendUsage, | 902 closedWorld.backendUsage, |
904 rtiNeed, | 903 rtiNeed, |
905 customElementsCodegenAnalysis, | 904 customElementsCodegenAnalysis, |
906 typeVariableCodegenAnalysis, | 905 typeVariableCodegenAnalysis, |
907 lookupMapAnalysis, | 906 lookupMapAnalysis, |
908 mirrorsCodegenAnalysis, | 907 mirrorsCodegenAnalysis, |
909 nativeCodegenEnqueuer)); | 908 nativeCodegenEnqueuer)); |
910 } | 909 } |
911 | 910 |
912 WorldImpact codegen(CodegenWorkItem work, ClosedWorld closedWorld) { | 911 WorldImpact codegen(CodegenWorkItem work, ClosedWorld closedWorld) { |
913 MemberElement element = work.element; | 912 MemberEntity element = work.element; |
914 if (compiler.elementHasCompileTimeError(element)) { | 913 if (compiler.elementHasCompileTimeError(element)) { |
915 DiagnosticMessage message = | 914 DiagnosticMessage message = |
916 // If there's more than one error, the first is probably most | 915 // If there's more than one error, the first is probably most |
917 // informative, as the following errors may be side-effects of the | 916 // informative, as the following errors may be side-effects of the |
918 // first error. | 917 // first error. |
919 compiler.elementsWithCompileTimeErrors[element].first; | 918 compiler.elementsWithCompileTimeErrors[element].first; |
920 String messageText = message.message.computeMessage(); | 919 String messageText = message.message.computeMessage(); |
921 jsAst.LiteralString messageLiteral = | 920 jsAst.LiteralString messageLiteral = |
922 js.escapedString("Compile time error in $element: $messageText"); | 921 js.escapedString("Compile time error in $element: $messageText"); |
923 generatedCode[element] = | 922 generatedCode[element] = |
924 js("function () { throw new Error(#); }", [messageLiteral]); | 923 js("function () { throw new Error(#); }", [messageLiteral]); |
925 return const CodegenImpact(); | |
926 } | |
927 var kind = element.kind; | |
928 if (kind == ElementKind.TYPEDEF) { | |
929 return const WorldImpact(); | 924 return const WorldImpact(); |
930 } | 925 } |
931 if (element.isConstructor && | 926 if (element.isConstructor && |
932 element.enclosingClass == commonElements.jsNullClass) { | 927 element.enclosingClass == commonElements.jsNullClass) { |
933 // Work around a problem compiling JSNull's constructor. | 928 // Work around a problem compiling JSNull's constructor. |
934 return const CodegenImpact(); | 929 return const WorldImpact(); |
935 } | |
936 if (kind.category == ElementCategory.VARIABLE) { | |
937 FieldElement variableElement = element; | |
938 ConstantExpression constant = variableElement.constant; | |
939 if (constant != null) { | |
940 ConstantValue initialValue = constants.getConstantValue(constant); | |
941 if (initialValue != null) { | |
942 work.registry.worldImpact | |
943 .registerConstantUse(new ConstantUse.init(initialValue)); | |
944 // We don't need to generate code for static or top-level | |
945 // variables. For instance variables, we may need to generate | |
946 // the checked setter. | |
947 if (Elements.isStaticOrTopLevel(element)) { | |
948 return _codegenImpactTransformer | |
949 .transformCodegenImpact(work.registry.worldImpact); | |
950 } | |
951 } else { | |
952 assert(invariant( | |
953 variableElement, | |
954 variableElement.isInstanceMember || | |
955 constant.isImplicit || | |
956 constant.isPotential, | |
957 message: "Constant expression without value: " | |
958 "${constant.toStructuredText()}.")); | |
959 } | |
960 } else { | |
961 // If the constant-handler was not able to produce a result we have to | |
962 // go through the builder (below) to generate the lazy initializer for | |
963 // the static variable. | |
964 // We also need to register the use of the cyclic-error helper. | |
965 work.registry.worldImpact.registerStaticUse(new StaticUse.staticInvoke( | |
966 commonElements.cyclicThrowHelper, CallStructure.ONE_ARG)); | |
967 } | |
968 } | 930 } |
969 | 931 |
970 jsAst.Fun function = functionCompiler.compile(work, closedWorld); | 932 jsAst.Fun function = functionCompiler.compile(work, closedWorld); |
971 if (function.sourceInformation == null) { | 933 if (function != null) { |
972 function = function.withSourceInformation( | 934 if (function.sourceInformation == null) { |
973 sourceInformationStrategy.buildSourceMappedMarker()); | 935 function = function.withSourceInformation( |
| 936 sourceInformationStrategy.buildSourceMappedMarker()); |
| 937 } |
| 938 generatedCode[element] = function; |
974 } | 939 } |
975 generatedCode[element] = function; | |
976 WorldImpact worldImpact = _codegenImpactTransformer | 940 WorldImpact worldImpact = _codegenImpactTransformer |
977 .transformCodegenImpact(work.registry.worldImpact); | 941 .transformCodegenImpact(work.registry.worldImpact); |
978 compiler.dumpInfoTask.registerImpact(element, worldImpact); | 942 compiler.dumpInfoTask.registerImpact(element, worldImpact); |
979 return worldImpact; | 943 return worldImpact; |
980 } | 944 } |
981 | 945 |
982 native.NativeResolutionEnqueuer get nativeResolutionEnqueuerForTesting => | 946 native.NativeResolutionEnqueuer get nativeResolutionEnqueuerForTesting => |
983 _nativeResolutionEnqueuer; | 947 _nativeResolutionEnqueuer; |
984 | 948 |
985 native.NativeEnqueuer get nativeCodegenEnqueuer => _nativeCodegenEnqueuer; | 949 native.NativeEnqueuer get nativeCodegenEnqueuer => _nativeCodegenEnqueuer; |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1432 | 1396 |
1433 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { | 1397 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { |
1434 return !selector.isGetter; | 1398 return !selector.isGetter; |
1435 } | 1399 } |
1436 | 1400 |
1437 /// Returns `true` if [member] is called from a subclass via `super`. | 1401 /// Returns `true` if [member] is called from a subclass via `super`. |
1438 bool isAliasedSuperMember(MemberEntity member) { | 1402 bool isAliasedSuperMember(MemberEntity member) { |
1439 return _aliasedSuperMembers.contains(member); | 1403 return _aliasedSuperMembers.contains(member); |
1440 } | 1404 } |
1441 } | 1405 } |
OLD | NEW |