| 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 /** | 5 /** |
| 6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
| 7 * from the given element. | 7 * from the given element. |
| 8 */ | 8 */ |
| 9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
| 10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 * in classes) are ignored, since they can be treated as non-class elements. | 27 * in classes) are ignored, since they can be treated as non-class elements. |
| 28 * | 28 * |
| 29 * The code for the containing (used) methods must exist in the [:universe:]. | 29 * The code for the containing (used) methods must exist in the [:universe:]. |
| 30 */ | 30 */ |
| 31 class CodeEmitterTask extends CompilerTask { | 31 class CodeEmitterTask extends CompilerTask { |
| 32 bool needsInheritFunction = false; | 32 bool needsInheritFunction = false; |
| 33 bool needsDefineClass = false; | 33 bool needsDefineClass = false; |
| 34 bool needsClosureClass = false; | 34 bool needsClosureClass = false; |
| 35 bool needsLazyInitializer = false; | 35 bool needsLazyInitializer = false; |
| 36 final Namer namer; | 36 final Namer namer; |
| 37 ConstantEmitter constantEmitter; | |
| 38 NativeEmitter nativeEmitter; | 37 NativeEmitter nativeEmitter; |
| 39 CodeBuffer boundClosureBuffer; | 38 CodeBuffer boundClosureBuffer; |
| 40 CodeBuffer mainBuffer; | 39 CodeBuffer mainBuffer; |
| 41 /** Shorter access to [isolatePropertiesName]. Both here in the code, as | 40 /** Shorter access to [isolatePropertiesName]. Both here in the code, as |
| 42 well as in the generated code. */ | 41 well as in the generated code. */ |
| 43 String isolateProperties; | 42 String isolateProperties; |
| 44 String classesCollector; | 43 String classesCollector; |
| 45 final Map<int, String> boundClosureCache; | 44 final Map<int, String> boundClosureCache; |
| 46 | 45 |
| 47 final bool generateSourceMap; | 46 final bool generateSourceMap; |
| 48 | 47 |
| 49 CodeEmitterTask(Compiler compiler, Namer namer, | 48 CodeEmitterTask(Compiler compiler, this.namer, |
| 50 [bool generateSourceMap = false]) | 49 [bool generateSourceMap = false]) |
| 51 : boundClosureBuffer = new CodeBuffer(), | 50 : boundClosureBuffer = new CodeBuffer(), |
| 52 mainBuffer = new CodeBuffer(), | 51 mainBuffer = new CodeBuffer(), |
| 53 this.namer = namer, | |
| 54 boundClosureCache = new Map<int, String>(), | 52 boundClosureCache = new Map<int, String>(), |
| 55 generateSourceMap = generateSourceMap, | 53 generateSourceMap = generateSourceMap, |
| 56 constantEmitter = new ConstantEmitter(compiler, namer), | |
| 57 super(compiler) { | 54 super(compiler) { |
| 58 nativeEmitter = new NativeEmitter(this); | 55 nativeEmitter = new NativeEmitter(this); |
| 59 } | 56 } |
| 60 | 57 |
| 61 void writeConstantToBuffer(Constant value, CodeBuffer buffer, | |
| 62 [emitCanonicalVersion = true]) { | |
| 63 if (emitCanonicalVersion) { | |
| 64 constantEmitter.emitCanonicalVersionOfConstant(value, buffer); | |
| 65 } else { | |
| 66 constantEmitter.emitJavaScriptCodeForConstant(value, buffer); | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 String get name => 'CodeEmitter'; | 58 String get name => 'CodeEmitter'; |
| 71 | 59 |
| 72 String get defineClassName | 60 String get defineClassName |
| 73 => '${namer.ISOLATE}.\$defineClass'; | 61 => '${namer.ISOLATE}.\$defineClass'; |
| 74 String get finishClassesName | 62 String get finishClassesName |
| 75 => '${namer.ISOLATE}.\$finishClasses'; | 63 => '${namer.ISOLATE}.\$finishClasses'; |
| 76 String get finishIsolateConstructorName | 64 String get finishIsolateConstructorName |
| 77 => '${namer.ISOLATE}.\$finishIsolateConstructor'; | 65 => '${namer.ISOLATE}.\$finishIsolateConstructor'; |
| 78 String get pendingClassesName | 66 String get pendingClassesName |
| 79 => '${namer.ISOLATE}.\$pendingClasses'; | 67 => '${namer.ISOLATE}.\$pendingClasses'; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 int index = names.indexOf(element.name); | 391 int index = names.indexOf(element.name); |
| 404 if (index != -1) { | 392 if (index != -1) { |
| 405 indexOfLastOptionalArgumentInParameters = count; | 393 indexOfLastOptionalArgumentInParameters = count; |
| 406 // The order of the named arguments is not the same as the | 394 // The order of the named arguments is not the same as the |
| 407 // one in the real method (which is in Dart source order). | 395 // one in the real method (which is in Dart source order). |
| 408 argumentsBuffer[count] = jsName; | 396 argumentsBuffer[count] = jsName; |
| 409 parametersBuffer[selector.positionalArgumentCount + index] = jsName; | 397 parametersBuffer[selector.positionalArgumentCount + index] = jsName; |
| 410 // Note that [elements] may be null for a synthetized [member]. | 398 // Note that [elements] may be null for a synthetized [member]. |
| 411 } else if (elements != null && elements.isParameterChecked(element)) { | 399 } else if (elements != null && elements.isParameterChecked(element)) { |
| 412 CodeBuffer argumentBuffer = new CodeBuffer(); | 400 CodeBuffer argumentBuffer = new CodeBuffer(); |
| 413 writeConstantToBuffer(SentinelConstant.SENTINEL, argumentBuffer); | 401 handler.writeConstant(argumentBuffer, SentinelConstant.SENTINEL); |
| 414 argumentsBuffer[count] = argumentBuffer.toString(); | 402 argumentsBuffer[count] = argumentBuffer.toString(); |
| 415 } else { | 403 } else { |
| 416 Constant value = handler.initialVariableValues[element]; | 404 Constant value = handler.initialVariableValues[element]; |
| 417 if (value == null) { | 405 if (value == null) { |
| 418 argumentsBuffer[count] = NullConstant.JsNull; | 406 argumentsBuffer[count] = NullConstant.JsNull; |
| 419 } else { | 407 } else { |
| 420 if (!value.isNull()) { | 408 if (!value.isNull()) { |
| 421 // If the value is the null constant, we should not pass it | 409 // If the value is the null constant, we should not pass it |
| 422 // down to the native method. | 410 // down to the native method. |
| 423 indexOfLastOptionalArgumentInParameters = count; | 411 indexOfLastOptionalArgumentInParameters = count; |
| 424 } | 412 } |
| 425 CodeBuffer argumentBuffer = new CodeBuffer(); | 413 CodeBuffer argumentBuffer = new CodeBuffer(); |
| 426 writeConstantToBuffer(value, argumentBuffer); | 414 handler.writeConstant(argumentBuffer, value); |
| 427 argumentsBuffer[count] = argumentBuffer.toString(); | 415 argumentsBuffer[count] = argumentBuffer.toString(); |
| 428 } | 416 } |
| 429 } | 417 } |
| 430 } | 418 } |
| 431 count++; | 419 count++; |
| 432 }); | 420 }); |
| 433 String parametersString = Strings.join(parametersBuffer, ","); | 421 String parametersString = Strings.join(parametersBuffer, ","); |
| 434 buffer.add('$parametersString) {\n'); | 422 buffer.add('$parametersString) {\n'); |
| 435 | 423 |
| 436 if (member.isNative()) { | 424 if (member.isNative()) { |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 } | 915 } |
| 928 } | 916 } |
| 929 | 917 |
| 930 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 918 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { |
| 931 ConstantHandler handler = compiler.constantHandler; | 919 ConstantHandler handler = compiler.constantHandler; |
| 932 List<VariableElement> staticNonFinalFields = | 920 List<VariableElement> staticNonFinalFields = |
| 933 handler.getStaticNonFinalFieldsForEmission(); | 921 handler.getStaticNonFinalFieldsForEmission(); |
| 934 for (Element element in staticNonFinalFields) { | 922 for (Element element in staticNonFinalFields) { |
| 935 buffer.add('$isolateProperties.${namer.getName(element)} = '); | 923 buffer.add('$isolateProperties.${namer.getName(element)} = '); |
| 936 compiler.withCurrentElement(element, () { | 924 compiler.withCurrentElement(element, () { |
| 937 Constant initialValue = handler.getInitialValueFor(element); | 925 handler.writeJsCodeForVariable(buffer, element); |
| 938 writeConstantToBuffer(initialValue, buffer); | |
| 939 }); | 926 }); |
| 940 buffer.add(';\n'); | 927 buffer.add(';\n'); |
| 941 } | 928 } |
| 942 } | 929 } |
| 943 | 930 |
| 944 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { | 931 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { |
| 945 ConstantHandler handler = compiler.constantHandler; | 932 ConstantHandler handler = compiler.constantHandler; |
| 946 List<VariableElement> lazyFields = | 933 List<VariableElement> lazyFields = |
| 947 handler.getLazilyInitializedFieldsForEmission(); | 934 handler.getLazilyInitializedFieldsForEmission(); |
| 948 if (!lazyFields.isEmpty()) { | 935 if (!lazyFields.isEmpty()) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 969 buffer.add(");\n"); | 956 buffer.add(");\n"); |
| 970 } | 957 } |
| 971 } | 958 } |
| 972 } | 959 } |
| 973 | 960 |
| 974 void emitCompileTimeConstants(CodeBuffer buffer) { | 961 void emitCompileTimeConstants(CodeBuffer buffer) { |
| 975 ConstantHandler handler = compiler.constantHandler; | 962 ConstantHandler handler = compiler.constantHandler; |
| 976 List<Constant> constants = handler.getConstantsForEmission(); | 963 List<Constant> constants = handler.getConstantsForEmission(); |
| 977 bool addedMakeConstantList = false; | 964 bool addedMakeConstantList = false; |
| 978 for (Constant constant in constants) { | 965 for (Constant constant in constants) { |
| 979 // No need to emit functions. We already did that. | 966 String name = handler.getNameForConstant(constant); |
| 980 if (constant.isFunction()) continue; | |
| 981 | |
| 982 String name = namer.constantName(constant); | |
| 983 // The name is null when the constant is already a JS constant. | 967 // The name is null when the constant is already a JS constant. |
| 984 // TODO(floitsch): every constant should be registered, so that we can | 968 // TODO(floitsch): every constant should be registered, so that we can |
| 985 // share the ones that take up too much space (like some strings). | 969 // share the ones that take up too much space (like some strings). |
| 986 if (name === null) continue; | 970 if (name === null) continue; |
| 987 if (!addedMakeConstantList && constant.isList()) { | 971 if (!addedMakeConstantList && constant.isList()) { |
| 988 addedMakeConstantList = true; | 972 addedMakeConstantList = true; |
| 989 emitMakeConstantList(buffer); | 973 emitMakeConstantList(buffer); |
| 990 } | 974 } |
| 991 buffer.add('$isolateProperties.$name = '); | 975 buffer.add('$isolateProperties.$name = '); |
| 992 writeConstantToBuffer(constant, buffer, emitCanonicalVersion: false); | 976 handler.writeJsCode(buffer, constant); |
| 993 buffer.add(';\n'); | 977 buffer.add(';\n'); |
| 994 } | 978 } |
| 995 } | 979 } |
| 996 | 980 |
| 997 void emitMakeConstantList(CodeBuffer buffer) { | 981 void emitMakeConstantList(CodeBuffer buffer) { |
| 998 buffer.add(namer.ISOLATE); | 982 buffer.add(namer.ISOLATE); |
| 999 buffer.add(@'''.makeConstantList = function(list) { | 983 buffer.add(@'''.makeConstantList = function(list) { |
| 1000 list.immutable$list = true; | 984 list.immutable$list = true; |
| 1001 list.fixed$length = true; | 985 list.fixed$length = true; |
| 1002 return list; | 986 return list; |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 sourceName = token.slowToString(); | 1297 sourceName = token.slowToString(); |
| 1314 } | 1298 } |
| 1315 sourceMapBuilder.addMapping( | 1299 sourceMapBuilder.addMapping( |
| 1316 sourceFile, token.charOffset, sourceName, offset); | 1300 sourceFile, token.charOffset, sourceName, offset); |
| 1317 }); | 1301 }); |
| 1318 return sourceMapBuilder.build(compiledFile); | 1302 return sourceMapBuilder.build(compiledFile); |
| 1319 } | 1303 } |
| 1320 } | 1304 } |
| 1321 | 1305 |
| 1322 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); | 1306 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); |
| OLD | NEW |