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

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

Issue 10533151: Make undefined and null equivalent. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 8 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: lib/compiler/implementation/ssa/codegen.dart
diff --git a/lib/compiler/implementation/ssa/codegen.dart b/lib/compiler/implementation/ssa/codegen.dart
index 5635bd0b1c1fd024b53a4f3da6d0ca37161dc0fd..22825bc7ecc46d719c4a2634e13db6e8184d95be 100644
--- a/lib/compiler/implementation/ssa/codegen.dart
+++ b/lib/compiler/implementation/ssa/codegen.dart
@@ -242,6 +242,15 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
}
}
+ void withPrecedence(int precedence, void action()) {
+ int oldPrecedence = expectedPrecedence;
+ beginExpression(precedence);
+ expectedPrecedence = precedence;
+ action();
+ expectedPrecedence = oldPrecedence;
+ endExpression(precedence);
+ }
+
void preGenerateMethod(HGraph graph) {
new SsaInstructionMerger(generateAtUseSite).visitGraph(graph);
new SsaConditionMerger(generateAtUseSite,
@@ -1169,13 +1178,52 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
}
}
- visitEquals(HEquals node) {
- if (node.builtin) {
+ void emitIdentityComparison(HInstruction left, HInstruction right) {
+ HType leftType = left.propagatedType;
+ HType rightType = right.propagatedType;
+ if (leftType.canBeNull() && rightType.canBeNull()) {
+ if (left.isConstantNull() || right.isConstantNull() ||
+ (leftType.isPrimitive() && leftType == rightType)) {
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ use(left, JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(' == ');
+ use(right, JSPrecedence.RELATIONAL_PRECEDENCE);
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ } else {
+ assert(NullConstant.JsNull == 'null');
+ withPrecedence(JSPrecedence.CONDITIONAL_PRECEDENCE, () {
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ use(left, JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(' == null');
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(' ? ');
+ this.expectedPrecedence = JSPrecedence.ASSIGNMENT_PRECEDENCE;
+ withPrecedence(JSPrecedence.LOGICAL_AND_PRECEDENCE, () {
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ use(right, JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(' == null');
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(" : ");
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ use(left, JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(' === ');
+ use(right, JSPrecedence.EQUALITY_PRECEDENCE);
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ });
+ });
+ }
+ } else {
beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
- use(node.left, JSPrecedence.EQUALITY_PRECEDENCE);
+ use(left, JSPrecedence.EQUALITY_PRECEDENCE);
buffer.add(' === ');
- use(node.right, JSPrecedence.RELATIONAL_PRECEDENCE);
+ use(right, JSPrecedence.RELATIONAL_PRECEDENCE);
endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ }
+ }
+
+ visitEquals(HEquals node) {
+ if (node.builtin) {
+ emitIdentityComparison(node.left, node.right);
} else if (node.element === equalsNullElement ||
node.element === boolifiedEqualsNullElement) {
beginExpression(JSPrecedence.CALL_PRECEDENCE);
@@ -1189,6 +1237,11 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
}
}
+ visitIdentity(HIdentity node) {
+ assert(node.builtin);
+ emitIdentityComparison(node.left, node.right);
+ }
+
visitAdd(HAdd node) => visitInvokeBinary(node, '+');
visitDivide(HDivide node) => visitInvokeBinary(node, '/');
visitMultiply(HMultiply node) => visitInvokeBinary(node, '*');
@@ -1207,7 +1260,6 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
visitNegate(HNegate node) => visitInvokeUnary(node, '-');
- visitIdentity(HIdentity node) => visitInvokeBinary(node, '===');
visitLess(HLess node) => visitInvokeBinary(node, '<');
visitLessEqual(HLessEqual node) => visitInvokeBinary(node, '<=');
visitGreater(HGreater node) => visitInvokeBinary(node, '>');
@@ -1767,16 +1819,16 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
}
visitForeignNew(HForeignNew node) {
- var i = 0;
+ int j = 0;
node.element.forEachInstanceField(
includeBackendMembers: true,
includeSuperMembers: true,
f: (ClassElement enclosingClass, Element member) {
world.registerFieldInitializer(member.name,
enclosingClass.computeType(compiler),
- node.inputs[i].isInteger());
+ node.inputs[j].isInteger());
- i++;
+ j++;
});
String jsClassReference = compiler.namer.isolateAccess(node.element);
beginExpression(JSPrecedence.MEMBER_PRECEDENCE);
@@ -2225,11 +2277,35 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
}
void checkObject(HInstruction input, String cmp) {
- beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
- buffer.add('typeof ');
- use(input, JSPrecedence.PREFIX_PRECEDENCE);
- buffer.add(" $cmp 'object'");
- endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ assert(NullConstant.JsNull == 'null');
+ if (cmp == "===") {
+ withPrecedence(JSPrecedence.LOGICAL_AND_PRECEDENCE, () {
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add('typeof ');
+ use(input, JSPrecedence.PREFIX_PRECEDENCE);
+ buffer.add(" === 'object'");
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(" && ");
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ use(input, JSPrecedence.PREFIX_PRECEDENCE);
+ buffer.add(" !== null");
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ });
+ } else {
+ assert(cmp == "!==");
+ withPrecedence(JSPrecedence.LOGICAL_OR_PRECEDENCE, () {
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add('typeof ');
+ use(input, JSPrecedence.PREFIX_PRECEDENCE);
+ buffer.add(" !== 'object'");
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(" || ");
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ use(input, JSPrecedence.PREFIX_PRECEDENCE);
+ buffer.add(" === null");
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ });
+ }
}
void checkArray(HInstruction input, String cmp) {
@@ -2265,24 +2341,24 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
void checkNull(HInstruction input) {
beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
use(input, JSPrecedence.EQUALITY_PRECEDENCE);
- buffer.add(" === (void 0)");
+ buffer.add(" == null");
endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
}
void checkFunction(HInstruction input, Element element) {
- beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
- beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
- buffer.add('typeof ');
- use(input, JSPrecedence.PREFIX_PRECEDENCE);
- buffer.add(" === 'function'");
- endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
- buffer.add(" || ");
- beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
- checkObject(input, '===');
- buffer.add(" && ");
- checkType(input, element);
- endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
- endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
+ withPrecedence(JSPrecedence.LOGICAL_OR_PRECEDENCE, () {
+ beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add('typeof ');
+ use(input, JSPrecedence.PREFIX_PRECEDENCE);
+ buffer.add(" === 'function'");
+ endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
+ buffer.add(" || ");
+ beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
+ checkObject(input, '===');
+ buffer.add(" && ");
+ checkType(input, element);
+ endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
+ });
}
void checkType(HInstruction input, Element element, [bool negative = false]) {
@@ -2309,15 +2385,15 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
// would need to check for List too.
assert(element !== compiler.listClass
&& !Elements.isListSupertype(element, compiler));
- beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
- checkString(input, '===');
- buffer.add(' || ');
- beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
- checkObject(input, '===');
- buffer.add(' && ');
- checkType(input, element);
- endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
- endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
+ withPrecedence(JSPrecedence.LOGICAL_OR_PRECEDENCE, () {
+ checkString(input, '===');
+ buffer.add(' || ');
+ withPrecedence(JSPrecedence.LOGICAL_AND_PRECEDENCE, () {
+ checkObject(input, '===');
+ buffer.add(' && ');
+ checkType(input, element);
+ });
+ });
}
void handleListOrSupertypeCheck(HInstruction input, Element element) {
@@ -2349,8 +2425,11 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
ClassElement objectClass = compiler.objectClass;
HInstruction input = node.expression;
+ int oldPrecedence;
if (node.nullOk) {
+ oldPrecedence = expectedPrecedence;
beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
+ expectedPrecedence = JSPrecedence.LOGICAL_OR_PRECEDENCE;
checkNull(input);
buffer.add(' || ');
}
@@ -2404,6 +2483,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
});
}
if (node.nullOk) {
+ expectedPrecedence = oldPrecedence;
endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
}
}

Powered by Google App Engine
This is Rietveld 408576698