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

Unified Diff: compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java

Issue 8393015: Add additional runtime type checks. Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 2 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: compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java
===================================================================
--- compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java (revision 650)
+++ compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java (working copy)
@@ -1669,8 +1669,9 @@
int numParams = params.size();
for (int i = 0; i < numParams; ++i) {
JsNameRef jsParam = jsParams.get(i).getName().makeRef();
- JsExpression expr = rtt.addTypeCheck(getCurrentClass(), jsParam,
- typeOf(params.get(i).getTypeNode()), null, params.get(i));
+ DartParameter param = params.get(i);
+ Type paramType = param.getSymbol().getType();
+ JsExpression expr = rtt.addTypeCheck(getCurrentClass(), jsParam, paramType, null, param);
fabiomfv 2011/10/26 14:43:25 assuming this change is basically refactoring?
jat 2011/10/31 20:16:14 No, this is what actually fixes issue 6. The prob
if (expr != jsParam) {
// if the expression was returned unchanged, omit the check
checks.add(new JsExprStmt(expr));
@@ -1843,6 +1844,8 @@
@Override
public JsNode visitIfStatement(DartIfStatement x) {
JsExpression jsCondition = (JsExpression) generate(x.getCondition());
+ jsCondition = rtt.addTypeCheck(getCurrentClass(), jsCondition, typeProvider.getBoolType(),
+ x.getCondition().getType(), x);
JsStatement jsThenStmt = (JsStatement) generate(x.getThenStatement());
JsStatement jsElseStmt = null;
if (x.getElseStatement() != null) {
@@ -1877,6 +1880,8 @@
@Override
public JsNode visitWhileStatement(DartWhileStatement x) {
JsExpression condition = (JsExpression) generate(x.getCondition());
+ condition = rtt.addTypeCheck(getCurrentClass(), condition, typeProvider.getBoolType(),
+ x.getCondition().getType(), x);
JsBlock body = (JsBlock) generate(x.getBody());
return new JsWhile(condition, body).setSourceRef(x);
}
@@ -1884,6 +1889,8 @@
@Override
public JsNode visitDoWhileStatement(DartDoWhileStatement x) {
JsExpression condition = (JsExpression) generate(x.getCondition());
+ condition = rtt.addTypeCheck(getCurrentClass(), condition, typeProvider.getBoolType(),
+ x.getCondition().getType(), x);
JsBlock body = (JsBlock) generate(x.getBody());
return new JsDoWhile(condition, body).setSourceRef(x);
}
@@ -1895,7 +1902,10 @@
JsFor jsFor = new JsFor().setSourceRef(x);
if (x.getCondition() != null) {
- jsFor.setCondition((JsExpression) generate(x.getCondition()));
+ JsExpression condExpr = (JsExpression) generate(x.getCondition());
+ condExpr = rtt.addTypeCheck(getCurrentClass(), condExpr, typeProvider.getBoolType(),
+ x.getCondition().getType(), x);
+ jsFor.setCondition(condExpr);
}
if (x.getIncrement() != null) {
jsFor.setIncrExpr((JsExpression) generate(x.getIncrement()));
@@ -1944,15 +1954,33 @@
DartFunction function = functionStack.peek();
if (function != null) {
// NOTE: FunctionExpressionInliner might be leaving return statements around
- DartTypeNode returnType = function.getReturnTypeNode();
- expr = rtt.addTypeCheck(getCurrentClass(), expr, typeOf(returnType),
- returnValue.getType(), x);
+ DartTypeNode returnTypeNode = function.getReturnTypeNode();
+ Type returnType = null;
+ if (returnTypeNode == null) {
+ // check for factory methods, which return the type of their name
+ returnType = getFactoryReturnType(function);
+ }
+ if (returnType == null) {
+ returnType = typeOf(returnTypeNode);
+ }
+ expr = rtt.addTypeCheck(getCurrentClass(), expr, returnType, returnValue.getType(), x);
}
jsRet.setExpr(expr);
}
return jsRet.setSourceRef(x);
}
+ /**
+ * Get the return type of a factory method.
+ *
+ * @param function
+ * @return {@link Type} instance or null if not a factory method or otherwise unavailable
+ */
+ private Type getFactoryReturnType(DartFunction function) {
+ // TODO: implement
+ return null;
+ }
+
@Override
public JsNode visitTryStatement(DartTryStatement x) {
JsTry jsTry = new JsTry();
@@ -2177,6 +2205,8 @@
@Override
public JsNode visitConditional(DartConditional x) {
JsExpression testExpr = (JsExpression) generate(x.getCondition());
+ testExpr = rtt.addTypeCheck(getCurrentClass(), testExpr, typeProvider.getBoolType(),
+ x.getCondition().getType(), x);
JsExpression thenExpr = (JsExpression) generate(x.getThenExpression());
JsExpression elseExpr = (JsExpression) generate(x.getElseExpression());
return new JsConditional(testExpr, thenExpr, elseExpr).setSourceRef(x);
@@ -2192,10 +2222,11 @@
return generateInstanceOfComparison(x);
}
+ DartExpression arg1 = x.getArg1();
DartExpression arg2 = x.getArg2();
JsExpression rhs = (JsExpression) generate(arg2);
if (operator == Token.ASSIGN) {
- return x.getArg1().accept(new Assignment(x, rhs, arg2.getType()));
+ return arg1.accept(new Assignment(x, rhs, arg2.getType()));
}
assert !operator.isUserDefinableOperator() || !operator.isAssignmentOperator() : x;
@@ -2208,8 +2239,12 @@
skipShim = optStrategy.canSkipOperatorShim(x);
}
- JsExpression lhs = (JsExpression) generate(x.getArg1());
+ JsExpression lhs = (JsExpression) generate(arg1);
Token op = x.getOperator();
+
+ lhs = rtt.addTypeCheck(getCurrentClass(), lhs, getRequiredType(op), arg1.getType(), arg1);
+ rhs = rtt.addTypeCheck(getCurrentClass(), rhs, getRequiredType(op), arg2.getType(), arg2);
+
if (skipShim) {
if (op.isEqualityOperator()) {
op = mapToStrictEquals(op);
@@ -2220,7 +2255,7 @@
op = mapToNonStrictEquals(op);
rhs = nulle();
}
- if (x.getArg1() instanceof DartNullLiteral) {
+ if (arg1 instanceof DartNullLiteral) {
JsExpression tmp = lhs;
lhs = rhs;
rhs = tmp;
@@ -2237,6 +2272,25 @@
}
}
+ /**
+ * Return a type which an operator requires for its operands.
+ *
+ * @param op operator
+ * @return a {@link Type} instance, which will be {@code null} if there are
+ * no restrictions
+ */
+ private Type getRequiredType(Token op) {
+ switch (op) {
+ case NOT:
fabiomfv 2011/10/26 14:43:25 we probably dont need NOT since we dont call getRe
jat 2011/10/31 20:16:14 Done.
+ case OR:
+ case AND:
+ return typeProvider.getBoolType();
+ // TODO: other operators?
+ default:
+ return null;
+ }
+ }
+
private Type getTypeOfIdentifier(DartIdentifier ident) {
Element element = ident.getReferencedElement();
DartTypeNode typeNode = null;
@@ -2374,6 +2428,8 @@
break;
case NOT:
jsUnaryOperator = JsUnaryOperator.NOT;
+ arg = rtt.addTypeCheck(getCurrentClass(), arg, typeProvider.getBoolType(),
+ x.getArg().getType(), x.getArg());
break;
default:
throw new AssertionError("Unexpected unary operator " + operator.name());

Powered by Google App Engine
This is Rietveld 408576698