OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 dart2js.js_emitter.full_emitter; | 5 part of dart2js.js_emitter.full_emitter; |
6 | 6 |
7 // TODO(ahe): Share these with js_helper.dart. | 7 // TODO(ahe): Share these with js_helper.dart. |
8 const FUNCTION_INDEX = 0; | 8 const FUNCTION_INDEX = 0; |
9 const NAME_INDEX = 1; | 9 const NAME_INDEX = 1; |
10 const CALL_NAME_INDEX = 2; | 10 const CALL_NAME_INDEX = 2; |
11 const REQUIRED_PARAMETER_INDEX = 3; | 11 const REQUIRED_PARAMETER_INDEX = 3; |
12 const OPTIONAL_PARAMETER_INDEX = 4; | 12 const OPTIONAL_PARAMETER_INDEX = 4; |
13 const DEFAULT_ARGUMENTS_INDEX = 5; | 13 const DEFAULT_ARGUMENTS_INDEX = 5; |
14 | 14 |
15 const bool VALIDATE_DATA = false; | 15 const bool VALIDATE_DATA = false; |
16 | 16 |
17 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1; | 17 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1; |
18 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1; | 18 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1; |
19 const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST); | 19 const RANGE1_ADJUST = -(FIRST_FIELD_CODE - RANGE1_FIRST); |
20 const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST); | 20 const RANGE2_ADJUST = -(FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST); |
21 const RANGE3_ADJUST = | 21 const RANGE3_ADJUST = |
22 - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST); | 22 -(FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST); |
23 | 23 |
24 const String setupProgramName ='setupProgram'; | 24 const String setupProgramName = 'setupProgram'; |
25 // TODO(floitsch): make sure this property can't clash with anything. It's | 25 // TODO(floitsch): make sure this property can't clash with anything. It's |
26 // unlikely since it lives on types, but still. | 26 // unlikely since it lives on types, but still. |
27 const String typeNameProperty = r'builtin$cls'; | 27 const String typeNameProperty = r'builtin$cls'; |
28 | 28 |
29 jsAst.Statement buildSetupProgram(Program program, Compiler compiler, | 29 jsAst.Statement buildSetupProgram(Program program, Compiler compiler, |
30 JavaScriptBackend backend, | 30 JavaScriptBackend backend, Namer namer, Emitter emitter) { |
31 Namer namer, | |
32 Emitter emitter) { | |
33 | |
34 jsAst.Expression typeInformationAccess = | 31 jsAst.Expression typeInformationAccess = |
35 emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPE_INFORMATION); | 32 emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPE_INFORMATION); |
36 jsAst.Expression globalFunctionsAccess = | 33 jsAst.Expression globalFunctionsAccess = |
37 emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS); | 34 emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS); |
38 jsAst.Expression staticsAccess = | 35 jsAst.Expression staticsAccess = |
39 emitter.generateEmbeddedGlobalAccess(embeddedNames.STATICS); | 36 emitter.generateEmbeddedGlobalAccess(embeddedNames.STATICS); |
40 jsAst.Expression interceptedNamesAccess = | 37 jsAst.Expression interceptedNamesAccess = |
41 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES); | 38 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES); |
42 jsAst.Expression mangledGlobalNamesAccess = | 39 jsAst.Expression mangledGlobalNamesAccess = |
43 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); | 40 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); |
(...skipping 10 matching lines...) Expand all Loading... |
54 jsAst.Expression allClassesAccess = | 51 jsAst.Expression allClassesAccess = |
55 emitter.generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); | 52 emitter.generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); |
56 jsAst.Expression precompiledAccess = | 53 jsAst.Expression precompiledAccess = |
57 emitter.generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED); | 54 emitter.generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED); |
58 jsAst.Expression finishedClassesAccess = | 55 jsAst.Expression finishedClassesAccess = |
59 emitter.generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); | 56 emitter.generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
60 jsAst.Expression interceptorsByTagAccess = | 57 jsAst.Expression interceptorsByTagAccess = |
61 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 58 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
62 jsAst.Expression leafTagsAccess = | 59 jsAst.Expression leafTagsAccess = |
63 emitter.generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | 60 emitter.generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
64 jsAst.Expression initializeEmptyInstanceAccess = | 61 jsAst.Expression initializeEmptyInstanceAccess = emitter |
65 emitter.generateEmbeddedGlobalAccess( | 62 .generateEmbeddedGlobalAccess(embeddedNames.INITIALIZE_EMPTY_INSTANCE); |
66 embeddedNames.INITIALIZE_EMPTY_INSTANCE); | 63 jsAst.Expression classFieldsExtractorAccess = emitter |
67 jsAst.Expression classFieldsExtractorAccess = | 64 .generateEmbeddedGlobalAccess(embeddedNames.CLASS_FIELDS_EXTRACTOR); |
68 emitter.generateEmbeddedGlobalAccess( | 65 jsAst.Expression instanceFromClassIdAccess = emitter |
69 embeddedNames.CLASS_FIELDS_EXTRACTOR); | 66 .generateEmbeddedGlobalAccess(embeddedNames.INSTANCE_FROM_CLASS_ID); |
70 jsAst.Expression instanceFromClassIdAccess = | |
71 emitter.generateEmbeddedGlobalAccess( | |
72 embeddedNames.INSTANCE_FROM_CLASS_ID); | |
73 | 67 |
74 String reflectableField = namer.reflectableField; | 68 String reflectableField = namer.reflectableField; |
75 String reflectionInfoField = namer.reflectionInfoField; | 69 String reflectionInfoField = namer.reflectionInfoField; |
76 String reflectionNameField = namer.reflectionNameField; | 70 String reflectionNameField = namer.reflectionNameField; |
77 String metadataIndexField = namer.metadataIndexField; | 71 String metadataIndexField = namer.metadataIndexField; |
78 String defaultValuesField = namer.defaultValuesField; | 72 String defaultValuesField = namer.defaultValuesField; |
79 String methodsWithOptionalArgumentsField = | 73 String methodsWithOptionalArgumentsField = |
80 namer.methodsWithOptionalArgumentsField; | 74 namer.methodsWithOptionalArgumentsField; |
81 String unmangledNameIndex = backend.mustRetainMetadata | 75 String unmangledNameIndex = backend.mustRetainMetadata |
82 ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3' | 76 ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3' |
83 : ' 2 * optionalParameterCount + requiredParameterCount + 3'; | 77 : ' 2 * optionalParameterCount + requiredParameterCount + 3'; |
84 String receiverParamName = compiler.options.enableMinification | 78 String receiverParamName = |
85 ? "r" : "receiver"; | 79 compiler.options.enableMinification ? "r" : "receiver"; |
86 String valueParamName = compiler.options.enableMinification ? "v" : "value"; | 80 String valueParamName = compiler.options.enableMinification ? "v" : "value"; |
87 String space = compiler.options.enableMinification ? "" : " "; | 81 String space = compiler.options.enableMinification ? "" : " "; |
88 String _ = space; | 82 String _ = space; |
89 | 83 |
90 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" | 84 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" |
91 jsAst.Expression nativeInfoAccess = js('prototype[$specProperty]', []); | 85 jsAst.Expression nativeInfoAccess = js('prototype[$specProperty]', []); |
92 jsAst.Expression constructorAccess = js('constructor', []); | 86 jsAst.Expression constructorAccess = js('constructor', []); |
93 Function subclassReadGenerator = | 87 Function subclassReadGenerator = |
94 (jsAst.Expression subclass) => js('allClasses[#]', subclass); | 88 (jsAst.Expression subclass) => js('allClasses[#]', subclass); |
95 jsAst.Statement nativeInfoHandler = emitter. | 89 jsAst.Statement nativeInfoHandler = emitter.buildNativeInfoHandler( |
96 buildNativeInfoHandler(nativeInfoAccess, constructorAccess, | 90 nativeInfoAccess, |
97 subclassReadGenerator, interceptorsByTagAccess, | 91 constructorAccess, |
98 leafTagsAccess); | 92 subclassReadGenerator, |
| 93 interceptorsByTagAccess, |
| 94 leafTagsAccess); |
99 | 95 |
100 Map<String, dynamic> holes = | 96 Map<String, dynamic> holes = { |
101 {'needsClassSupport': emitter.needsClassSupport, | 97 'needsClassSupport': emitter.needsClassSupport, |
102 'libraries': librariesAccess, | 98 'libraries': librariesAccess, |
103 'mangledNames': mangledNamesAccess, | 99 'mangledNames': mangledNamesAccess, |
104 'mangledGlobalNames': mangledGlobalNamesAccess, | 100 'mangledGlobalNames': mangledGlobalNamesAccess, |
105 'statics': staticsAccess, | 101 'statics': staticsAccess, |
106 'staticsPropertyName': namer.staticsPropertyName, | 102 'staticsPropertyName': namer.staticsPropertyName, |
107 'staticsPropertyNameString': js.quoteName(namer.staticsPropertyName), | 103 'staticsPropertyNameString': js.quoteName(namer.staticsPropertyName), |
108 'typeInformation': typeInformationAccess, | 104 'typeInformation': typeInformationAccess, |
109 'globalFunctions': globalFunctionsAccess, | 105 'globalFunctions': globalFunctionsAccess, |
110 'enabledInvokeOn': compiler.enabledInvokeOn, | 106 'enabledInvokeOn': compiler.enabledInvokeOn, |
111 'interceptedNames': interceptedNamesAccess, | 107 'interceptedNames': interceptedNamesAccess, |
112 'interceptedNamesSet': emitter.generateInterceptedNamesSet(), | 108 'interceptedNamesSet': emitter.generateInterceptedNamesSet(), |
113 'notInCspMode': !compiler.options.useContentSecurityPolicy, | 109 'notInCspMode': !compiler.options.useContentSecurityPolicy, |
114 'inCspMode': compiler.options.useContentSecurityPolicy, | 110 'inCspMode': compiler.options.useContentSecurityPolicy, |
115 'deferredAction': namer.deferredAction, | 111 'deferredAction': namer.deferredAction, |
116 'hasIsolateSupport': program.hasIsolateSupport, | 112 'hasIsolateSupport': program.hasIsolateSupport, |
117 'fieldNamesProperty': js.string(Emitter.FIELD_NAMES_PROPERTY_NAME), | 113 'fieldNamesProperty': js.string(Emitter.FIELD_NAMES_PROPERTY_NAME), |
118 'hasIncrementalSupport': compiler.options.hasIncrementalSupport, | 114 'hasIncrementalSupport': compiler.options.hasIncrementalSupport, |
119 'incrementalHelper': namer.accessIncrementalHelper, | 115 'incrementalHelper': namer.accessIncrementalHelper, |
120 'createNewIsolateFunction': createNewIsolateFunctionAccess, | 116 'createNewIsolateFunction': createNewIsolateFunctionAccess, |
121 'isolateName': namer.isolateName, | 117 'isolateName': namer.isolateName, |
122 'classIdExtractor': classIdExtractorAccess, | 118 'classIdExtractor': classIdExtractorAccess, |
123 'classFieldsExtractor': classFieldsExtractorAccess, | 119 'classFieldsExtractor': classFieldsExtractorAccess, |
124 'instanceFromClassId': instanceFromClassIdAccess, | 120 'instanceFromClassId': instanceFromClassIdAccess, |
125 'initializeEmptyInstance': initializeEmptyInstanceAccess, | 121 'initializeEmptyInstance': initializeEmptyInstanceAccess, |
126 'allClasses': allClassesAccess, | 122 'allClasses': allClassesAccess, |
127 'debugFastObjects': DEBUG_FAST_OBJECTS, | 123 'debugFastObjects': DEBUG_FAST_OBJECTS, |
128 'isTreeShakingDisabled': backend.isTreeShakingDisabled, | 124 'isTreeShakingDisabled': backend.isTreeShakingDisabled, |
129 'precompiled': precompiledAccess, | 125 'precompiled': precompiledAccess, |
130 'finishedClassesAccess': finishedClassesAccess, | 126 'finishedClassesAccess': finishedClassesAccess, |
131 'needsMixinSupport': emitter.needsMixinSupport, | 127 'needsMixinSupport': emitter.needsMixinSupport, |
132 'needsNativeSupport': program.needsNativeSupport, | 128 'needsNativeSupport': program.needsNativeSupport, |
133 'enabledJsInterop': backend.jsInteropAnalysis.enabledJsInterop, | 129 'enabledJsInterop': backend.jsInteropAnalysis.enabledJsInterop, |
134 'jsInteropBoostrap':backend.jsInteropAnalysis.buildJsInteropBootstrap(), | 130 'jsInteropBoostrap': backend.jsInteropAnalysis.buildJsInteropBootstrap(), |
135 'isInterceptorClass': namer.operatorIs(backend.helpers.jsInterceptorClass), | 131 'isInterceptorClass': namer.operatorIs(backend.helpers.jsInterceptorClass), |
136 'isObject' : namer.operatorIs(compiler.coreClasses.objectClass), | 132 'isObject': namer.operatorIs(compiler.coreClasses.objectClass), |
137 'specProperty': js.string(namer.nativeSpecProperty), | 133 'specProperty': js.string(namer.nativeSpecProperty), |
138 'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(), | 134 'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(), |
139 'hasRetainedMetadata': backend.hasRetainedMetadata, | 135 'hasRetainedMetadata': backend.hasRetainedMetadata, |
140 'types': typesAccess, | 136 'types': typesAccess, |
141 'objectClassName': js.quoteName( | 137 'objectClassName': |
142 namer.runtimeTypeName(compiler.coreClasses.objectClass)), | 138 js.quoteName(namer.runtimeTypeName(compiler.coreClasses.objectClass)), |
143 'needsStructuredMemberInfo': emitter.needsStructuredMemberInfo, | 139 'needsStructuredMemberInfo': emitter.needsStructuredMemberInfo, |
144 'usesMangledNames': | 140 'usesMangledNames': |
145 compiler.mirrorsLibrary != null || compiler.enabledFunctionApply, | 141 compiler.mirrorsLibrary != null || compiler.enabledFunctionApply, |
146 'tearOffCode': buildTearOffCode(backend), | 142 'tearOffCode': buildTearOffCode(backend), |
147 'nativeInfoHandler': nativeInfoHandler, | 143 'nativeInfoHandler': nativeInfoHandler, |
148 'operatorIsPrefix' : js.string(namer.operatorIsPrefix), | 144 'operatorIsPrefix': js.string(namer.operatorIsPrefix), |
149 'deferredActionString': js.string(namer.deferredAction)}; | 145 'deferredActionString': js.string(namer.deferredAction) |
150 String skeleton = ''' | 146 }; |
| 147 String skeleton = ''' |
151 function $setupProgramName(programData, typesOffset) { | 148 function $setupProgramName(programData, typesOffset) { |
152 "use strict"; | 149 "use strict"; |
153 if (#needsClassSupport) { | 150 if (#needsClassSupport) { |
154 | 151 |
155 function generateAccessor(fieldDescriptor, accessors, cls) { | 152 function generateAccessor(fieldDescriptor, accessors, cls) { |
156 var fieldInformation = fieldDescriptor.split("-"); | 153 var fieldInformation = fieldDescriptor.split("-"); |
157 var field = fieldInformation[0]; | 154 var field = fieldInformation[0]; |
158 var len = field.length; | 155 var len = field.length; |
159 var code = field.charCodeAt(len - 1); | 156 var code = field.charCodeAt(len - 1); |
160 var reflectable; | 157 var reflectable; |
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 return js.statement(skeleton, holes); | 825 return js.statement(skeleton, holes); |
829 } | 826 } |
830 | 827 |
831 String readString(String array, String index) { | 828 String readString(String array, String index) { |
832 return readChecked( | 829 return readChecked( |
833 array, index, 'result != null && typeof result != "string"', 'string'); | 830 array, index, 'result != null && typeof result != "string"', 'string'); |
834 } | 831 } |
835 | 832 |
836 String readInt(String array, String index) { | 833 String readInt(String array, String index) { |
837 return readChecked( | 834 return readChecked( |
838 array, index, | 835 array, |
| 836 index, |
839 'result != null && (typeof result != "number" || (result|0) !== result)', | 837 'result != null && (typeof result != "number" || (result|0) !== result)', |
840 'int'); | 838 'int'); |
841 } | 839 } |
842 | 840 |
843 String readFunctionType(String array, String index) { | 841 String readFunctionType(String array, String index) { |
844 return readChecked( | 842 return readChecked( |
845 array, index, | 843 array, |
| 844 index, |
846 'result != null && ' | 845 'result != null && ' |
847 '(typeof result != "number" || (result|0) !== result) && ' | 846 '(typeof result != "number" || (result|0) !== result) && ' |
848 'typeof result != "function"', | 847 'typeof result != "function"', |
849 'function or int'); | 848 'function or int'); |
850 } | 849 } |
851 | 850 |
852 String readChecked(String array, String index, String check, String type) { | 851 String readChecked(String array, String index, String check, String type) { |
853 if (!VALIDATE_DATA) return '$array[$index]'; | 852 if (!VALIDATE_DATA) return '$array[$index]'; |
854 return ''' | 853 return ''' |
855 (function() { | 854 (function() { |
856 var result = $array[$index]; | 855 var result = $array[$index]; |
857 if ($check) { | 856 if ($check) { |
858 throw new Error( | 857 throw new Error( |
859 name + ": expected value of type \'$type\' at index " + ($index) + | 858 name + ": expected value of type \'$type\' at index " + ($index) + |
860 " but got " + (typeof result)); | 859 " but got " + (typeof result)); |
861 } | 860 } |
862 return result; | 861 return result; |
863 })()'''; | 862 })()'''; |
864 } | 863 } |
OLD | NEW |