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

Side by Side Diff: frog/gen.dart

Issue 9222004: passing and good perf (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 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
« no previous file with comments | « no previous file | frog/lib/corelib_impl.dart » ('j') | frog/lib/corelib_impl.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /** 5 /**
6 * Top level generator object for writing code and keeping track of 6 * Top level generator object for writing code and keeping track of
7 * dependencies. 7 * dependencies.
8 * 8 *
9 * Should have two compilation models, but only one implemented so far. 9 * Should have two compilation models, but only one implemented so far.
10 * 10 *
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 || world.coreimpl.types['ReceivePortImpl'].isUsed) { 55 || world.coreimpl.types['ReceivePortImpl'].isUsed) {
56 56
57 // Generate callbacks from JS to isolate code if needed 57 // Generate callbacks from JS to isolate code if needed
58 if (corejs.useWrap0 || corejs.useWrap1) { 58 if (corejs.useWrap0 || corejs.useWrap1) {
59 genMethod(world.coreimpl.types['IsolateContext'].getMember('eval')); 59 genMethod(world.coreimpl.types['IsolateContext'].getMember('eval'));
60 genMethod(world.coreimpl.types['EventLoop'].getMember('run')); 60 genMethod(world.coreimpl.types['EventLoop'].getMember('run'));
61 } 61 }
62 62
63 corejs.useIsolates = true; 63 corejs.useIsolates = true;
64 MethodMember isolateMain = 64 MethodMember isolateMain =
65 world.coreimpl.topType.resolveMember('startRootIsolate').members[0]; 65 world.coreimpl.lookup('startRootIsolate', main.span);
66 var isolateMainTarget = new TypeValue(world.coreimpl.topType, main.span); 66 var isolateMainTarget = new TypeValue(world.coreimpl.topType, main.span);
67 mainCall = isolateMain.invoke(metaGen, null, isolateMainTarget, 67 mainCall = isolateMain.invoke(metaGen, null, isolateMainTarget,
68 new Arguments(null, [main._get(metaGen, main.definition, null)])); 68 new Arguments(null, [main._get(metaGen, main.definition, null)]));
69 } 69 }
70 70
71 writeTypes(world.coreimpl); 71 writeTypes(world.coreimpl);
72 writeTypes(world.corelib); 72 writeTypes(world.corelib);
73 73
74 // Write the main library. This will cause all libraries to be written in 74 // Write the main library. This will cause all libraries to be written in
75 // the topographic sort order. 75 // the topographic sort order.
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 return v; 815 return v;
816 } else { 816 } else {
817 // TODO(jmesserly): we should mark this returned value with the temp 817 // TODO(jmesserly): we should mark this returned value with the temp
818 // somehow, so getTemp will reuse it instead of allocating a new one. 818 // somehow, so getTemp will reuse it instead of allocating a new one.
819 // (we could do this now if we had a "TempValue" or something like that) 819 // (we could do this now if we had a "TempValue" or something like that)
820 return new Value(v.type, '(${tmp.code} = ${v.code})', v.span); 820 return new Value(v.type, '(${tmp.code} = ${v.code})', v.span);
821 } 821 }
822 } 822 }
823 823
824 void freeTemp(VariableValue value) { 824 void freeTemp(VariableValue value) {
825 // TODO(jimhug): Need to do this right - for now we can just skip freeing.
Jennifer Messerly 2012/01/18 00:03:00 yeah, I'm with you on this, having tripped over th
826 /*
825 if (_usedTemps.remove(value.code)) { 827 if (_usedTemps.remove(value.code)) {
826 _freeTemps.add(value.code); 828 _freeTemps.add(value.code);
827 } else { 829 } else {
828 world.internalError( 830 world.internalError(
829 'tried to free unused value or non-temp "${value.code}"'); 831 'tried to free unused value or non-temp "${value.code}"');
830 } 832 }
833 */
831 } 834 }
832 835
833 /*
834 run1(Value thisValue, Arguments args) {
835 // Use some sort of key to do a lookup
836
837
838 }*/
839
840 run() { 836 run() {
841 if (method.isGenerated) return; 837 if (method.isGenerated) return;
842 838
843 // This avoids any attempts to infer across recursion. 839 // This avoids any attempts to infer across recursion.
844 method.isGenerated = true; 840 method.isGenerated = true;
845 method.generator = this; 841 method.generator = this;
846 842
847 // Create most generic possible call for this method. 843 // Create most generic possible call for this method.
848 var thisObject; 844 var thisObject;
849 if (method.isConstructor) { 845 if (method.isConstructor) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 } else { 912 } else {
917 suffix = world.gen._writePrototypePatch(method.declaringType, 913 suffix = world.gen._writePrototypePatch(method.declaringType,
918 method.jsname, 'function$_params {', defWriter, false); 914 method.jsname, 'function$_params {', defWriter, false);
919 } 915 }
920 916
921 if (needsThis) { 917 if (needsThis) {
922 defWriter.writeln('var \$this = this; // closure support'); 918 defWriter.writeln('var \$this = this; // closure support');
923 } 919 }
924 920
925 if (_usedTemps.length > 0 || _freeTemps.length > 0) { 921 if (_usedTemps.length > 0 || _freeTemps.length > 0) {
926 assert(_usedTemps.length == 0); // all temps should be freed. 922 //TODO(jimhug): assert(_usedTemps.length == 0); // all temps should be fre ed.
927 _freeTemps.addAll(_usedTemps); 923 _freeTemps.addAll(_usedTemps);
928 _freeTemps.sort((x, y) => x.compareTo(y)); 924 _freeTemps.sort((x, y) => x.compareTo(y));
929 defWriter.writeln('var ${Strings.join(_freeTemps, ", ")};'); 925 defWriter.writeln('var ${Strings.join(_freeTemps, ", ")};');
930 } 926 }
931 927
932 // TODO(jimhug): Lots of string translation here - perf bottleneck? 928 // TODO(jimhug): Lots of string translation here - perf bottleneck?
933 defWriter.writeln(writer.text); 929 defWriter.writeln(writer.text);
934 930
935 if (names != null) { 931 if (names != null) {
936 // TODO(jmesserly): bind isn't implemented in older Safari. 932 // TODO(jmesserly): bind isn't implemented in older Safari.
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 return x.binop(kind, y, this, node); 1955 return x.binop(kind, y, this, node);
1960 } 1956 }
1961 1957
1962 final assignKind = TokenKind.kindFromAssign(node.op.kind); 1958 final assignKind = TokenKind.kindFromAssign(node.op.kind);
1963 if (assignKind == -1) { 1959 if (assignKind == -1) {
1964 final x = visitValue(node.x); 1960 final x = visitValue(node.x);
1965 final y = visitValue(node.y); 1961 final y = visitValue(node.y);
1966 return x.binop(kind, y, this, node); 1962 return x.binop(kind, y, this, node);
1967 } else if ((assignKind != 0) && _expressionNeedsParens(node.y)) { 1963 } else if ((assignKind != 0) && _expressionNeedsParens(node.y)) {
1968 return _visitAssign(assignKind, node.x, 1964 return _visitAssign(assignKind, node.x,
1969 new ParenExpression(node.y, node.y.span), node, null, isVoid); 1965 new ParenExpression(node.y, node.y.span), node,
1966 isVoid ? ReturnKind.IGNORE : ReturnKind.POST);
Jennifer Messerly 2012/01/18 00:03:00 nice cleanup
1970 } else { 1967 } else {
1971 return _visitAssign(assignKind, node.x, node.y, node, null, isVoid); 1968 return _visitAssign(assignKind, node.x, node.y, node,
1969 isVoid ? ReturnKind.IGNORE : ReturnKind.POST);
1972 } 1970 }
1973 } 1971 }
1974 1972
1975 /** 1973 /**
1976 * Visits an assignment expression. 1974 * Visits an assignment expression.
1977 * Note: captureOriginal can optionally capture the original value of the
1978 * left side. This is used by postfix expressions to ensure they return the
1979 * original value, before it has been modified.
1980 */ 1975 */
1981 _visitAssign(int kind, Expression xn, Expression yn, Node position, 1976 _visitAssign(int kind, Expression xn, Expression yn, Node position,
1982 Value captureOriginal(Value right), [bool isVoid = false]) { 1977 int returnKind) {
1983
1984 if (captureOriginal == null) {
1985 captureOriginal = (x) => x;
1986 }
1987
1988 // TODO(jimhug): The usual battle with making assign impl not look ugly. 1978 // TODO(jimhug): The usual battle with making assign impl not look ugly.
1989 if (xn is VarExpression) { 1979 if (xn is VarExpression) {
1990 return _visitVarAssign(kind, xn, yn, position, captureOriginal); 1980 return _visitVarAssign(kind, xn, yn, position, returnKind);
1991 } else if (xn is IndexExpression) { 1981 } else if (xn is IndexExpression) {
1992 return _visitIndexAssign(kind, xn, yn, position, captureOriginal, isVoid); 1982 return _visitIndexAssign(kind, xn, yn, position, returnKind);
1993 } else if (xn is DotExpression) { 1983 } else if (xn is DotExpression) {
1994 return _visitDotAssign(kind, xn, yn, position, captureOriginal); 1984 return _visitDotAssign(kind, xn, yn, position, returnKind);
1995 } else { 1985 } else {
1996 world.error('illegal lhs', xn.span); 1986 world.error('illegal lhs', xn.span);
1997 } 1987 }
1998 } 1988 }
1999 1989
2000 // TODO(jmesserly): it'd be nice if we didn't have to deal directly with 1990 // TODO(jmesserly): it'd be nice if we didn't have to deal directly with
2001 // MemberSets here and in visitVarExpression. 1991 // MemberSets here and in visitVarExpression.
2002 _visitVarAssign(int kind, VarExpression xn, Expression yn, Node position, 1992 _visitVarAssign(int kind, VarExpression xn, Expression yn, Node position,
2003 Value captureOriginal(Value right)) { 1993 int returnKind) {
2004 final name = xn.name.name; 1994 final name = xn.name.name;
2005 1995
2006 // First check in block scopes. 1996 // First check in block scopes.
2007 var x = _scope.lookup(name); 1997 var x = _scope.lookup(name);
2008 var y = visitValue(yn); 1998 var y = visitValue(yn);
2009 1999
2010 if (x != null) { 2000 if (x != null) {
2011 y = y.convertTo(this, x.staticType); 2001 y = y.convertTo(this, x.staticType);
2012 // Update the inferred value 2002 // Update the inferred value
2013 // Note: for now we aren't very flow sensitive, so this is a "union" 2003 // Note: for now we aren't very flow sensitive, so this is a "union"
2014 // rather than simply setting it to "y" 2004 // rather than simply setting it to "y"
2015 _scope.inferAssign(name, Value.union(x, y)); 2005 _scope.inferAssign(name, Value.union(x, y));
2016 } else { 2006
2017 // TODO(jmesserly): this needs serious cleanup... 2007 // TODO(jimhug): This is "legacy" and should be cleaned ASAP
Jennifer Messerly 2012/01/18 00:03:00 yay, another TODO gone
2018 // Look for a setter in the class 2008 if (x.isFinal) {
2019 var members = method.declaringType.resolveMember(name); 2009 world.error('final variable "${x.code}" is not assignable',
2020 x = _makeThisOrType(position.span); 2010 position.span);
2021 if (members != null) { 2011 }
2022 if (options.forceDynamic && !members.isStatic) { 2012
2023 members = findMembers(xn.name.name); 2013 // Handle different ReturnKind values here...
2014 if (kind == 0) {
2015 return new Value(y.type, '${x.code} = ${y.code}', position.span);
2016 } else if (x.type.isNum && y.type.isNum && (kind != TokenKind.TRUNCDIV)) {
2017 // Process everything but ~/ , which has no equivalent JS operator
2018 // Very localized optimization for numbers!
Jennifer Messerly 2012/01/18 00:03:00 (should we have a TODO to make this optimization g
2019 if (returnKind == ReturnKind.PRE) {
2020 world.internalError('should not be here', position.span);
Jennifer Messerly 2012/01/18 00:03:00 I use this pattern too. Almost wonder if we need a
2024 } 2021 }
2025 if (kind == 0) { 2022 final op = TokenKind.kindToString(kind);
2026 return x.set_(this, name, position, y); 2023 return new Value(y.type, '${x.code} $op= ${y.code}', position.span);
2027 } else if (!members.treatAsField || members.containsMethods) { 2024 } else {
2028 var right = x.get_(this, name, position); 2025 var right = x;
2029 right = captureOriginal(right); 2026 y = right.binop(kind, y, this, position);
2030 y = right.invoke(this, TokenKind.binaryMethodName(kind), 2027 if (returnKind == ReturnKind.PRE) {
2031 position, new Arguments(null, [y])); 2028 var tmp = forceTemp(x);
2032 return x.set_(this, name, position, y); 2029 var ret = new Value(x.type,
2030 '(${tmp.code} = ${x.code}, ${x.code} = ${y.code}, ${tmp.code})',
2031 position.span);
2032 freeTemp(tmp);
2033 return ret;
2033 } else { 2034 } else {
2034 x = x.get_(this, name, position); 2035 return new Value(x.type, '${x.code} = ${y.code}', position.span);
2035 }
2036 } else {
2037 // Look for a top-level setter
2038 final member = library.lookup(name, xn.name.span);
2039 if (member == null) {
2040 world.warning('can not resolve ${name}', xn.span);
2041 return _makeMissingValue(name);
2042 }
2043 members = new MemberSet(member);
2044 // If we can't treat it as a field, generate a setter call.
2045 // Also make sure we dont't try to set a method.
2046 if (!members.treatAsField || members.containsMethods) {
2047 if (kind != 0) {
2048 var right = members._get(this, position, x);
2049 right = captureOriginal(right);
2050 y = right.invoke(this, TokenKind.binaryMethodName(kind),
2051 position, new Arguments(null, [y]));
2052 }
2053 return members._set(this, position, x, y);
2054 } else {
2055 x = members._get(this, position, x);
2056 } 2036 }
2057 } 2037 }
2058
2059 // Otherwise treat it as a field.
2060 // This makes for nicer code in the $op= case
2061 y = y.convertTo(this, x.staticType);
2062 }
2063
2064 if (x.isFinal) {
2065 world.error('final variable "${x.code}" is not assignable',
2066 position.span);
2067 }
2068
2069 if (kind == 0) {
2070 x = captureOriginal(x);
2071 return new Value(y.type, '${x.code} = ${y.code}', position.span);
2072 } else if (x.type.isNum && y.type.isNum && (kind != TokenKind.TRUNCDIV)) {
2073 // Process everything but ~/ , which has no equivalent JS operator
2074 x = captureOriginal(x);
2075 // Very localized optimization for numbers!
2076 final op = TokenKind.kindToString(kind);
2077 return new Value(y.type, '${x.code} $op= ${y.code}', position.span);
2078 } else { 2038 } else {
2079 var right = x; 2039 x = _makeThisOrType(position.span);
2080 right = captureOriginal(right); 2040 return x.set_(this, name, position, y, kind: kind,
Jennifer Messerly 2012/01/18 00:03:00 Personally prefer passing these without the named
2081 y = right.invoke(this, TokenKind.binaryMethodName(kind), 2041 returnKind: returnKind);
2082 position, new Arguments(null, [y]));
2083 return new Value(y.type, '${x.code} = ${y.code}', position.span);
2084 } 2042 }
2085 } 2043 }
2086 2044
2087 _visitIndexAssign(int kind, IndexExpression xn, Expression yn, Node position, 2045 _visitIndexAssign(int kind, IndexExpression xn, Expression yn,
Jennifer Messerly 2012/01/18 00:03:00 wow, so much nicer! index assign and do assign fin
2088 Value captureOriginal(Value right), [bool isVoid = false]) { 2046 Node position, int returnKind) {
2089 var target = visitValue(xn.target); 2047 var target = visitValue(xn.target);
2048 var index = visitValue(xn.index);
2049 var y = visitValue(yn);
2090 2050
2091 // Note: need to get temps eagerly so they don't get reused 2051 return target.setIndex(this, index, position, y, kind: kind,
2092 var tmptarget = target; 2052 returnKind: returnKind);
2093 if (kind != 0) tmptarget = getTemp(target);
2094
2095 var index = visitValue(xn.index);
2096 var tmpindex = index;
2097 if (kind != 0) tmpindex = getTemp(index);
2098
2099 var y = visitValue(yn);
2100 if (kind != 0) {
2101 index = assignTemp(tmpindex, index);
2102 var right = tmptarget.invoke(this, ':index',
2103 position, new Arguments(null, [tmpindex]));
2104 right = captureOriginal(right);
2105 y = right.invoke(this, TokenKind.binaryMethodName(kind),
2106 position, new Arguments(null, [y]));
2107 }
2108
2109 var tmpy = null;
2110 // If the assignment is an expression statement (x[i] = y;) it is translated
2111 // as (x.$setindex(i, y)), otherwise as (x.$setindex(i, t = y), t).
2112 if (!isVoid) {
2113 tmpy = getTemp(y);
2114 y = assignTemp(tmpy, y);
2115 }
2116 var ret = assignTemp(tmptarget, target).invoke(this, ':setindex',
2117 position, new Arguments(null, [index, y]));
2118 if (tmpy != null) {
2119 ret = new Value(ret.type, '(${ret.code}, ${tmpy.code})', ret.span);
2120 if (tmpy != y) freeTemp(tmpy);
2121 }
2122 if (tmptarget != target) freeTemp(tmptarget);
2123 if (tmpindex != index) freeTemp(tmpindex);
2124 return ret;
2125 } 2053 }
2126 2054
2127 _visitDotAssign(int kind, DotExpression xn, Expression yn, Node position, 2055 _visitDotAssign(int kind, DotExpression xn, Expression yn, Node position,
2128 Value captureOriginal(Value right)) { 2056 int returnKind) {
2057 // This is not visitValue because types members are assignable.
2058 var target = xn.self.visit(this);
2059 var y = visitValue(yn);
2129 2060
2130 // This is not visitValue because types are assignable through . 2061 return target.set_(this, xn.name.name, xn.name, y, kind: kind,
2131 var target = xn.self.visit(this); 2062 returnKind: returnKind);
2132
2133 var y = visitValue(yn);
2134 var tmptarget = target;
2135 if (kind != 0) {
2136 tmptarget = getTemp(target);
2137 var right = tmptarget.get_(this, xn.name.name, xn.name);
2138 right = captureOriginal(right);
2139 y = right.invoke(this, TokenKind.binaryMethodName(kind),
2140 position, new Arguments(null, [y]));
2141 }
2142 var ret = assignTemp(tmptarget, target).set_(
2143 this, xn.name.name, xn.name, y);
2144 if (tmptarget != target) freeTemp(tmptarget);
2145 return ret;
2146 } 2063 }
2147 2064
2148 visitUnaryExpression(UnaryExpression node) { 2065 visitUnaryExpression(UnaryExpression node) {
2149 var value = visitValue(node.self); 2066 var value = visitValue(node.self);
2150 switch (node.op.kind) { 2067 switch (node.op.kind) {
2151 case TokenKind.INCR: 2068 case TokenKind.INCR:
2152 case TokenKind.DECR: 2069 case TokenKind.DECR:
2153 // TODO(jimhug): Requires non-null num to be correct. 2070 // TODO(jimhug): Requires non-null num to be correct.
2154 if (value.type.isNum) { 2071 if (value.type.isNum) {
2155 return new Value(value.type, '${node.op}${value.code}', node.span); 2072 return new Value(value.type, '${node.op}${value.code}', node.span);
2156 } else { 2073 } else {
2157 // ++x becomes x += 1 2074 // ++x becomes x += 1
2158 // --x becomes x -= 1 2075 // --x becomes x -= 1
2159 // TODO(jimhug): Confirm that --x becomes x -= 1 as it is in VM. 2076 // TODO(jimhug): Confirm that --x becomes x -= 1 as it is in VM.
2160 var kind = (TokenKind.INCR == node.op.kind ? 2077 var kind = (TokenKind.INCR == node.op.kind ?
2161 TokenKind.ADD : TokenKind.SUB); 2078 TokenKind.ADD : TokenKind.SUB);
2162 // TODO(jimhug): Shouldn't need a full-expression here. 2079 // TODO(jimhug): Shouldn't need a full-expression here.
2163 var operand = new LiteralExpression(Value.fromInt(1, node.span), 2080 var operand = new LiteralExpression(Value.fromInt(1, node.span),
2164 node.span); 2081 node.span);
2165 2082
2166 var assignValue = _visitAssign(kind, node.self, operand, node, null); 2083 var assignValue = _visitAssign(kind, node.self, operand, node,
2084 ReturnKind.POST);
2167 return new Value(assignValue.type, '(${assignValue.code})', 2085 return new Value(assignValue.type, '(${assignValue.code})',
2168 node.span); 2086 node.span);
2169 } 2087 }
2170 } 2088 }
2171 return value.unop(node.op.kind, this, node); 2089 return value.unop(node.op.kind, this, node);
2172 } 2090 }
2173 2091
2174 visitDeclaredIdentifier(DeclaredIdentifier node) { 2092 visitDeclaredIdentifier(DeclaredIdentifier node) {
2175 world.error('Expected expression', node.span); 2093 world.error('Expected expression', node.span);
2176 } 2094 }
2177 2095
2178 visitAwaitExpression(AwaitExpression node) { 2096 visitAwaitExpression(AwaitExpression node) {
2179 world.internalError( 2097 world.internalError(
2180 'Await expressions should have been eliminated before code generation', 2098 'Await expressions should have been eliminated before code generation',
2181 node.span); 2099 node.span);
2182 } 2100 }
2183 2101
2184 visitPostfixExpression(PostfixExpression node, [bool isVoid = false]) { 2102 visitPostfixExpression(PostfixExpression node, [bool isVoid = false]) {
2185 var value = visitValue(node.body); 2103 var value = visitValue(node.body);
2104 // TODO(jimhug): Move and validate this code with nullable ints.
2186 if (value.type.isNum && !value.isFinal) { 2105 if (value.type.isNum && !value.isFinal) {
2187 return new Value(value.type, '${value.code}${node.op}', node.span); 2106 return new Value(value.type, '${value.code}${node.op}', node.span);
2188 } 2107 }
2189 2108
2190 // x++ is equivalent to (t = x, x = t + 1, t), where we capture all temps 2109 // x++ is equivalent to (t = x, x = t + 1, t), where we capture all temps
2191 // needed to evaluate x so we're not evaluating multiple times. Likewise, 2110 // needed to evaluate x so we're not evaluating multiple times. Likewise,
2192 // x-- is equivalent to (t = x, x = t - 1, t). 2111 // x-- is equivalent to (t = x, x = t - 1, t).
2193 var kind = (TokenKind.INCR == node.op.kind) ? TokenKind.ADD : TokenKind.SUB; 2112 var kind = (TokenKind.INCR == node.op.kind) ?
2113 TokenKind.ADD : TokenKind.SUB;
2194 // TODO(jimhug): Shouldn't need a full-expression here. 2114 // TODO(jimhug): Shouldn't need a full-expression here.
2195 var operand = new LiteralExpression(Value.fromInt(1, node.span), 2115 var operand = new LiteralExpression(Value.fromInt(1, node.span),
2196 node.span); 2116 node.span);
2197 2117 var ret = _visitAssign(kind, node.body, operand, node,
2198 // Use _visitAssign to do most of the work, but save the right side in a 2118 isVoid ? ReturnKind.IGNORE : ReturnKind.PRE);
2199 // temporary variable if needed.
2200 // TODO(jmesserly): I don't like passing function args like this, but the
2201 // alternative is duplicating most of the _visitAssign logic. Needs cleanup.
2202 var tmpleft = null, left = null;
2203 var ret = _visitAssign(kind, node.body, operand, node, (l) {
2204 if (isVoid) {
2205 // No need for a temp if we're throwing away the result.
2206 return l;
2207 } else {
2208 // We always need a temp to capture the old value
2209 left = l;
2210 tmpleft = forceTemp(l);
2211 return assignTemp(tmpleft, left);
2212 }
2213 });
2214
2215 if (tmpleft != null) {
2216 ret = new Value(ret.type, "(${ret.code}, ${tmpleft.code})", node.span);
2217 }
2218 if (tmpleft != left) {
2219 freeTemp(tmpleft);
2220 }
2221 return ret; 2119 return ret;
2222 } 2120 }
2223 2121
2224 visitNewExpression(NewExpression node) { 2122 visitNewExpression(NewExpression node) {
2225 var typeRef = node.type; 2123 var typeRef = node.type;
2226 2124
2227 var constructorName = ''; 2125 var constructorName = '';
2228 if (node.name != null) { 2126 if (node.name != null) {
2229 constructorName = node.name.name; 2127 constructorName = node.name.name;
2230 } 2128 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 result.add(new VariableValue(world.varType, '\$$i', null)); 2466 result.add(new VariableValue(world.varType, '\$$i', null));
2569 } 2467 }
2570 for (int i = bareCount; i < length; i++) { 2468 for (int i = bareCount; i < length; i++) {
2571 var name = getName(i); 2469 var name = getName(i);
2572 if (name == null) name = '\$$i'; 2470 if (name == null) name = '\$$i';
2573 result.add(new VariableValue(world.varType, name, null)); 2471 result.add(new VariableValue(world.varType, name, null));
2574 } 2472 }
2575 return new Arguments(nodes, result); 2473 return new Arguments(nodes, result);
2576 } 2474 }
2577 } 2475 }
2476
2477 class ReturnKind {
2478 static final int IGNORE = 1;
2479 static final int POST = 2;
2480 static final int PRE = 3;
2481 }
OLDNEW
« no previous file with comments | « no previous file | frog/lib/corelib_impl.dart » ('j') | frog/lib/corelib_impl.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698