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 |