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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 final JavaScriptBackend backend; 6 final JavaScriptBackend backend;
7 SsaCodeGeneratorTask(JavaScriptBackend backend) 7 SsaCodeGeneratorTask(JavaScriptBackend backend)
8 : this.backend = backend, 8 : this.backend = backend,
9 super(backend.compiler); 9 super(backend.compiler);
10 String get name() => 'SSA code generator'; 10 String get name() => 'SSA code generator';
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 buffer.add('('); 235 buffer.add('(');
236 } 236 }
237 } 237 }
238 238
239 void endExpression(int precedence) { 239 void endExpression(int precedence) {
240 if (precedence < expectedPrecedence) { 240 if (precedence < expectedPrecedence) {
241 buffer.add(')'); 241 buffer.add(')');
242 } 242 }
243 } 243 }
244 244
245 void withPrecedence(int precedence, void action()) {
246 int oldPrecedence = expectedPrecedence;
247 beginExpression(precedence);
248 expectedPrecedence = precedence;
249 action();
250 expectedPrecedence = oldPrecedence;
251 endExpression(precedence);
252 }
253
245 void preGenerateMethod(HGraph graph) { 254 void preGenerateMethod(HGraph graph) {
246 new SsaInstructionMerger(generateAtUseSite).visitGraph(graph); 255 new SsaInstructionMerger(generateAtUseSite).visitGraph(graph);
247 new SsaConditionMerger(generateAtUseSite, 256 new SsaConditionMerger(generateAtUseSite,
248 controlFlowOperators).visitGraph(graph); 257 controlFlowOperators).visitGraph(graph);
249 SsaLiveIntervalBuilder intervalBuilder = 258 SsaLiveIntervalBuilder intervalBuilder =
250 new SsaLiveIntervalBuilder(compiler); 259 new SsaLiveIntervalBuilder(compiler);
251 intervalBuilder.visitGraph(graph); 260 intervalBuilder.visitGraph(graph);
252 SsaVariableAllocator allocator = new SsaVariableAllocator( 261 SsaVariableAllocator allocator = new SsaVariableAllocator(
253 compiler, 262 compiler,
254 intervalBuilder.liveInstructions, 263 intervalBuilder.liveInstructions,
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; 1171 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE;
1163 visitInvokeUnary(node, op); 1172 visitInvokeUnary(node, op);
1164 buffer.add(' >>> 0'); 1173 buffer.add(' >>> 0');
1165 this.expectedPrecedence = oldPrecedence; 1174 this.expectedPrecedence = oldPrecedence;
1166 endExpression(unsignedShiftPrecedences.precedence); 1175 endExpression(unsignedShiftPrecedences.precedence);
1167 } else { 1176 } else {
1168 visitInvokeUnary(node, op); 1177 visitInvokeUnary(node, op);
1169 } 1178 }
1170 } 1179 }
1171 1180
1181 void emitIdentityComparison(HInstruction left, HInstruction right) {
1182 HType leftType = left.propagatedType;
1183 HType rightType = right.propagatedType;
1184 if (leftType.canBeNull() && rightType.canBeNull()) {
1185 if (left.isConstantNull() || right.isConstantNull() ||
1186 (leftType.isPrimitive() && leftType == rightType)) {
1187 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1188 use(left, JSPrecedence.EQUALITY_PRECEDENCE);
1189 buffer.add(' == ');
1190 use(right, JSPrecedence.RELATIONAL_PRECEDENCE);
1191 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1192 } else {
1193 assert(NullConstant.JsNull == 'null');
1194 withPrecedence(JSPrecedence.CONDITIONAL_PRECEDENCE, () {
1195 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1196 use(left, JSPrecedence.EQUALITY_PRECEDENCE);
1197 buffer.add(' == null');
1198 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1199 buffer.add(' ? ');
1200 this.expectedPrecedence = JSPrecedence.ASSIGNMENT_PRECEDENCE;
1201 withPrecedence(JSPrecedence.LOGICAL_AND_PRECEDENCE, () {
1202 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1203 use(right, JSPrecedence.EQUALITY_PRECEDENCE);
1204 buffer.add(' == null');
1205 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1206 buffer.add(" : ");
1207 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1208 use(left, JSPrecedence.EQUALITY_PRECEDENCE);
1209 buffer.add(' === ');
1210 use(right, JSPrecedence.EQUALITY_PRECEDENCE);
1211 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1212 });
1213 });
1214 }
1215 } else {
1216 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1217 use(left, JSPrecedence.EQUALITY_PRECEDENCE);
1218 buffer.add(' === ');
1219 use(right, JSPrecedence.RELATIONAL_PRECEDENCE);
1220 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1221 }
1222 }
1223
1172 visitEquals(HEquals node) { 1224 visitEquals(HEquals node) {
1173 if (node.builtin) { 1225 if (node.builtin) {
1174 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); 1226 emitIdentityComparison(node.left, node.right);
1175 use(node.left, JSPrecedence.EQUALITY_PRECEDENCE);
1176 buffer.add(' === ');
1177 use(node.right, JSPrecedence.RELATIONAL_PRECEDENCE);
1178 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1179 } else if (node.element === equalsNullElement || 1227 } else if (node.element === equalsNullElement ||
1180 node.element === boolifiedEqualsNullElement) { 1228 node.element === boolifiedEqualsNullElement) {
1181 beginExpression(JSPrecedence.CALL_PRECEDENCE); 1229 beginExpression(JSPrecedence.CALL_PRECEDENCE);
1182 use(node.target, JSPrecedence.CALL_PRECEDENCE); 1230 use(node.target, JSPrecedence.CALL_PRECEDENCE);
1183 buffer.add('('); 1231 buffer.add('(');
1184 use(node.left, JSPrecedence.ASSIGNMENT_PRECEDENCE); 1232 use(node.left, JSPrecedence.ASSIGNMENT_PRECEDENCE);
1185 buffer.add(')'); 1233 buffer.add(')');
1186 endExpression(JSPrecedence.CALL_PRECEDENCE); 1234 endExpression(JSPrecedence.CALL_PRECEDENCE);
1187 } else { 1235 } else {
1188 visitInvokeStatic(node); 1236 visitInvokeStatic(node);
1189 } 1237 }
1190 } 1238 }
1191 1239
1240 visitIdentity(HIdentity node) {
1241 assert(node.builtin);
1242 emitIdentityComparison(node.left, node.right);
1243 }
1244
1192 visitAdd(HAdd node) => visitInvokeBinary(node, '+'); 1245 visitAdd(HAdd node) => visitInvokeBinary(node, '+');
1193 visitDivide(HDivide node) => visitInvokeBinary(node, '/'); 1246 visitDivide(HDivide node) => visitInvokeBinary(node, '/');
1194 visitMultiply(HMultiply node) => visitInvokeBinary(node, '*'); 1247 visitMultiply(HMultiply node) => visitInvokeBinary(node, '*');
1195 visitSubtract(HSubtract node) => visitInvokeBinary(node, '-'); 1248 visitSubtract(HSubtract node) => visitInvokeBinary(node, '-');
1196 // Truncating divide does not have a JS equivalent. 1249 // Truncating divide does not have a JS equivalent.
1197 visitTruncatingDivide(HTruncatingDivide node) => visitInvokeStatic(node); 1250 visitTruncatingDivide(HTruncatingDivide node) => visitInvokeStatic(node);
1198 // Modulo cannot be mapped to the native operator (different semantics). 1251 // Modulo cannot be mapped to the native operator (different semantics).
1199 visitModulo(HModulo node) => visitInvokeStatic(node); 1252 visitModulo(HModulo node) => visitInvokeStatic(node);
1200 1253
1201 visitBitAnd(HBitAnd node) => visitBitInvokeBinary(node, '&'); 1254 visitBitAnd(HBitAnd node) => visitBitInvokeBinary(node, '&');
1202 visitBitNot(HBitNot node) => visitBitInvokeUnary(node, '~'); 1255 visitBitNot(HBitNot node) => visitBitInvokeUnary(node, '~');
1203 visitBitOr(HBitOr node) => visitBitInvokeBinary(node, '|'); 1256 visitBitOr(HBitOr node) => visitBitInvokeBinary(node, '|');
1204 visitBitXor(HBitXor node) => visitBitInvokeBinary(node, '^'); 1257 visitBitXor(HBitXor node) => visitBitInvokeBinary(node, '^');
1205 visitShiftRight(HShiftRight node) => visitBitInvokeBinary(node, '>>'); 1258 visitShiftRight(HShiftRight node) => visitBitInvokeBinary(node, '>>');
1206 visitShiftLeft(HShiftLeft node) => visitBitInvokeBinary(node, '<<'); 1259 visitShiftLeft(HShiftLeft node) => visitBitInvokeBinary(node, '<<');
1207 1260
1208 visitNegate(HNegate node) => visitInvokeUnary(node, '-'); 1261 visitNegate(HNegate node) => visitInvokeUnary(node, '-');
1209 1262
1210 visitIdentity(HIdentity node) => visitInvokeBinary(node, '===');
1211 visitLess(HLess node) => visitInvokeBinary(node, '<'); 1263 visitLess(HLess node) => visitInvokeBinary(node, '<');
1212 visitLessEqual(HLessEqual node) => visitInvokeBinary(node, '<='); 1264 visitLessEqual(HLessEqual node) => visitInvokeBinary(node, '<=');
1213 visitGreater(HGreater node) => visitInvokeBinary(node, '>'); 1265 visitGreater(HGreater node) => visitInvokeBinary(node, '>');
1214 visitGreaterEqual(HGreaterEqual node) => visitInvokeBinary(node, '>='); 1266 visitGreaterEqual(HGreaterEqual node) => visitInvokeBinary(node, '>=');
1215 1267
1216 visitBoolify(HBoolify node) { 1268 visitBoolify(HBoolify node) {
1217 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); 1269 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
1218 assert(node.inputs.length == 1); 1270 assert(node.inputs.length == 1);
1219 use(node.inputs[0], JSPrecedence.EQUALITY_PRECEDENCE); 1271 use(node.inputs[0], JSPrecedence.EQUALITY_PRECEDENCE);
1220 buffer.add(' === true'); 1272 buffer.add(' === true');
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE); 1812 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE);
1761 buffer.add(parts[0]); 1813 buffer.add(parts[0]);
1762 for (int i = 0; i < inputs.length; i++) { 1814 for (int i = 0; i < inputs.length; i++) {
1763 use(inputs[i], JSPrecedence.EXPRESSION_PRECEDENCE); 1815 use(inputs[i], JSPrecedence.EXPRESSION_PRECEDENCE);
1764 buffer.add(parts[i + 1]); 1816 buffer.add(parts[i + 1]);
1765 } 1817 }
1766 endExpression(JSPrecedence.EXPRESSION_PRECEDENCE); 1818 endExpression(JSPrecedence.EXPRESSION_PRECEDENCE);
1767 } 1819 }
1768 1820
1769 visitForeignNew(HForeignNew node) { 1821 visitForeignNew(HForeignNew node) {
1770 var i = 0; 1822 int j = 0;
1771 node.element.forEachInstanceField( 1823 node.element.forEachInstanceField(
1772 includeBackendMembers: true, 1824 includeBackendMembers: true,
1773 includeSuperMembers: true, 1825 includeSuperMembers: true,
1774 f: (ClassElement enclosingClass, Element member) { 1826 f: (ClassElement enclosingClass, Element member) {
1775 world.registerFieldInitializer(member.name, 1827 world.registerFieldInitializer(member.name,
1776 enclosingClass.computeType(compiler), 1828 enclosingClass.computeType(compiler),
1777 node.inputs[i].isInteger()); 1829 node.inputs[j].isInteger());
1778 1830
1779 i++; 1831 j++;
1780 }); 1832 });
1781 String jsClassReference = compiler.namer.isolateAccess(node.element); 1833 String jsClassReference = compiler.namer.isolateAccess(node.element);
1782 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); 1834 beginExpression(JSPrecedence.MEMBER_PRECEDENCE);
1783 buffer.add('new $jsClassReference('); 1835 buffer.add('new $jsClassReference(');
1784 // We can't use 'visitArguments', since our arguments start at input[0]. 1836 // We can't use 'visitArguments', since our arguments start at input[0].
1785 List<HInstruction> inputs = node.inputs; 1837 List<HInstruction> inputs = node.inputs;
1786 for (int i = 0; i < inputs.length; i++) { 1838 for (int i = 0; i < inputs.length; i++) {
1787 if (i != 0) buffer.add(', '); 1839 if (i != 0) buffer.add(', ');
1788 use(inputs[i], JSPrecedence.ASSIGNMENT_PRECEDENCE); 1840 use(inputs[i], JSPrecedence.ASSIGNMENT_PRECEDENCE);
1789 } 1841 }
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 2270
2219 void checkBool(HInstruction input, String cmp) { 2271 void checkBool(HInstruction input, String cmp) {
2220 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2272 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2221 buffer.add('typeof '); 2273 buffer.add('typeof ');
2222 use(input, JSPrecedence.PREFIX_PRECEDENCE); 2274 use(input, JSPrecedence.PREFIX_PRECEDENCE);
2223 buffer.add(" $cmp 'boolean'"); 2275 buffer.add(" $cmp 'boolean'");
2224 endExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2276 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2225 } 2277 }
2226 2278
2227 void checkObject(HInstruction input, String cmp) { 2279 void checkObject(HInstruction input, String cmp) {
2228 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2280 assert(NullConstant.JsNull == 'null');
2229 buffer.add('typeof '); 2281 if (cmp == "===") {
2230 use(input, JSPrecedence.PREFIX_PRECEDENCE); 2282 withPrecedence(JSPrecedence.LOGICAL_AND_PRECEDENCE, () {
2231 buffer.add(" $cmp 'object'"); 2283 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2232 endExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2284 buffer.add('typeof ');
2285 use(input, JSPrecedence.PREFIX_PRECEDENCE);
2286 buffer.add(" === 'object'");
2287 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2288 buffer.add(" && ");
2289 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2290 use(input, JSPrecedence.PREFIX_PRECEDENCE);
2291 buffer.add(" !== null");
2292 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2293 });
2294 } else {
2295 assert(cmp == "!==");
2296 withPrecedence(JSPrecedence.LOGICAL_OR_PRECEDENCE, () {
2297 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2298 buffer.add('typeof ');
2299 use(input, JSPrecedence.PREFIX_PRECEDENCE);
2300 buffer.add(" !== 'object'");
2301 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2302 buffer.add(" || ");
2303 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2304 use(input, JSPrecedence.PREFIX_PRECEDENCE);
2305 buffer.add(" === null");
2306 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2307 });
2308 }
2233 } 2309 }
2234 2310
2235 void checkArray(HInstruction input, String cmp) { 2311 void checkArray(HInstruction input, String cmp) {
2236 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2312 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2237 use(input, JSPrecedence.MEMBER_PRECEDENCE); 2313 use(input, JSPrecedence.MEMBER_PRECEDENCE);
2238 buffer.add('.constructor $cmp Array'); 2314 buffer.add('.constructor $cmp Array');
2239 endExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2315 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2240 } 2316 }
2241 2317
2242 void checkImmutableArray(HInstruction input) { 2318 void checkImmutableArray(HInstruction input) {
(...skipping 15 matching lines...) Expand all
2258 void checkFixedArray(HInstruction input) { 2334 void checkFixedArray(HInstruction input) {
2259 beginExpression(JSPrecedence.PREFIX_PRECEDENCE); 2335 beginExpression(JSPrecedence.PREFIX_PRECEDENCE);
2260 use(input, JSPrecedence.MEMBER_PRECEDENCE); 2336 use(input, JSPrecedence.MEMBER_PRECEDENCE);
2261 buffer.add('.fixed\$length'); 2337 buffer.add('.fixed\$length');
2262 endExpression(JSPrecedence.PREFIX_PRECEDENCE); 2338 endExpression(JSPrecedence.PREFIX_PRECEDENCE);
2263 } 2339 }
2264 2340
2265 void checkNull(HInstruction input) { 2341 void checkNull(HInstruction input) {
2266 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2342 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2267 use(input, JSPrecedence.EQUALITY_PRECEDENCE); 2343 use(input, JSPrecedence.EQUALITY_PRECEDENCE);
2268 buffer.add(" === (void 0)"); 2344 buffer.add(" == null");
2269 endExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2345 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2270 } 2346 }
2271 2347
2272 void checkFunction(HInstruction input, Element element) { 2348 void checkFunction(HInstruction input, Element element) {
2273 beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2349 withPrecedence(JSPrecedence.LOGICAL_OR_PRECEDENCE, () {
2274 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2350 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2275 buffer.add('typeof '); 2351 buffer.add('typeof ');
2276 use(input, JSPrecedence.PREFIX_PRECEDENCE); 2352 use(input, JSPrecedence.PREFIX_PRECEDENCE);
2277 buffer.add(" === 'function'"); 2353 buffer.add(" === 'function'");
2278 endExpression(JSPrecedence.EQUALITY_PRECEDENCE); 2354 endExpression(JSPrecedence.EQUALITY_PRECEDENCE);
2279 buffer.add(" || "); 2355 buffer.add(" || ");
2280 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2356 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2281 checkObject(input, '==='); 2357 checkObject(input, '===');
2282 buffer.add(" && "); 2358 buffer.add(" && ");
2283 checkType(input, element); 2359 checkType(input, element);
2284 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2360 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2285 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2361 });
2286 } 2362 }
2287 2363
2288 void checkType(HInstruction input, Element element, [bool negative = false]) { 2364 void checkType(HInstruction input, Element element, [bool negative = false]) {
2289 world.registerIsCheck(element); 2365 world.registerIsCheck(element);
2290 bool requiresNativeIsCheck = 2366 bool requiresNativeIsCheck =
2291 backend.emitter.nativeEmitter.requiresNativeIsCheck(element); 2367 backend.emitter.nativeEmitter.requiresNativeIsCheck(element);
2292 if (!requiresNativeIsCheck) { 2368 if (!requiresNativeIsCheck) {
2293 if (negative) { 2369 if (negative) {
2294 buffer.add('!'); 2370 buffer.add('!');
2295 } else { 2371 } else {
2296 buffer.add('!!'); 2372 buffer.add('!!');
2297 } 2373 }
2298 } else if (negative) { 2374 } else if (negative) {
2299 buffer.add('!'); 2375 buffer.add('!');
2300 } 2376 }
2301 use(input, JSPrecedence.MEMBER_PRECEDENCE); 2377 use(input, JSPrecedence.MEMBER_PRECEDENCE);
2302 buffer.add('.'); 2378 buffer.add('.');
2303 buffer.add(compiler.namer.operatorIs(element)); 2379 buffer.add(compiler.namer.operatorIs(element));
2304 if (requiresNativeIsCheck) buffer.add('()'); 2380 if (requiresNativeIsCheck) buffer.add('()');
2305 } 2381 }
2306 2382
2307 void handleStringSupertypeCheck(HInstruction input, Element element) { 2383 void handleStringSupertypeCheck(HInstruction input, Element element) {
2308 // Make sure List and String don't share supertypes, otherwise we 2384 // Make sure List and String don't share supertypes, otherwise we
2309 // would need to check for List too. 2385 // would need to check for List too.
2310 assert(element !== compiler.listClass 2386 assert(element !== compiler.listClass
2311 && !Elements.isListSupertype(element, compiler)); 2387 && !Elements.isListSupertype(element, compiler));
2312 beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2388 withPrecedence(JSPrecedence.LOGICAL_OR_PRECEDENCE, () {
2313 checkString(input, '==='); 2389 checkString(input, '===');
2314 buffer.add(' || '); 2390 buffer.add(' || ');
2315 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2391 withPrecedence(JSPrecedence.LOGICAL_AND_PRECEDENCE, () {
2316 checkObject(input, '==='); 2392 checkObject(input, '===');
2317 buffer.add(' && '); 2393 buffer.add(' && ');
2318 checkType(input, element); 2394 checkType(input, element);
2319 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2395 });
2320 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2396 });
2321 } 2397 }
2322 2398
2323 void handleListOrSupertypeCheck(HInstruction input, Element element) { 2399 void handleListOrSupertypeCheck(HInstruction input, Element element) {
2324 // Make sure List and String don't share supertypes, otherwise we 2400 // Make sure List and String don't share supertypes, otherwise we
2325 // would need to check for String too. 2401 // would need to check for String too.
2326 assert(element !== compiler.stringClass 2402 assert(element !== compiler.stringClass
2327 && !Elements.isStringSupertype(element, compiler)); 2403 && !Elements.isStringSupertype(element, compiler));
2328 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2404 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2329 checkObject(input, '==='); 2405 checkObject(input, '===');
2330 buffer.add(' && ('); 2406 buffer.add(' && (');
(...skipping 11 matching lines...) Expand all
2342 Element element = type.element; 2418 Element element = type.element;
2343 if (element.kind === ElementKind.TYPE_VARIABLE) { 2419 if (element.kind === ElementKind.TYPE_VARIABLE) {
2344 compiler.unimplemented("visitIs for type variables", instruction: node); 2420 compiler.unimplemented("visitIs for type variables", instruction: node);
2345 } else if (element.kind === ElementKind.TYPEDEF) { 2421 } else if (element.kind === ElementKind.TYPEDEF) {
2346 compiler.unimplemented("visitIs for typedefs", instruction: node); 2422 compiler.unimplemented("visitIs for typedefs", instruction: node);
2347 } 2423 }
2348 LibraryElement coreLibrary = compiler.coreLibrary; 2424 LibraryElement coreLibrary = compiler.coreLibrary;
2349 ClassElement objectClass = compiler.objectClass; 2425 ClassElement objectClass = compiler.objectClass;
2350 HInstruction input = node.expression; 2426 HInstruction input = node.expression;
2351 2427
2428 int oldPrecedence;
2352 if (node.nullOk) { 2429 if (node.nullOk) {
2430 oldPrecedence = expectedPrecedence;
2353 beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2431 beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2432 expectedPrecedence = JSPrecedence.LOGICAL_OR_PRECEDENCE;
2354 checkNull(input); 2433 checkNull(input);
2355 buffer.add(' || '); 2434 buffer.add(' || ');
2356 } 2435 }
2357 if (element === objectClass || element === compiler.dynamicClass) { 2436 if (element === objectClass || element === compiler.dynamicClass) {
2358 // The constant folder also does this optimization, but we make 2437 // The constant folder also does this optimization, but we make
2359 // it safe by assuming it may have not run. 2438 // it safe by assuming it may have not run.
2360 buffer.add('true'); 2439 buffer.add('true');
2361 } else if (element == compiler.stringClass) { 2440 } else if (element == compiler.stringClass) {
2362 checkString(input, '==='); 2441 checkString(input, '===');
2363 } else if (element == compiler.doubleClass) { 2442 } else if (element == compiler.doubleClass) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 checkObject(node.typeInfoCall, '==='); 2476 checkObject(node.typeInfoCall, '===');
2398 cls.typeParameters.forEach((name, _) { 2477 cls.typeParameters.forEach((name, _) {
2399 buffer.add(' && '); 2478 buffer.add(' && ');
2400 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2479 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2401 use(node.typeInfoCall, JSPrecedence.EQUALITY_PRECEDENCE); 2480 use(node.typeInfoCall, JSPrecedence.EQUALITY_PRECEDENCE);
2402 buffer.add(".${name.slowToString()} === '${arguments.head}'"); 2481 buffer.add(".${name.slowToString()} === '${arguments.head}'");
2403 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2482 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2404 }); 2483 });
2405 } 2484 }
2406 if (node.nullOk) { 2485 if (node.nullOk) {
2486 expectedPrecedence = oldPrecedence;
2407 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2487 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2408 } 2488 }
2409 } 2489 }
2410 2490
2411 void visitTypeConversion(HTypeConversion node) { 2491 void visitTypeConversion(HTypeConversion node) {
2412 if (node.isChecked()) { 2492 if (node.isChecked()) {
2413 Element element = node.type.computeType(compiler).element; 2493 Element element = node.type.computeType(compiler).element;
2414 world.registerIsCheck(element); 2494 world.registerIsCheck(element);
2415 SourceString helper; 2495 SourceString helper;
2416 String additionalArgument; 2496 String additionalArgument;
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
2917 startBailoutSwitch(); 2997 startBailoutSwitch();
2918 } 2998 }
2919 } 2999 }
2920 3000
2921 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 3001 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2922 if (labeledBlockInfo.body.start.hasGuards()) { 3002 if (labeledBlockInfo.body.start.hasGuards()) {
2923 endBailoutSwitch(); 3003 endBailoutSwitch();
2924 } 3004 }
2925 } 3005 }
2926 } 3006 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698