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

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix status files Created 7 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 1cd2255ddc3b30cfbbc2a6efd1319821010383c1..f5c347a79760fe7b422c79b8a16507b43fa127ee 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1783,6 +1783,30 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HInstruction typeVariable = addTypeVariableReference(type);
return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
original, typeVariable);
+ } else if (type.kind == TypeKind.FUNCTION) {
+ HType subtype = original.instructionType;
+ bool contextIsTypeArguments = false;
+ HInstruction context;
+ if (type.containsTypeVariables) {
+ if (currentElement.isInstanceMember()) {
+ context = localsHandler.readThis();
+ } else {
+ ClassElement contextClass = Types.getClassContext(type);
+ List<HInstruction> inputs = <HInstruction>[];
+ for (Link<DartType> link = contextClass.typeVariables;
+ !link.isEmpty;
+ link = link.tail) {
+ inputs.add(addTypeVariableReference(link.head));
+ }
+ context = buildLiteralList(inputs);
+ add(context);
+ contextIsTypeArguments = true;
+ }
+ } else {
+ context = graph.addConstantNull(compiler);
+ }
+ return new HTypeConversion.withContext(type, kind, subtype,
karlklose 2013/06/20 07:32:55 I'd rather not create a new conversion withContext
Johnni Winther 2013/06/21 12:19:15 Done.
+ original, context, contextIsTypeArguments: contextIsTypeArguments);
} else {
return original.convertType(compiler, type, kind);
}
@@ -1791,8 +1815,10 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HInstruction potentiallyCheckType(HInstruction original, DartType type,
{ int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
if (!compiler.enableTypeAssertions) return original;
+ type = type.unalias(compiler);
HInstruction other = buildTypeConversion(original, type, kind);
if (other != original) add(other);
+ compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree);
return other;
}
@@ -2438,6 +2464,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
compiler.functionClass.computeType(compiler),
compiler);
push(new HForeignNew(closureClassElement, type, capturedVariables));
+
+ Element methodElement = nestedClosureData.closureElement;
+ if (compiler.backend.methodNeedsRti(methodElement)) {
+ compiler.backend.registerGenericClosure(
+ methodElement, compiler.enqueuer.codegen, work.resolutionTree);
+ }
}
visitFunctionDeclaration(FunctionDeclaration node) {
@@ -2721,7 +2753,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
}
- visitOperatorSend(node) {
+ visitOperatorSend(Send node) {
Operator op = node.selector;
if (const SourceString("[]") == op.source) {
visitDynamicSend(node);
@@ -2740,6 +2772,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
Node argument = node.arguments.head;
TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
DartType type = elements.getType(typeAnnotation);
+ type = type.unalias(compiler);
karlklose 2013/06/20 07:32:55 Move to buildTypeConversion?
Johnni Winther 2013/06/21 12:19:15 Done.
HInstruction converted = buildTypeConversion(
expression, type, HTypeConversion.CAST_TYPE_CHECK);
if (converted != expression) add(converted);
@@ -2758,6 +2791,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HInstruction expression = pop();
bool isNot = node.isIsNotCheck;
DartType type = elements.getType(node.typeAnnotationFromIsCheck);
+ type = type.unalias(compiler);
karlklose 2013/06/20 07:32:55 Move to buildIsNode? isMalformed on an unaliased t
Johnni Winther 2013/06/21 12:19:15 Currently we can't. And this will be removed when
if (type.isMalformed) {
String reasons = Types.fetchReasonsFromMalformedType(type);
if (compiler.enableTypeAssertions) {
@@ -2776,7 +2810,51 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
- if (type.kind == TypeKind.TYPE_VARIABLE) {
+ if (type.kind == TypeKind.FUNCTION) {
+ Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
+
+ HInstruction signatureName = graph.addConstantString(
+ new DartString.literal(backend.namer.getFunctionTypeName(type)),
+ node, compiler);
+
+ HInstruction contextName;
+ HInstruction context;
+ HInstruction typeArguments;
+ if (type.containsTypeVariables) {
+ ClassElement contextClass = Types.getClassContext(type);
+ contextName = graph.addConstantString(
+ new DartString.literal(backend.namer.getName(contextClass)),
+ node, compiler);
+ if (currentElement.isInstanceMember()) {
+ context = localsHandler.readThis();
+ typeArguments = graph.addConstantNull(compiler);
+ } else {
+ context = graph.addConstantNull(compiler);
karlklose 2013/06/20 07:32:55 This code (and the else-branch) could be shared wi
Johnni Winther 2013/06/21 12:19:15 Added a buildTypeVariableList method used by both
+ List<HInstruction> inputs = <HInstruction>[];
+ for (Link<DartType> link = contextClass.typeVariables;
+ !link.isEmpty;
+ link = link.tail) {
+ inputs.add(addTypeVariableReference(link.head));
+ }
+ typeArguments = buildLiteralList(inputs);
+ add(typeArguments);
+ }
+ } else {
+ contextName = graph.addConstantNull(compiler);
+ context = graph.addConstantNull(compiler);
+ typeArguments = graph.addConstantNull(compiler);
+ }
+
+ List<HInstruction> inputs = <HInstruction>[expression,
+ signatureName,
+ contextName,
+ context,
+ typeArguments];
+ pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN);
karlklose 2013/06/20 07:32:55 Could you move this to the codegen by creating a n
Johnni Winther 2013/06/21 12:19:15 The generation is already handle in codegen. We ju
+ HInstruction call = pop();
+ return new HIs(type, <HInstruction>[expression, call],
+ HIs.COMPOUND_CHECK);
+ } else if (type.kind == TypeKind.TYPE_VARIABLE) {
HInstruction runtimeType = addTypeVariableReference(type);
Element helper = backend.getCheckSubtypeOfRuntimeType();
List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
@@ -2974,6 +3052,18 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
}
+ void handleForeignJsSetupObject(Send node) {
+ if (!node.arguments.isEmpty) {
+ compiler.cancel(
+ 'Too many arguments to JS_SETUP_OBJECT', node: node);
+ }
+
+ String name = backend.namer.SETUP_OBJECT;
+ push(new HForeign(new js.LiteralString(name),
+ HType.UNKNOWN,
+ <HInstruction>[]));
+ }
+
void handleForeignJsCallInIsolate(Send node) {
Link<Node> link = node.arguments;
if (!compiler.hasIsolateSupport()) {
@@ -3085,6 +3175,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
handleForeignJs(node);
} else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) {
handleForeignJsCurrentIsolateContext(node);
+ } else if (name == const SourceString('JS_SETUP_OBJECT')) {
+ handleForeignJsSetupObject(node);
} else if (name == const SourceString('JS_CALL_IN_ISOLATE')) {
handleForeignJsCallInIsolate(node);
} else if (name == const SourceString('DART_CLOSURE_TO_JS')) {
@@ -3100,8 +3192,33 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
} else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) {
String name = backend.namer.getRuntimeTypeName(compiler.objectClass);
stack.add(addConstantString(node, name));
+ } else if (name == const SourceString('JS_FUNCTION_CLASS_NAME')) {
+ String name = backend.namer.getRuntimeTypeName(compiler.functionClass);
+ stack.add(addConstantString(node, name));
} else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
+ } else if (name == const SourceString('JS_SIGNATURE_NAME')) {
+ stack.add(addConstantString(node, backend.namer.operatorSignature()));
+ } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) {
+ stack.add(addConstantString(node, backend.namer.functionTypeTag()));
+ } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) {
+ stack.add(addConstantString(node,
+ backend.namer.functionTypeVoidReturnTag()));
+ } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) {
+ stack.add(addConstantString(node,
+ backend.namer.functionTypeReturnTypeTag()));
+ } else if (name ==
+ const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) {
+ stack.add(addConstantString(node,
+ backend.namer.functionTypeRequiredParametersTag()));
+ } else if (name ==
+ const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) {
+ stack.add(addConstantString(node,
+ backend.namer.functionTypeOptionalParametersTag()));
+ } else if (name ==
+ const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) {
+ stack.add(addConstantString(node,
+ backend.namer.functionTypeNamedParametersTag()));
} else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
handleForeignDartObjectJsConstructorFunction(node);
} else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) {
@@ -3218,17 +3335,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
TypeVariableElement variable) {
assert(currentElement.isInstanceMember());
int index = RuntimeTypes.getTypeVariableIndex(variable);
- String substitutionNameString = backend.namer.substitutionName(cls);
+ String substitutionNameString = backend.namer.getName(cls);
karlklose 2013/06/20 07:32:55 How does this work? substitutionName contains the
Johnni Winther 2013/06/21 12:19:15 getRuntimeTypeArgument has been changed to take th
HInstruction substitutionName = graph.addConstantString(
new LiteralDartString(substitutionNameString), null, compiler);
HInstruction target = localsHandler.readThis();
- HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
- <HInstruction>[target, substitutionName]);
- add(substitution);
pushInvokeStatic(null,
backend.getGetRuntimeTypeArgument(),
[target,
- substitution,
+ substitutionName,
graph.addConstantInt(index, compiler)],
HType.UNKNOWN);
return pop();

Powered by Google App Engine
This is Rietveld 408576698