Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: pkg/fletchc/lib/src/compiled_function.dart

Issue 1170123004: Rename CompiledFunction to FletchFunctionBuilder and CompiledClass to FletchClassBuilder. (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/fletchc/lib/src/compiled_class.dart ('k') | pkg/fletchc/lib/src/constructor_codegen.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file
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.md file.
4
5 library fletchc.compiled_function;
6
7 import 'package:compiler/src/constants/values.dart' show
8 ConstantValue;
9
10 import 'package:compiler/src/constants/expressions.dart' show
11 ConstantExpression;
12
13 import 'package:compiler/src/tree/tree.dart' show
14 Expression;
15
16 import 'package:compiler/src/elements/elements.dart';
17
18 import 'fletch_constants.dart' show
19 FletchFunctionConstant,
20 FletchClassConstant;
21
22 import 'package:compiler/src/universe/universe.dart'
23 show Selector;
24
25 import '../bytecodes.dart' show
26 Bytecode;
27
28 import 'compiled_class.dart' show
29 CompiledClass;
30
31 import 'fletch_context.dart';
32 import 'bytecode_builder.dart';
33 import 'debug_info.dart';
34
35 enum CompiledFunctionKind {
36 NORMAL,
37 LAZY_FIELD_INITIALIZER,
38 INITIALIZER_LIST,
39 PARAMETER_STUB,
40 ACCESSOR
41 }
42
43 class CompiledFunction {
44 final BytecodeBuilder builder;
45 final int methodId;
46
47 /**
48 * The signature of the CompiledFunction.
49 *
50 * Som compiled functions does not have a signature (for example, generated
51 * accessors).
52 */
53 final FunctionSignature signature;
54
55 /**
56 * If the functions is an instance member, [memberOf] is set to the compiled
57 * class.
58 *
59 * If [memberOf] is set, the compiled function takes an 'this' argument in
60 * addition to that of [signature].
61 */
62 final CompiledClass memberOf;
63 final String name;
64 final Element element;
65 final Map<ConstantValue, int> constants = <ConstantValue, int>{};
66 final Map<int, ConstantValue> functionConstantValues = <int, ConstantValue>{};
67 final Map<int, ConstantValue> classConstantValues = <int, ConstantValue>{};
68 final Map<Selector, CompiledFunction> parameterMappings =
69 <Selector, CompiledFunction>{};
70 final int arity;
71 final CompiledFunctionKind kind;
72
73 DebugInfo debugInfo;
74
75 CompiledFunction(this.methodId,
76 this.name,
77 this.element,
78 FunctionSignature signature,
79 CompiledClass memberOf,
80 {this.kind: CompiledFunctionKind.NORMAL})
81 : this.signature = signature,
82 this.memberOf = memberOf,
83 arity = signature.parameterCount + (memberOf != null ? 1 : 0),
84 builder = new BytecodeBuilder(
85 signature.parameterCount + (memberOf != null ? 1 : 0));
86
87 CompiledFunction.normal(this.methodId, int argumentCount)
88 : arity = argumentCount,
89 builder = new BytecodeBuilder(argumentCount),
90 kind = CompiledFunctionKind.NORMAL;
91
92 CompiledFunction.lazyInit(this.methodId,
93 this.name,
94 this.element,
95 int argumentCount)
96 : arity = argumentCount,
97 builder = new BytecodeBuilder(argumentCount),
98 kind = CompiledFunctionKind.LAZY_FIELD_INITIALIZER;
99
100 CompiledFunction.parameterStub(this.methodId, int argumentCount)
101 : arity = argumentCount,
102 builder = new BytecodeBuilder(argumentCount),
103 kind = CompiledFunctionKind.PARAMETER_STUB;
104
105 CompiledFunction.accessor(this.methodId, bool setter)
106 : arity = setter ? 2 : 1,
107 builder = new BytecodeBuilder(setter ? 2 : 1),
108 kind = CompiledFunctionKind.ACCESSOR;
109
110 void reuse() {
111 builder.reuse();
112 constants.clear();
113 functionConstantValues.clear();
114 classConstantValues.clear();
115 }
116
117 bool get hasThisArgument => memberOf != null;
118
119 bool get isLazyFieldInitializer {
120 return kind == CompiledFunctionKind.LAZY_FIELD_INITIALIZER;
121 }
122
123 bool get isInitializerList {
124 return kind == CompiledFunctionKind.INITIALIZER_LIST;
125 }
126
127 bool get isAccessor {
128 return kind == CompiledFunctionKind.ACCESSOR;
129 }
130
131 bool get isParameterStub {
132 return kind == CompiledFunctionKind.PARAMETER_STUB;
133 }
134
135 bool get isConstructor => element != null && element.isConstructor;
136
137 int allocateConstant(ConstantValue constant) {
138 if (constant == null) throw "bad constant";
139 return constants.putIfAbsent(constant, () => constants.length);
140 }
141
142 int allocateConstantFromFunction(int methodId) {
143 FletchFunctionConstant constant =
144 functionConstantValues.putIfAbsent(
145 methodId, () => new FletchFunctionConstant(methodId));
146 return allocateConstant(constant);
147 }
148
149 int allocateConstantFromClass(int classId) {
150 FletchClassConstant constant =
151 classConstantValues.putIfAbsent(
152 classId, () => new FletchClassConstant(classId));
153 return allocateConstant(constant);
154 }
155
156 // TODO(ajohnsen): Remove this function when usage is avoided in
157 // FletchBackend.
158 void copyFrom(CompiledFunction function) {
159 builder.bytecodes.addAll(function.builder.bytecodes);
160 builder.catchRanges.addAll(function.builder.catchRanges);
161 constants.addAll(function.constants);
162 functionConstantValues.addAll(function.functionConstantValues);
163 classConstantValues.addAll(function.classConstantValues);
164 }
165
166 bool matchesSelector(Selector selector) {
167 if (!canBeCalledAs(selector)) return false;
168 if (selector.namedArguments.length != signature.optionalParameterCount) {
169 return false;
170 }
171 int index = 0;
172 bool match = true;
173 for (var parameter in signature.orderedOptionalParameters) {
174 if (parameter.name != selector.namedArguments[index++]) match = false;
175 }
176 return match;
177 }
178
179 // TODO(ajohnsen): Remove and use the one one Selector, when it takes a
180 // FunctionSignature directly.
181 // This is raw copy of Selector.signaturesApplies.
182 bool canBeCalledAs(Selector selector) {
183 if (selector.argumentCount > signature.parameterCount) return false;
184 int requiredParameterCount = signature.requiredParameterCount;
185 int optionalParameterCount = signature.optionalParameterCount;
186 if (selector.positionalArgumentCount < requiredParameterCount) return false;
187
188 if (!signature.optionalParametersAreNamed) {
189 // We have already checked that the number of arguments are
190 // not greater than the number of signature. Therefore the
191 // number of positional arguments are not greater than the
192 // number of signature.
193 assert(selector.positionalArgumentCount <= signature.parameterCount);
194 return selector.namedArguments.isEmpty;
195 } else {
196 if (selector.positionalArgumentCount > requiredParameterCount) {
197 return false;
198 }
199 assert(selector.positionalArgumentCount == requiredParameterCount);
200 if (selector.namedArgumentCount > optionalParameterCount) return false;
201 Set<String> nameSet = new Set<String>();
202 signature.optionalParameters.forEach((Element element) {
203 nameSet.add(element.name);
204 });
205 for (String name in selector.namedArguments) {
206 if (!nameSet.contains(name)) return false;
207 // TODO(5213): By removing from the set we are checking
208 // that we are not passing the name twice. We should have this
209 // check in the resolver also.
210 nameSet.remove(name);
211 }
212 return true;
213 }
214 }
215
216 CompiledFunction createParameterMappingFor(
217 Selector selector,
218 FletchContext context) {
219 return parameterMappings.putIfAbsent(selector, () {
220 assert(canBeCalledAs(selector));
221 int arity = selector.argumentCount;
222 if (hasThisArgument) arity++;
223
224 CompiledFunction compiledFunction = new CompiledFunction.parameterStub(
225 context.backend.functions.length,
226 arity);
227 context.backend.functions.add(compiledFunction);
228
229 BytecodeBuilder builder = compiledFunction.builder;
230
231 void loadInitializerOrNull(ParameterElement parameter) {
232 Expression initializer = parameter.initializer;
233 if (initializer != null) {
234 ConstantExpression expression = context.compileConstant(
235 initializer,
236 parameter.memberContext.resolvedAst.elements,
237 isConst: true);
238 int constId = compiledFunction.allocateConstant(
239 context.getConstantValue(expression));
240 builder.loadConst(constId);
241 } else {
242 builder.loadLiteralNull();
243 }
244 }
245
246 // Load this.
247 if (hasThisArgument) builder.loadParameter(0);
248
249 int index = hasThisArgument ? 1 : 0;
250 signature.orderedForEachParameter((ParameterElement parameter) {
251 if (!parameter.isOptional) {
252 builder.loadParameter(index);
253 } else if (parameter.isNamed) {
254 int parameterIndex = selector.namedArguments.indexOf(parameter.name);
255 if (parameterIndex >= 0) {
256 if (hasThisArgument) parameterIndex++;
257 int position = selector.positionalArgumentCount + parameterIndex;
258 builder.loadParameter(position);
259 } else {
260 loadInitializerOrNull(parameter);
261 }
262 } else {
263 if (index < arity) {
264 builder.loadParameter(index);
265 } else {
266 loadInitializerOrNull(parameter);
267 }
268 }
269 index++;
270 });
271
272 // TODO(ajohnsen): We have to be extra careful when overriding a
273 // method that takes optional arguments. We really should
274 // enumerate all the stubs in the superclasses and make sure
275 // they're overridden.
276 int constId = compiledFunction.allocateConstantFromFunction(methodId);
277 builder
278 ..invokeStatic(constId, index)
279 ..ret()
280 ..methodEnd();
281
282 if (memberOf != null) {
283 int fletchSelector = context.toFletchSelector(selector);
284 memberOf.addToMethodTable(fletchSelector, compiledFunction);
285 }
286
287 return compiledFunction;
288 });
289 }
290
291 String verboseToString() {
292 StringBuffer sb = new StringBuffer();
293
294 sb.writeln("Method $methodId, Arity=${builder.functionArity}");
295 sb.writeln("Constants:");
296 constants.forEach((constant, int index) {
297 if (constant is ConstantValue) {
298 constant = constant.toStructuredString();
299 }
300 sb.writeln(" #$index: $constant");
301 });
302
303 sb.writeln("Bytecodes:");
304 int offset = 0;
305 for (Bytecode bytecode in builder.bytecodes) {
306 sb.writeln(" $offset: $bytecode");
307 offset += bytecode.size;
308 }
309
310 return '$sb';
311 }
312 }
OLDNEW
« no previous file with comments | « pkg/fletchc/lib/src/compiled_class.dart ('k') | pkg/fletchc/lib/src/constructor_codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698