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

Unified Diff: lib/src/codegen/js_codegen.dart

Issue 961513002: Flesh out dynamic invocation code (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Revert runtime changes Created 5 years, 10 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
« no previous file with comments | « no previous file | test/codegen/expect/dart/_interceptors.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/codegen/js_codegen.dart
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
index cadeb9090c0f1e429e6bb906ea58913be5bbd7f2..d0981c32aadec08e504e97dc801530608dad4b04 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -698,10 +698,27 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
return result;
}
+ JS.Node _emitDPutIfDynamic(
+ Expression target, SimpleIdentifier id, Expression rhs) {
+ if (rules.isDynamicTarget(target)) {
+ return js.call('dart.dput(#, #, #)', [
+ _visit(target),
+ js.string(id.name, "'"),
+ _visit(rhs)
+ ]);
+ } else {
+ return null;
+ }
+ }
+
@override
JS.Node visitAssignmentExpression(AssignmentExpression node) {
var lhs = node.leftHandSide;
var rhs = node.rightHandSide;
+ return _emitAssignment(lhs, rhs, node.parent);
+ }
+
+ JS.Node _emitAssignment(Expression lhs, Expression rhs, [AstNode parent]) {
if (lhs is IndexExpression) {
String code;
var target = _getTarget(lhs);
@@ -714,17 +731,15 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
}
if (lhs is PropertyAccess) {
- var target = _getTarget(lhs);
- if (rules.isDynamicTarget(target)) {
- return js.call('dart.dput(#, #, #)', [
- _visit(target),
- js.string(lhs.propertyName.name, "'"),
- _visit(rhs)
- ]);
- }
+ var result = _emitDPutIfDynamic(_getTarget(lhs), lhs.propertyName, rhs);
+ if (result != null) return result;
+ } else if (lhs is PrefixedIdentifier) {
+ // TODO(vsm): Is this the right code if the prefix is a library?
Jennifer Messerly 2015/03/04 01:09:31 how can this happen? I don't think PrefixedIdentif
Siggi Cherem (dart-lang) 2015/03/04 03:56:07 My understanding is that PrefixedIdentifier is use
+ var result = _emitDPutIfDynamic(lhs.prefix, lhs.identifier, rhs);
+ if (result != null) return result;
}
- if (node.parent is ExpressionStatement &&
+ if (parent is ExpressionStatement &&
rhs is CascadeExpression &&
_isStateless(lhs, rhs)) {
// Special case: cascade assignment to a variable in a statement.
@@ -1169,6 +1184,35 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
bool _isNull(Expression expr) => expr is NullLiteral;
+ JS.Expression _emitIncrement(Token op, Expression expr, {bool prefix}) {
+ assert(prefix != null);
+
+ // TODO(vsm): If the expression has a side effect, we need something different.
Jennifer Messerly 2015/03/04 01:09:31 long line
vsm 2015/03/04 14:59:27 removed
+ if (!_isStateless(expr) &&
vsm 2015/03/04 00:54:21 Actually, I think this is unnecessary...
Jennifer Messerly 2015/03/04 01:09:31 right, your temps are handling this? consider `fo
vsm 2015/03/04 14:59:27 right
+ (expr is! SimpleIdentifier ||
+ (expr as SimpleIdentifier).staticElement is! LocalVariableElement)) {
+ return null;
+ }
+
+ // TODO(vsm): Should we generate a runtime helper for this?
+ var tmp = '_';
+ var applied = prefix ? '$tmp$op' : '$op$tmp';
vsm 2015/03/04 00:54:21 This might not be a number. I'll change this to c
Jennifer Messerly 2015/03/04 01:09:31 yeah. ideally it could "desugar" to `expr += 1`, a
vsm 2015/03/04 14:59:27 mapping to x = x + 1 for now, but yeah.
+ var id =
+ new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, tmp, 0));
+ id.staticElement = new LocalVariableElementImpl.forNode(id);
+ id.staticType = expr.staticType;
+ var assignment = _emitAssignment(expr, id);
+ return js.call('''
+(function () {
+ var $tmp = #;
+ if (typeof($tmp) != 'number') throw 'number expected';
+ var result = $applied;
+ #;
+ return result;
+})()
+''', [expr.accept(this), assignment]);
+ }
+
@override
JS.Expression visitPostfixExpression(PostfixExpression node) {
var op = node.operator;
@@ -1179,8 +1223,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
// TODO(vsm): When do Dart ops not map to JS?
return js.call('#$op', notNull(expr));
} else {
- // TODO(vsm): Figure out operator calling convention / dispatch.
- return visitExpression(node);
+ assert(op.lexeme == '++' || op.lexeme == '--');
+ var result = _emitIncrement(op, expr, prefix: false);
+ return (result != null) ? result : visitExpression(node);
}
}
@@ -1194,8 +1239,24 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
// TODO(vsm): When do Dart ops not map to JS?
return js.call('$op#', notNull(expr));
} else {
- // TODO(vsm): Figure out operator calling convention / dispatch.
- return visitExpression(node);
+ // Increment or decrement must be numerical
+ if (op.lexeme == '++' || op.lexeme == '--') {
+ var result = _emitIncrement(op, expr, prefix: true);
+ return (result != null) ? result : visitExpression(node);
+ }
+ }
+ // TODO(vsm): Statically invoke the operator if the type is known.
+ // Fall back to dynamic dispatch.
+ var opString = _jsMemberName(op.lexeme, unary: true);
+ if (rules.isDynamicTarget(expr)) {
+ // dynamic dispatch
+ return js.call('dart.dunary(#, #)', [opString, _visit(expr)]);
+ } else if (_isJSBuiltinType(dispatchType)) {
+ return js.call(
+ '#.#(#)', [_emitTypeName(dispatchType), opString, _visit(expr)]);
+ } else {
+ // Generic static-dispatch, user-defined operator code path.
+ return js.call('#.#()', [_visit(expr), opString]);
}
}
« no previous file with comments | « no previous file | test/codegen/expect/dart/_interceptors.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698