1 4 package gnu.expr; 5 import gnu.bytecode.*; 6 import gnu.mapping.WrongType; 7 8 11 12 public class CheckedTarget extends StackTarget 13 { 14 LambdaExp proc; 15 String procname; 16 18 int argno; 19 20 public CheckedTarget(Type type) 21 { 22 super(type); 23 argno = WrongType.ARG_CAST; 24 } 25 26 public CheckedTarget(Type type, LambdaExp proc, int argno) 27 { 28 super(type); 29 this.proc = proc; 30 this.procname = proc.getName(); 31 this.argno = argno; 32 } 33 34 public CheckedTarget(Type type, String procname, int argno) 35 { 36 super(type); 37 this.procname = procname; 38 this.argno = argno; 39 } 40 41 public static Target getInstance(Type type, String procname, int argno) 42 { 43 return (type == Type.pointer_type ? Target.pushObject 44 : new CheckedTarget(type, procname, argno)); 45 } 46 47 public static Target getInstance(Type type, LambdaExp proc, int argno) 48 { 49 return (type == Type.pointer_type ? Target.pushObject 50 : new CheckedTarget(type, proc, argno)); 51 } 52 53 public static Target getInstance(Type type) 54 { 55 return (type == Type.pointer_type ? Target.pushObject 56 : new CheckedTarget(type)); 57 } 58 59 static ClassType typeClassCastException; 60 static ClassType typeWrongType; 61 static Method initWrongTypeStringMethod; 62 static Method initWrongTypeProcMethod; 63 64 private static void initWrongType() 65 { 66 if (typeClassCastException == null) 67 typeClassCastException = ClassType.make("java.lang.ClassCastException"); 68 if (typeWrongType == null) 69 { 70 typeWrongType= ClassType.make("gnu.mapping.WrongType"); 71 Type[] args = new Type[4]; 72 args[0] = typeClassCastException; 73 args[1] = Compilation.javaStringType; 74 args[2] = Type.int_type; 75 args[3] = Type.pointer_type; 76 initWrongTypeStringMethod 77 = typeWrongType.addMethod("<init>", Access.PUBLIC, 78 args, Type.void_type); 79 args = new Type[4]; 80 args[0] = typeClassCastException; 81 args[1] = Compilation.typeProcedure; 82 args[2] = Type.int_type; 83 args[3] = Type.pointer_type; 84 initWrongTypeProcMethod 85 = typeWrongType.addMethod("<init>", Access.PUBLIC, 86 args, Type.void_type); 87 } 88 } 89 90 public void compileFromStack(Compilation comp, Type stackType) 91 { 92 if (! compileFromStack0(comp, stackType)) 93 emitCheckedCoerce(comp, proc, procname, argno, type, null); 94 } 95 96 public static void emitCheckedCoerce(Compilation comp, 97 String procname, int argno, Type type) 98 { 99 emitCheckedCoerce(comp, null, procname, argno, type, null); 100 } 101 102 public static void emitCheckedCoerce(Compilation comp, LambdaExp proc, 103 int argno, Type type) 104 { 105 emitCheckedCoerce(comp, proc, proc.getName(), argno, type, null); 106 } 107 108 public static void emitCheckedCoerce(Compilation comp, LambdaExp proc, 109 int argno, Type type, Variable argValue) 110 { 111 emitCheckedCoerce(comp, proc, proc.getName(), argno, type, argValue); 112 } 113 114 static void emitCheckedCoerce(Compilation comp, LambdaExp proc, 115 String procname, int argno, Type type, 116 Variable argValue) 117 { 118 CodeAttr code = comp.getCode(); 119 boolean isInTry = code.isInTry(); 124 initWrongType(); 125 Label startTry = new Label(code); 126 Scope tmpScope; 127 if (argValue == null && type != Type.tostring_type) 128 { 129 tmpScope = code.pushScope(); 130 argValue = code.addLocal(Type.pointer_type); 131 code.emitDup(1); 132 code.emitStore(argValue); 133 } 134 else 135 tmpScope = null; 136 int startPC = code.getPC(); 137 startTry.define(code); 138 emitCoerceFromObject(type, comp); 139 140 int endPC = code.getPC(); 141 if (endPC == startPC 146 || type == Type.tostring_type) 147 { 148 if (tmpScope != null) 151 code.popScope(); 152 return; 153 } 154 155 Label endTry = new Label(code); 156 endTry.define(code); 157 158 Label endLabel = new Label(code); 159 if (isInTry) 160 code.emitGoto(endLabel); 161 int fragment_cookie = 0; 162 if (! isInTry) 163 fragment_cookie = code.beginFragment(new Label(code), endLabel); 164 code.addHandler(startTry, endTry, typeClassCastException); 165 code.pushType(typeClassCastException); 168 boolean thisIsProc = false; 169 if (proc != null && proc.isClassGenerated() 170 && ! comp.method.getStaticFlag()) 171 { 172 if (comp.method.getDeclaringClass() == proc.getCompiledClassType(comp)) 173 thisIsProc = true; 174 } 175 int line = comp.getLineNumber(); 176 if (line > 0) 177 code.putLineNumber(line); 178 code.emitNew(typeWrongType); 179 code.emitDupX(); code.emitSwap(); 181 if (thisIsProc) 182 code.emitPushThis(); 183 else 184 code.emitPushString(procname == null && argno != WrongType.ARG_CAST 185 ? "lambda" 186 : procname); 187 code.emitPushInt(argno); 188 code.emitLoad(argValue); 189 code.emitInvokeSpecial(thisIsProc ? initWrongTypeProcMethod 190 : initWrongTypeStringMethod); 191 if (tmpScope != null) 192 code.popScope(); 193 code.emitThrow(); 194 if (isInTry) 195 endLabel.define(code); 196 else 197 code.endFragment(fragment_cookie); 198 } 199 } 200 | Popular Tags |