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 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
8 | 8 |
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 } | 344 } |
345 | 345 |
346 ConstantSystem get constantSystem => constants.constantSystem; | 346 ConstantSystem get constantSystem => constants.constantSystem; |
347 | 347 |
348 /// Returns constant environment for the JavaScript interpretation of the | 348 /// Returns constant environment for the JavaScript interpretation of the |
349 /// constants. | 349 /// constants. |
350 JavaScriptConstantCompiler get constants { | 350 JavaScriptConstantCompiler get constants { |
351 return constantCompilerTask.jsConstantCompiler; | 351 return constantCompilerTask.jsConstantCompiler; |
352 } | 352 } |
353 | 353 |
354 // TODO(karlklose): split into findHelperFunction and findHelperClass and | 354 // TODO(karlklose): Split into findHelperFunction and findHelperClass and |
355 // add a check that the element has the expected kind. | 355 // add a check that the element has the expected kind. |
356 Element findHelper(String name) | 356 Element findHelper(String name) => find(jsHelperLibrary, name); |
357 => jsHelperLibrary.findLocal(name); | 357 Element findInterceptor(String name) => find(interceptorsLibrary, name); |
358 Element findInterceptor(String name) | 358 |
359 => interceptorsLibrary.findLocal(name); | 359 Element find(LibraryElement library, String name) { |
360 Element element = library.findLocal(name); | |
361 assert(invariant(library, element != null, | |
362 message: "Element '$name' not found in '${library.canonicalUri}'.")); | |
363 return element; | |
364 } | |
360 | 365 |
361 bool isForeign(Element element) => element.library == foreignLibrary; | 366 bool isForeign(Element element) => element.library == foreignLibrary; |
362 | 367 |
363 bool isBackendLibrary(LibraryElement library) { | 368 bool isBackendLibrary(LibraryElement library) { |
364 return library == interceptorsLibrary || | 369 return library == interceptorsLibrary || |
365 library == jsHelperLibrary; | 370 library == jsHelperLibrary; |
366 } | 371 } |
367 | 372 |
368 static Namer determineNamer(Compiler compiler) { | 373 static Namer determineNamer(Compiler compiler) { |
369 return compiler.enableMinification ? | 374 return compiler.enableMinification ? |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 typeVariableHandler.registerClassWithTypeVariables(cls); | 661 typeVariableHandler.registerClassWithTypeVariables(cls); |
657 } | 662 } |
658 | 663 |
659 // Register any helper that will be needed by the backend. | 664 // Register any helper that will be needed by the backend. |
660 if (enqueuer.isResolutionQueue) { | 665 if (enqueuer.isResolutionQueue) { |
661 if (cls == compiler.intClass | 666 if (cls == compiler.intClass |
662 || cls == compiler.doubleClass | 667 || cls == compiler.doubleClass |
663 || cls == compiler.numClass) { | 668 || cls == compiler.numClass) { |
664 // The backend will try to optimize number operations and use the | 669 // The backend will try to optimize number operations and use the |
665 // `iae` helper directly. | 670 // `iae` helper directly. |
666 enqueue(enqueuer, findHelper('iae'), registry); | 671 enqueue(enqueuer, find(jsHelperLibrary, 'iae'), registry); |
karlklose
2014/07/03 08:31:15
Why did you change all the calls to findHelper? I
Johnni Winther
2014/07/03 09:23:25
Changed to findHelper.
| |
667 } else if (cls == compiler.listClass | 672 } else if (cls == compiler.listClass |
668 || cls == compiler.stringClass) { | 673 || cls == compiler.stringClass) { |
669 // The backend will try to optimize array and string access and use the | 674 // The backend will try to optimize array and string access and use the |
670 // `ioore` and `iae` helpers directly. | 675 // `ioore` and `iae` helpers directly. |
671 enqueue(enqueuer, findHelper('ioore'), registry); | 676 enqueue(enqueuer, find(jsHelperLibrary, 'ioore'), registry); |
672 enqueue(enqueuer, findHelper('iae'), registry); | 677 enqueue(enqueuer, find(jsHelperLibrary, 'iae'), registry); |
673 } else if (cls == compiler.functionClass) { | 678 } else if (cls == compiler.functionClass) { |
674 enqueueClass(enqueuer, closureClass, registry); | 679 enqueueClass(enqueuer, closureClass, registry); |
675 } else if (cls == compiler.mapClass) { | 680 } else if (cls == compiler.mapClass) { |
676 // The backend will use a literal list to initialize the entries | 681 // The backend will use a literal list to initialize the entries |
677 // of the map. | 682 // of the map. |
678 enqueueClass(enqueuer, compiler.listClass, registry); | 683 enqueueClass(enqueuer, compiler.listClass, registry); |
679 enqueueClass(enqueuer, mapLiteralClass, registry); | 684 enqueueClass(enqueuer, mapLiteralClass, registry); |
680 // For map literals, the dependency between the implementation class | 685 // For map literals, the dependency between the implementation class |
681 // and [Map] is not visible, so we have to add it manually. | 686 // and [Map] is not visible, so we have to add it manually. |
682 rti.registerRtiDependency(mapLiteralClass, cls); | 687 rti.registerRtiDependency(mapLiteralClass, cls); |
(...skipping 21 matching lines...) Expand all Loading... | |
704 " ${mapLiteralClass.constructors}"); | 709 " ${mapLiteralClass.constructors}"); |
705 }); | 710 }); |
706 } | 711 } |
707 mapLiteralConstructor = getFactory('_literal', 1); | 712 mapLiteralConstructor = getFactory('_literal', 1); |
708 mapLiteralConstructorEmpty = getFactory('_empty', 0); | 713 mapLiteralConstructorEmpty = getFactory('_empty', 0); |
709 enqueueInResolution(mapLiteralConstructor, registry); | 714 enqueueInResolution(mapLiteralConstructor, registry); |
710 enqueueInResolution(mapLiteralConstructorEmpty, registry); | 715 enqueueInResolution(mapLiteralConstructorEmpty, registry); |
711 } | 716 } |
712 } | 717 } |
713 if (cls == closureClass) { | 718 if (cls == closureClass) { |
714 enqueue(enqueuer, findHelper('closureFromTearOff'), registry); | 719 enqueue(enqueuer, find(jsHelperLibrary, 'closureFromTearOff'), registry); |
715 } | 720 } |
716 ClassElement result = null; | 721 ClassElement result = null; |
717 if (cls == compiler.stringClass || cls == jsStringClass) { | 722 if (cls == compiler.stringClass || cls == jsStringClass) { |
718 addInterceptors(jsStringClass, enqueuer, registry); | 723 addInterceptors(jsStringClass, enqueuer, registry); |
719 } else if (cls == compiler.listClass || | 724 } else if (cls == compiler.listClass || |
720 cls == jsArrayClass || | 725 cls == jsArrayClass || |
721 cls == jsFixedArrayClass || | 726 cls == jsFixedArrayClass || |
722 cls == jsExtendableArrayClass) { | 727 cls == jsExtendableArrayClass) { |
723 addInterceptors(jsArrayClass, enqueuer, registry); | 728 addInterceptors(jsArrayClass, enqueuer, registry); |
724 addInterceptors(jsMutableArrayClass, enqueuer, registry); | 729 addInterceptors(jsMutableArrayClass, enqueuer, registry); |
(...skipping 22 matching lines...) Expand all Loading... | |
747 } else if (cls == jsPlainJavaScriptObjectClass) { | 752 } else if (cls == jsPlainJavaScriptObjectClass) { |
748 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry); | 753 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry); |
749 } else if (cls == jsUnknownJavaScriptObjectClass) { | 754 } else if (cls == jsUnknownJavaScriptObjectClass) { |
750 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry); | 755 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry); |
751 } else if (Elements.isNativeOrExtendsNative(cls)) { | 756 } else if (Elements.isNativeOrExtendsNative(cls)) { |
752 addInterceptorsForNativeClassMembers(cls, enqueuer); | 757 addInterceptorsForNativeClassMembers(cls, enqueuer); |
753 } else if (cls == jsIndexingBehaviorInterface) { | 758 } else if (cls == jsIndexingBehaviorInterface) { |
754 // These two helpers are used by the emitter and the codegen. | 759 // These two helpers are used by the emitter and the codegen. |
755 // Because we cannot enqueue elements at the time of emission, | 760 // Because we cannot enqueue elements at the time of emission, |
756 // we make sure they are always generated. | 761 // we make sure they are always generated. |
757 enqueue(enqueuer, findHelper('isJsIndexable'), registry); | 762 enqueue(enqueuer, find(jsHelperLibrary, 'isJsIndexable'), registry); |
758 enqueue(enqueuer, findInterceptor('dispatchPropertyName'), registry); | |
759 } | 763 } |
760 | 764 |
761 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); | 765 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); |
762 } | 766 } |
763 | 767 |
764 void registerUseInterceptor(Enqueuer enqueuer) { | 768 void registerUseInterceptor(Enqueuer enqueuer) { |
765 assert(!enqueuer.isResolutionQueue); | 769 assert(!enqueuer.isResolutionQueue); |
766 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; | 770 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; |
767 Registry registry = compiler.globalDependencies; | 771 Registry registry = compiler.globalDependencies; |
768 enqueue(enqueuer, getNativeInterceptorMethod, registry); | 772 enqueue(enqueuer, getNativeInterceptorMethod, registry); |
(...skipping 10 matching lines...) Expand all Loading... | |
779 assert(interceptorsLibrary != null); | 783 assert(interceptorsLibrary != null); |
780 // TODO(ngeoffray): Not enqueuing those two classes currently make | 784 // TODO(ngeoffray): Not enqueuing those two classes currently make |
781 // the compiler potentially crash. However, any reasonable program | 785 // the compiler potentially crash. However, any reasonable program |
782 // will instantiate those two classes. | 786 // will instantiate those two classes. |
783 addInterceptors(jsBoolClass, world, registry); | 787 addInterceptors(jsBoolClass, world, registry); |
784 addInterceptors(jsNullClass, world, registry); | 788 addInterceptors(jsNullClass, world, registry); |
785 if (compiler.enableTypeAssertions) { | 789 if (compiler.enableTypeAssertions) { |
786 // Unconditionally register the helper that checks if the | 790 // Unconditionally register the helper that checks if the |
787 // expression in an if/while/for is a boolean. | 791 // expression in an if/while/for is a boolean. |
788 // TODO(ngeoffray): Should we have the resolver register those instead? | 792 // TODO(ngeoffray): Should we have the resolver register those instead? |
789 Element e = findHelper('boolConversionCheck'); | 793 Element e = find(jsHelperLibrary, 'boolConversionCheck'); |
790 if (e != null) enqueue(world, e, registry); | 794 if (e != null) enqueue(world, e, registry); |
791 } | 795 } |
792 if (TRACE_CALLS) { | 796 if (TRACE_CALLS) { |
793 traceHelper = findHelper('traceHelper'); | 797 traceHelper = find(jsHelperLibrary, 'traceHelper'); |
794 assert(traceHelper != null); | 798 assert(traceHelper != null); |
795 enqueueInResolution(traceHelper, registry); | 799 enqueueInResolution(traceHelper, registry); |
796 } | 800 } |
797 registerCheckedModeHelpers(registry); | 801 registerCheckedModeHelpers(registry); |
798 } | 802 } |
799 | 803 |
800 onResolutionComplete() => rti.computeClassesNeedingRti(); | 804 onResolutionComplete() => rti.computeClassesNeedingRti(); |
801 | 805 |
802 void registerGetRuntimeTypeArgument(Registry registry) { | 806 void registerGetRuntimeTypeArgument(Registry registry) { |
803 enqueueInResolution(getGetRuntimeTypeArgument(), registry); | 807 enqueueInResolution(getGetRuntimeTypeArgument(), registry); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
874 enqueue(world, helper.getElement(compiler), registry); | 878 enqueue(world, helper.getElement(compiler), registry); |
875 } | 879 } |
876 } | 880 } |
877 if (!type.treatAsRaw || type.containsTypeVariables) { | 881 if (!type.treatAsRaw || type.containsTypeVariables) { |
878 enqueueClass(world, compiler.listClass, registry); | 882 enqueueClass(world, compiler.listClass, registry); |
879 } | 883 } |
880 if (type.element != null && type.element.isNative) { | 884 if (type.element != null && type.element.isNative) { |
881 // We will neeed to add the "$is" and "$as" properties on the | 885 // We will neeed to add the "$is" and "$as" properties on the |
882 // JavaScript object prototype, so we make sure | 886 // JavaScript object prototype, so we make sure |
883 // [:defineProperty:] is compiled. | 887 // [:defineProperty:] is compiled. |
884 enqueue(world, findHelper('defineProperty'), registry); | 888 enqueue(world, find(jsHelperLibrary, 'defineProperty'), registry); |
885 } | 889 } |
886 } | 890 } |
887 | 891 |
888 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, | 892 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, |
889 DartType bound) { | 893 DartType bound) { |
890 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); | 894 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); |
891 } | 895 } |
892 | 896 |
893 void registerCheckDeferredIsLoaded(Registry registry) { | 897 void registerCheckDeferredIsLoaded(Registry registry) { |
894 enqueueInResolution(getCheckDeferredIsLoaded(), registry); | 898 enqueueInResolution(getCheckDeferredIsLoaded(), registry); |
895 // Also register the types of the arguments passed to this method. | 899 // Also register the types of the arguments passed to this method. |
896 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, registry); | 900 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, registry); |
897 } | 901 } |
898 | 902 |
899 void enableNoSuchMethod(Enqueuer world) { | 903 void enableNoSuchMethod(Enqueuer world) { |
900 enqueue(world, getCreateInvocationMirror(), compiler.globalDependencies); | 904 enqueue(world, getCreateInvocationMirror(), compiler.globalDependencies); |
901 world.registerInvocation(compiler.noSuchMethodSelector); | 905 world.registerInvocation(compiler.noSuchMethodSelector); |
902 } | 906 } |
903 | 907 |
904 void enableIsolateSupport(Enqueuer enqueuer) { | 908 void enableIsolateSupport(Enqueuer enqueuer) { |
905 if (enqueuer.isResolutionQueue) { | 909 if (enqueuer.isResolutionQueue) { |
906 for (String name in const [START_ROOT_ISOLATE, | 910 for (String name in const [START_ROOT_ISOLATE, |
907 '_currentIsolate', | 911 '_currentIsolate', |
908 '_callInIsolate']) { | 912 '_callInIsolate']) { |
909 Element element = isolateHelperLibrary.find(name); | 913 Element element = find(isolateHelperLibrary, name); |
910 enqueuer.addToWorkList(element); | 914 enqueuer.addToWorkList(element); |
911 compiler.globalDependencies.registerDependency(element); | 915 compiler.globalDependencies.registerDependency(element); |
912 } | 916 } |
913 } else { | 917 } else { |
914 enqueuer.addToWorkList(isolateHelperLibrary.find(START_ROOT_ISOLATE)); | 918 enqueuer.addToWorkList(find(isolateHelperLibrary, START_ROOT_ISOLATE)); |
915 } | 919 } |
916 } | 920 } |
917 | 921 |
918 bool isAssertMethod(Element element) => element == assertMethod; | 922 bool isAssertMethod(Element element) => element == assertMethod; |
919 | 923 |
920 void registerRequiredType(DartType type, Element enclosingElement) { | 924 void registerRequiredType(DartType type, Element enclosingElement) { |
921 // If [argument] has type variables or is a type variable, this method | 925 // If [argument] has type variables or is a type variable, this method |
922 // registers a RTI dependency between the class where the type variable is | 926 // registers a RTI dependency between the class where the type variable is |
923 // defined (that is the enclosing class of the current element being | 927 // defined (that is the enclosing class of the current element being |
924 // resolved) and the class of [type]. If the class of [type] requires RTI, | 928 // resolved) and the class of [type]. If the class of [type] requires RTI, |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1271 element == compiler.numClass || | 1275 element == compiler.numClass || |
1272 element == compiler.intClass || | 1276 element == compiler.intClass || |
1273 element == compiler.doubleClass || | 1277 element == compiler.doubleClass || |
1274 element == jsArrayClass || | 1278 element == jsArrayClass || |
1275 element == jsMutableArrayClass || | 1279 element == jsMutableArrayClass || |
1276 element == jsExtendableArrayClass || | 1280 element == jsExtendableArrayClass || |
1277 element == jsFixedArrayClass; | 1281 element == jsFixedArrayClass; |
1278 } | 1282 } |
1279 | 1283 |
1280 Element getExceptionUnwrapper() { | 1284 Element getExceptionUnwrapper() { |
1281 return findHelper('unwrapException'); | 1285 return find(jsHelperLibrary, 'unwrapException'); |
1282 } | 1286 } |
1283 | 1287 |
1284 Element getThrowRuntimeError() { | 1288 Element getThrowRuntimeError() { |
1285 return findHelper('throwRuntimeError'); | 1289 return find(jsHelperLibrary, 'throwRuntimeError'); |
1286 } | 1290 } |
1287 | 1291 |
1288 Element getThrowTypeError() { | 1292 Element getThrowTypeError() { |
1289 return findHelper('throwTypeError'); | 1293 return find(jsHelperLibrary, 'throwTypeError'); |
1290 } | 1294 } |
1291 | 1295 |
1292 Element getThrowAbstractClassInstantiationError() { | 1296 Element getThrowAbstractClassInstantiationError() { |
1293 return findHelper('throwAbstractClassInstantiationError'); | 1297 return find(jsHelperLibrary, 'throwAbstractClassInstantiationError'); |
1294 } | 1298 } |
1295 | 1299 |
1296 Element getStringInterpolationHelper() { | 1300 Element getStringInterpolationHelper() { |
1297 return findHelper('S'); | 1301 return find(jsHelperLibrary, 'S'); |
1298 } | 1302 } |
1299 | 1303 |
1300 Element getWrapExceptionHelper() { | 1304 Element getWrapExceptionHelper() { |
1301 return findHelper(r'wrapException'); | 1305 return find(jsHelperLibrary, r'wrapException'); |
1302 } | 1306 } |
1303 | 1307 |
1304 Element getThrowExpressionHelper() { | 1308 Element getThrowExpressionHelper() { |
1305 return findHelper('throwExpression'); | 1309 return find(jsHelperLibrary, 'throwExpression'); |
1306 } | 1310 } |
1307 | 1311 |
1308 Element getClosureConverter() { | 1312 Element getClosureConverter() { |
1309 return findHelper('convertDartClosureToJS'); | 1313 return find(jsHelperLibrary, 'convertDartClosureToJS'); |
1310 } | 1314 } |
1311 | 1315 |
1312 Element getTraceFromException() { | 1316 Element getTraceFromException() { |
1313 return findHelper('getTraceFromException'); | 1317 return find(jsHelperLibrary, 'getTraceFromException'); |
1314 } | 1318 } |
1315 | 1319 |
1316 Element getSetRuntimeTypeInfo() { | 1320 Element getSetRuntimeTypeInfo() { |
1317 return findHelper('setRuntimeTypeInfo'); | 1321 return find(jsHelperLibrary, 'setRuntimeTypeInfo'); |
1318 } | 1322 } |
1319 | 1323 |
1320 Element getGetRuntimeTypeInfo() { | 1324 Element getGetRuntimeTypeInfo() { |
1321 return findHelper('getRuntimeTypeInfo'); | 1325 return find(jsHelperLibrary, 'getRuntimeTypeInfo'); |
1322 } | 1326 } |
1323 | 1327 |
1324 Element getGetTypeArgumentByIndex() { | 1328 Element getGetTypeArgumentByIndex() { |
1325 return findHelper('getTypeArgumentByIndex'); | 1329 return find(jsHelperLibrary, 'getTypeArgumentByIndex'); |
1326 } | 1330 } |
1327 | 1331 |
1328 Element getCopyTypeArguments() { | 1332 Element getCopyTypeArguments() { |
1329 return findHelper('copyTypeArguments'); | 1333 return find(jsHelperLibrary, 'copyTypeArguments'); |
1330 } | 1334 } |
1331 | 1335 |
1332 Element getComputeSignature() { | 1336 Element getComputeSignature() { |
1333 return findHelper('computeSignature'); | 1337 return find(jsHelperLibrary, 'computeSignature'); |
1334 } | 1338 } |
1335 | 1339 |
1336 Element getGetRuntimeTypeArguments() { | 1340 Element getGetRuntimeTypeArguments() { |
1337 return findHelper('getRuntimeTypeArguments'); | 1341 return find(jsHelperLibrary, 'getRuntimeTypeArguments'); |
1338 } | 1342 } |
1339 | 1343 |
1340 Element getGetRuntimeTypeArgument() { | 1344 Element getGetRuntimeTypeArgument() { |
1341 return findHelper('getRuntimeTypeArgument'); | 1345 return find(jsHelperLibrary, 'getRuntimeTypeArgument'); |
1342 } | 1346 } |
1343 | 1347 |
1344 Element getRuntimeTypeToString() { | 1348 Element getRuntimeTypeToString() { |
1345 return findHelper('runtimeTypeToString'); | 1349 return find(jsHelperLibrary, 'runtimeTypeToString'); |
1346 } | 1350 } |
1347 | 1351 |
1348 Element getAssertIsSubtype() { | 1352 Element getAssertIsSubtype() { |
1349 return findHelper('assertIsSubtype'); | 1353 return find(jsHelperLibrary, 'assertIsSubtype'); |
1350 } | 1354 } |
1351 | 1355 |
1352 Element getCheckSubtype() { | 1356 Element getCheckSubtype() { |
1353 return findHelper('checkSubtype'); | 1357 return find(jsHelperLibrary, 'checkSubtype'); |
1354 } | 1358 } |
1355 | 1359 |
1356 Element getAssertSubtype() { | 1360 Element getAssertSubtype() { |
1357 return findHelper('assertSubtype'); | 1361 return find(jsHelperLibrary, 'assertSubtype'); |
1358 } | 1362 } |
1359 | 1363 |
1360 Element getCheckSubtypeOfRuntimeType() { | 1364 Element getCheckSubtypeOfRuntimeType() { |
1361 return findHelper('checkSubtypeOfRuntimeType'); | 1365 return find(jsHelperLibrary, 'checkSubtypeOfRuntimeType'); |
1362 } | 1366 } |
1363 | 1367 |
1364 Element getCheckDeferredIsLoaded() { | 1368 Element getCheckDeferredIsLoaded() { |
1365 return findHelper('checkDeferredIsLoaded'); | 1369 return find(jsHelperLibrary, 'checkDeferredIsLoaded'); |
1366 } | 1370 } |
1367 | 1371 |
1368 Element getAssertSubtypeOfRuntimeType() { | 1372 Element getAssertSubtypeOfRuntimeType() { |
1369 return findHelper('assertSubtypeOfRuntimeType'); | 1373 return find(jsHelperLibrary, 'assertSubtypeOfRuntimeType'); |
1370 } | 1374 } |
1371 | 1375 |
1372 Element getThrowNoSuchMethod() { | 1376 Element getThrowNoSuchMethod() { |
1373 return findHelper('throwNoSuchMethod'); | 1377 return find(jsHelperLibrary, 'throwNoSuchMethod'); |
1374 } | 1378 } |
1375 | 1379 |
1376 Element getCreateRuntimeType() { | 1380 Element getCreateRuntimeType() { |
1377 return findHelper('createRuntimeType'); | 1381 return find(jsHelperLibrary, 'createRuntimeType'); |
1378 } | 1382 } |
1379 | 1383 |
1380 Element getFallThroughError() { | 1384 Element getFallThroughError() { |
1381 return findHelper("getFallThroughError"); | 1385 return find(jsHelperLibrary, "getFallThroughError"); |
1382 } | 1386 } |
1383 | 1387 |
1384 Element getCreateInvocationMirror() { | 1388 Element getCreateInvocationMirror() { |
1385 return findHelper(Compiler.CREATE_INVOCATION_MIRROR); | 1389 return find(jsHelperLibrary, Compiler.CREATE_INVOCATION_MIRROR); |
1386 } | 1390 } |
1387 | 1391 |
1388 Element getCyclicThrowHelper() { | 1392 Element getCyclicThrowHelper() { |
1389 return findHelper("throwCyclicInit"); | 1393 return find(jsHelperLibrary, "throwCyclicInit"); |
1390 } | 1394 } |
1391 | 1395 |
1392 bool isNullImplementation(ClassElement cls) { | 1396 bool isNullImplementation(ClassElement cls) { |
1393 return cls == jsNullClass; | 1397 return cls == jsNullClass; |
1394 } | 1398 } |
1395 | 1399 |
1396 ClassElement get intImplementation => jsIntClass; | 1400 ClassElement get intImplementation => jsIntClass; |
1397 ClassElement get uint32Implementation => jsUInt32Class; | 1401 ClassElement get uint32Implementation => jsUInt32Class; |
1398 ClassElement get uint31Implementation => jsUInt31Class; | 1402 ClassElement get uint31Implementation => jsUInt31Class; |
1399 ClassElement get positiveIntImplementation => jsPositiveIntClass; | 1403 ClassElement get positiveIntImplementation => jsPositiveIntClass; |
(...skipping 18 matching lines...) Expand all Loading... | |
1418 } else if (element == preserveNamesMarker) { | 1422 } else if (element == preserveNamesMarker) { |
1419 mustPreserveNames = true; | 1423 mustPreserveNames = true; |
1420 } else if (element == preserveMetadataMarker) { | 1424 } else if (element == preserveMetadataMarker) { |
1421 mustRetainMetadata = true; | 1425 mustRetainMetadata = true; |
1422 } else if (element == getIsolateAffinityTagMarker) { | 1426 } else if (element == getIsolateAffinityTagMarker) { |
1423 needToInitializeIsolateAffinityTag = true; | 1427 needToInitializeIsolateAffinityTag = true; |
1424 } else if (element.isDeferredLoaderGetter) { | 1428 } else if (element.isDeferredLoaderGetter) { |
1425 // TODO(sigurdm): Create a function registerLoadLibraryAccess. | 1429 // TODO(sigurdm): Create a function registerLoadLibraryAccess. |
1426 if (compiler.loadLibraryFunction == null) { | 1430 if (compiler.loadLibraryFunction == null) { |
1427 compiler.loadLibraryFunction = | 1431 compiler.loadLibraryFunction = |
1428 findHelper("_loadLibraryWrapper"); | 1432 find(jsHelperLibrary, "_loadLibraryWrapper"); |
1429 enqueueInResolution(compiler.loadLibraryFunction, | 1433 enqueueInResolution(compiler.loadLibraryFunction, |
1430 compiler.globalDependencies); | 1434 compiler.globalDependencies); |
1431 } | 1435 } |
1432 } | 1436 } |
1433 customElementsAnalysis.registerStaticUse(element, enqueuer); | 1437 customElementsAnalysis.registerStaticUse(element, enqueuer); |
1434 } | 1438 } |
1435 | 1439 |
1436 /// Called when [:const Symbol(name):] is seen. | 1440 /// Called when [:const Symbol(name):] is seen. |
1437 void registerConstSymbol(String name, Registry registry) { | 1441 void registerConstSymbol(String name, Registry registry) { |
1438 symbolsUsed.add(name); | 1442 symbolsUsed.add(name); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1482 } else if (uri == DART_FOREIGN_HELPER) { | 1486 } else if (uri == DART_FOREIGN_HELPER) { |
1483 foreignLibrary = library; | 1487 foreignLibrary = library; |
1484 } else if (uri == DART_ISOLATE_HELPER) { | 1488 } else if (uri == DART_ISOLATE_HELPER) { |
1485 isolateHelperLibrary = library; | 1489 isolateHelperLibrary = library; |
1486 } | 1490 } |
1487 } | 1491 } |
1488 | 1492 |
1489 void initializeHelperClasses() { | 1493 void initializeHelperClasses() { |
1490 final List missingHelperClasses = []; | 1494 final List missingHelperClasses = []; |
1491 ClassElement lookupHelperClass(String name) { | 1495 ClassElement lookupHelperClass(String name) { |
1492 ClassElement result = jsHelperLibrary.find(name); | 1496 ClassElement result = find(jsHelperLibrary, name); |
1493 if (result == null) { | 1497 if (result == null) { |
1494 missingHelperClasses.add(name); | 1498 missingHelperClasses.add(name); |
1495 } | 1499 } |
1496 return result; | 1500 return result; |
1497 } | 1501 } |
1498 jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror'); | 1502 jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror'); |
1499 boundClosureClass = lookupHelperClass('BoundClosure'); | 1503 boundClosureClass = lookupHelperClass('BoundClosure'); |
1500 closureClass = lookupHelperClass('Closure'); | 1504 closureClass = lookupHelperClass('Closure'); |
1501 if (!missingHelperClasses.isEmpty) { | 1505 if (!missingHelperClasses.isEmpty) { |
1502 compiler.internalError(jsHelperLibrary, | 1506 compiler.internalError(jsHelperLibrary, |
1503 'dart:_js_helper library does not contain required classes: ' | 1507 'dart:_js_helper library does not contain required classes: ' |
1504 '$missingHelperClasses'); | 1508 '$missingHelperClasses'); |
1505 } | 1509 } |
1506 } | 1510 } |
1507 | 1511 |
1508 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 1512 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
1509 return super.onLibraryScanned(library, loader).then((_) { | 1513 return super.onLibraryScanned(library, loader).then((_) { |
1510 Uri uri = library.canonicalUri; | 1514 Uri uri = library.canonicalUri; |
1511 | 1515 |
1512 // TODO(johnniwinther): Assert that the elements are found. | 1516 // TODO(johnniwinther): Assert that the elements are found. |
1513 VariableElement findVariable(String name) { | 1517 VariableElement findVariable(String name) { |
1514 return library.find(name); | 1518 return find(library, name); |
1515 } | 1519 } |
1516 | 1520 |
1517 FunctionElement findMethod(String name) { | 1521 FunctionElement findMethod(String name) { |
1518 return library.find(name); | 1522 return find(library, name); |
1519 } | 1523 } |
1520 | 1524 |
1521 ClassElement findClass(String name) { | 1525 ClassElement findClass(String name) { |
1522 return library.find(name); | 1526 return find(library, name); |
1523 } | 1527 } |
1524 | 1528 |
1525 if (uri == DART_INTERCEPTORS) { | 1529 if (uri == DART_INTERCEPTORS) { |
1526 getInterceptorMethod = findMethod('getInterceptor'); | 1530 getInterceptorMethod = findMethod('getInterceptor'); |
1527 interceptedNames = findVariable('interceptedNames'); | 1531 interceptedNames = findVariable('interceptedNames'); |
1528 mapTypeToInterceptor = findVariable('mapTypeToInterceptor'); | 1532 mapTypeToInterceptor = findVariable('mapTypeToInterceptor'); |
1529 getNativeInterceptorMethod = findMethod('getNativeInterceptor'); | 1533 getNativeInterceptorMethod = findMethod('getNativeInterceptor'); |
1530 | 1534 |
1531 List<ClassElement> classes = [ | 1535 List<ClassElement> classes = [ |
1532 jsInterceptorClass = findClass('Interceptor'), | 1536 jsInterceptorClass = findClass('Interceptor'), |
(...skipping 13 matching lines...) Expand all Loading... | |
1546 jsFixedArrayClass = findClass('JSFixedArray'), | 1550 jsFixedArrayClass = findClass('JSFixedArray'), |
1547 jsExtendableArrayClass = findClass('JSExtendableArray'), | 1551 jsExtendableArrayClass = findClass('JSExtendableArray'), |
1548 jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject'), | 1552 jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject'), |
1549 jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject'), | 1553 jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject'), |
1550 ]; | 1554 ]; |
1551 | 1555 |
1552 jsIndexableClass = findClass('JSIndexable'); | 1556 jsIndexableClass = findClass('JSIndexable'); |
1553 jsMutableIndexableClass = findClass('JSMutableIndexable'); | 1557 jsMutableIndexableClass = findClass('JSMutableIndexable'); |
1554 } else if (uri == DART_JS_HELPER) { | 1558 } else if (uri == DART_JS_HELPER) { |
1555 initializeHelperClasses(); | 1559 initializeHelperClasses(); |
1556 assertMethod = jsHelperLibrary.find('assertHelper'); | 1560 assertMethod = find(jsHelperLibrary, 'assertHelper'); |
1557 | 1561 |
1558 typeLiteralClass = findClass('TypeImpl'); | 1562 typeLiteralClass = findClass('TypeImpl'); |
1559 constMapLiteralClass = findClass('ConstantMap'); | 1563 constMapLiteralClass = findClass('ConstantMap'); |
1560 typeVariableClass = findClass('TypeVariable'); | 1564 typeVariableClass = findClass('TypeVariable'); |
1561 | 1565 |
1562 jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior'); | 1566 jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior'); |
1563 | 1567 |
1564 noSideEffectsClass = findClass('NoSideEffects'); | 1568 noSideEffectsClass = findClass('NoSideEffects'); |
1565 noThrowsClass = findClass('NoThrows'); | 1569 noThrowsClass = findClass('NoThrows'); |
1566 noInlineClass = findClass('NoInline'); | 1570 noInlineClass = findClass('NoInline'); |
1567 irRepresentationClass = findClass('IrRepresentation'); | 1571 irRepresentationClass = findClass('IrRepresentation'); |
1568 | 1572 |
1569 getIsolateAffinityTagMarker = library.find('getIsolateAffinityTag'); | 1573 getIsolateAffinityTagMarker = find(library, 'getIsolateAffinityTag'); |
1570 } else if (uri == DART_JS_MIRRORS) { | 1574 } else if (uri == DART_JS_MIRRORS) { |
1571 disableTreeShakingMarker = library.find('disableTreeShaking'); | 1575 disableTreeShakingMarker = find(library, 'disableTreeShaking'); |
1572 preserveMetadataMarker = library.find('preserveMetadata'); | 1576 preserveMetadataMarker = find(library, 'preserveMetadata'); |
1573 } else if (uri == DART_JS_NAMES) { | 1577 } else if (uri == DART_JS_NAMES) { |
1574 preserveNamesMarker = library.find('preserveNames'); | 1578 preserveNamesMarker = find(library, 'preserveNames'); |
1575 } | 1579 } |
1576 }); | 1580 }); |
1577 } | 1581 } |
1578 | 1582 |
1579 Future onLibrariesLoaded(Map<Uri, LibraryElement> loadedLibraries) { | 1583 Future onLibrariesLoaded(Map<Uri, LibraryElement> loadedLibraries) { |
1580 if (!loadedLibraries.containsKey(Compiler.DART_CORE)) { | 1584 if (!loadedLibraries.containsKey(Compiler.DART_CORE)) { |
1581 return new Future.value(); | 1585 return new Future.value(); |
1582 } | 1586 } |
1583 | 1587 |
1584 assert(loadedLibraries.containsKey(Compiler.DART_CORE)); | 1588 assert(loadedLibraries.containsKey(Compiler.DART_CORE)); |
1585 assert(loadedLibraries.containsKey(DART_INTERCEPTORS)); | 1589 assert(loadedLibraries.containsKey(DART_INTERCEPTORS)); |
1586 assert(loadedLibraries.containsKey(DART_JS_HELPER)); | 1590 assert(loadedLibraries.containsKey(DART_JS_HELPER)); |
1587 | 1591 |
1588 if (jsInvocationMirrorClass != null) { | 1592 if (jsInvocationMirrorClass != null) { |
1589 jsInvocationMirrorClass.ensureResolved(compiler); | 1593 jsInvocationMirrorClass.ensureResolved(compiler); |
1590 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); | 1594 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); |
1591 } | 1595 } |
1592 | 1596 |
1593 // [LinkedHashMap] is reexported from dart:collection and can therefore not | 1597 // [LinkedHashMap] is reexported from dart:collection and can therefore not |
1594 // be loaded from dart:core in [onLibraryScanned]. | 1598 // be loaded from dart:core in [onLibraryScanned]. |
1595 mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap'); | 1599 mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap'); |
1600 assert(invariant(compiler.coreLibrary, mapLiteralClass != null, | |
1601 message: "Element 'LinkedHashMap' not found in 'dart:core'.")); | |
1596 | 1602 |
1597 implementationClasses = <ClassElement, ClassElement>{}; | 1603 implementationClasses = <ClassElement, ClassElement>{}; |
1598 implementationClasses[compiler.intClass] = jsIntClass; | 1604 implementationClasses[compiler.intClass] = jsIntClass; |
1599 implementationClasses[compiler.boolClass] = jsBoolClass; | 1605 implementationClasses[compiler.boolClass] = jsBoolClass; |
1600 implementationClasses[compiler.numClass] = jsNumberClass; | 1606 implementationClasses[compiler.numClass] = jsNumberClass; |
1601 implementationClasses[compiler.doubleClass] = jsDoubleClass; | 1607 implementationClasses[compiler.doubleClass] = jsDoubleClass; |
1602 implementationClasses[compiler.stringClass] = jsStringClass; | 1608 implementationClasses[compiler.stringClass] = jsStringClass; |
1603 implementationClasses[compiler.listClass] = jsArrayClass; | 1609 implementationClasses[compiler.listClass] = jsArrayClass; |
1604 implementationClasses[compiler.nullClass] = jsNullClass; | 1610 implementationClasses[compiler.nullClass] = jsNullClass; |
1605 | 1611 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1756 jsAst.Expression use2) { | 1762 jsAst.Expression use2) { |
1757 String dispatchPropertyName = 'init.dispatchPropertyName'; | 1763 String dispatchPropertyName = 'init.dispatchPropertyName'; |
1758 | 1764 |
1759 // We pass the dispatch property record to the isJsIndexable | 1765 // We pass the dispatch property record to the isJsIndexable |
1760 // helper rather than reading it inside the helper to increase the | 1766 // helper rather than reading it inside the helper to increase the |
1761 // chance of making the dispatch record access monomorphic. | 1767 // chance of making the dispatch record access monomorphic. |
1762 jsAst.PropertyAccess record = new jsAst.PropertyAccess( | 1768 jsAst.PropertyAccess record = new jsAst.PropertyAccess( |
1763 use2, js(dispatchPropertyName)); | 1769 use2, js(dispatchPropertyName)); |
1764 | 1770 |
1765 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; | 1771 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; |
1766 FunctionElement helper = findHelper('isJsIndexable'); | 1772 FunctionElement helper = find(jsHelperLibrary, 'isJsIndexable'); |
1767 jsAst.Expression helperExpression = namer.elementAccess(helper); | 1773 jsAst.Expression helperExpression = namer.elementAccess(helper); |
1768 return new jsAst.Call(helperExpression, arguments); | 1774 return new jsAst.Call(helperExpression, arguments); |
1769 } | 1775 } |
1770 | 1776 |
1771 bool isTypedArray(TypeMask mask) { | 1777 bool isTypedArray(TypeMask mask) { |
1772 // Just checking for [:TypedData:] is not sufficient, as it is an | 1778 // Just checking for [:TypedData:] is not sufficient, as it is an |
1773 // abstract class any user-defined class can implement. So we also | 1779 // abstract class any user-defined class can implement. So we also |
1774 // check for the interface [JavaScriptIndexingBehavior]. | 1780 // check for the interface [JavaScriptIndexingBehavior]. |
1775 return compiler.typedDataClass != null | 1781 return compiler.typedDataClass != null |
1776 && mask.satisfies(compiler.typedDataClass, compiler) | 1782 && mask.satisfies(compiler.typedDataClass, compiler) |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2013 backend.getCheckSubtypeOfRuntimeType(), registry); | 2019 backend.getCheckSubtypeOfRuntimeType(), registry); |
2014 if (inCheckedMode) { | 2020 if (inCheckedMode) { |
2015 registerBackendStaticInvocation( | 2021 registerBackendStaticInvocation( |
2016 backend.getAssertSubtypeOfRuntimeType(), registry); | 2022 backend.getAssertSubtypeOfRuntimeType(), registry); |
2017 } | 2023 } |
2018 } | 2024 } |
2019 registerBackendInstantiation(backend.compiler.listClass, registry); | 2025 registerBackendInstantiation(backend.compiler.listClass, registry); |
2020 } | 2026 } |
2021 if (type is FunctionType) { | 2027 if (type is FunctionType) { |
2022 registerBackendStaticInvocation( | 2028 registerBackendStaticInvocation( |
2023 backend.findHelper('functionTypeTestMetaHelper'), registry); | 2029 backend.find(backend.jsHelperLibrary, 'functionTypeTestMetaHelper'), |
2030 registry); | |
2024 } | 2031 } |
2025 if (type.element != null && type.element.isNative) { | 2032 if (type.element != null && type.element.isNative) { |
2026 // We will neeed to add the "$is" and "$as" properties on the | 2033 // We will neeed to add the "$is" and "$as" properties on the |
2027 // JavaScript object prototype, so we make sure | 2034 // JavaScript object prototype, so we make sure |
2028 // [:defineProperty:] is compiled. | 2035 // [:defineProperty:] is compiled. |
2029 registerBackendStaticInvocation( | 2036 registerBackendStaticInvocation( |
2030 backend.findHelper('defineProperty'), registry); | 2037 backend.find(backend.jsHelperLibrary, 'defineProperty'), registry); |
2031 } | 2038 } |
2032 } | 2039 } |
2033 | 2040 |
2034 void onTypeVariableBoundCheck(Registry registry) { | 2041 void onTypeVariableBoundCheck(Registry registry) { |
2035 assert(registry.isForResolution); | 2042 assert(registry.isForResolution); |
2036 registerBackendStaticInvocation(backend.getThrowTypeError(), registry); | 2043 registerBackendStaticInvocation(backend.getThrowTypeError(), registry); |
2037 registerBackendStaticInvocation(backend.getAssertIsSubtype(), registry); | 2044 registerBackendStaticInvocation(backend.getAssertIsSubtype(), registry); |
2038 } | 2045 } |
2039 | 2046 |
2040 void onAbstractClassInstantiation(Registry registry) { | 2047 void onAbstractClassInstantiation(Registry registry) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2076 backend.getCreateInvocationMirror(), registry); | 2083 backend.getCreateInvocationMirror(), registry); |
2077 registerBackendStaticInvocation( | 2084 registerBackendStaticInvocation( |
2078 backend.compiler.objectClass.lookupLocalMember(Compiler.NO_SUCH_METHOD), | 2085 backend.compiler.objectClass.lookupLocalMember(Compiler.NO_SUCH_METHOD), |
2079 registry); | 2086 registry); |
2080 registerBackendInstantiation(backend.compiler.listClass, registry); | 2087 registerBackendInstantiation(backend.compiler.listClass, registry); |
2081 } | 2088 } |
2082 | 2089 |
2083 void onConstantMap(Registry registry) { | 2090 void onConstantMap(Registry registry) { |
2084 assert(registry.isForResolution); | 2091 assert(registry.isForResolution); |
2085 void enqueue(String name) { | 2092 void enqueue(String name) { |
2086 Element e = backend.findHelper(name); | 2093 Element e = backend.find(backend.jsHelperLibrary, name); |
2087 registerBackendInstantiation(e, registry); | 2094 registerBackendInstantiation(e, registry); |
2088 } | 2095 } |
2089 | 2096 |
2090 enqueue(JavaScriptMapConstant.DART_CLASS); | 2097 enqueue(JavaScriptMapConstant.DART_CLASS); |
2091 enqueue(JavaScriptMapConstant.DART_PROTO_CLASS); | 2098 enqueue(JavaScriptMapConstant.DART_PROTO_CLASS); |
2092 enqueue(JavaScriptMapConstant.DART_STRING_CLASS); | 2099 enqueue(JavaScriptMapConstant.DART_STRING_CLASS); |
2093 enqueue(JavaScriptMapConstant.DART_GENERAL_CLASS); | 2100 enqueue(JavaScriptMapConstant.DART_GENERAL_CLASS); |
2094 } | 2101 } |
2095 | 2102 |
2096 /// Called when resolving the `Symbol` constructor. | 2103 /// Called when resolving the `Symbol` constructor. |
2097 void onSymbolConstructor(Registry registry) { | 2104 void onSymbolConstructor(Registry registry) { |
2098 assert(registry.isForResolution); | 2105 assert(registry.isForResolution); |
2099 // Make sure that _internals.Symbol.validated is registered. | 2106 // Make sure that _internals.Symbol.validated is registered. |
2100 assert(backend.compiler.symbolValidatedConstructor != null); | 2107 assert(backend.compiler.symbolValidatedConstructor != null); |
2101 registerBackendStaticInvocation( | 2108 registerBackendStaticInvocation( |
2102 backend.compiler.symbolValidatedConstructor, registry); | 2109 backend.compiler.symbolValidatedConstructor, registry); |
2103 } | 2110 } |
2104 } | 2111 } |
2105 | 2112 |
2106 /// Records that [constant] is used by the element behind [registry]. | 2113 /// Records that [constant] is used by the element behind [registry]. |
2107 class Dependency { | 2114 class Dependency { |
2108 final Constant constant; | 2115 final Constant constant; |
2109 // TODO(johnniwinther): Change to [Element] when dependency nodes are added. | 2116 // TODO(johnniwinther): Change to [Element] when dependency nodes are added. |
2110 final Registry registry; | 2117 final Registry registry; |
2111 | 2118 |
2112 const Dependency(this.constant, this.registry); | 2119 const Dependency(this.constant, this.registry); |
2113 } | 2120 } |
OLD | NEW |