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.JBlock; 21 import com.google.gwt.dev.jjs.ast.JExpression; 22 import com.google.gwt.dev.jjs.ast.JExpressionStatement; 23 import com.google.gwt.dev.jjs.ast.JIfStatement; 24 import com.google.gwt.dev.jjs.ast.JInstanceOf; 25 import com.google.gwt.dev.jjs.ast.JLocal; 26 import com.google.gwt.dev.jjs.ast.JLocalRef; 27 import com.google.gwt.dev.jjs.ast.JMethod; 28 import com.google.gwt.dev.jjs.ast.JMethodCall; 29 import com.google.gwt.dev.jjs.ast.JModVisitor; 30 import com.google.gwt.dev.jjs.ast.JProgram; 31 import com.google.gwt.dev.jjs.ast.JReferenceType; 32 import com.google.gwt.dev.jjs.ast.JStatement; 33 import com.google.gwt.dev.jjs.ast.JThrowStatement; 34 import com.google.gwt.dev.jjs.ast.JTryStatement; 35 36 import java.util.ArrayList ; 37 import java.util.List ; 38 39 43 public class CatchBlockNormalizer { 44 45 48 private class CollapseCatchBlocks extends JModVisitor { 49 50 public void endVisit(JMethod x, Context ctx) { 52 clearLocals(); 53 currentMethod = null; 54 } 55 56 public void endVisit(JTryStatement x, Context ctx) { 58 if (x.getCatchBlocks().isEmpty()) { 59 return; 60 } 61 62 SourceInfo catchInfo = ((JBlock) x.getCatchBlocks().get(0)).getSourceInfo(); 63 64 JLocal exObj = popTempLocal(); 65 JLocalRef exRef = new JLocalRef(program, catchInfo, exObj); 66 JBlock newCatchBlock = new JBlock(program, catchInfo); 67 JMethod caughtMethod = program.getSpecialMethod("Exceptions.caught"); 69 JMethodCall call = new JMethodCall(program, catchInfo, null, caughtMethod); 70 call.getArgs().add(exRef); 71 JExpressionStatement asg = program.createAssignmentStmt(catchInfo, exRef, 72 call); 73 newCatchBlock.statements.add(asg); 74 75 81 JStatement cur = new JThrowStatement(program, null, exRef); 83 for (int i = x.getCatchBlocks().size() - 1; i >= 0; --i) { 84 JBlock block = (JBlock) x.getCatchBlocks().get(i); 85 JLocalRef arg = (JLocalRef) x.getCatchArgs().get(i); 86 catchInfo = block.getSourceInfo(); 87 JReferenceType argType = (JReferenceType) arg.getType(); 88 JExpression ifTest = new JInstanceOf(program, catchInfo, argType, exRef); 90 asg = program.createAssignmentStmt(catchInfo, arg, exRef); 91 if (!block.statements.isEmpty()) { 92 block.statements.add(0, asg); 94 } 95 cur = new JIfStatement(program, catchInfo, ifTest, block, cur); 97 } 98 99 newCatchBlock.statements.add(cur); 100 x.getCatchArgs().clear(); 101 x.getCatchArgs().add(exRef); 102 x.getCatchBlocks().clear(); 103 x.getCatchBlocks().add(newCatchBlock); 104 } 105 106 public boolean visit(JMethod x, Context ctx) { 108 currentMethod = x; 109 clearLocals(); 110 return true; 111 } 112 113 public boolean visit(JTryStatement x, Context ctx) { 115 if (!x.getCatchBlocks().isEmpty()) { 116 pushTempLocal(); 117 } 118 return true; 119 } 120 } 121 122 public static void exec(JProgram program) { 123 new CatchBlockNormalizer(program).execImpl(); 124 } 125 126 private JMethod currentMethod; 127 private int localIndex; 128 private final JProgram program; 129 private final List tempLocals = new ArrayList (); 130 131 private CatchBlockNormalizer(JProgram program) { 132 this.program = program; 133 } 134 135 private void clearLocals() { 136 tempLocals.clear(); 137 localIndex = 0; 138 } 139 140 private void execImpl() { 141 CollapseCatchBlocks collapser = new CollapseCatchBlocks(); 142 collapser.accept(program); 143 } 144 145 private JLocal popTempLocal() { 146 return (JLocal) tempLocals.get(--localIndex); 147 } 148 149 private void pushTempLocal() { 150 if (localIndex == tempLocals.size()) { 151 JLocal newTemp = program.createLocal(null, 152 ("$e" + localIndex).toCharArray(), program.getTypeJavaLangObject(), 153 false, currentMethod); 154 tempLocals.add(newTemp); 155 } 156 ++localIndex; 157 } 158 159 } 160 | Popular Tags |