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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/deferred_load.dart

Issue 232563006: Insert checks before deferred calls and accesses. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Forgot to stage deferred_load.dart Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 deferred_load; 5 library deferred_load;
6 6
7 import 'dart2jslib.dart' show 7 import 'dart2jslib.dart' show
8 Backend, 8 Backend,
9 Compiler, 9 Compiler,
10 CompilerTask, 10 CompilerTask,
11 Constant, 11 Constant,
12 ConstructedConstant, 12 ConstructedConstant,
13 MessageKind, 13 MessageKind,
14 StringConstant, 14 StringConstant,
15 invariant; 15 invariant,
16 Backend;
16 17
17 import 'dart_backend/dart_backend.dart' show 18 import 'dart_backend/dart_backend.dart' show
18 DartBackend; 19 DartBackend;
19 20
21 import 'js_backend/js_backend.dart' show
22 JavaScriptBackend;
23
20 import 'elements/elements.dart' show 24 import 'elements/elements.dart' show
21 Element, 25 Element,
22 ClassElement, 26 ClassElement,
23 ElementKind, 27 ElementKind,
24 Elements, 28 Elements,
25 FunctionElement, 29 FunctionElement,
26 LibraryElement, 30 LibraryElement,
27 MetadataAnnotation, 31 MetadataAnnotation,
28 ScopeContainerElement, 32 ScopeContainerElement,
29 PrefixElement, 33 PrefixElement,
30 ClosureContainer; 34 ClosureContainer;
31 35
32 import 'util/util.dart' show 36 import 'util/util.dart' show
33 Link; 37 Link;
34 38
35 import 'util/setlet.dart' show 39 import 'util/setlet.dart' show
36 Setlet; 40 Setlet;
37 41
38 import 'tree/tree.dart' show 42 import 'tree/tree.dart' show
39 LibraryTag, 43 LibraryTag,
40 Node, 44 Node,
41 NewExpression, 45 NewExpression,
42 Import, 46 Import,
43 LiteralString, 47 LiteralString,
44 LiteralDartString; 48 LiteralDartString;
45 49
50 import 'tree/tree.dart' as ast;
51
46 import 'resolution/resolution.dart' show 52 import 'resolution/resolution.dart' show
47 TreeElements; 53 TreeElements;
48 54
49 import 'mirrors_used.dart' show 55 import 'mirrors_used.dart' show
50 MirrorUsageAnalyzer, 56 MirrorUsageAnalyzer,
51 MirrorUsageAnalyzerTask, 57 MirrorUsageAnalyzerTask,
52 MirrorUsage; 58 MirrorUsage;
53 59
54 /// A "hunk" of the program that will be loaded whenever one of its [imports] 60 /// A "hunk" of the program that will be loaded whenever one of its [imports]
55 /// are loaded. 61 /// are loaded.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 OutputUnit outputUnitForConstant(Constant constant) { 179 OutputUnit outputUnitForConstant(Constant constant) {
174 if (!splitProgram) return mainOutputUnit; 180 if (!splitProgram) return mainOutputUnit;
175 181
176 return _constantToOutputUnit[constant]; 182 return _constantToOutputUnit[constant];
177 } 183 }
178 184
179 bool isDeferred(Element element) { 185 bool isDeferred(Element element) {
180 return outputUnitForElement(element) != mainOutputUnit; 186 return outputUnitForElement(element) != mainOutputUnit;
181 } 187 }
182 188
189 /// Returns true if e1 and e2 are in the same output unit.
190 bool inSameOutputUnit(Element e1, Element e2) {
191 return outputUnitForElement(e1) == outputUnitForElement(e2);
192 }
193
183 /// Mark that [import] is part of the [OutputputUnit] for [element]. 194 /// Mark that [import] is part of the [OutputputUnit] for [element].
184 /// 195 ///
185 /// [element] can be either a [Constant] or an [Element]. 196 /// [element] can be either a [Constant] or an [Element].
186 void _addImportToOutputUnitOfElement(Element element, Import import) { 197 void _addImportToOutputUnitOfElement(Element element, Import import) {
187 // Only one file should be loaded when the program starts, so make 198 // Only one file should be loaded when the program starts, so make
188 // sure that only one OutputUnit is created for [fakeMainImport]. 199 // sure that only one OutputUnit is created for [fakeMainImport].
189 if (import == _fakeMainImport) { 200 if (import == _fakeMainImport) {
190 _elementToOutputUnit[element] = mainOutputUnit; 201 _elementToOutputUnit[element] = mainOutputUnit;
191 } 202 }
192 _elementToOutputUnit.putIfAbsent(element, () => new OutputUnit()) 203 _elementToOutputUnit.putIfAbsent(element, () => new OutputUnit())
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 if (imports.isEmpty) return false; 261 if (imports.isEmpty) return false;
251 // An element could potentially be loaded by several imports. If all of them 262 // An element could potentially be loaded by several imports. If all of them
252 // is explicitly deferred, we say the element is explicitly deferred. 263 // is explicitly deferred, we say the element is explicitly deferred.
253 // TODO(sigurdm): We might want to give a warning if the imports do not 264 // TODO(sigurdm): We might want to give a warning if the imports do not
254 // agree. 265 // agree.
255 return imports.every(_isImportDeferred); 266 return imports.every(_isImportDeferred);
256 } 267 }
257 268
258 /// Returns a [Link] of every [Import] that imports [element] into [library]. 269 /// Returns a [Link] of every [Import] that imports [element] into [library].
259 Link<Import> _getImports(Element element, LibraryElement library) { 270 Link<Import> _getImports(Element element, LibraryElement library) {
260 if (!element.isTopLevel()) { 271 if (element.isMember()) {
261 element = element.getEnclosingClass(); 272 element = element.getEnclosingClass();
262 } 273 }
263 274 if (element.isAccessor()) {
275 element = (element as FunctionElement).abstractField;
276 }
264 return library.getImportsFor(element); 277 return library.getImportsFor(element);
265 } 278 }
266 279
267 /// Replaces the imports of [outputUnit] with those in 280 /// Replaces the imports of [outputUnit] with those in
268 /// [replacementImports]. Because mainOutputUnit has a special handling we 281 /// [replacementImports]. Because mainOutputUnit has a special handling we
269 /// create a new outputUnit instead, and update the mapping from the 282 /// create a new outputUnit instead, and update the mapping from the
270 /// dependency to its outputUnit. 283 /// dependency to its outputUnit.
271 void _replaceOutputUnitImports(dynamic dependency, 284 void _replaceOutputUnitImports(dynamic dependency,
272 OutputUnit outputUnit, 285 OutputUnit outputUnit,
273 Iterable<Import> replacementImports) { 286 Iterable<Import> replacementImports) {
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 ? previousDeferredImport 808 ? previousDeferredImport
796 : import; 809 : import;
797 compiler.reportError(failingImport.prefix, 810 compiler.reportError(failingImport.prefix,
798 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); 811 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX);
799 } 812 }
800 usedPrefixes.add(prefix); 813 usedPrefixes.add(prefix);
801 } 814 }
802 } 815 }
803 }); 816 });
804 } 817 }
818 Backend backend = compiler.backend;
819 if (splitProgram && backend is JavaScriptBackend) {
820 backend.registerCheckDeferredIsLoaded(compiler.globalDependencies);
821 }
805 if (splitProgram && backend is DartBackend) { 822 if (splitProgram && backend is DartBackend) {
806 // TODO(sigurdm): Implement deferred loading for dart2dart. 823 // TODO(sigurdm): Implement deferred loading for dart2dart.
807 splitProgram = false; 824 splitProgram = false;
808 compiler.reportInfo( 825 compiler.reportInfo(
809 lastDeferred, 826 lastDeferred,
810 MessageKind.DEFERRED_LIBRARY_DART_2_DART); 827 MessageKind.DEFERRED_LIBRARY_DART_2_DART);
811 } 828 }
812 } 829 }
830
831 /// If [send] is a static send with a deferred element, returns the
832 /// [PrefixElement] that the first prefix of the send resolves to.
833 /// Otherwise returns null.
834 /// Precondition: send must be static.
floitsch 2014/04/22 12:33:44 New line before Precondition.
sigurdm 2014/04/23 14:01:46 Done.
835 ///
836 /// Example:
837 ///
838 /// import "a.dart" deferred as a;
839 ///
840 /// main() {
841 /// print(a.loadLibrary.toString());
842 /// a.loadLibrary().then((_) {
843 /// a.run();
844 /// a.foo.method();
845 /// });
846 /// }
847 ///
848 /// Returns null for a.loadLibrary() (the special
849 /// function loadLibrary is not deferred). And returns the PrefixElement for
850 /// a.run() and a.foo.
851 /// a.loadLibrary.toString() and a.foo.method() are dynamic sends - and
852 /// this functions should not be called on them.
853 PrefixElement deferredPrefixElement(ast.Send send, TreeElements elements) {
854 Element element = elements[send];
855 // The DeferredLoaderGetter is not deferred, therefore we do not return the
856 // prefix.
857 if (element != null && element.isDeferredLoaderGetter()) return null;
858
859 ast.Node firstNode(ast.Node node) {
860 if (node is! ast.Send) {
861 return node;
862 } else {
863 ast.Send send = node;
864 ast.Node receiver = send.receiver;
865 ast.Node receiverFirst = firstNode(receiver);
866 if (receiverFirst != null) {
867 return receiverFirst;
868 } else {
869 return firstNode(send.selector);
870 }
871 }
872 }
873 ast.Node first = firstNode(send);
874 ast.Node identifier = first.asIdentifier();
875 if (identifier == null) return null;
876 Element maybePrefix = elements[identifier];
877 if (maybePrefix != null && maybePrefix.isPrefix()) {
878 PrefixElement prefixElement = maybePrefix;
879 if (prefixElement.isDeferred) {
880 return prefixElement;
881 }
882 }
883 return null;
884 }
813 } 885 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698