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

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

Issue 10232011: Implement simple dynamic type check. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor edits. Created 8 years, 8 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 961d1081d3df829add1b569632d8f23911e588af..c9c167c223ca5e21649418ae121265577135d429 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -123,6 +123,15 @@ class Interceptors {
Element getMapMaker() {
return compiler.findHelper(const SourceString('makeLiteralMap'));
}
+
+ // TODO(karlklose): move these to different class or rename class?
+ Element getSetRuntimeTypeInfo() {
+ return compiler.findHelper(const SourceString('setRuntimeTypeInfo'));
+ }
+
+ Element getGetRuntimeTypeInfo() {
+ return compiler.findHelper(const SourceString('getRuntimeTypeInfo'));
+ }
}
class SsaBuilderTask extends CompilerTask {
@@ -1790,7 +1799,17 @@ class SsaBuilder implements Visitor {
typeAnnotation = argument.asSend().receiver;
isNot = true;
}
+
Type type = elements.getType(typeAnnotation);
+ HInstruction typeInfo = null;
+ if (compiler.universe.rti.hasTypeArguments(type)) {
+ HInstruction typeInfoGetter =
+ new HStatic(interceptors.getGetRuntimeTypeInfo());
+ add(typeInfoGetter);
+ typeInfo = new HInvokeStatic(Selector.INVOCATION_1,
+ <HInstruction>[typeInfoGetter, expression]);
kasperl 2012/04/30 08:48:32 Line too long.
ngeoffray 2012/04/30 08:51:12 line too long
karlklose 2012/05/01 11:20:55 Done.
karlklose 2012/05/01 11:20:55 Done.
+ add(typeInfo);
+ }
if (type.element.kind === ElementKind.TYPE_VARIABLE) {
// TODO(karlklose): We emulate the frog behavior and answer
// true to any is check involving a type variable -- both is T
@@ -1798,7 +1817,12 @@ class SsaBuilder implements Visitor {
// reified generics.
stack.add(graph.addConstantBool(true));
} else {
- HInstruction instruction = new HIs(type, expression);
+ HInstruction instruction;
+ if (compiler.universe.rti.hasTypeArguments(type)) {
kasperl 2012/04/30 08:48:32 Change this check to typeInfo != null?
karlklose 2012/05/01 11:20:55 Done.
+ instruction = new HIs.withTypeInfo(type, expression, typeInfo);
+ } else {
+ instruction = new HIs(type, expression);
+ }
if (isNot) {
add(instruction);
instruction = new HNot(instruction);
@@ -2153,20 +2177,68 @@ class SsaBuilder implements Visitor {
}
}
- visitStaticSend(Send node) {
+ visitNewSend(Send node) {
Selector selector = elements.getSelector(node);
Element element = elements[node];
- if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
- compiler.resolver.resolveMethodElement(element);
- FunctionElement functionElement = element;
- element = functionElement.defaultImplementation;
+ compiler.resolver.resolveMethodElement(element);
+ FunctionElement functionElement = element;
+ element = functionElement.defaultImplementation;
+ HInstruction target = new HStatic(element);
+ add(target);
+ var inputs = <HInstruction>[];
+ inputs.add(target);
+ bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
+ element, inputs);
+ if (!succeeded) {
+ // TODO(ngeoffray): Match the VM behavior and throw an
+ // exception at runtime.
+ compiler.cancel('Unimplemented non-matching static call', node: node);
}
+
+ HType elementType = HType.UNKNOWN;
kasperl 2012/04/30 08:48:32 Factor out the computation of elementType?
karlklose 2012/05/01 11:20:55 Done.
+ Element originalElement = elements[node];
+ if (originalElement.enclosingElement === compiler.listClass) {
+ if (node.arguments.isEmpty()) {
+ elementType = HType.EXTENDABLE_ARRAY;
+ } else {
+ elementType = HType.MUTABLE_ARRAY;
+ }
+ } else if (element.isGenerativeConstructor()) {
+ ClassElement cls = element.enclosingElement;
+ elementType = new HNonPrimitiveType(cls.type);
+ }
+ HInstruction newInstance = new HInvokeStatic(selector, inputs, elementType);
+ push(newInstance);
+
+ TypeAnnotation annotation = getTypeAnnotationFromSend(node);
+ Type type = elements.getType(annotation);
+
+ if (compiler.universe.rti.hasTypeArguments(type)) {
kasperl 2012/04/30 08:48:32 Factor out the code in this if?
karlklose 2012/05/01 11:20:55 Done.
+ String typeString = compiler.universe.rti.asJsString(type);
+ HInstruction typeInfo = new HForeign(new LiteralDartString(typeString),
+ new LiteralDartString('Object'),
+ <HInstruction>[]);
+ add(typeInfo);
+
+ HInstruction typeInfoSetter =
+ new HStatic(interceptors.getSetRuntimeTypeInfo());
+ add(typeInfoSetter);
+ Selector setSelector = Selector.INVOCATION_2;
+ add(new HInvokeStatic(setSelector,
+ <HInstruction>[typeInfoSetter, newInstance,
+ typeInfo]));
+ }
+ }
+
+ visitStaticSend(Send node) {
+ Selector selector = elements.getSelector(node);
+ Element element = elements[node];
+ compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR);
HInstruction target = new HStatic(element);
add(target);
var inputs = <HInstruction>[];
inputs.add(target);
- if (element.kind == ElementKind.FUNCTION ||
- element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+ if (element.kind == ElementKind.FUNCTION) {
bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
element, inputs);
if (!succeeded) {
@@ -2174,20 +2246,7 @@ class SsaBuilder implements Visitor {
// exception at runtime.
compiler.cancel('Unimplemented non-matching static call', node: node);
}
- HType type = HType.UNKNOWN;
- Element originalElement = elements[node];
- if (originalElement.isGenerativeConstructor()
- && originalElement.enclosingElement === compiler.listClass) {
- if (node.arguments.isEmpty()) {
- type = HType.EXTENDABLE_ARRAY;
- } else {
- type = HType.MUTABLE_ARRAY;
- }
- } else if (element.isGenerativeConstructor()) {
- ClassElement cls = element.enclosingElement;
- type = new HNonPrimitiveType(cls.type);
- }
- push(new HInvokeStatic(selector, inputs, type));
+ push(new HInvokeStatic(selector, inputs));
} else {
if (element.kind == ElementKind.GETTER) {
target = new HInvokeStatic(Selector.GETTER, inputs);
@@ -2235,13 +2294,28 @@ class SsaBuilder implements Visitor {
}
}
+ // TODO(karlklose): share with resolver.
+ TypeAnnotation getTypeAnnotationFromSend(Send send) {
+ if (send.selector.asTypeAnnotation() !== null) {
kasperl 2012/04/30 08:48:32 I wonder if it wouldn't be cleaner with is checks
karlklose 2012/05/01 11:20:55 Changed to is-checks.
+ return send.selector;
+ } else if (send.selector.asSend() !== null) {
+ Send selector = send.selector;
+ if (selector.receiver.asTypeAnnotation() !== null) {
+ return selector.receiver;
+ }
+ } else {
+ compiler.internalError("malformed send in new expression");
kasperl 2012/04/30 08:48:32 Do we usually start our error messages with a capi
karlklose 2012/05/01 11:20:55 We use both variants.
+ }
+ }
+
visitNewExpression(NewExpression node) {
if (node.isConst()) {
+ // TODO(karlklose): add type representation
ConstantHandler handler = compiler.constantHandler;
Constant constant = handler.compileNodeWithDefinitions(node, elements);
stack.add(graph.addConstant(constant));
} else {
- visitSend(node.send);
+ visitNewSend(node.send);
}
}

Powered by Google App Engine
This is Rietveld 408576698