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

Unified Diff: lib/src/compiler/code_generator.dart

Issue 1964263002: fuse some null checks with type checks, introduce a special bool variant (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 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 side-by-side diff with in-line comments
Download patch
Index: lib/src/compiler/code_generator.dart
diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart
index 95dba1cdabaa92703a3e0c6a11ea8fa81638d0fa..d7a99ba629d8fc93344eb2be4c897b47d924a21c 100644
--- a/lib/src/compiler/code_generator.dart
+++ b/lib/src/compiler/code_generator.dart
@@ -446,27 +446,49 @@ class CodeGenerator extends GeneralizingAstVisitor
}
@override
- visitAsExpression(AsExpression node) {
- var from = getStaticType(node.expression);
- var to = node.type.type;
+ visitAsExpression(AsExpression node) =>
+ _emitCast(node.expression, to: node.type.type);
- var fromExpr = _visit(node.expression);
+ /// Emits a cast and/or a null check (i.e. a cast to a non-null type).
+ JS.Expression _emitCast(Expression fromExpr,
+ {DartType to, bool checkNull: false}) {
+
+ var jsFrom = _visit(fromExpr);
+ var from = getStaticType(fromExpr);
+
+ JS.Expression maybeCheckNull(JS.Expression jsExpr) {
Jennifer Messerly 2016/05/10 23:42:12 aside: it might be a better architecture to fuse t
+ if (checkNull && isNullable(fromExpr)) {
+ return js.call('dart.notNull(#)', jsExpr);
+ }
+ return jsExpr;
+ }
// Skip the cast if it's not needed.
- if (rules.isSubtypeOf(from, to)) return fromExpr;
+ if (to == null || rules.isSubtypeOf(from, to)) {
+ return maybeCheckNull(jsFrom);
+ }
// All Dart number types map to a JS double.
if (_isNumberInJS(from) && _isNumberInJS(to)) {
// Make sure to check when converting to int.
if (from != types.intType && to == types.intType) {
- return js.call('dart.asInt(#)', [fromExpr]);
+ // TODO(jmesserly): fuse this with notNull check.
+ return maybeCheckNull(js.call('dart.asInt(#)', [jsFrom]));
}
// A no-op in JavaScript.
- return fromExpr;
+ return maybeCheckNull(jsFrom);
}
- return js.call('dart.as(#, #)', [fromExpr, _emitType(to)]);
+ if (to == types.boolType && checkNull) {
+ return js.call('dart.test(#)', _visit(fromExpr));
+ }
+
+ if (checkNull && isNullable(fromExpr)) {
+ return js.call('dart.asNotNull(#, #)', [jsFrom, _emitType(to)]);
+ } else {
+ return js.call('dart.as(#, #)', [jsFrom, _emitType(to)]);
+ }
}
@override
@@ -3059,9 +3081,10 @@ class CodeGenerator extends GeneralizingAstVisitor
JS.Expression notNull(Expression expr) {
if (expr == null) return null;
- var jsExpr = _visit(expr);
- if (!isNullable(expr)) return jsExpr;
- return js.call('dart.notNull(#)', jsExpr);
+ if (expr is AsExpression) {
+ return _emitCast(expr.expression, to: expr.type.type, checkNull: true);
+ }
+ return _emitCast(expr, checkNull: true);
}
@override

Powered by Google App Engine
This is Rietveld 408576698