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

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: 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 OutputUnit outputUnitForConstant(Constant constant) { 174 OutputUnit outputUnitForConstant(Constant constant) {
169 if (!splitProgram) return mainOutputUnit; 175 if (!splitProgram) return mainOutputUnit;
170 176
171 return _constantToOutputUnit[constant]; 177 return _constantToOutputUnit[constant];
172 } 178 }
173 179
174 bool isDeferred(Element element) { 180 bool isDeferred(Element element) {
175 return outputUnitForElement(element) != mainOutputUnit; 181 return outputUnitForElement(element) != mainOutputUnit;
176 } 182 }
177 183
184 /// Returns true if e1 and e2 are in the same output unit.
185 bool inSameOutputUnit(Element e1, Element e2) {
186 return outputUnitForElement(e1) == outputUnitForElement(e2);
187 }
188
178 /// Mark that [import] is part of the [OutputputUnit] for [element]. 189 /// Mark that [import] is part of the [OutputputUnit] for [element].
179 /// 190 ///
180 /// [element] can be either a [Constant] or an [Element]. 191 /// [element] can be either a [Constant] or an [Element].
181 void _addImportToOutputUnitOfElement(Element element, Import import) { 192 void _addImportToOutputUnitOfElement(Element element, Import import) {
182 // Only one file should be loaded when the program starts, so make 193 // Only one file should be loaded when the program starts, so make
183 // sure that only one OutputUnit is created for [fakeMainImport]. 194 // sure that only one OutputUnit is created for [fakeMainImport].
184 if (import == _fakeMainImport) { 195 if (import == _fakeMainImport) {
185 _elementToOutputUnit[element] = mainOutputUnit; 196 _elementToOutputUnit[element] = mainOutputUnit;
186 } 197 }
187 _elementToOutputUnit.putIfAbsent(element, () => new OutputUnit()) 198 _elementToOutputUnit.putIfAbsent(element, () => new OutputUnit())
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if (imports.isEmpty) return false; 256 if (imports.isEmpty) return false;
246 // An element could potentially be loaded by several imports. If all of them 257 // An element could potentially be loaded by several imports. If all of them
247 // is explicitly deferred, we say the element is explicitly deferred. 258 // is explicitly deferred, we say the element is explicitly deferred.
248 // TODO(sigurdm): We might want to give a warning if the imports do not 259 // TODO(sigurdm): We might want to give a warning if the imports do not
249 // agree. 260 // agree.
250 return imports.every(_isImportDeferred); 261 return imports.every(_isImportDeferred);
251 } 262 }
252 263
253 /// Returns a [Link] of every [Import] that imports [element] into [library]. 264 /// Returns a [Link] of every [Import] that imports [element] into [library].
254 Link<Import> _getImports(Element element, LibraryElement library) { 265 Link<Import> _getImports(Element element, LibraryElement library) {
255 if (!element.isTopLevel()) { 266 if (element.isMember()) {
256 element = element.getEnclosingClass(); 267 element = element.getEnclosingClass();
257 } 268 }
258 269 if (element.isAccessor()) {
270 element = (element as FunctionElement).abstractField;
271 }
259 return library.getImportsFor(element); 272 return library.getImportsFor(element);
260 } 273 }
261 274
262 /// Replaces the imports of [outputUnit] with those in 275 /// Replaces the imports of [outputUnit] with those in
263 /// [replacementImports]. Because mainOutputUnit has a special handling we 276 /// [replacementImports]. Because mainOutputUnit has a special handling we
264 /// create a new outputUnit instead, and update the mapping from the 277 /// create a new outputUnit instead, and update the mapping from the
265 /// dependency to its outputUnit. 278 /// dependency to its outputUnit.
266 void _replaceOutputUnitImports(dynamic dependency, 279 void _replaceOutputUnitImports(dynamic dependency,
267 OutputUnit outputUnit, 280 OutputUnit outputUnit,
268 Iterable<Import> replacementImports) { 281 Iterable<Import> replacementImports) {
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 ? previousDeferredImport 783 ? previousDeferredImport
771 : import; 784 : import;
772 compiler.reportError(failingImport.prefix, 785 compiler.reportError(failingImport.prefix,
773 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); 786 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX);
774 } 787 }
775 usedPrefixes.add(prefix); 788 usedPrefixes.add(prefix);
776 } 789 }
777 } 790 }
778 }); 791 });
779 } 792 }
793 Backend backend = compiler.backend;
794 if (splitProgram && backend is JavaScriptBackend) {
795 backend.registerCheckDeferredIsLoaded(compiler.globalDependencies);
796 }
780 if (splitProgram && backend is DartBackend) { 797 if (splitProgram && backend is DartBackend) {
781 // TODO(sigurdm): Implement deferred loading for dart2dart. 798 // TODO(sigurdm): Implement deferred loading for dart2dart.
782 splitProgram = false; 799 splitProgram = false;
783 compiler.reportInfo( 800 compiler.reportInfo(
784 lastDeferred, 801 lastDeferred,
785 MessageKind.DEFERRED_LIBRARY_DART_2_DART); 802 MessageKind.DEFERRED_LIBRARY_DART_2_DART);
786 } 803 }
787 } 804 }
805
806 /// Returns the prefixElement associated with the first prefix of [send] in
807 /// the context of [elements] if the prefix of the send resolves to a deferred
808 /// import. Otherwise returns null.
809 PrefixElement deferredPrefixElement(ast.Send send, TreeElements elements) {
810 Element element = elements[send];
811 if (element != null && element.isDeferredLoaderGetter()) return null;
812 ast.Node firstNode(ast.Node node) {
813 if (node is! ast.Send) {
814 return node;
815 } else {
816 ast.Send send = node;
817 ast.Node receiver = send.receiver;
818 ast.Node receiverFirst = firstNode(receiver);
819 if (receiverFirst != null) {
820 return receiverFirst;
821 } else {
822 return firstNode(send.selector);
823 }
824 }
825 }
826 ast.Node first = firstNode(send);
827 if (first is! ast.Identifier) return null;
Johnni Winther 2014/04/11 07:34:54 Change to: astNode identifier = first.asIdentifier
sigurdm 2014/04/11 09:11:38 Done.
828 Element maybePrefix = elements[first.asIdentifier()];
829 if (maybePrefix != null && maybePrefix.isPrefix() && (maybePrefix as
Johnni Winther 2014/04/11 07:34:54 Change to: if (maybePrefix != null && maybePrefix.
sigurdm 2014/04/11 09:11:38 Done.
830 PrefixElement).isDeferred) {
831 return maybePrefix;
832 }
833 return null;
834 }
788 } 835 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698