1 16 package com.google.gwt.dev.jjs.impl; 17 18 import com.google.gwt.dev.jjs.SourceInfo; 19 import com.google.gwt.dev.jjs.ast.Context; 20 import com.google.gwt.dev.jjs.ast.JClassType; 21 import com.google.gwt.dev.jjs.ast.JLocal; 22 import com.google.gwt.dev.jjs.ast.JLocalRef; 23 import com.google.gwt.dev.jjs.ast.JMethod; 24 import com.google.gwt.dev.jjs.ast.JMethodCall; 25 import com.google.gwt.dev.jjs.ast.JModVisitor; 26 import com.google.gwt.dev.jjs.ast.JParameter; 27 import com.google.gwt.dev.jjs.ast.JParameterRef; 28 import com.google.gwt.dev.jjs.ast.JProgram; 29 import com.google.gwt.dev.jjs.ast.JReturnStatement; 30 import com.google.gwt.dev.jjs.ast.JStatement; 31 import com.google.gwt.dev.jjs.ast.JThisRef; 32 import com.google.gwt.dev.jjs.ast.JType; 33 import com.google.gwt.dev.jjs.ast.JVisitor; 34 35 import java.util.HashSet ; 36 import java.util.IdentityHashMap ; 37 import java.util.Map ; 38 import java.util.Set ; 39 40 54 public class MakeCallsStatic { 55 56 62 private class CreateStaticImplsVisitor extends JModVisitor { 63 64 public boolean visit(JMethod x, Context ctx) { 66 if (!toBeMadeStatic.contains(x)) { 67 return false; 68 } 69 70 JClassType enclosingType = (JClassType) x.getEnclosingType(); 72 JType oldReturnType = x.getType(); 73 74 String newName = "$" + x.getName(); 76 77 81 JMethod newMethod = new JMethod(program, x.getSourceInfo(), newName, 82 enclosingType, oldReturnType, false, true, true, x.isPrivate()); 83 84 JParameter thisParam = program.createParameter(null, 86 "this$static".toCharArray(), enclosingType, true, newMethod); 87 Map varMap = new IdentityHashMap (); 88 for (int i = 0; i < x.params.size(); ++i) { 89 JParameter oldVar = (JParameter) x.params.get(i); 90 JParameter newVar = program.createParameter(oldVar.getSourceInfo(), 91 oldVar.getName().toCharArray(), oldVar.getType(), oldVar.isFinal(), 92 newMethod); 93 varMap.put(oldVar, newVar); 94 } 95 newMethod.freezeParamTypes(); 96 97 for (int i = 0; i < x.locals.size(); ++i) { 99 JLocal oldVar = (JLocal) x.locals.get(i); 100 JLocal newVar = program.createLocal(oldVar.getSourceInfo(), 101 oldVar.getName().toCharArray(), oldVar.getType(), oldVar.isFinal(), 102 newMethod); 103 varMap.put(oldVar, newVar); 104 } 105 x.locals.clear(); 106 107 newMethod.body.statements.addAll(x.body.statements); 109 x.body.statements.clear(); 110 111 115 RewriteMethodBody rewriter = new RewriteMethodBody(thisParam, varMap); 116 rewriter.accept(newMethod); 117 118 SourceInfo bodyInfo = x.body.getSourceInfo(); 119 JMethodCall newCall = new JMethodCall(program, bodyInfo, null, newMethod); 121 newCall.getArgs().add(program.getExprThisRef(bodyInfo, enclosingType)); 122 for (int i = 0; i < x.params.size(); ++i) { 123 JParameter param = (JParameter) x.params.get(i); 124 newCall.getArgs().add(new JParameterRef(program, bodyInfo, param)); 125 } 126 JStatement statement; 127 if (oldReturnType == program.getTypeVoid()) { 128 statement = newCall.makeStatement(); 129 } else { 130 statement = new JReturnStatement(program, bodyInfo, newCall); 131 } 132 x.body.statements.add(statement); 133 134 program.putStaticImpl(x, newMethod); 136 assert (ctx.canInsert()); 137 ctx.insertAfter(newMethod); 138 return false; 139 } 140 } 141 142 146 private class FindStaticDispatchSitesVisitor extends JVisitor { 147 148 public void endVisit(JMethodCall x, Context ctx) { 150 JMethod method = x.getTarget(); 151 152 if (program.getStaticImpl(method) != null 154 || toBeMadeStatic.contains(method)) { 155 return; 156 } 157 158 if (x.canBePolymorphic()) { 160 return; 161 } 162 if (method.isStatic()) { 163 return; 164 } 165 if (method.isAbstract()) { 166 return; 167 } 168 if (method.isNative()) { 169 return; 170 } 171 if (method == program.getNullMethod()) { 172 return; 174 } 175 176 toBeMadeStatic.add(method); 178 } 179 } 180 181 186 private class RewriteCallSites extends JModVisitor { 187 188 193 public void endVisit(JMethodCall x, Context ctx) { 195 JMethod oldMethod = x.getTarget(); 196 JMethod newMethod = program.getStaticImpl(oldMethod); 197 if (newMethod == null || x.canBePolymorphic()) { 198 return; 199 } 200 201 JMethodCall newCall = new JMethodCall(program, x.getSourceInfo(), null, 203 newMethod); 204 205 newCall.getArgs().add(x.getInstance()); 207 for (int i = 0; i < x.getArgs().size(); ++i) { 209 newCall.getArgs().add(x.getArgs().get(i)); 210 } 211 ctx.replaceMe(newCall); 212 } 213 } 214 215 219 private class RewriteMethodBody extends JModVisitor { 220 221 private final JParameter thisParam; 222 private final Map varMap; 223 224 public RewriteMethodBody(JParameter thisParam, 225 Map varMap) { 226 this.thisParam = thisParam; 227 this.varMap = varMap; 228 } 229 230 public void endVisit(JLocalRef x, Context ctx) { 232 JLocal local = (JLocal) varMap.get(x.getTarget()); 233 JLocalRef localRef = new JLocalRef(program, x.getSourceInfo(), local); 234 ctx.replaceMe(localRef); 235 } 236 237 public void endVisit(JParameterRef x, Context ctx) { 239 JParameter param = (JParameter) varMap.get(x.getTarget()); 240 JParameterRef paramRef = new JParameterRef(program, x.getSourceInfo(), 241 param); 242 ctx.replaceMe(paramRef); 243 } 244 245 public void endVisit(JThisRef x, Context ctx) { 247 JParameterRef paramRef = new JParameterRef(program, x.getSourceInfo(), 248 thisParam); 249 ctx.replaceMe(paramRef); 250 } 251 } 252 253 public static boolean exec(JProgram program) { 254 return new MakeCallsStatic(program).execImpl(); 255 } 256 257 public Set toBeMadeStatic = new HashSet (); 258 259 private final JProgram program; 260 261 private MakeCallsStatic(JProgram program) { 262 this.program = program; 263 } 264 265 private boolean execImpl() { 266 FindStaticDispatchSitesVisitor finder = new FindStaticDispatchSitesVisitor(); 267 finder.accept(program); 268 if (toBeMadeStatic.isEmpty()) { 269 return false; 270 } 271 272 CreateStaticImplsVisitor creator = new CreateStaticImplsVisitor(); 273 creator.accept(program); 274 if (!creator.didChange()) { 275 return false; 276 } 277 278 RewriteCallSites rewriter = new RewriteCallSites(); 279 rewriter.accept(program); 280 assert (rewriter.didChange()); 281 return true; 282 } 283 284 } 285 | Popular Tags |