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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart

Issue 13019003: Enable full type-checks in checked mode. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use HTypeConversion instead of HIs. Created 7 years, 7 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 part of ssa; 5 part of ssa;
6 6
7 class SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 2449 matching lines...) Expand 10 before | Expand all | Expand 10 after
2460 js.Binary notObjectOrIndexingTest = 2460 js.Binary notObjectOrIndexingTest =
2461 new js.Binary('||', objectTest, notIndexingTest); 2461 new js.Binary('||', objectTest, notIndexingTest);
2462 test = new js.Binary('&&', stringTest, notObjectOrIndexingTest); 2462 test = new js.Binary('&&', stringTest, notObjectOrIndexingTest);
2463 } else { 2463 } else {
2464 compiler.internalError('Unexpected type guard', instruction: input); 2464 compiler.internalError('Unexpected type guard', instruction: input);
2465 } 2465 }
2466 return test; 2466 return test;
2467 } 2467 }
2468 2468
2469 void visitTypeConversion(HTypeConversion node) { 2469 void visitTypeConversion(HTypeConversion node) {
2470 if (node.isChecked) { 2470 if (!node.isChecked) {
2471 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { 2471 use(node.checkedInput);
2472 js.Expression test = generateTest(node); 2472 return;
2473 js.Block oldContainer = currentContainer; 2473 } else if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
ngeoffray 2013/05/13 09:10:59 I would remove the else.
karlklose 2013/05/14 13:49:41 Done.
2474 js.Statement body = new js.Block.empty(); 2474 js.Expression test = generateTest(node);
2475 currentContainer = body; 2475 js.Block oldContainer = currentContainer;
2476 if (node.isArgumentTypeCheck) { 2476 js.Statement body = new js.Block.empty();
2477 generateThrowWithHelper('iae', node.checkedInput); 2477 currentContainer = body;
2478 } else if (node.isReceiverTypeCheck) { 2478 if (node.isArgumentTypeCheck) {
2479 use(node.checkedInput); 2479 generateThrowWithHelper('iae', node.checkedInput);
2480 String methodName = 2480 } else if (node.isReceiverTypeCheck) {
2481 backend.namer.invocationName(node.receiverTypeCheckSelector); 2481 use(node.checkedInput);
2482 js.Expression call = jsPropertyCall(pop(), methodName, []); 2482 String methodName =
2483 pushStatement(new js.Throw(call)); 2483 backend.namer.invocationName(node.receiverTypeCheckSelector);
2484 } 2484 js.Expression call = jsPropertyCall(pop(), methodName, []);
2485 currentContainer = oldContainer; 2485 pushStatement(new js.Throw(call));
2486 body = unwrapStatement(body);
2487 pushStatement(new js.If.noElse(test, body), node);
2488 return;
2489 } 2486 }
2487 currentContainer = oldContainer;
2488 body = unwrapStatement(body);
2489 pushStatement(new js.If.noElse(test, body), node);
2490 return;
2491 }
2490 2492
2491 assert(node.isCheckedModeCheck || node.isCastTypeCheck); 2493 assert(node.isCheckedModeCheck || node.isCastTypeCheck);
2492 DartType type = node.typeExpression; 2494 DartType type = node.typeExpression;
2493 world.registerIsCheck(type, work.resolutionTree); 2495 world.registerIsCheck(type, work.resolutionTree);
2494 2496
2495 // TODO(kasperl): For now, we ignore type checks against type 2497 FunctionElement helperElement;
2496 // variables. This is clearly wrong. 2498 if (node.isBooleanConversionCheck) {
2497 if (type.kind == TypeKind.TYPE_VARIABLE) { 2499 helperElement =
2498 use(node.checkedInput); 2500 compiler.findHelper(const SourceString('boolConversionCheck'));
2499 return; 2501 } else {
2500 } 2502 helperElement = backend.getCheckedModeHelper(type,
2501 2503 typeCast: node.isCastTypeCheck);
2502 FunctionElement helperElement; 2504 }
2503 if (node.isBooleanConversionCheck) { 2505 world.registerStaticUse(helperElement);
2504 helperElement = 2506 List<js.Expression> arguments = <js.Expression>[];
2505 compiler.findHelper(const SourceString('boolConversionCheck')); 2507 use(node.checkedInput);
2506 } else { 2508 arguments.add(pop());
2507 helperElement = backend.getCheckedModeHelper(type, 2509 int parameterCount =
2508 typeCast: node.isCastTypeCheck); 2510 helperElement.computeSignature(compiler).parameterCount;
2509 } 2511 // TODO(johnniwinther): Refactor this to avoid using the parameter count
2510 world.registerStaticUse(helperElement); 2512 // to determine how the helper should be called.
2511 List<js.Expression> arguments = <js.Expression>[]; 2513 if (node.typeExpression.kind == TypeKind.TYPE_VARIABLE) {
2512 use(node.checkedInput); 2514 assert(parameterCount == 2);
2515 use(node.typeRepresentation);
2513 arguments.add(pop()); 2516 arguments.add(pop());
2514 int parameterCount = 2517 } else if (parameterCount == 2) {
2515 helperElement.computeSignature(compiler).parameterCount; 2518 // 2 arguments implies that the method is either [propertyTypeCheck],
2516 // TODO(johnniwinther): Refactor this to avoid using the parameter count 2519 // [propertyTypeCast] or [assertObjectIsSubtype].
2517 // to determine how the helper should be called. 2520 assert(!type.isMalformed);
2518 if (parameterCount == 2) { 2521 String additionalArgument = backend.namer.operatorIs(type.element);
2519 // 2 arguments implies that the method is either [propertyTypeCheck] 2522 arguments.add(js.string(additionalArgument));
2520 // or [propertyTypeCast]. 2523 } else if (parameterCount == 3) {
2521 assert(!type.isMalformed); 2524 // 3 arguments implies that the method is [malformedTypeCheck].
2522 String additionalArgument = backend.namer.operatorIs(type.element); 2525 assert(type.isMalformed);
2523 arguments.add(js.string(additionalArgument)); 2526 String reasons = Types.fetchReasonsFromMalformedType(type);
2524 } else if (parameterCount == 3) { 2527 arguments.add(js.string('$type'));
2525 // 3 arguments implies that the method is [malformedTypeCheck]. 2528 // TODO(johnniwinther): Handle escaping correctly.
2526 assert(type.isMalformed); 2529 arguments.add(js.string(reasons));
2527 String reasons = Types.fetchReasonsFromMalformedType(type); 2530 } else if (parameterCount == 4) {
2528 arguments.add(js.string('$type')); 2531 Element element = type.element;
2529 // TODO(johnniwinther): Handle escaping correctly. 2532 String isField = backend.namer.operatorIs(element);
2530 arguments.add(js.string(reasons)); 2533 arguments.add(js.string(isField));
2531 } else { 2534 use(node.typeRepresentation);
2532 assert(!type.isMalformed); 2535 arguments.add(pop());
2533 } 2536 String asField = backend.namer.substitutionName(element);
2534 String helperName = backend.namer.isolateAccess(helperElement); 2537 arguments.add(js.string(asField));
2535 push(new js.Call(new js.VariableUse(helperName), arguments));
2536 } else { 2538 } else {
2537 use(node.checkedInput); 2539 assert(!type.isMalformed);
2540 // No additional arguments needed.
2538 } 2541 }
2542 String helperName = backend.namer.isolateAccess(helperElement);
2543 push(new js.Call(new js.VariableUse(helperName), arguments));
2539 } 2544 }
2540 } 2545 }
2541 2546
2542 class SsaOptimizedCodeGenerator extends SsaCodeGenerator { 2547 class SsaOptimizedCodeGenerator extends SsaCodeGenerator {
2543 SsaOptimizedCodeGenerator(backend, work) : super(backend, work); 2548 SsaOptimizedCodeGenerator(backend, work) : super(backend, work);
2544 2549
2545 HBasicBlock beginGraph(HGraph graph) { 2550 HBasicBlock beginGraph(HGraph graph) {
2546 return graph.entry; 2551 return graph.entry;
2547 } 2552 }
2548 2553
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
2976 if (leftType.canBeNull() && rightType.canBeNull()) { 2981 if (leftType.canBeNull() && rightType.canBeNull()) {
2977 if (left.isConstantNull() || right.isConstantNull() || 2982 if (left.isConstantNull() || right.isConstantNull() ||
2978 (leftType.isPrimitive() && leftType == rightType)) { 2983 (leftType.isPrimitive() && leftType == rightType)) {
2979 return '=='; 2984 return '==';
2980 } 2985 }
2981 return null; 2986 return null;
2982 } else { 2987 } else {
2983 return '==='; 2988 return '===';
2984 } 2989 }
2985 } 2990 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698