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

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

Issue 10942028: Support class and typedef literals as expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add a test for literals. Created 8 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 side-by-side diff with in-line comments
Download patch
Index: lib/compiler/implementation/ssa/builder.dart
diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
index 3c14e96c96e250dbd0b8e58796aefaf20127b774..22a8163070d0ea028b3d522323750f65ed34e560 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -2927,7 +2927,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs);
add(runtimeType);
runtimeCodeInputs.add(runtimeType);
- runtimeCode.add('runtimeType: #');
+ runtimeCode.add("runtimeType: '#'");
}
if (needsRti) {
if (runtimeTypeIsUsed) runtimeCode.add(', ');
@@ -2999,9 +2999,23 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
return;
}
if (compiler.world.needsRti(constructor.enclosingElement)) {
- type.arguments.forEach((DartType argument) {
- inputs.add(analyzeTypeArgument(argument, node));
- });
+ if (!type.arguments.isEmpty) {
+ type.arguments.forEach((DartType argument) {
+ inputs.add(analyzeTypeArgument(argument, node));
+ });
+ } else if (compiler.enabledRuntimeType) {
+ Link<DartType> variables =
+ constructor.getEnclosingClass().typeVariables;
+ if (!variables.isEmpty) {
+ // If the class has type variables but no type arguments have been
+ // provided, add [:dynamic:] as argument for all type variables.
ngeoffray 2012/10/31 10:33:03 Can't we find that at runtime instead?
karlklose 2012/10/31 13:01:18 We could by wrapping each type variable in a call
ngeoffray 2012/10/31 14:32:43 What other solution are you thinking of? One that
+ DartString stringDynamic = new DartString.literal('dynamic');
+ HInstruction input = graph.addConstantString(stringDynamic,
+ node,
+ constantSystem);
+ variables.forEach((_) => inputs.add(input));
+ }
+ }
}
HType elementType = computeType(constructor);
@@ -3073,6 +3087,46 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
}
+ HConstant addConstantString(Send node, String string) {
+ DartString dartString = new DartString.literal(string);
+ Constant constant = constantSystem.createString(dartString, node);
+ return graph.addConstant(constant);
+ }
+
+ visitTypeReferenceSend(Send node) {
+ Element element = elements[node];
+ HInstruction name;
+ Element helper =
+ compiler.findHelper(RuntimeTypeInformation.CACHE_HELPER_NAME);
+ if (element.isClass()) {
+ String string = rti.generateRuntimeTypeString(element, 0);
+ name = addConstantString(node.selector, string);
+ } else if (element.isTypedef()) {
+ // TODO(karlklose): implement support for type variables in typedefs.
+ name = addConstantString(node.selector, rti.getName(element));
+ } else if (element.isTypeVariable()) {
+ // TODO(6248): implement support for type variables.
+ compiler.unimplemented('first class type for type variable', node: node);
+ } else {
+ internalError('unexpected element $element', node: node);
+ }
+ pushInvokeHelper1(helper, name);
+ if (node.isFunctionObjectInvocation) {
+ // This send is of the form 'e(...)', where e is resolved to a type
+ // reference.
ngeoffray 2012/10/31 10:33:03 Please add a comment that you're doing a regular c
karlklose 2012/10/31 13:01:18 Done.
+ HInstruction target = pop();
+ Selector selector = elements.getSelector(node);
+ selector = new Selector.callClosure(selector.argumentCount,
+ selector.namedArguments);
+ List<HInstruction> inputs = <HInstruction>[target];
+ addDynamicSendArgumentsToList(node, inputs);
+ push(new HInvokeDynamicMethod(selector, inputs));
ngeoffray 2012/10/31 10:33:03 Could you use HInvokeDynamicClosure? You should no
karlklose 2012/10/31 13:01:18 Yes, it works!
+ }
+ // Enable the runtime type cache, so that the emitter generates one even
+ // if we do not have [runtimeType] in the program.
ngeoffray 2012/10/31 10:33:03 How can that happen?
karlklose 2012/10/31 13:01:18 If we use a class literal, but not the runtimeType
+ compiler.enableRuntimeTypeCache();
+ }
+
visitGetterSend(Send node) {
generateGetter(node, elements[node]);
}
@@ -3083,10 +3137,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
void generateError(Node node, String message, Element helper) {
- DartString messageObject = new DartString.literal(message);
- Constant messageConstant =
- constantSystem.createString(messageObject, node);
- HInstruction errorMessage = graph.addConstant(messageConstant);
+ HInstruction errorMessage = addConstantString(node, message);
pushInvokeHelper1(helper, errorMessage);
}
@@ -3266,7 +3317,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
// [receiver] is only used if the node is an instance send.
HInstruction receiver = null;
- if (Elements.isInstanceSend(node, elements)) {
+ Element selectorElement = elements[node.selector];
ngeoffray 2012/10/31 10:33:03 Why is the class on the selector and not the recei
karlklose 2012/10/31 13:01:18 It is on both, but I changed it to read it from th
+ if (!Elements.isUnresolved(selectorElement)
+ && selectorElement.impliesType()) {
+ visitTypeReferenceSend(node);
+ } else if (Elements.isInstanceSend(node, elements)) {
receiver = generateInstanceSendReceiver(node);
generateInstanceGetterWithCompiledReceiver(node, receiver);
} else {

Powered by Google App Engine
This is Rietveld 408576698