1 4 package gnu.expr; 5 import gnu.mapping.*; 6 import java.lang.reflect.*; 7 8 13 14 public class ModuleMethod extends MethodProc 15 { 16 public ModuleBody module; 17 public final int selector; 18 protected int numArgs; 19 20 public ModuleMethod(ModuleBody module, int selector, 21 Object name, int numArgs) 22 { 23 this.module = module; 24 this.selector = selector; 25 this.numArgs = numArgs; 26 if (name != null) 27 setSymbol(name); 28 } 29 30 public ModuleMethod (ModuleBody module, int selector, 31 Object name, int numArgs, Object argTypes) 32 { 33 this.module = module; 34 this.selector = selector; 35 this.numArgs = numArgs; 36 if (name != null) 37 setSymbol(name); 38 this.argTypes = argTypes; 39 } 40 41 44 protected void resolveParameterTypes() 45 { 46 Method method = null; 47 try 48 { 49 Class moduleClass = module.getClass(); 50 Method[] methods = moduleClass.getDeclaredMethods(); 51 String mangledName = Compilation.mangleNameIfNeeded(getName()); 52 for (int i = methods.length; --i >= 0; ) 53 { 54 if (methods[i].getName().equals(mangledName)) 55 { 56 if (method != null) 57 { 58 method = null; 59 break; 60 } 61 method = methods[i]; 62 } 63 } 64 if (method != null) 65 { 66 Language lang = Language.getDefaultLanguage(); 67 Class [] parameterClasses = method.getParameterTypes(); 68 int numParamTypes = parameterClasses.length; 69 gnu.bytecode.Type[] atypes = new gnu.bytecode.Type[numParamTypes]; 70 for (int i = numParamTypes; --i >= 0; ) 71 { 72 atypes[i] = lang.getTypeFor(parameterClasses[i]); 73 } 74 this.argTypes = atypes; 75 } 76 } 77 catch (Throwable ex) 78 { 79 } 80 if (argTypes == null) 81 super.resolveParameterTypes(); 82 } 83 84 public int numArgs() { return numArgs; } 85 86 public int match0 (CallContext ctx) 87 { 88 ctx.count = 0; 89 ctx.where = 0; 90 return module.match0(this, ctx); 91 } 92 93 public int match1 (Object arg1, CallContext ctx) 94 { 95 ctx.count = 1; 96 ctx.where = CallContext.ARG_IN_VALUE1; 97 return module.match1(this, arg1, ctx); 98 } 99 100 public int match2 (Object arg1, Object arg2, CallContext ctx) 101 { 102 ctx.count = 2; 103 ctx.where = CallContext.ARG_IN_VALUE1 104 |(CallContext.ARG_IN_VALUE2<<4); 105 return module.match2(this, arg1, arg2, ctx); 106 } 107 108 public int match3 (Object arg1, Object arg2, Object arg3, CallContext ctx) 109 { 110 ctx.count = 3; 111 ctx.where = CallContext.ARG_IN_VALUE1 112 |(CallContext.ARG_IN_VALUE2<<4) 113 |(CallContext.ARG_IN_VALUE3<<8); 114 return module.match3(this, arg1, arg2, arg3, ctx); 115 } 116 117 public int match4 (Object arg1, Object arg2, Object arg3, Object arg4, 118 CallContext ctx) 119 { 120 ctx.count = 4; 121 ctx.where = (CallContext.ARG_IN_VALUE1 122 |(CallContext.ARG_IN_VALUE2<<4) 123 |(CallContext.ARG_IN_VALUE3<<8) 124 |(CallContext.ARG_IN_VALUE4<<12)); 125 return module.match4(this, arg1, arg2, arg3, arg4, ctx); 126 } 127 128 public int matchN (Object [] args, CallContext ctx) 129 { 130 ctx.count = args.length; 131 ctx.where = 0; 132 return module.matchN(this, args, ctx); 133 } 134 135 public void apply (CallContext ctx) 136 throws Throwable 137 { 138 Object result; 147 switch (ctx.pc) 148 { 149 case 0: 150 result = apply0(); 151 break; 152 case 1: 153 result = apply1(ctx.value1); 154 break; 155 case 2: 156 result = apply2(ctx.value1, ctx.value2); 157 break; 158 case 3: 159 result = apply3(ctx.value1, ctx.value2, ctx.value3); 160 break; 161 case 4: 162 result = apply4(ctx.value1, ctx.value2, ctx.value3, ctx.value4); 163 break; 164 case 5: 165 result = applyN(ctx.values); 166 break; 167 default: 168 throw new Error ("internal error - apply "+this); 169 } 170 ctx.writeValue(result); 171 } 172 173 public Object apply0() 174 throws Throwable 175 { 176 return module.apply0(this); 177 } 178 179 public Object apply1(Object arg1) 180 throws Throwable 181 { 182 return module.apply1(this, arg1); 183 } 184 185 public Object apply2(Object arg1, Object arg2) 186 throws Throwable 187 { 188 return module.apply2(this, arg1, arg2); 189 } 190 191 public Object apply3(Object arg1, Object arg2, Object arg3) 192 throws Throwable 193 { 194 return module.apply3(this, arg1, arg2, arg3); 195 } 196 197 public Object apply4(Object arg1, Object arg2, Object arg3, Object arg4) 198 throws Throwable 199 { 200 return module.apply4(this, arg1, arg2, arg3, arg4); 201 } 202 203 public Object applyN(Object [] args) 204 throws Throwable 205 { 206 return module.applyN(this, args); 207 } 208 209 public static Object apply0Default(ModuleMethod method) 210 throws Throwable 211 { 212 return method.module.applyN(method, Values.noArgs); 213 } 214 215 public static Object apply1Default(ModuleMethod method, Object arg1) 216 throws Throwable 217 { 218 Object [] args = new Object [1]; 219 args[0] = arg1; 220 return method.module.applyN(method, args); 221 } 222 223 public static Object apply2Default(ModuleMethod method, Object arg1, Object arg2) 224 throws Throwable 225 { 226 Object [] args = new Object [2]; 227 args[0] = arg1; 228 args[1] = arg2; 229 return method.module.applyN(method, args); 230 } 231 232 public static Object apply3Default(ModuleMethod method, 233 Object arg1, Object arg2, Object arg3) 234 throws Throwable 235 { 236 Object [] args = new Object [3]; 237 args[0] = arg1; 238 args[1] = arg2; 239 args[2] = arg3; 240 return method.module.applyN(method, args); 241 } 242 243 public static Object apply4Default(ModuleMethod method, 244 Object arg1, Object arg2, Object arg3, Object arg4) 245 throws Throwable 246 { 247 Object [] args = new Object [4]; 248 args[0] = arg1; 249 args[1] = arg2; 250 args[2] = arg3; 251 args[3] = arg4; 252 return method.module.applyN(method, args); 253 } 254 255 public static Object applyNDefault(ModuleMethod method, Object [] args) 256 throws Throwable 257 { 258 int count = args.length; 259 int num = method.numArgs(); 260 ModuleBody module = method.module; 261 if (count >= (num & 0xFFF) 262 && (num < 0 || count <= (num >> 12))) 263 { 264 switch (count) 265 { 266 case 0: 267 return module.apply0(method); 268 case 1: 269 return module.apply1(method, args[0]); 270 case 2: 271 return module.apply2(method, args[0], args[1]); 272 case 3: 273 return module.apply3(method, args[0], args[1], args[2]); 274 case 4: 275 return module.apply4(method, args[0], args[1], args[2], args[3]); 276 } 277 } 278 throw new WrongArguments(method, count); 279 } 280 281 282 283 public static void applyError() 284 { 285 throw new Error ("internal error - bad selector"); 286 } 287 } 288 | Popular Tags |