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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart

Issue 1071133002: dart2js: create a 'types' table for each deferred unit. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 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 dart2js.new_js_emitter.model_emitter; 5 library dart2js.new_js_emitter.model_emitter;
6 6
7 import '../../constants/values.dart' show ConstantValue, FunctionConstantValue; 7 import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
8 import '../../dart2jslib.dart' show Compiler; 8 import '../../dart2jslib.dart' show Compiler;
9 import '../../dart_types.dart' show DartType; 9 import '../../dart_types.dart' show DartType;
10 import '../../elements/elements.dart' show ClassElement, FunctionElement; 10 import '../../elements/elements.dart' show ClassElement, FunctionElement;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 this.constantEmitter = new ConstantEmitter( 61 this.constantEmitter = new ConstantEmitter(
62 compiler, namer, this.generateConstantReference, 62 compiler, namer, this.generateConstantReference,
63 makeConstantListTemplate); 63 makeConstantListTemplate);
64 } 64 }
65 65
66 js.Expression generateEmbeddedGlobalAccess(String global) { 66 js.Expression generateEmbeddedGlobalAccess(String global) {
67 // TODO(floitsch): We should not use "init" for globals. 67 // TODO(floitsch): We should not use "init" for globals.
68 return js.js("init.$global"); 68 return js.js("init.$global");
69 } 69 }
70 70
71 String generateEmbeddedGlobalAccessString(String global) {
72 // TODO(floitsch): We should not use "init" for globals.
73 return "init.$global";
74 }
75
71 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { 76 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
72 if (constant.isFunction) return true; // Already emitted. 77 if (constant.isFunction) return true; // Already emitted.
73 if (constant.isPrimitive) return true; // Inlined. 78 if (constant.isPrimitive) return true; // Inlined.
74 if (constant.isDummy) return true; // Inlined. 79 if (constant.isDummy) return true; // Inlined.
75 // The name is null when the constant is already a JS constant. 80 // The name is null when the constant is already a JS constant.
76 // TODO(floitsch): every constant should be registered, so that we can 81 // TODO(floitsch): every constant should be registered, so that we can
77 // share the ones that take up too much space (like some strings). 82 // share the ones that take up too much space (like some strings).
78 if (namer.constantName(constant) == null) return true; 83 if (namer.constantName(constant) == null) return true;
79 return false; 84 return false;
80 } 85 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 int emitProgram(Program program) { 130 int emitProgram(Program program) {
126 List<Fragment> fragments = program.fragments; 131 List<Fragment> fragments = program.fragments;
127 MainFragment mainFragment = fragments.first; 132 MainFragment mainFragment = fragments.first;
128 133
129 int totalSize = 0; 134 int totalSize = 0;
130 135
131 // We have to emit the deferred fragments first, since we need their 136 // We have to emit the deferred fragments first, since we need their
132 // deferred hash (which depends on the output) when emitting the main 137 // deferred hash (which depends on the output) when emitting the main
133 // fragment. 138 // fragment.
134 fragments.skip(1).forEach((DeferredFragment deferredUnit) { 139 fragments.skip(1).forEach((DeferredFragment deferredUnit) {
135 js.Expression ast = emitDeferredFragment(deferredUnit, program.holders); 140 List<String> types = program.metadataTypes[deferredUnit.outputUnit];
141 js.Expression ast = emitDeferredFragment(types, deferredUnit,
142 program.holders);
136 String code = js.prettyPrint(ast, compiler).getText(); 143 String code = js.prettyPrint(ast, compiler).getText();
137 totalSize += code.length; 144 totalSize += code.length;
138 compiler.outputProvider(deferredUnit.outputFileName, deferredExtension) 145 compiler.outputProvider(deferredUnit.outputFileName, deferredExtension)
139 ..add(code) 146 ..add(code)
140 ..close(); 147 ..close();
141 }); 148 });
142 149
143 js.Statement mainAst = emitMainFragment(program); 150 js.Statement mainAst = emitMainFragment(program);
144 String mainCode = js.prettyPrint(mainAst, compiler).getText(); 151 String mainCode = js.prettyPrint(mainAst, compiler).getText();
145 compiler.outputProvider(mainFragment.outputFileName, 'js') 152 compiler.outputProvider(mainFragment.outputFileName, 'js')
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 js.Expression isHunkLoadedFunction = 384 js.Expression isHunkLoadedFunction =
378 js.js("function(hash) { return !!$deferredInitializersGlobal[hash]; }"); 385 js.js("function(hash) { return !!$deferredInitializersGlobal[hash]; }");
379 globals.add(new js.Property(js.string(IS_HUNK_LOADED), 386 globals.add(new js.Property(js.string(IS_HUNK_LOADED),
380 isHunkLoadedFunction)); 387 isHunkLoadedFunction));
381 388
382 js.Expression isHunkInitializedFunction = 389 js.Expression isHunkInitializedFunction =
383 js.js("function(hash) { return false; }"); 390 js.js("function(hash) { return false; }");
384 globals.add(new js.Property(js.string(IS_HUNK_INITIALIZED), 391 globals.add(new js.Property(js.string(IS_HUNK_INITIALIZED),
385 isHunkInitializedFunction)); 392 isHunkInitializedFunction));
386 393
394 String typesAccess = generateEmbeddedGlobalAccessString(TYPES);
395
387 /// See [emitEmbeddedGlobalsForDeferredLoading] for the format of the 396 /// See [emitEmbeddedGlobalsForDeferredLoading] for the format of the
388 /// deferred hunk. 397 /// deferred hunk.
389 js.Expression initializeLoadedHunkFunction = 398 js.Expression initializeLoadedHunkFunction =
390 js.js(""" 399 js.js("""
391 function(hash) { 400 function(hash) {
392 var hunk = $deferredInitializersGlobal[hash]; 401 var hunk = $deferredInitializersGlobal[hash];
393 $setupProgramName(hunk[0]); 402 $setupProgramName(hunk[0], ${typesAccess}.length);
sigurdm 2015/04/09 13:00:15 Why not $setupProgramName(hunk[0], #typesAcces
zarah 2015/04/10 10:56:03 Done.
394 eval(hunk[1]); 403 eval(hunk[1]);
404 var deferredTypes = eval(hunk[2]);
405 ${typesAccess}.push.apply(${typesAccess}, deferredTypes);
395 }"""); 406 }""");
396 407
397 globals.add(new js.Property(js.string(INITIALIZE_LOADED_HUNK), 408 globals.add(new js.Property(js.string(INITIALIZE_LOADED_HUNK),
398 initializeLoadedHunkFunction)); 409 initializeLoadedHunkFunction));
399 410
400 return globals; 411 return globals;
401 } 412 }
402 413
403 js.Property emitGetTypeFromName() { 414 js.Property emitGetTypeFromName() {
404 js.Expression function = 415 js.Expression function =
405 js.js( """function(name) { 416 js.js( """function(name) {
406 return holdersMap[name][name].ensureResolved(); 417 return holdersMap[name][name].ensureResolved();
407 }"""); 418 }""");
408 return new js.Property(js.string(GET_TYPE_FROM_NAME), function); 419 return new js.Property(js.string(GET_TYPE_FROM_NAME), function);
409 } 420 }
410 421
411 List<js.Property> emitMetadata(Program program) { 422 List<js.Property> emitMetadata(Program program) {
412 423
413 List<js.Property> metadataGlobals = <js.Property>[]; 424 List<js.Property> metadataGlobals = <js.Property>[];
414 425
415 js.Property createGlobal(List<String> list, String global) { 426 js.Property createGlobal(List<String> list, String global) {
416 String listAsString = "[${list.join(",")}]"; 427 String listAsString = "[${list.join(",")}]";
417 js.Expression metadata = 428 js.Expression metadata =
418 js.js.uncachedExpressionTemplate(listAsString).instantiate([]); 429 js.js.uncachedExpressionTemplate(listAsString).instantiate([]);
419 return new js.Property(js.string(global), metadata); 430 return new js.Property(js.string(global), metadata);
420 } 431 }
421 432
422 metadataGlobals.add(createGlobal(program.metadata, METADATA)); 433 metadataGlobals.add(createGlobal(program.metadata, METADATA));
423 metadataGlobals.add(createGlobal(program.metadataTypes, TYPES)); 434 List<String> types =
435 program.metadataTypes[program.fragments.first.outputUnit];
436 if (types == null) types = <String>[];
437 metadataGlobals.add(createGlobal(types, TYPES));
424 438
425 return metadataGlobals; 439 return metadataGlobals;
426 } 440 }
427 441
428 js.Expression emitDeferredFragment(DeferredFragment fragment, 442 js.Expression emitDeferredFragment(List<String> types,
443 DeferredFragment fragment,
429 List<Holder> holders) { 444 List<Holder> holders) {
430 // TODO(floitsch): initialize eager classes. 445 // TODO(floitsch): initialize eager classes.
431 // TODO(floitsch): the hash must depend on the output. 446 // TODO(floitsch): the hash must depend on the output.
432 int hash = fragment.hashCode; 447 int hash = fragment.hashCode;
433 448
434 List<js.Expression> deferredCode = 449 List<js.Expression> deferredCode =
435 fragment.libraries.map(emitLibrary).toList(); 450 fragment.libraries.map(emitLibrary).toList();
436 451
437 deferredCode.add( 452 deferredCode.add(
438 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields)); 453 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
439 454
440 deferredCode.add(emitConstants(fragment.constants)); 455 deferredCode.add(emitConstants(fragment.constants));
441 456
442 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode); 457 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode);
443 458
444 // This is the code that must be evaluated after all deferred classes have 459 // This is the code that must be evaluated after all deferred classes have
445 // been setup. 460 // been setup.
446 js.Statement immediateCode = 461 js.Statement immediateCode =
447 emitEagerClassInitializations(fragment.libraries); 462 emitEagerClassInitializations(fragment.libraries);
448 463
449 js.LiteralString immediateString = unparse(compiler, immediateCode); 464 js.LiteralString immediateString = unparse(compiler, immediateCode);
465
466 js.Expression deferredTypes = types == null
467 ? js.string("[]")
468 : js.string("[${types.join(",")}]");
469
450 js.ArrayInitializer hunk = 470 js.ArrayInitializer hunk =
451 new js.ArrayInitializer([deferredArray, immediateString]); 471 new js.ArrayInitializer([deferredArray, immediateString,
472 deferredTypes]);
452 473
453 return js.js("$deferredInitializersGlobal[$hash] = #", hunk); 474 return js.js("$deferredInitializersGlobal[$hash] = #", hunk);
454 } 475 }
455 476
456 // This string should be referenced wherever JavaScript code makes assumptions 477 // This string should be referenced wherever JavaScript code makes assumptions
457 // on the constants format. 478 // on the constants format.
458 static final String constantsDescription = 479 static final String constantsDescription =
459 "The constants are encoded as a follows:" 480 "The constants are encoded as a follows:"
460 " [constantsHolderIndex, name, code, name2, code2, ...]." 481 " [constantsHolderIndex, name, code, name2, code2, ...]."
461 "The array is completely empty if there is no constant at all."; 482 "The array is completely empty if there is no constant at all.";
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 /// 677 ///
657 /// for each stub in [DartMethod.parameterStubs]. 678 /// for each stub in [DartMethod.parameterStubs].
658 /// 679 ///
659 /// If the closure could be used in `Function.apply` (i.e. 680 /// If the closure could be used in `Function.apply` (i.e.
660 /// [DartMethod.canBeApplied] is true) then the following fields are appended: 681 /// [DartMethod.canBeApplied] is true) then the following fields are appended:
661 /// 682 ///
662 /// * [DartMethod.requiredParameterCount] 683 /// * [DartMethod.requiredParameterCount]
663 /// * [DartMethod.optionalParameterDefaultValues] 684 /// * [DartMethod.optionalParameterDefaultValues]
664 685
665 static final String parseFunctionDescriptorBoilerplate = r""" 686 static final String parseFunctionDescriptorBoilerplate = r"""
666 function parseFunctionDescriptor(proto, name, descriptor) { 687 function parseFunctionDescriptor(proto, name, descriptor, typesOffset) {
667 if (descriptor instanceof Array) { 688 if (descriptor instanceof Array) {
668 // 'pos' points to the last read entry. 689 // 'pos' points to the last read entry.
669 var f, pos = -1; 690 var f, pos = -1;
670 var aliasOrFunction = descriptor[++pos]; 691 var aliasOrFunction = descriptor[++pos];
671 if (typeof aliasOrFunction == "string") { 692 if (typeof aliasOrFunction == "string") {
672 // Install the alias for super calls on the prototype chain. 693 // Install the alias for super calls on the prototype chain.
673 proto[aliasOrFunction] = f = descriptor[++pos]; 694 proto[aliasOrFunction] = f = descriptor[++pos];
674 } else { 695 } else {
675 f = aliasOrFunction; 696 f = aliasOrFunction;
676 } 697 }
677 698
678 proto[name] = f; 699 proto[name] = f;
679 var funs = [f]; 700 var funs = [f];
680 f[#callName] = descriptor[++pos]; 701 f[#callName] = descriptor[++pos];
681 702
682 var isInterceptedOrParameterStubName = descriptor[pos + 1]; 703 var isInterceptedOrParameterStubName = descriptor[pos + 1];
683 var isIntercepted, tearOffName, reflectionInfo; 704 var isIntercepted, tearOffName, reflectionInfo;
684 if (typeof isInterceptedOrParameterStubName == "boolean") { 705 if (typeof isInterceptedOrParameterStubName == "boolean") {
685 isIntercepted = descriptor[++pos]; 706 isIntercepted = descriptor[++pos];
686 tearOffName = descriptor[++pos]; 707 tearOffName = descriptor[++pos];
687 reflectionInfo = descriptor[++pos]; 708 reflectionInfo = descriptor[++pos];
709 if (typeof reflectionInfo == "number") {
710 reflectionInfo = reflectionInfo + typesOffset;
711 }
688 } 712 }
689 713
690 // We iterate in blocks of 3 but have to stop before we reach the (optional) 714 // We iterate in blocks of 3 but have to stop before we reach the (optional)
691 // two trailing items. To accomplish this, we only iterate until we reach 715 // two trailing items. To accomplish this, we only iterate until we reach
692 // length - 2. 716 // length - 2.
693 for (++pos; pos < descriptor.length - 2; pos += 3) { 717 for (++pos; pos < descriptor.length - 2; pos += 3) {
694 var stub = descriptor[pos + 2]; 718 var stub = descriptor[pos + 2];
695 stub[#callName] = descriptor[pos + 1]; 719 stub[#callName] = descriptor[pos + 1];
696 proto[descriptor[pos]] = stub; 720 proto[descriptor[pos]] = stub;
697 funs.push(stub); 721 funs.push(stub);
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 #deferredInitializer; 856 #deferredInitializer;
833 857
834 !function(start, program) { 858 !function(start, program) {
835 // Initialize holder objects. 859 // Initialize holder objects.
836 #holders; 860 #holders;
837 var nativeInfos = Object.create(null); 861 var nativeInfos = Object.create(null);
838 862
839 // Counter to generate unique names for tear offs. 863 // Counter to generate unique names for tear offs.
840 var functionCounter = 0; 864 var functionCounter = 0;
841 865
842 function $setupProgramName(program) { 866 function $setupProgramName(program, typesOffset) {
843 for (var i = 0; i < program.length - 2; i++) { 867 for (var i = 0; i < program.length - 2; i++) {
844 setupLibrary(program[i]); 868 setupLibrary(program[i], typesOffset);
845 } 869 }
846 setupLazyStatics(program[i]); 870 setupLazyStatics(program[i]);
847 setupConstants(program[i + 1]); 871 setupConstants(program[i + 1]);
848 } 872 }
849 873
850 function setupLibrary(library) { 874 function setupLibrary(library, typesOffset) {
851 var statics = library[0]; 875 var statics = library[0];
852 for (var i = 0; i < statics.length; i += 3) { 876 for (var i = 0; i < statics.length; i += 3) {
853 var holderIndex = statics[i + 1]; 877 var holderIndex = statics[i + 1];
854 setupStatic(statics[i], holders[holderIndex], statics[i + 2]); 878 setupStatic(statics[i], holders[holderIndex], statics[i + 2],
879 typesOffset);
855 } 880 }
856 881
857 var classes = library[1]; 882 var classes = library[1];
858 for (var i = 0; i < classes.length; i += 3) { 883 for (var i = 0; i < classes.length; i += 3) {
859 var name = classes[i]; 884 var name = classes[i];
860 var cls = classes[i + 1]; 885 var cls = classes[i + 1];
861 886
862 if (#needsNativeSupport) { 887 if (#needsNativeSupport) {
863 // $nativeInfoDescription. 888 // $nativeInfoDescription.
864 var indexOrNativeInfo = classes[i + 2]; 889 var indexOrNativeInfo = classes[i + 2];
865 if (typeof indexOrNativeInfo == "number") { 890 if (typeof indexOrNativeInfo == "number") {
866 var holderIndex = classes[i + 2]; 891 var holderIndex = classes[i + 2];
867 } else { 892 } else {
868 nativeInfos[name] = indexOrNativeInfo; 893 nativeInfos[name] = indexOrNativeInfo;
869 holderIndex = classes[i + 3]; 894 holderIndex = classes[i + 3];
870 i++; 895 i++;
871 } 896 }
872 } 897 }
873 898
874 if (#needsNoNativeSupport) { 899 if (#needsNoNativeSupport) {
875 var holderIndex = classes[i + 2]; 900 var holderIndex = classes[i + 2];
876 } 901 }
877 902
878 holdersMap[name] = holders[holderIndex]; 903 holdersMap[name] = holders[holderIndex];
879 setupClass(name, holders[holderIndex], cls); 904 setupClass(name, holders[holderIndex], cls, typesOffset);
880 } 905 }
881 } 906 }
882 907
883 function setupLazyStatics(statics) { 908 function setupLazyStatics(statics) {
884 for (var i = 0; i < statics.length; i += 4) { 909 for (var i = 0; i < statics.length; i += 4) {
885 var name = statics[i]; 910 var name = statics[i];
886 var getterName = statics[i + 1]; 911 var getterName = statics[i + 1];
887 var holderIndex = statics[i + 2]; 912 var holderIndex = statics[i + 2];
888 var initializer = statics[i + 3]; 913 var initializer = statics[i + 3];
889 setupLazyStatic(name, getterName, holders[holderIndex], initializer); 914 setupLazyStatic(name, getterName, holders[holderIndex], initializer);
890 } 915 }
891 } 916 }
892 917
893 function setupConstants(constants) { 918 function setupConstants(constants) {
894 // $constantsDescription. 919 // $constantsDescription.
895 if (constants.length == 0) return; 920 if (constants.length == 0) return;
896 // We assume that all constants are in the same holder. 921 // We assume that all constants are in the same holder.
897 var holder = holders[constants[0]]; 922 var holder = holders[constants[0]];
898 for (var i = 1; i < constants.length; i += 2) { 923 for (var i = 1; i < constants.length; i += 2) {
899 var name = constants[i]; 924 var name = constants[i];
900 var initializer = constants[i + 1]; 925 var initializer = constants[i + 1];
901 setupConstant(name, holder, initializer); 926 setupConstant(name, holder, initializer);
902 } 927 }
903 } 928 }
904 929
905 function setupStatic(name, holder, descriptor) { 930 function setupStatic(name, holder, descriptor, typesOffset) {
906 if (typeof descriptor == 'string') { 931 if (typeof descriptor == 'string') {
907 holder[name] = function() { 932 holder[name] = function() {
908 if (descriptor == null) { 933 if (descriptor == null) {
909 // Already compiled. This happens when we have calls to the static as 934 // Already compiled. This happens when we have calls to the static as
910 // arguments to the static: `foo(foo(499))`; 935 // arguments to the static: `foo(foo(499))`;
911 return holder[name].apply(this, arguments); 936 return holder[name].apply(this, arguments);
912 } 937 }
913 var method = compile(name, descriptor); 938 var method = compile(name, descriptor);
914 holder[name] = method; 939 holder[name] = method;
915 descriptor = null; // GC the descriptor. 940 descriptor = null; // GC the descriptor.
916 return method.apply(this, arguments); 941 return method.apply(this, arguments);
917 }; 942 };
918 } else { 943 } else {
919 // Parse the tear off information and generate compile handlers. 944 // Parse the tear off information and generate compile handlers.
920 // TODO(herhut): Share parser with instance methods. 945 // TODO(herhut): Share parser with instance methods.
921 function compileAllStubs() { 946 function compileAllStubs(typesOffset) {
922 var funs; 947 var funs;
923 var fun = compile(name, descriptor[0]); 948 var fun = compile(name, descriptor[0]);
924 fun[#callName] = descriptor[1]; 949 fun[#callName] = descriptor[1];
925 holder[name] = fun; 950 holder[name] = fun;
926 funs = [fun]; 951 funs = [fun];
927 // We iterate in blocks of 3 but have to stop before we reach the 952 // We iterate in blocks of 3 but have to stop before we reach the
928 // (optional) two trailing items. To accomplish this, we only iterate 953 // (optional) two trailing items. To accomplish this, we only iterate
929 // until we reach length - 2. 954 // until we reach length - 2.
930 for (var pos = 4; pos < descriptor.length - 2; pos += 3) { 955 for (var pos = 4; pos < descriptor.length - 2; pos += 3) {
931 var stubName = descriptor[pos]; 956 var stubName = descriptor[pos];
932 fun = compile(stubName, descriptor[pos + 2]); 957 fun = compile(stubName, descriptor[pos + 2]);
933 fun[#callName] = descriptor[pos + 1]; 958 fun[#callName] = descriptor[pos + 1];
934 holder[stubName] = fun; 959 holder[stubName] = fun;
935 funs.push(fun); 960 funs.push(fun);
936 } 961 }
937 if (descriptor[2] != null) { // tear-off name. 962 if (descriptor[2] != null) { // tear-off name.
938 // functions, reflectionInfo, isStatic, name, isIntercepted. 963 // functions, reflectionInfo, isStatic, name, isIntercepted.
964 var reflectionInfo = descriptor[3];
965 if (typeof reflectionInfo == "number") {
966 reflectionInfo = reflectionInfo + typesOffset;
967 }
939 holder[descriptor[2]] = 968 holder[descriptor[2]] =
940 tearOff(funs, descriptor[3], true, name, false); 969 tearOff(funs, reflectionInfo, true, name, false);
941 } 970 }
942 if (pos < descriptor.length) { 971 if (pos < descriptor.length) {
943 fun[#argumentCount] = descriptor[pos]; 972 fun[#argumentCount] = descriptor[pos];
944 fun[#defaultArgumentValues] = descriptor[pos + 1]; 973 fun[#defaultArgumentValues] = descriptor[pos + 1];
945 } 974 }
946 } 975 }
947 976
948 function setupCompileAllAndDelegateStub(name) { 977 function setupCompileAllAndDelegateStub(name, typesOffset) {
949 holder[name] = function() { 978 holder[name] = function() {
950 // The descriptor is null if we already compiled this function. This 979 // The descriptor is null if we already compiled this function. This
951 // happens when we have calls to the static as arguments to the 980 // happens when we have calls to the static as arguments to the
952 // static: `foo(foo(499))`; 981 // static: `foo(foo(499))`;
953 if (descriptor != null) { 982 if (descriptor != null) {
954 compileAllStubs(); 983 compileAllStubs(typesOffset);
955 descriptor = null; // GC the descriptor. 984 descriptor = null; // GC the descriptor.
956 } 985 }
957 return holder[name].apply(this, arguments); 986 return holder[name].apply(this, arguments);
958 }; 987 };
959 } 988 }
960 989
961 setupCompileAllAndDelegateStub(name); 990 setupCompileAllAndDelegateStub(name, typesOffset);
962 for (var pos = 4; pos < descriptor.length; pos += 3) { 991 for (var pos = 4; pos < descriptor.length; pos += 3) {
963 setupCompileAllAndDelegateStub(descriptor[pos]); 992 setupCompileAllAndDelegateStub(descriptor[pos], typesOffset);
964 } 993 }
965 if (descriptor[2] != null) { // tear-off name. 994 if (descriptor[2] != null) { // tear-off name.
966 setupCompileAllAndDelegateStub(descriptor[2]) 995 setupCompileAllAndDelegateStub(descriptor[2], typesOffset)
967 } 996 }
968 } 997 }
969 } 998 }
970 999
971 function setupLazyStatic(name, getterName, holder, descriptor) { 1000 function setupLazyStatic(name, getterName, holder, descriptor) {
972 holder[name] = null; 1001 holder[name] = null;
973 holder[getterName] = function() { 1002 holder[getterName] = function() {
974 var initializer = compile(name, descriptor); 1003 var initializer = compile(name, descriptor);
975 holder[getterName] = function() { #cyclicThrow(name) }; 1004 holder[getterName] = function() { #cyclicThrow(name) };
976 var result; 1005 var result;
(...skipping 22 matching lines...) Expand all
999 holder[name] = function() { 1028 holder[name] = function() {
1000 if (descriptor !== null) { 1029 if (descriptor !== null) {
1001 c = compile(name, descriptor); 1030 c = compile(name, descriptor);
1002 name = null; 1031 name = null;
1003 descriptor = null; 1032 descriptor = null;
1004 } 1033 }
1005 return c; 1034 return c;
1006 }; 1035 };
1007 } 1036 }
1008 1037
1009 function setupClass(name, holder, descriptor) { 1038 function setupClass(name, holder, descriptor, typesOffset) {
1010 var patch = function() { 1039 var patch = function() {
1011 if (patch.ensureResolved == patch) { 1040 if (patch.ensureResolved == patch) {
1012 // We have not yet been compiled. 1041 // We have not yet been compiled.
1013 var constructor = compileConstructor(name, descriptor); 1042 var constructor = compileConstructor(name, descriptor, typesOffset);
1014 holder[name] = constructor; 1043 holder[name] = constructor;
1015 name = holder = descriptor = null; // GC the captured arguments. 1044 name = holder = descriptor = null; // GC the captured arguments.
1016 // Make sure we can invoke 'ensureResolved' multiple times on the patch 1045 // Make sure we can invoke 'ensureResolved' multiple times on the patch
1017 // function. 1046 // function.
1018 patch.ensureResolved = function() { return constructor; }; 1047 patch.ensureResolved = function() { return constructor; };
1019 constructor.ensureResolved = function() { return this; }; 1048 constructor.ensureResolved = function() { return this; };
1020 } else { 1049 } else {
1021 // This can happen when arguments to the constructor are of the same 1050 // This can happen when arguments to the constructor are of the same
1022 // class, like in `new A(new A(null))`. 1051 // class, like in `new A(new A(null))`.
1023 constructor = patch.ensureResolved(); 1052 constructor = patch.ensureResolved();
1024 } 1053 }
1025 // If the patch has been called as "ensureResolved" return. 1054 // If the patch has been called as "ensureResolved" return.
1026 if (this === patch) return constructor; 1055 if (this === patch) return constructor;
1027 var object = new constructor(); 1056 var object = new constructor();
1028 constructor.apply(object, arguments); 1057 constructor.apply(object, arguments);
1029 return object; 1058 return object;
1030 }; 1059 };
1031 1060
1032 // We store the patch function on itself to make it 1061 // We store the patch function on itself to make it
1033 // possible to resolve superclass references without constructing instances. 1062 // possible to resolve superclass references without constructing instances.
1034 patch.ensureResolved = patch; 1063 patch.ensureResolved = patch;
1035 holder[name] = patch; 1064 holder[name] = patch;
1036 } 1065 }
1037 1066
1038 #tearOff; 1067 #tearOff;
1039 1068
1040 #parseFunctionDescriptor; 1069 #parseFunctionDescriptor;
1041 1070
1042 function compileConstructor(name, descriptor) { 1071 function compileConstructor(name, descriptor, typesOffset) {
1043 descriptor = compile(name, descriptor); 1072 descriptor = compile(name, descriptor);
1044 var prototype = determinePrototype(descriptor); 1073 var prototype = determinePrototype(descriptor);
1045 var constructor; 1074 var constructor;
1046 var functionsIndex; 1075 var functionsIndex;
1047 // $mixinFormatDescription. 1076 // $mixinFormatDescription.
1048 if (typeof descriptor[2] !== 'function') { 1077 if (typeof descriptor[2] !== 'function') {
1049 fillPrototypeWithMixedIn(descriptor[2], descriptor[3], prototype); 1078 fillPrototypeWithMixedIn(descriptor[2], descriptor[3], prototype);
1050 // descriptor[4] contains the constructor if the mixin application is 1079 // descriptor[4] contains the constructor if the mixin application is
1051 // directly instantiated. 1080 // directly instantiated.
1052 if (typeof descriptor[4] === 'function') { 1081 if (typeof descriptor[4] === 'function') {
1053 constructor = descriptor[4]; 1082 constructor = descriptor[4];
1054 functionsIndex = 5; 1083 functionsIndex = 5;
1055 } else { 1084 } else {
1056 constructor = function() {}; 1085 constructor = function() {};
1057 functionsIndex = 4; 1086 functionsIndex = 4;
1058 } 1087 }
1059 } else { 1088 } else {
1060 constructor = descriptor[2]; 1089 constructor = descriptor[2];
1061 functionsIndex = 3; 1090 functionsIndex = 3;
1062 } 1091 }
1063 1092
1064 for (var i = functionsIndex; i < descriptor.length; i += 2) { 1093 for (var i = functionsIndex; i < descriptor.length; i += 2) {
1065 parseFunctionDescriptor(prototype, descriptor[i], descriptor[i + 1]); 1094 parseFunctionDescriptor(prototype, descriptor[i], descriptor[i + 1],
1095 typesOffset);
1066 } 1096 }
1067 1097
1068 constructor.builtin\$cls = name; // Needed for RTI. 1098 constructor.builtin\$cls = name; // Needed for RTI.
1069 constructor.prototype = prototype; 1099 constructor.prototype = prototype;
1070 prototype[#operatorIsPrefix + name] = constructor; 1100 prototype[#operatorIsPrefix + name] = constructor;
1071 prototype.constructor = constructor; 1101 prototype.constructor = constructor;
1072 return constructor; 1102 return constructor;
1073 } 1103 }
1074 1104
1075 function fillPrototypeWithMixedIn(mixinName, mixinHolderIndex, prototype) { 1105 function fillPrototypeWithMixedIn(mixinName, mixinHolderIndex, prototype) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 if (#needsNativeSupport) { 1149 if (#needsNativeSupport) {
1120 function handleNativeClassInfos() { 1150 function handleNativeClassInfos() {
1121 for (var nativeClass in nativeInfos) { 1151 for (var nativeClass in nativeInfos) {
1122 var constructor = holdersMap[nativeClass][nativeClass].ensureResolved(); 1152 var constructor = holdersMap[nativeClass][nativeClass].ensureResolved();
1123 var nativeInfo = nativeInfos[nativeClass]; 1153 var nativeInfo = nativeInfos[nativeClass];
1124 #nativeInfoHandler; 1154 #nativeInfoHandler;
1125 } 1155 }
1126 } 1156 }
1127 } 1157 }
1128 1158
1129 $setupProgramName(program); 1159 $setupProgramName(program, 0);
1130 1160
1131 // Initialize globals. 1161 // Initialize globals.
1132 #embeddedGlobals; 1162 #embeddedGlobals;
1133 1163
1134 // TODO(floitsch): this order means that native classes may not be 1164 // TODO(floitsch): this order means that native classes may not be
1135 // referenced from constants. I'm mostly afraid of things like using them as 1165 // referenced from constants. I'm mostly afraid of things like using them as
1136 // generic arguments (which should be fine, but maybe there are other 1166 // generic arguments (which should be fine, but maybe there are other
1137 // similar things). 1167 // similar things).
1138 // Initialize natives. 1168 // Initialize natives.
1139 if (#needsNativeSupport) handleNativeClassInfos(); 1169 if (#needsNativeSupport) handleNativeClassInfos();
1140 1170
1141 // Initialize static non-final fields. 1171 // Initialize static non-final fields.
1142 #staticNonFinals; 1172 #staticNonFinals;
1143 1173
1144 // Add native boilerplate code. 1174 // Add native boilerplate code.
1145 #nativeIsolateAffinityTagInitialization; 1175 #nativeIsolateAffinityTagInitialization;
1146 1176
1147 // Initialize eager classes. 1177 // Initialize eager classes.
1148 #eagerClasses; 1178 #eagerClasses;
1149 1179
1150 var end = Date.now(); 1180 var end = Date.now();
1151 // print('Setup: ' + (end - start) + ' ms.'); 1181 // print('Setup: ' + (end - start) + ' ms.');
1152 1182
1153 #invokeMain; // Start main. 1183 #invokeMain; // Start main.
1154 1184
1155 }(Date.now(), #code) 1185 }(Date.now(), #code)
1156 }"""; 1186 }""";
1157 1187
1158 } 1188 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698