diff --git a/bin/parser_generator_for_spec.dart b/bin/parser_generator_for_spec.dart index 03bac6d07..66ca7f01e 100644 --- a/bin/parser_generator_for_spec.dart +++ b/bin/parser_generator_for_spec.dart @@ -27,6 +27,7 @@ main(arguments) { "a.b.c", "x.b.c", "e1.b", + "o.f()", "1", "-1", "+1", "!true", "3*4/2%5", "3+6-2", diff --git a/lib/core/parser/backend.dart b/lib/core/parser/backend.dart index 9c506671e..b0d000799 100644 --- a/lib/core/parser/backend.dart +++ b/lib/core/parser/backend.dart @@ -4,7 +4,7 @@ class BoundExpression { var _context; Expression expression; - BoundExpression(this._context, this.expression); + BoundExpression(this._context, Expression this.expression); call([locals]) => expression.eval(_context, locals); assign(value, [locals]) => expression.assign(_context, value, locals); @@ -17,7 +17,15 @@ class Expression implements ParserAST { String exp; List parts; - Expression(this.eval, [this.assign]); + // Expressions that represent field accesses have a couple of + // extra fields. We use that to generate an optimized closure + // for calling fields of objects without having to load the + // field separately. + Expression fieldHolder; + String fieldName; + bool get isFieldAccess => fieldHolder != null; + + Expression(ParsedGetter this.eval, [ParsedSetter this.assign]); bind(context) => new BoundExpression(context, this); @@ -93,7 +101,7 @@ class ParserBackend { GetterSetter _getterSetter; FilterMap _filters; - ParserBackend(this._getterSetter, this._filters); + ParserBackend(GetterSetter this._getterSetter, FilterMap this._filters); static Expression ZERO = new Expression((_, [_x]) => 0); @@ -314,7 +322,9 @@ class FilterExpression extends Expression { final Expression leftHandSide; final List parameters; - FilterExpression(this.filterFn, this.leftHandSide, this.parameters): super(null); + FilterExpression(Function this.filterFn, + Expression this.leftHandSide, + List this.parameters): super(null); get eval => _eval; diff --git a/perf/parser_perf.dart b/perf/parser_perf.dart index 4ec1dc76d..6f293490d 100644 --- a/perf/parser_perf.dart +++ b/perf/parser_perf.dart @@ -38,6 +38,7 @@ main() { scope['a'] = new ATest(); scope['e1'] = new EqualsThrows(); + scope['o'] = new OTest(); compare(expr, idealFn) { var nf = new NumberFormat.decimalPattern(); @@ -63,6 +64,7 @@ main() { compare('a.b.c', (scope) => scope['a'].b.c); compare('e1.b', (scope) => scope['e1'].b); + compare('o.f()', (scope) => scope['o'].f()); compare('null', (scope) => null); compare('x.b.c', (s, [l]) { if (l != null && l.containsKey('x')) s = l['x']; @@ -83,6 +85,10 @@ class BTest { var c = 6; } +class OTest { + f() => 42; +} + class EqualsThrows { var b = 3; operator ==(x) {