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

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

Issue 24493006: Implement named arguments in InstanceMirror.invoke. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Tweaked test to get a little test coverage Created 7 years, 2 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 /// Enables debugging of fast/slow objects using V8-specific primitives. 7 /// Enables debugging of fast/slow objects using V8-specific primitives.
8 const DEBUG_FAST_OBJECTS = false; 8 const DEBUG_FAST_OBJECTS = false;
9 9
10 /** 10 /**
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 if (backend.isInterceptedMethod(member)) { 1258 if (backend.isInterceptedMethod(member)) {
1259 interceptorInvocationNames.add(name); 1259 interceptorInvocationNames.add(name);
1260 } 1260 }
1261 code = extendWithMetadata(member, code); 1261 code = extendWithMetadata(member, code);
1262 builder.addProperty(name, code); 1262 builder.addProperty(name, code);
1263 String reflectionName = getReflectionName(member, name); 1263 String reflectionName = getReflectionName(member, name);
1264 if (reflectionName != null) { 1264 if (reflectionName != null) {
1265 var reflectable = 1265 var reflectable =
1266 js(backend.isAccessibleByReflection(member) ? '1' : '0'); 1266 js(backend.isAccessibleByReflection(member) ? '1' : '0');
1267 builder.addProperty('+$reflectionName', reflectable); 1267 builder.addProperty('+$reflectionName', reflectable);
1268 jsAst.Node defaultValues = reifyDefaultArguments(member);
1269 if (defaultValues != null) {
1270 String unmangledName = member.name.slowToString();
1271 builder.addProperty('*$unmangledName', defaultValues);
1272 }
1268 } 1273 }
1269 code = backend.generatedBailoutCode[member]; 1274 code = backend.generatedBailoutCode[member];
1270 if (code != null) { 1275 if (code != null) {
1271 builder.addProperty(namer.getBailoutName(member), code); 1276 builder.addProperty(namer.getBailoutName(member), code);
1272 } 1277 }
1273 FunctionElement function = member; 1278 FunctionElement function = member;
1274 FunctionSignature parameters = function.computeSignature(compiler); 1279 FunctionSignature parameters = function.computeSignature(compiler);
1275 if (!parameters.optionalParameters.isEmpty) { 1280 if (!parameters.optionalParameters.isEmpty) {
1276 addParameterStubs(member, builder.addProperty); 1281 addParameterStubs(function, builder.addProperty);
1277 } 1282 }
1278 } else if (!member.isField()) { 1283 } else if (!member.isField()) {
1279 compiler.internalError('unexpected kind: "${member.kind}"', 1284 compiler.internalError('unexpected kind: "${member.kind}"',
1280 element: member); 1285 element: member);
1281 } 1286 }
1282 emitExtraAccessors(member, builder); 1287 emitExtraAccessors(member, builder);
1283 } 1288 }
1284 1289
1285 /// Returns the "reflection name" of an [Element] or [Selector]. 1290 /// Returns the "reflection name" of an [Element] or [Selector].
1286 /// The reflection name of a getter 'foo' is 'foo'. 1291 /// The reflection name of a getter 'foo' is 'foo'.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 } else if (element.isClass()) { 1374 } else if (element.isClass()) {
1370 ClassElement cls = element; 1375 ClassElement cls = element;
1371 if (cls.isUnnamedMixinApplication) return null; 1376 if (cls.isUnnamedMixinApplication) return null;
1372 return cls.name.slowToString(); 1377 return cls.name.slowToString();
1373 } 1378 }
1374 throw compiler.internalErrorOnElement( 1379 throw compiler.internalErrorOnElement(
1375 element, 'Do not know how to reflect on this $element'); 1380 element, 'Do not know how to reflect on this $element');
1376 } 1381 }
1377 1382
1378 String namedParametersAsReflectionNames(Selector selector) { 1383 String namedParametersAsReflectionNames(Selector selector) {
1379 if (selector.orderedNamedArguments.isEmpty) return ''; 1384 if (selector.getOrderedNamedArguments().isEmpty) return '';
1380 String names = 1385 String names = selector.getOrderedNamedArguments().map(
1381 selector.orderedNamedArguments.map((x) => x.slowToString()).join(':'); 1386 (x) => x.slowToString()).join(':');
1382 return ':$names'; 1387 return ':$names';
1383 } 1388 }
1384 1389
1385 /** 1390 /**
1386 * Documentation wanted -- johnniwinther 1391 * Documentation wanted -- johnniwinther
1387 * 1392 *
1388 * Invariant: [classElement] must be a declaration element. 1393 * Invariant: [classElement] must be a declaration element.
1389 */ 1394 */
1390 void emitInstanceMembers(ClassElement classElement, 1395 void emitInstanceMembers(ClassElement classElement,
1391 ClassBuilder builder) { 1396 ClassBuilder builder) {
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 for (Element element in Elements.sortedByPosition(elements)) { 2381 for (Element element in Elements.sortedByPosition(elements)) {
2377 CodeBuffer buffer = bufferForElement(element, eagerBuffer); 2382 CodeBuffer buffer = bufferForElement(element, eagerBuffer);
2378 jsAst.Expression code = backend.generatedCode[element]; 2383 jsAst.Expression code = backend.generatedCode[element];
2379 String name = namer.getNameOfGlobalFunction(element); 2384 String name = namer.getNameOfGlobalFunction(element);
2380 code = extendWithMetadata(element, code); 2385 code = extendWithMetadata(element, code);
2381 emitStaticFunction(buffer, name, code); 2386 emitStaticFunction(buffer, name, code);
2382 String reflectionName = getReflectionName(element, name); 2387 String reflectionName = getReflectionName(element, name);
2383 if (reflectionName != null) { 2388 if (reflectionName != null) {
2384 var reflectable = backend.isAccessibleByReflection(element) ? 1 : 0; 2389 var reflectable = backend.isAccessibleByReflection(element) ? 1 : 0;
2385 buffer.write(',$n$n"+$reflectionName":${_}$reflectable'); 2390 buffer.write(',$n$n"+$reflectionName":${_}$reflectable');
2391 jsAst.Node defaultValues = reifyDefaultArguments(element);
2392 if (defaultValues != null) {
2393 String unmangledName = element.name.slowToString();
2394 buffer.write(',$n$n"*$unmangledName":${_}');
2395 buffer.write(jsAst.prettyPrint(defaultValues, compiler));
2396 }
2386 } 2397 }
2387 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; 2398 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
2388 if (bailoutCode != null) { 2399 if (bailoutCode != null) {
2389 pendingElementsWithBailouts.remove(element); 2400 pendingElementsWithBailouts.remove(element);
2390 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); 2401 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
2391 } 2402 }
2392 } 2403 }
2393 2404
2394 if (!pendingElementsWithBailouts.isEmpty) { 2405 if (!pendingElementsWithBailouts.isEmpty) {
2395 addComment('pendingElementsWithBailouts', eagerBuffer); 2406 addComment('pendingElementsWithBailouts', eagerBuffer);
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after
3688 metadata.add(constantReference(value)); 3699 metadata.add(constantReference(value));
3689 } 3700 }
3690 } 3701 }
3691 } 3702 }
3692 if (metadata.isEmpty) return null; 3703 if (metadata.isEmpty) return null;
3693 return js.fun( 3704 return js.fun(
3694 [], [js.return_(new jsAst.ArrayInitializer.from(metadata))]); 3705 [], [js.return_(new jsAst.ArrayInitializer.from(metadata))]);
3695 }); 3706 });
3696 } 3707 }
3697 3708
3709 jsAst.Node reifyDefaultArguments(FunctionElement function) {
3710 FunctionSignature signature = function.computeSignature(compiler);
3711 if (signature.optionalParameterCount == 0) return null;
3712 List<int> defaultValues = <int>[];
3713 for (Element element in signature.orderedOptionalParameters) {
3714 Constant value =
3715 compiler.constantHandler.initialVariableValues[element];
3716 String stringRepresentation = (value == null) ? "null"
3717 : jsAst.prettyPrint(constantReference(value), compiler).getText();
3718 defaultValues.add(addGlobalMetadata(stringRepresentation));
3719 }
3720 return js.toExpression(defaultValues);
3721 }
3722
3698 int reifyMetadata(MetadataAnnotation annotation) { 3723 int reifyMetadata(MetadataAnnotation annotation) {
3699 Constant value = annotation.value; 3724 Constant value = annotation.value;
3700 if (value == null) { 3725 if (value == null) {
3701 compiler.reportInternalError( 3726 compiler.reportInternalError(
3702 annotation, 'Internal error: value is null'); 3727 annotation, 'Internal error: value is null');
3703 return -1; 3728 return -1;
3704 } 3729 }
3705 return addGlobalMetadata( 3730 return addGlobalMetadata(
3706 jsAst.prettyPrint(constantReference(value), compiler).getText()); 3731 jsAst.prettyPrint(constantReference(value), compiler).getText());
3707 } 3732 }
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
4260 void warnNotImplemented(Element element, String message) { 4285 void warnNotImplemented(Element element, String message) {
4261 compiler.reportMessage(compiler.spanFromSpannable(element), 4286 compiler.reportMessage(compiler.spanFromSpannable(element),
4262 MessageKind.GENERIC.error({'text': message}), 4287 MessageKind.GENERIC.error({'text': message}),
4263 api.Diagnostic.WARNING); 4288 api.Diagnostic.WARNING);
4264 } 4289 }
4265 4290
4266 // TODO(ahe): This code should be integrated in finishClasses. 4291 // TODO(ahe): This code should be integrated in finishClasses.
4267 String getReflectionDataParser() { 4292 String getReflectionDataParser() {
4268 String metadataField = '"${namer.metadataField}"'; 4293 String metadataField = '"${namer.metadataField}"';
4269 String reflectableField = namer.reflectableField; 4294 String reflectableField = namer.reflectableField;
4295 String defaultValuesField = namer.defaultValuesField;
4296 String methodsWithOptionalArgumentsField =
4297 namer.methodsWithOptionalArgumentsField;
4270 return ''' 4298 return '''
4271 (function (reflectionData) { 4299 (function (reflectionData) {
4272 ''' 4300 '''
4273 // [map] returns an object literal that V8 shouldn't try to optimize with a 4301 // [map] returns an object literal that V8 shouldn't try to optimize with a
4274 // hidden class. This prevents a potential performance problem where V8 tries 4302 // hidden class. This prevents a potential performance problem where V8 tries
4275 // to build a hidden class for an object used as a hashMap. 4303 // to build a hidden class for an object used as a hashMap.
4276 ''' 4304 '''
4277 function map(x){x={x:x};delete x.x;return x} 4305 function map(x){x={x:x};delete x.x;return x}
4278 if (!init.libraries) init.libraries = []; 4306 if (!init.libraries) init.libraries = [];
4279 if (!init.mangledNames) init.mangledNames = map(); 4307 if (!init.mangledNames) init.mangledNames = map();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4318 var previousProperty; 4346 var previousProperty;
4319 if (firstChar === "+") { 4347 if (firstChar === "+") {
4320 mangledGlobalNames[previousProperty] = property.substring(1); 4348 mangledGlobalNames[previousProperty] = property.substring(1);
4321 if (descriptor[property] == 1) ''' // Break long line. 4349 if (descriptor[property] == 1) ''' // Break long line.
4322 '''descriptor[previousProperty].$reflectableField = 1; 4350 '''descriptor[previousProperty].$reflectableField = 1;
4323 if (element && element.length) ''' // Break long line. 4351 if (element && element.length) ''' // Break long line.
4324 '''init.interfaces[previousProperty] = element; 4352 '''init.interfaces[previousProperty] = element;
4325 } else if (firstChar === "@") { 4353 } else if (firstChar === "@") {
4326 property = property.substring(1); 4354 property = property.substring(1);
4327 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; 4355 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element;
4356 } else if (firstChar === "*") {
4357 globalObject[previousProperty].$defaultValuesField = element;
4358 var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
4359 if (!optionalMethods) {
4360 descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
4361 }
4362 optionalMethods[property] = previousProperty;
4328 } else if (typeof element === "function") { 4363 } else if (typeof element === "function") {
4329 globalObject[previousProperty = property] = element; 4364 globalObject[previousProperty = property] = element;
4330 functions.push(property); 4365 functions.push(property);
4331 init.globalFunctions[property] = element; 4366 init.globalFunctions[property] = element;
4332 } else { 4367 } else {
4333 previousProperty = property; 4368 previousProperty = property;
4334 var newDesc = {}; 4369 var newDesc = {};
4335 var previousProp; 4370 var previousProp;
4336 for (var prop in element) { 4371 for (var prop in element) {
4337 if (!hasOwnProperty.call(element, prop)) continue; 4372 if (!hasOwnProperty.call(element, prop)) continue;
4338 firstChar = prop.substring(0, 1); 4373 firstChar = prop.substring(0, 1);
4339 if (prop === "static") { 4374 if (prop === "static") {
4340 processStatics(init.statics[property] = element[prop]); 4375 processStatics(init.statics[property] = element[prop]);
4341 } else if (firstChar === "+") { 4376 } else if (firstChar === "+") {
4342 mangledNames[previousProp] = prop.substring(1); 4377 mangledNames[previousProp] = prop.substring(1);
4343 if (element[prop] == 1) ''' // Break long line. 4378 if (element[prop] == 1) ''' // Break long line.
4344 '''element[previousProp].$reflectableField = 1; 4379 '''element[previousProp].$reflectableField = 1;
4345 } else if (firstChar === "@" && prop !== "@") { 4380 } else if (firstChar === "@" && prop !== "@") {
4346 newDesc[prop.substring(1)][$metadataField] = element[prop]; 4381 newDesc[prop.substring(1)][$metadataField] = element[prop];
4382 } else if (firstChar === "*") {
4383 newDesc[previousProp].$defaultValuesField = element[prop];
4384 var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
4385 if (!optionalMethods) {
4386 newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
4387 }
4388 optionalMethods[prop] = previousProp;
4347 } else { 4389 } else {
4348 newDesc[previousProp = prop] = element[prop]; 4390 newDesc[previousProp = prop] = element[prop];
4349 } 4391 }
4350 } 4392 }
4351 $classesCollector[property] = [globalObject, newDesc]; 4393 $classesCollector[property] = [globalObject, newDesc];
4352 classes.push(property); 4394 classes.push(property);
4353 } 4395 }
4354 } 4396 }
4355 } 4397 }
4356 processStatics(descriptor); 4398 processStatics(descriptor);
(...skipping 10 matching lines...) Expand all
4367 4409
4368 const String HOOKS_API_USAGE = """ 4410 const String HOOKS_API_USAGE = """
4369 // The code supports the following hooks: 4411 // The code supports the following hooks:
4370 // dartPrint(message) - if this function is defined it is called 4412 // dartPrint(message) - if this function is defined it is called
4371 // instead of the Dart [print] method. 4413 // instead of the Dart [print] method.
4372 // dartMainRunner(main) - if this function is defined, the Dart [main] 4414 // dartMainRunner(main) - if this function is defined, the Dart [main]
4373 // method will not be invoked directly. 4415 // method will not be invoked directly.
4374 // Instead, a closure that will invoke [main] is 4416 // Instead, a closure that will invoke [main] is
4375 // passed to [dartMainRunner]. 4417 // passed to [dartMainRunner].
4376 """; 4418 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698