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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: New check encoding Created 7 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index 51be7e59f755541d7a427f0ef6ce0238e3ce28bf..79813e19ed6495a9630215926b9482049ce7dc72 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -18,6 +18,7 @@ class RuntimeTypes {
final Map<ClassElement, Set<ClassElement>> rtiDependencies;
final Set<ClassElement> classesNeedingRti;
+ final Set<Element> methodsNeedingRti;
// The set of classes that use one of their type variables as expressions
// to get the runtime type.
final Set<ClassElement> classesUsingTypeVariableExpression;
@@ -28,6 +29,7 @@ class RuntimeTypes {
: this.compiler = compiler,
representationGenerator = new TypeRepresentationGenerator(compiler),
classesNeedingRti = new Set<ClassElement>(),
+ methodsNeedingRti = new Set<Element>(),
rtiDependencies = new Map<ClassElement, Set<ClassElement>>(),
classesUsingTypeVariableExpression = new Set<ClassElement>();
@@ -104,9 +106,23 @@ class RuntimeTypes {
if (!itf.isRaw) {
potentiallyAddForRti(itf.element);
}
- } else if (type.kind == TypeKind.TYPE_VARIABLE) {
- TypeVariableElement variable = type.element;
- potentiallyAddForRti(variable.enclosingElement);
+ } else {
+ ClassElement contextClass = Types.getClassContext(type);
+ if (contextClass != null) {
+ potentiallyAddForRti(contextClass);
+ } else if (type.kind == TypeKind.FUNCTION) {
+ void analyzeMethod(Element method) {
+ DartType memberType = method.computeType(compiler);
+ contextClass = Types.getClassContext(memberType);
+ if (contextClass != null &&
+ compiler.types.isPotentialSubtype(memberType, type)) {
+ potentiallyAddForRti(contextClass);
+ methodsNeedingRti.add(method);
+ }
+ }
+ compiler.resolverWorld.closurizedGenericMembers.forEach(analyzeMethod);
karlklose 2013/03/22 13:17:46 Long line.
Johnni Winther 2013/06/21 12:19:14 Done.
+ compiler.resolverWorld.genericCallMethods.forEach(analyzeMethod);
+ }
}
});
// Add the classes that need RTI because they use a type variable as
@@ -288,6 +304,42 @@ class RuntimeTypes {
}
}
+ String getTypeEncoding(DartType type,
+ {bool alwaysGenerateFunction: false}) {
+ ClassElement contextClass = Types.getClassContext(type);
+ String onVariable(TypeVariableType v) {
+ return v.toString();
+ };
+ String encoding = _getTypeRepresentation(type, onVariable);
+ if (contextClass == null && !alwaysGenerateFunction) {
+ return encoding;
+ } else {
+ String parameters = contextClass != null
+ ? contextClass.typeVariables.toList().join(', ')
+ : '';
+ return 'function ($parameters) { return $encoding; }';
+ }
+ }
+
+ String getSignatureEncoding(DartType type, String generateThis()) {
+ ClassElement contextClass = Types.getClassContext(type);
+ String encoding = getTypeEncoding(type, alwaysGenerateFunction: true);
+ if (contextClass != null) {
+ String this_ = generateThis();
+ JavaScriptBackend backend = compiler.backend;
+ String applySignature =
+ backend.namer.getName(backend.getApplySignature());
+ String contextName = backend.namer.getName(contextClass);
+ return 'function () {'
+ ' return ${backend.namer.CURRENT_ISOLATE}.'
+ '$applySignature($encoding, $this_, "$contextName"); '
+ '}';
+ } else {
+ return encoding;
+ }
+ }
+
+
String getTypeRepresentation(DartType type, void onVariable(variable)) {
// Create a type representation. For type variables call the original
// callback for side effects and return a template placeholder.
@@ -327,6 +379,9 @@ class TypeRepresentationGenerator extends DartTypeVisitor {
OnVariableCallback onVariable;
StringBuffer builder;
+ JavaScriptBackend get backend => compiler.backend;
+ Namer get namer => backend.namer;
+
TypeRepresentationGenerator(Compiler this.compiler);
/**
@@ -344,8 +399,6 @@ class TypeRepresentationGenerator extends DartTypeVisitor {
}
String getJsName(Element element) {
- JavaScriptBackend backend = compiler.backend;
- Namer namer = backend.namer;
return namer.isolateAccess(element);
}
@@ -386,25 +439,25 @@ class TypeRepresentationGenerator extends DartTypeVisitor {
}
visitFunctionType(FunctionType type, _) {
- builder.write('{func: true');
+ builder.write('{${namer.functionTypeTag()}: true');
if (type.returnType.isVoid) {
- builder.write(', retvoid: true');
+ builder.write(', ${namer.functionTypeVoidReturnTag()}: true');
} else if (!type.returnType.isDynamic) {
- builder.write(', ret: ');
+ builder.write(', ${namer.functionTypeReturnTypeTag()}: ');
visit(type.returnType);
}
if (!type.parameterTypes.isEmpty) {
- builder.write(', args: [');
+ builder.write(', ${namer.functionTypeRequiredParametersTag()}: [');
visitList(type.parameterTypes);
builder.write(']');
}
if (!type.optionalParameterTypes.isEmpty) {
- builder.write(', opt: [');
+ builder.write(', ${namer.functionTypeOptionalParametersTag()}: [');
visitList(type.optionalParameterTypes);
builder.write(']');
}
if (!type.namedParameterTypes.isEmpty) {
- builder.write(', named: {');
+ builder.write(', ${namer.functionTypeNamedParametersTag()}: {');
bool first = true;
Link<SourceString> names = type.namedParameters;
Link<DartType> types = type.namedParameterTypes;

Powered by Google App Engine
This is Rietveld 408576698