| 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 |