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

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 18052004: Implement JsMethodMirror.parameters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review comments. Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
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 part of js_backend; 5 part of js_backend;
6 6
7 /** 7 /**
8 * A function element that represents a closure call. The signature is copied 8 * A function element that represents a closure call. The signature is copied
9 * from the given element. 9 * from the given element.
10 */ 10 */
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 String classesCollector; 78 String classesCollector;
79 final Set<ClassElement> neededClasses = new Set<ClassElement>(); 79 final Set<ClassElement> neededClasses = new Set<ClassElement>();
80 final List<ClassElement> regularClasses = <ClassElement>[]; 80 final List<ClassElement> regularClasses = <ClassElement>[];
81 final List<ClassElement> deferredClasses = <ClassElement>[]; 81 final List<ClassElement> deferredClasses = <ClassElement>[];
82 final List<ClassElement> nativeClasses = <ClassElement>[]; 82 final List<ClassElement> nativeClasses = <ClassElement>[];
83 final List<Selector> trivialNsmHandlers = <Selector>[]; 83 final List<Selector> trivialNsmHandlers = <Selector>[];
84 final Map<String, String> mangledFieldNames = <String, String>{}; 84 final Map<String, String> mangledFieldNames = <String, String>{};
85 final Set<String> recordedMangledNames = new Set<String>(); 85 final Set<String> recordedMangledNames = new Set<String>();
86 final Set<String> interceptorInvocationNames = new Set<String>(); 86 final Set<String> interceptorInvocationNames = new Set<String>();
87 87
88 /// A list of JS expressions that represent metadata, parameter names and
89 /// type, and return types.
90 final List<String> globalMetadata = [];
ngeoffray 2013/07/12 09:16:55 <String>[]
91
92 /// A map used to canonicalize the entries of globalMetadata.
93 final Map<String, int> globalMetadataMap = <String, int>{};
94
88 // TODO(ngeoffray): remove this field. 95 // TODO(ngeoffray): remove this field.
89 Set<ClassElement> instantiatedClasses; 96 Set<ClassElement> instantiatedClasses;
90 97
91 final List<jsAst.Expression> boundClosures = <jsAst.Expression>[]; 98 final List<jsAst.Expression> boundClosures = <jsAst.Expression>[];
92 99
93 JavaScriptBackend get backend => compiler.backend; 100 JavaScriptBackend get backend => compiler.backend;
94 101
95 String get _ => compiler.enableMinification ? "" : " "; 102 String get _ => compiler.enableMinification ? "" : " ";
96 String get n => compiler.enableMinification ? "" : "\n"; 103 String get n => compiler.enableMinification ? "" : "\n";
97 String get N => compiler.enableMinification ? "\n" : ";\n"; 104 String get N => compiler.enableMinification ? "\n" : ";\n";
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 if (member.isFunction() 1207 if (member.isFunction()
1201 || member.isGenerativeConstructorBody() 1208 || member.isGenerativeConstructorBody()
1202 || member.isAccessor()) { 1209 || member.isAccessor()) {
1203 if (member.isAbstract(compiler)) return; 1210 if (member.isAbstract(compiler)) return;
1204 jsAst.Expression code = backend.generatedCode[member]; 1211 jsAst.Expression code = backend.generatedCode[member];
1205 if (code == null) return; 1212 if (code == null) return;
1206 String name = namer.getName(member); 1213 String name = namer.getName(member);
1207 if (backend.isInterceptedMethod(member)) { 1214 if (backend.isInterceptedMethod(member)) {
1208 interceptorInvocationNames.add(name); 1215 interceptorInvocationNames.add(name);
1209 } 1216 }
1217 code = extendWithMetadata(member, code);
1210 builder.addProperty(name, code); 1218 builder.addProperty(name, code);
1211 var metadata = buildMetadataFunction(member);
1212 if (metadata != null) {
1213 builder.addProperty('@$name', metadata);
1214 }
1215 String reflectionName = getReflectionName(member, name); 1219 String reflectionName = getReflectionName(member, name);
1216 if (reflectionName != null) { 1220 if (reflectionName != null) {
1217 builder.addProperty('+$reflectionName', js('0')); 1221 builder.addProperty('+$reflectionName', js('0'));
1218 } 1222 }
1219 code = backend.generatedBailoutCode[member]; 1223 code = backend.generatedBailoutCode[member];
1220 if (code != null) { 1224 if (code != null) {
1221 builder.addProperty(namer.getBailoutName(member), code); 1225 builder.addProperty(namer.getBailoutName(member), code);
1222 } 1226 }
1223 FunctionElement function = member; 1227 FunctionElement function = member;
1224 FunctionSignature parameters = function.computeSignature(compiler); 1228 FunctionSignature parameters = function.computeSignature(compiler);
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
2049 backend.generatedCode.keys.where(isStaticFunction); 2053 backend.generatedCode.keys.where(isStaticFunction);
2050 Set<Element> pendingElementsWithBailouts = 2054 Set<Element> pendingElementsWithBailouts =
2051 backend.generatedBailoutCode.keys 2055 backend.generatedBailoutCode.keys
2052 .where(isStaticFunction) 2056 .where(isStaticFunction)
2053 .toSet(); 2057 .toSet();
2054 2058
2055 for (Element element in Elements.sortedByPosition(elements)) { 2059 for (Element element in Elements.sortedByPosition(elements)) {
2056 CodeBuffer buffer = bufferForElement(element, eagerBuffer); 2060 CodeBuffer buffer = bufferForElement(element, eagerBuffer);
2057 jsAst.Expression code = backend.generatedCode[element]; 2061 jsAst.Expression code = backend.generatedCode[element];
2058 String name = namer.getName(element); 2062 String name = namer.getName(element);
2063 code = extendWithMetadata(element, code);
2059 emitStaticFunction(buffer, name, code); 2064 emitStaticFunction(buffer, name, code);
2060 var metadata = buildMetadataFunction(element);
2061 if (metadata != null) {
2062 buffer.write(',$n$n"@$name":$_');
2063 buffer.write(jsAst.prettyPrint(metadata, compiler));
2064 }
2065 String reflectionName = getReflectionName(element, name); 2065 String reflectionName = getReflectionName(element, name);
2066 if (reflectionName != null) { 2066 if (reflectionName != null) {
2067 buffer.write(',$n$n"+$reflectionName":${_}0'); 2067 buffer.write(',$n$n"+$reflectionName":${_}0');
2068 } 2068 }
2069 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; 2069 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
2070 if (bailoutCode != null) { 2070 if (bailoutCode != null) {
2071 pendingElementsWithBailouts.remove(element); 2071 pendingElementsWithBailouts.remove(element);
2072 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); 2072 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
2073 } 2073 }
2074 } 2074 }
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after
3255 metadata.add(constantReference(value)); 3255 metadata.add(constantReference(value));
3256 } 3256 }
3257 } 3257 }
3258 } 3258 }
3259 if (metadata.isEmpty) return null; 3259 if (metadata.isEmpty) return null;
3260 return js.fun( 3260 return js.fun(
3261 [], [js.return_(new jsAst.ArrayInitializer.from(metadata))]); 3261 [], [js.return_(new jsAst.ArrayInitializer.from(metadata))]);
3262 }); 3262 });
3263 } 3263 }
3264 3264
3265 int reifyMetadata(MetadataAnnotation annotation) {
3266 Constant value = annotation.value;
3267 if (value == null) {
3268 compiler.reportInternalError(
3269 annotation, 'Internal error: value is null');
3270 return -1;
3271 }
3272 return addGlobalMetadata(
3273 jsAst.prettyPrint(constantReference(value), compiler).getText());
3274 }
3275
3276 int reifyType(DartType type) {
3277 // TODO(ahe): Handle type variables correctly instead of using "#".
3278 String representation = backend.rti.getTypeRepresentation(type, (_) {});
3279 return addGlobalMetadata(representation.replaceAll('#', 'null'));
3280 }
3281
3282 int reifyName(SourceString name) {
3283 return addGlobalMetadata('"${name.slowToString()}"');
3284 }
3285
3286 int addGlobalMetadata(String string) {
3287 return globalMetadataMap.putIfAbsent(string, () {
3288 globalMetadata.add(string);
3289 return globalMetadata.length - 1;
3290 });
3291 }
3292
3293 jsAst.Fun extendWithMetadata(FunctionElement element, jsAst.Fun code) {
3294 if (!backend.retainMetadataOf(element)) return code;
3295 return compiler.withCurrentElement(element, () {
3296 List<int> metadata = <int>[];
3297 FunctionSignature signature = element.functionSignature;
3298 if (element.isConstructor()) {
3299 metadata.add(reifyType(element.getEnclosingClass().thisType));
3300 } else {
3301 metadata.add(reifyType(signature.returnType));
3302 }
3303 signature.forEachParameter((Element parameter) {
3304 metadata
3305 ..add(reifyName(parameter.name))
3306 ..add(reifyType(parameter.computeType(compiler)));
3307 });
3308 Link link = element.metadata;
3309 // TODO(ahe): Why is metadata sometimes null?
3310 if (link != null) {
3311 for (; !link.isEmpty; link = link.tail) {
3312 metadata.add(reifyMetadata(link.head));
3313 }
3314 }
3315 code.body.statements.add(js.string(metadata.join(',')).toStatement());
3316 return code;
3317 });
3318 }
3319
3320 void emitMetadata(CodeBuffer buffer) {
3321 buffer.write('init.metadata$_=$_[');
3322 for (var metadata in globalMetadata) {
3323 if (metadata is String) {
3324 if (metadata != 'null') {
3325 buffer.write(metadata);
3326 }
3327 } else {
3328 throw 'Unexpected value in metadata: ${Error.safeToString(metadata)}';
3329 }
3330 buffer.write(',$n');
3331 }
3332 buffer.write('];$n');
3333 }
3334
3265 String assembleProgram() { 3335 String assembleProgram() {
3266 measure(() { 3336 measure(() {
3267 // Compute the required type checks to know which classes need a 3337 // Compute the required type checks to know which classes need a
3268 // 'is$' method. 3338 // 'is$' method.
3269 computeRequiredTypeChecks(); 3339 computeRequiredTypeChecks();
3270 3340
3271 computeNeededClasses(); 3341 computeNeededClasses();
3272 3342
3273 mainBuffer.add(buildGeneratedBy()); 3343 mainBuffer.add(buildGeneratedBy());
3274 addComment(HOOKS_API_USAGE, mainBuffer); 3344 addComment(HOOKS_API_USAGE, mainBuffer);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
3413 emitCompileTimeConstants(mainBuffer); 3483 emitCompileTimeConstants(mainBuffer);
3414 // Static field initializations require the classes and compile-time 3484 // Static field initializations require the classes and compile-time
3415 // constants to be set up. 3485 // constants to be set up.
3416 emitStaticNonFinalFieldInitializations(mainBuffer); 3486 emitStaticNonFinalFieldInitializations(mainBuffer);
3417 emitOneShotInterceptors(mainBuffer); 3487 emitOneShotInterceptors(mainBuffer);
3418 emitInterceptedNames(mainBuffer); 3488 emitInterceptedNames(mainBuffer);
3419 emitLazilyInitializedStaticFields(mainBuffer); 3489 emitLazilyInitializedStaticFields(mainBuffer);
3420 3490
3421 mainBuffer.add(nativeBuffer); 3491 mainBuffer.add(nativeBuffer);
3422 3492
3493 emitMetadata(mainBuffer);
3423 3494
3424 isolateProperties = isolatePropertiesName; 3495 isolateProperties = isolatePropertiesName;
3425 // The following code should not use the short-hand for the 3496 // The following code should not use the short-hand for the
3426 // initialStatics. 3497 // initialStatics.
3427 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_=${_}null$N'); 3498 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_=${_}null$N');
3428 3499
3429 emitFinishIsolateConstructorInvocation(mainBuffer); 3500 emitFinishIsolateConstructorInvocation(mainBuffer);
3430 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_=' 3501 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_='
3431 '${_}new ${namer.isolateName}()$N'); 3502 '${_}new ${namer.isolateName}()$N');
3432 3503
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
3629 3700
3630 const String HOOKS_API_USAGE = """ 3701 const String HOOKS_API_USAGE = """
3631 // The code supports the following hooks: 3702 // The code supports the following hooks:
3632 // dartPrint(message) - if this function is defined it is called 3703 // dartPrint(message) - if this function is defined it is called
3633 // instead of the Dart [print] method. 3704 // instead of the Dart [print] method.
3634 // dartMainRunner(main) - if this function is defined, the Dart [main] 3705 // dartMainRunner(main) - if this function is defined, the Dart [main]
3635 // method will not be invoked directly. 3706 // method will not be invoked directly.
3636 // Instead, a closure that will invoke [main] is 3707 // Instead, a closure that will invoke [main] is
3637 // passed to [dartMainRunner]. 3708 // passed to [dartMainRunner].
3638 """; 3709 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698