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

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

Issue 12218007: Implement substitution for type variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 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 ac19fea18e396464dbf01d6e55997d1c847618a7..3626faf229febfb42d869ef1e3bc89ad24725b0d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -2188,7 +2188,6 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
isAnd: (const SourceString("&&") == op.source));
}
-
void visitLogicalNot(Send node) {
assert(node.argumentsNode is Prefix);
visit(node.receiver);
@@ -2656,43 +2655,46 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HInstruction instruction;
if (type.element.isTypeVariable() ||
RuntimeTypeInformation.hasTypeArguments(type)) {
- HInstruction typeInfo = getRuntimeTypeInfo(expression);
- // TODO(karlklose): make isSubtype a HInstruction to enable
- // optimizations?
- Element helper = compiler.findHelper(const SourceString('isSubtype'));
- HInstruction isSubtype = new HStatic(helper);
- add(isSubtype);
- // Build a list of representations for the type arguments.
- List<HInstruction> representations =
- buildTypeArgumentRepresentations(type);
- // For each type argument, build a call to isSubtype, with the type
- // argument as first and the representation of the tested type as
- // second argument.
- List<HInstruction> checks = <HInstruction>[];
- int index = 0;
- representations.forEach((HInstruction representation) {
- HInstruction position = graph.addConstantInt(index, constantSystem);
- // Get the index'th type argument from the runtime type information.
- HInstruction typeArgument =
- createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]);
- add(typeArgument);
- // Create the call to isSubtype.
- List<HInstruction> inputs =
- <HInstruction>[isSubtype, typeArgument, representation];
- HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN);
- add(call);
- checks.add(call);
- index++;
- });
- instruction = new HIs(type, <HInstruction>[expression]..addAll(checks));
+
+ void argumentsCheck() {
karlklose 2013/02/08 14:51:46 @Nicolas: this is the main change to the previous
+ HInstruction typeInfo = getRuntimeTypeInfo(expression);
+ Element helper =
+ compiler.findHelper(const SourceString('checkArguments'));
+ HInstruction helperCall = new HStatic(helper);
+ add(helperCall);
+ List<HInstruction> representations =
+ buildTypeArgumentRepresentations(type);
+ Element element = type.element;
+ String substitution = backend.namer.substitutionName(element);
+ if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) {
+ substitution = '$substitution()';
+ }
+ HInstruction fieldGet =
+ createForeign('#.$substitution', HType.UNKNOWN, [expression]);
+ HInstruction representationList = new HLiteralList(representations);
+ add(fieldGet);
+ add(representationList);
+ List<HInstruction> inputs = <HInstruction>[helperCall,
+ fieldGet,
+ typeInfo,
+ representationList];
+ push(new HInvokeStatic(inputs, HType.UNKNOWN));
+ }
+
+ void classCheck() { push(new HIs(type, <HInstruction>[expression])); }
+
+ SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
+ branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, isAnd: true);
+ instruction = pop();
} else {
instruction = new HIs(type, <HInstruction>[expression]);
+ add(instruction);
}
if (isNot) {
- add(instruction);
instruction = new HNot(instruction);
+ add(instruction);
}
- push(instruction);
+ stack.add(instruction);
} else if (const SourceString("as") == op.source) {
visit(node.receiver);
HInstruction expression = pop();
@@ -3030,6 +3032,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
handleForeignCreateIsolate(node);
} else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) {
stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
+ } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
+ stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
} else {
throw "Unknown foreign: ${selector}";
}
@@ -3149,14 +3153,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
return graph.addConstantNull(constantSystem);
}
- // These variables are shared between invocations of the helper.
- HInstruction typeInfo;
+ // The inputs are shared between invocations of the helper.
List<HInstruction> inputs = <HInstruction>[];
/**
* Helper to create an instruction that gets the value of a type variable.
*/
- void addTypeVariableReference(TypeVariableType type) {
+ String addTypeVariableReference(TypeVariableType type) {
Element member = currentElement;
if (member.enclosingElement.isClosure()) {
ClosureClassElement closureClass = member.enclosingElement;
@@ -3164,22 +3167,17 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
member = member.getOutermostEnclosingMemberOrTopLevel();
}
if (member.isFactoryConstructor()) {
- // The type variable is stored in a parameter of the factory.
+ // The type variable is stored in a parameter of the method.
inputs.add(localsHandler.readLocal(type.element));
- } else if (member.isInstanceMember()
- || member.isGenerativeConstructor()) {
+ } else if (member.isInstanceMember() ||
+ member.isGenerativeConstructor()) {
// The type variable is stored in [this].
- if (typeInfo == null) {
- pushInvokeHelper1(backend.getGetRuntimeTypeInfo(),
- localsHandler.readThis(),
- HType.UNKNOWN);
- typeInfo = pop();
- }
int index = RuntimeTypeInformation.getTypeVariableIndex(type);
- HInstruction foreign = createForeign('#[$index]', HType.STRING,
- <HInstruction>[typeInfo]);
- add(foreign);
- inputs.add(foreign);
+ pushInvokeHelper2(backend.getGetRuntimeTypeArgument(),
+ localsHandler.readThis(),
+ graph.addConstantInt(index, constantSystem),
+ HType.UNKNOWN);
+ inputs.add(pop());
} else {
// TODO(ngeoffray): Match the VM behavior and throw an
// exception at runtime.
@@ -3199,13 +3197,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
Node currentNode,
HInstruction newObject) {
if (!compiler.world.needsRti(type.element)) return;
- List<HInstruction> inputs = <HInstruction>[];
if (!type.isRaw) {
+ List<HInstruction> inputs = <HInstruction>[];
type.typeArguments.forEach((DartType argument) {
inputs.add(analyzeTypeArgument(argument, currentNode));
});
+ callSetRuntimeTypeInfo(type.element, inputs, newObject);
}
- callSetRuntimeTypeInfo(type.element, inputs, newObject);
}
void callSetRuntimeTypeInfo(ClassElement element,

Powered by Google App Engine
This is Rietveld 408576698