Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 * Generates the code for all used classes in the program. Static fields (even | 6 * Generates the code for all used classes in the program. Static fields (even |
| 7 * in classes) are ignored, since they can be treated as non-class elements. | 7 * in classes) are ignored, since they can be treated as non-class elements. |
| 8 * | 8 * |
| 9 * The code for the containing (used) methods must exist in the [:universe:]. | 9 * The code for the containing (used) methods must exist in the [:universe:]. |
| 10 */ | 10 */ |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 addedInheritFunction = true; | 34 addedInheritFunction = true; |
| 35 buffer.add('$inheritsName = '); | 35 buffer.add('$inheritsName = '); |
| 36 buffer.add(INHERIT_FUNCTION); | 36 buffer.add(INHERIT_FUNCTION); |
| 37 buffer.add(';\n'); | 37 buffer.add(';\n'); |
| 38 } | 38 } |
| 39 | 39 |
| 40 void addParameterStub(FunctionElement member, | 40 void addParameterStub(FunctionElement member, |
| 41 String prototype, | 41 String prototype, |
| 42 StringBuffer buffer, | 42 StringBuffer buffer, |
| 43 Invocation invocation) { | 43 Invocation invocation) { |
| 44 // TODO(ngeoffray): also support invocation with names. | 44 FunctionParameters parameters = member.computeParameters(compiler); |
| 45 int positionalArgumentCount = invocation.positionalArgumentCount; | |
| 46 if (positionalArgumentCount == parameters.parameterCount) return; | |
|
floitsch
2012/02/01 12:19:17
assert that invocation.namedArgumentCount == 0 bef
ngeoffray
2012/02/01 13:02:40
Done.
| |
| 47 List<SourceString> names = invocation.orderedNamedArguments; | |
| 48 assert(names.length == invocation.namedArguments.length); | |
| 49 | |
| 45 String invocationName = | 50 String invocationName = |
| 46 namer.instanceMethodName(member.name, invocation.argumentCount); | 51 namer.instanceMethodInvocationName(member.name, invocation); |
| 47 int allParameters = member.parameterCount(compiler); | |
| 48 int missingParameters = allParameters - invocation.argumentCount; | |
| 49 if (missingParameters == 0) return; | |
| 50 assert(missingParameters > 0); | |
| 51 buffer.add('$prototype.$invocationName = function('); | 52 buffer.add('$prototype.$invocationName = function('); |
| 52 StringBuffer parameters = new StringBuffer(); | 53 |
| 53 for (int i = 0; i < invocation.argumentCount; i++) { | 54 // The parameters that this stub takes. |
| 54 if (i != 0) parameters.add(', '); | 55 StringBuffer parametersBuffer = new StringBuffer(); |
| 55 parameters.add('param$i'); | 56 // The missing and named arguments that will be passed to the real |
| 57 // method. | |
| 58 StringBuffer missingAndNamedArgumentsBuffer = new StringBuffer(); | |
| 59 // The positional arguments that will be passed to the real | |
| 60 // method. | |
| 61 StringBuffer positionalArgumentsBuffer = new StringBuffer(); | |
| 62 | |
| 63 // We fullfil the string buffers depending on the selector. For | |
|
floitsch
2012/02/01 12:19:17
s/fullfil/fill?
ngeoffray
2012/02/01 13:02:40
Done.
| |
| 64 // example, take method foo: | |
| 65 // foo(a, b, [c, d]); | |
| 66 // | |
| 67 // We may have multiple ways of calling foo: | |
| 68 // (1) foo(1, 2, 3, 4) | |
| 69 // (2) foo(1, 2); | |
| 70 // (3) foo(1, 2, c: 3); | |
| 71 // (4) foo(1, 2, d: 4); | |
| 72 // (5) foo(1, 2, c: 3, d: 4); | |
| 73 // (6) foo(1, 2, d: 4, c: 3); | |
| 74 // | |
| 75 // What we generate at the call sites are: | |
| 76 // (1) foo$4(1, 2, 3, 4) | |
| 77 // (2) foo$2(1, 2); | |
| 78 // (3) foo$3$c(1, 2, c: 3); | |
|
floitsch
2012/02/01 12:19:17
remove c:
ngeoffray
2012/02/01 13:02:40
Done.
| |
| 79 // (4) foo$3$d(1, 2, d: 4); | |
| 80 // (5) foo$4$c$d(1, 2, c: 3, d: 4); | |
| 81 // (6) foo$4$c$d(1, 2, d: 4, c: 3); | |
|
floitsch
2012/02/01 12:19:17
remove d: and c: and reorder 4 and 3.
ngeoffray
2012/02/01 13:02:40
Done.
| |
| 82 // | |
| 83 // The stubs we generate are (expressed in Dart): | |
| 84 // (1) No stub generated, call is direct. | |
| 85 // (2) foo$2(a, b) => foo$4(a, b, null, null) | |
| 86 // (3) foo$3$c(a, b, c) => foo$4(a, b, c, null); | |
| 87 // (4) foo$3$d(a, b, d) => foo$4(a, b, null, d); | |
| 88 // (5) foo$4$c$d(a, b, c, d) => foo$4(a, b, c, d); | |
| 89 // (6) Same as (5). | |
| 90 // | |
| 91 // We need to generate a stub for (5) because the order of the | |
| 92 // stub arguments and the real method may be different. | |
| 93 | |
| 94 int count = 0; | |
| 95 parameters.forEachParameter((Element element) { | |
| 96 if (count < positionalArgumentCount) { | |
| 97 if (count != 0) parametersBuffer.add(', '); | |
|
floitsch
2012/02/01 12:19:17
Given these annoyances with the string-buffer, may
ngeoffray
2012/02/01 13:02:40
Done.
| |
| 98 parametersBuffer.add('${element.name}'); | |
|
floitsch
2012/02/01 12:19:17
parameter names might need to be mangled (eg. 'wit
ngeoffray
2012/02/01 13:02:40
Done.
| |
| 99 positionalArgumentsBuffer.add('${element.name}'); | |
| 100 } else { | |
| 101 if (count != positionalArgumentCount || positionalArgumentCount != 0) { | |
| 102 missingAndNamedArgumentsBuffer.add(', '); | |
| 103 } | |
| 104 int index = names.indexOf(element.name); | |
| 105 if (index != -1) { | |
| 106 // The order of the named arguments is not the same as the | |
| 107 // one in the real method (which is in Dart source order). | |
| 108 // Therefore, we don't add the argument to the | |
| 109 // [parametersBuffer] just yet. | |
| 110 missingAndNamedArgumentsBuffer.add('${element.name}'); | |
| 111 } else { | |
| 112 // TODO(ngeoffray): Get the default value. | |
| 113 missingAndNamedArgumentsBuffer.add('(void 0)'); | |
| 114 } | |
| 115 } | |
| 116 count++; | |
| 117 }); | |
| 118 | |
| 119 // Add the named arguments to the parametersBuffer. | |
| 120 for (SourceString name in names) { | |
| 121 if (positionalArgumentCount != 0) parametersBuffer.add(', '); | |
|
floitsch
2012/02/01 12:19:17
Only the first name in names should not have a ','
ngeoffray
2012/02/01 13:02:40
Gone with Strings.join.
| |
| 122 parametersBuffer.add(name); | |
| 56 } | 123 } |
| 57 buffer.add('$parameters) {\n'); | 124 |
| 58 buffer.add(' this.${namer.getName(member)}($parameters'); | 125 buffer.add('$parametersBuffer) {\n'); |
| 59 for (int i = 0; i < missingParameters; i++) { | 126 buffer.add(' return this.${namer.getName(member)}'); |
| 60 if (i != 0 || invocation.argumentCount != 0) buffer.add(', '); | 127 buffer.add('($positionalArgumentsBuffer$missingAndNamedArgumentsBuffer)'); |
| 61 buffer.add('(void 0)'); | 128 buffer.add('\n}\n'); |
| 62 } | |
| 63 buffer.add(')\n}\n'); | |
| 64 } | 129 } |
| 65 | 130 |
| 66 void addParameterStubs(FunctionElement member, | 131 void addParameterStubs(FunctionElement member, |
| 67 String prototype, | 132 String prototype, |
| 68 StringBuffer buffer) { | 133 StringBuffer buffer) { |
| 69 Set<Invocation> invocations = compiler.universe.invokedNames[member.name]; | 134 Set<Invocation> invocations = compiler.universe.invokedNames[member.name]; |
| 70 if (invocations == null) return; | 135 if (invocations == null) return; |
| 71 for (Invocation invocation in invocations) { | 136 for (Invocation invocation in invocations) { |
| 72 if (!invocation.applies(compiler, member)) continue; | 137 if (!invocation.applies(compiler, member)) continue; |
| 73 addParameterStub(member, prototype, buffer, invocation); | 138 addParameterStub(member, prototype, buffer, invocation); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 emitStaticFunctions(buffer); | 353 emitStaticFunctions(buffer); |
| 289 emitStaticFinalFieldInitializations(buffer); | 354 emitStaticFinalFieldInitializations(buffer); |
| 290 buffer.add('var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); | 355 buffer.add('var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); |
| 291 Element main = compiler.universe.find(Compiler.MAIN); | 356 Element main = compiler.universe.find(Compiler.MAIN); |
| 292 buffer.add('${namer.isolateAccess(main)}();\n'); | 357 buffer.add('${namer.isolateAccess(main)}();\n'); |
| 293 compiler.assembledCode = buffer.toString(); | 358 compiler.assembledCode = buffer.toString(); |
| 294 }); | 359 }); |
| 295 return compiler.assembledCode; | 360 return compiler.assembledCode; |
| 296 } | 361 } |
| 297 } | 362 } |
| OLD | NEW |