View Javadoc

1   // Driver.java, created Fri Jan 11 17:13:17 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Main;
5   
6   import java.util.Collection;
7   import java.util.Comparator;
8   import java.util.HashSet;
9   import java.util.Iterator;
10  import java.util.LinkedList;
11  import java.util.List;
12  import java.util.StringTokenizer;
13  import java.util.TreeSet;
14  import java.io.BufferedReader;
15  import java.io.File;
16  import java.io.IOException;
17  import java.io.InputStreamReader;
18  import java.net.URL;
19  import joeq.Class.PrimordialClassLoader;
20  import joeq.Class.jq_Array;
21  import joeq.Class.jq_Class;
22  import joeq.Class.jq_Method;
23  import joeq.Class.jq_MethodVisitor;
24  import joeq.Class.jq_Primitive;
25  import joeq.Class.jq_StaticField;
26  import joeq.Class.jq_StaticMethod;
27  import joeq.Class.jq_Type;
28  import joeq.Class.jq_TypeVisitor;
29  import joeq.Compiler.Quad.BasicBlockVisitor;
30  import joeq.Compiler.Quad.CallGraph;
31  import joeq.Compiler.Quad.CodeCache;
32  import joeq.Compiler.Quad.ControlFlowGraphVisitor;
33  import joeq.Compiler.Quad.LoadedCallGraph;
34  import joeq.Compiler.Quad.QuadVisitor;
35  import joeq.Runtime.Reflection;
36  import joeq.UTF.Utf8;
37  import jwutil.console.SimpleInterpreter;
38  import jwutil.strings.Strings;
39  import jwutil.util.Assert;
40  
41  /*
42   * @author  John Whaley <jwhaley@alum.mit.edu>
43   * @version $Id: Driver.java 1931 2004-09-22 22:17:47Z joewhaley $
44   */
45  public abstract class Driver {
46  
47      public static void main(String[] args) {
48          // initialize jq
49          HostedVM.initialize();
50  
51          try {
52              interpreterClass = Class.forName("joeq.Interpreter.QuadInterpreter", false, Driver.class.getClassLoader());
53          } catch (ClassNotFoundException x) {
54              System.err.println("Warning: interpreter class not found.");
55          }
56  
57          SimpleInterpreter si = new SimpleInterpreter((URL[])null);
58          if ((args.length == 0) || args[0].equals("-i")) {
59              // interactive mode
60              BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
61              for (; ;) {
62                  String[] commands;
63                  try {
64                      System.out.print("joeq> ");
65                      String line = in.readLine();
66                      if (line == null) return;
67                      StringTokenizer st = new StringTokenizer(line);
68                      int size = st.countTokens();
69                      commands = new String[size];
70                      for (int i = 0; i < size; ++i) {
71                          commands[i] = st.nextToken();
72                      }
73                      Assert._assert(!st.hasMoreTokens());
74                  } catch (IOException x) {
75                      System.err.println(x.toString());
76                      return;
77                  }
78                  for (int i = 0; i < commands.length; ++i) {
79                      i = processCommand(commands, i, si);
80                  }
81              }
82          }
83          for (int i = 0; i < args.length; ++i) {
84              i = processCommand(args, i, si);
85          }
86      }
87  
88      public static List classesToProcess = new LinkedList();
89      static HashSet methodNamesToProcess;
90      static boolean trace_bb = false;
91      static boolean trace_cfg = false;
92      static boolean trace_method = false;
93      static boolean trace_type = false;
94      // public so that "set Main.Driver.ignore_linkage_errors true" works
95      public static boolean ignore_linkage_errors = false;
96  
97      static Class interpreterClass;
98  
99      private static void addClassesInPackage(String pkgName, boolean recursive) {
100         String canonicalPackageName = pkgName.replace('.', '/');
101         if (!canonicalPackageName.endsWith("/")) canonicalPackageName += '/';
102         Iterator i = PrimordialClassLoader.loader.listPackage(canonicalPackageName, recursive);
103         if (!i.hasNext()) {
104             System.err.println("Package " + canonicalPackageName + " not found.");
105         }
106         // Because listPackage() may return entries twice, we record loaded
107         // entries in 'loaded' and skip dups
108         HashSet loaded = new HashSet();
109         while (i.hasNext()) {
110             String canonicalClassName = canonicalizeClassName((String) i.next());
111             if (loaded.contains(canonicalClassName))
112                 continue;
113             loaded.add(canonicalClassName);
114             try {
115                 jq_Class c = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType(canonicalClassName);
116                 c.load();
117                 classesToProcess.add(c);
118             } catch (NoClassDefFoundError x) {
119                 System.err.println("Package " + pkgName + ": Class not found (canonical name " + canonicalClassName + ").");
120             } catch (LinkageError le) {
121                 if (!ignore_linkage_errors)
122                     throw le;
123                 System.err.println("Linkage error occurred while loading class (" + canonicalClassName + "):");
124                 le.printStackTrace(System.err);
125             }
126         }
127     }
128 
129     public static int processCommand(String[] commandBuffer, int index) {
130         return processCommand(commandBuffer, index, (SimpleInterpreter)null);
131     }
132 
133     public static int processCommand(String[] commandBuffer, int index, SimpleInterpreter si) {
134         try {
135             if (commandBuffer[index].equalsIgnoreCase("addtoclasspath")) {
136                 String path = commandBuffer[++index];
137                 PrimordialClassLoader.loader.addToClasspath(path);
138             } else if (commandBuffer[index].equalsIgnoreCase("trace")) {
139                 String which = commandBuffer[++index];
140                 if (which.equalsIgnoreCase("bb")) {
141                     trace_bb = true;
142                 } else if (which.equalsIgnoreCase("cfg")) {
143                     trace_cfg = true;
144                 } else if (which.equalsIgnoreCase("method")) {
145                     trace_method = true;
146                 } else if (which.equalsIgnoreCase("type")) {
147                     trace_type = true;
148                 } else {
149                     System.err.println("Unknown trace option " + which);
150                 }
151             } else if (commandBuffer[index].equalsIgnoreCase("method")) {
152                 if (methodNamesToProcess == null) methodNamesToProcess = new HashSet();
153                 methodNamesToProcess.add(commandBuffer[++index]);
154             } else if (commandBuffer[index].equalsIgnoreCase("class")) {
155                 String canonicalClassName = canonicalizeClassName(commandBuffer[++index]);
156                 try {
157                     jq_Class c = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType(canonicalClassName);
158                     c.load();
159                     classesToProcess.add(c);
160                 } catch (NoClassDefFoundError x) {
161                     System.err.println("Class " + commandBuffer[index] + " (canonical name " + canonicalClassName + ") not found.");
162                 }
163             } else if (commandBuffer[index].equalsIgnoreCase("package")) {
164                 addClassesInPackage(commandBuffer[++index], /*recursive=*/false);
165             } else if (commandBuffer[index].equalsIgnoreCase("packages")) {
166                 addClassesInPackage(commandBuffer[++index], /*recursive=*/true);
167             } else if (commandBuffer[index].equalsIgnoreCase("callgraph")) {
168                 String callgraphFile = commandBuffer[++index];
169                 try {
170                     CallGraph cg = new LoadedCallGraph(callgraphFile);
171                     HashSet set = new HashSet();
172                     for (Iterator i = cg.getAllMethods().iterator(); i.hasNext(); ) {
173                         jq_Method m = (jq_Method) i.next();
174                         set.add(m.getDeclaringClass());
175                     }
176                     classesToProcess.addAll(set);
177                 } catch (IOException x) {
178                 }
179             } else if (commandBuffer[index].equalsIgnoreCase("setinterpreter")) {
180                 String interpreterClassName = commandBuffer[++index];
181                 try {
182                     Class cl = Class.forName(interpreterClassName);
183                     if (Class.forName("joeq.Interpreter.QuadInterpreter").isAssignableFrom(cl)) {
184                         interpreterClass = cl;
185                         System.out.println("Interpreter class changed to " + interpreterClass);
186                     } else {
187                         System.err.println("Class " + interpreterClassName + " does not subclass joeq.Interpreter.QuadInterpreter.");
188                     }
189                 } catch (java.lang.ClassNotFoundException x) {
190                     System.err.println("Cannot find interpreter named " + interpreterClassName + ".");
191                     System.err.println("Check your classpath and make sure you compiled your interpreter.");
192                     return index;
193                 }
194 
195             } else if (commandBuffer[index].equalsIgnoreCase("interpret")) {
196                 String fullName = commandBuffer[++index];
197                 int b = fullName.lastIndexOf('.') + 1;
198                 String methodName = fullName.substring(b);
199                 String className = canonicalizeClassName(fullName.substring(0, b - 1));
200                 try {
201                     jq_Class c = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType(className);
202                     c.cls_initialize();
203                     jq_StaticMethod m = null;
204                     Utf8 rootm_name = Utf8.get(methodName);
205                     for (Iterator it = java.util.Arrays.asList(c.getDeclaredStaticMethods()).iterator(); it.hasNext();) {
206                         jq_StaticMethod sm = (jq_StaticMethod) it.next();
207                         if (sm.getName() == rootm_name) {
208                             m = sm;
209                             break;
210                         }
211                     }
212                     if (m != null) {
213                         Object[] args = new Object[m.getParamTypes().length];
214                         index = parseMethodArgs(args, m.getParamTypes(), commandBuffer, index);
215                         joeq.Interpreter.QuadInterpreter s = null;
216                         java.lang.reflect.Method im = interpreterClass.getMethod("interpretMethod", new Class[]{Class.forName("Class.jq_Method"), new Object[0].getClass()});
217                         s = (joeq.Interpreter.QuadInterpreter) im.invoke(null, new Object[]{m, args});
218                         //s = joeq.Interpreter.QuadInterpreter.interpretMethod(m, args);
219                         System.out.flush();
220                         System.out.println("Result of interpretation: " + s);
221                     } else {
222                         System.err.println("Class " + fullName.substring(0, b - 1) + " doesn't contain a void static no-argument method with name " + methodName);
223                     }
224                 } catch (NoClassDefFoundError x) {
225                     System.err.println("Class " + fullName.substring(0, b - 1) + " (canonical name " + className + ") not found.");
226                     return index;
227                 } catch (NoSuchMethodException x) {
228                     System.err.println("Interpreter method in " + interpreterClass + " not found! " + x);
229                     return index;
230                 } catch (ClassNotFoundException x) {
231                     System.err.println("Class.jq_Method class not found! " + x);
232                     return index;
233                 } catch (IllegalAccessException x) {
234                     System.err.println("Cannot access interpreter " + interpreterClass + ": " + x);
235                     return index;
236                 } catch (java.lang.reflect.InvocationTargetException x) {
237                     System.err.println("Interpreter threw exception: " + x.getTargetException());
238                     x.getTargetException().printStackTrace();
239                     return index;
240                 }
241 
242             } else if (commandBuffer[index].equalsIgnoreCase("set")) {
243                 String fullName = commandBuffer[++index];
244                 int b = fullName.lastIndexOf('.') + 1;
245                 String fieldName = fullName.substring(b);
246                 String className = canonicalizeClassName(fullName.substring(0, b - 1));
247                 try {
248                     jq_Class c = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType(className);
249                     c.cls_initialize();
250                     jq_StaticField m = null;
251                     Utf8 sf_name = Utf8.get(fieldName);
252                     for (Iterator it = java.util.Arrays.asList(c.getDeclaredStaticFields()).iterator(); it.hasNext();) {
253                         jq_StaticField sm = (jq_StaticField) it.next();
254                         if (sm.getName() == sf_name) {
255                             m = sm;
256                             break;
257                         }
258                     }
259                     if (m != null) {
260                         java.lang.reflect.Field f = (java.lang.reflect.Field) Reflection.getJDKMember(m);
261                         f.setAccessible(true);
262                         Object[] o = new Object[1];
263                         index = parseArg(o, 0, m.getType(), commandBuffer, index);
264                         f.set(null, o[0]);
265                     } else {
266                         System.err.println("Class " + fullName.substring(0, b - 1) + " doesn't contain a static field with name " + fieldName);
267                     }
268                 } catch (NoClassDefFoundError x) {
269                     System.err.println("Class " + fullName.substring(0, b - 1) + " (canonical name " + className + ") not found.");
270                     return index;
271                 } catch (IllegalAccessException x) {
272                     System.err.println("Cannot access field: " + x);
273                     return index;
274                 }
275 
276             } else if (commandBuffer[index].equalsIgnoreCase("addpass")) {
277                 String passname = commandBuffer[++index];
278                 ControlFlowGraphVisitor mv = null;
279                 BasicBlockVisitor bbv = null;
280                 QuadVisitor qv = null;
281                 Object o;
282                 try {
283                     Class c = Class.forName(passname);
284                     o = c.newInstance();
285                     if (o instanceof ControlFlowGraphVisitor) {
286                         mv = (ControlFlowGraphVisitor) o;
287                     } else {
288                         if (o instanceof BasicBlockVisitor) {
289                             bbv = (BasicBlockVisitor) o;
290                         } else {
291                             if (o instanceof QuadVisitor) {
292                                 qv = (QuadVisitor) o;
293                             } else {
294                                 System.err.println("Unknown pass type " + c);
295                                 return index;
296                             }
297                             bbv = new QuadVisitor.AllQuadVisitor(qv, trace_bb);
298                         }
299                         mv = new BasicBlockVisitor.AllBasicBlockVisitor(bbv, trace_method);
300                     }
301                     CodeCache.passes.add(mv);
302                 } catch (java.lang.ClassNotFoundException x) {
303                     System.err.println("Cannot find pass named " + passname + ".");
304                     System.err.println("Check your classpath and make sure you compiled your pass.");
305                     return index;
306                 } catch (java.lang.InstantiationException x) {
307                     System.err.println("Cannot instantiate pass " + passname + ": " + x);
308                     return index;
309                 } catch (java.lang.IllegalAccessException x) {
310                     System.err.println("Cannot access pass " + passname + ": " + x);
311                     System.err.println("Be sure that you made your class public?");
312                     return index;
313                 }
314             } else if (commandBuffer[index].equalsIgnoreCase("runpass")) {
315                 String passname = commandBuffer[++index];
316                 jq_TypeVisitor cv = null;
317                 jq_MethodVisitor mv = null;
318                 ControlFlowGraphVisitor cfgv = null;
319                 BasicBlockVisitor bbv = null;
320                 QuadVisitor qv = null;
321                 Object o;
322                 try {
323                     passname = passname.replace('/', '.');
324                     Class c = Class.forName(passname);
325                     o = c.newInstance();
326                     if (o instanceof jq_TypeVisitor) {
327                         cv = (jq_TypeVisitor) o;
328                     } else {
329                         if (o instanceof jq_MethodVisitor) {
330                             mv = (jq_MethodVisitor) o;
331                         } else {
332                             if (o instanceof ControlFlowGraphVisitor) {
333                                 cfgv = (ControlFlowGraphVisitor) o;
334                             } else {
335                                 if (o instanceof BasicBlockVisitor) {
336                                     bbv = (BasicBlockVisitor) o;
337                                 } else {
338                                     if (o instanceof QuadVisitor) {
339                                         qv = (QuadVisitor) o;
340                                     } else {
341                                         System.err.println("Unknown pass type " + c);
342                                         return index;
343                                     }
344                                     bbv = new QuadVisitor.AllQuadVisitor(qv, trace_bb);
345                                 }
346                                 cfgv = new BasicBlockVisitor.AllBasicBlockVisitor(bbv, trace_cfg);
347                             }
348                             mv = new ControlFlowGraphVisitor.CodeCacheVisitor(cfgv, trace_method);
349                         }
350                         cv = new jq_MethodVisitor.DeclaredMethodVisitor(mv, methodNamesToProcess, trace_type);
351                     }
352                 } catch (java.lang.ClassNotFoundException x) {
353                     System.err.println("Cannot find pass named " + passname + ".");
354                     System.err.println("Check your classpath and make sure you compiled your pass.");
355                     return index;
356                 } catch (java.lang.InstantiationException x) {
357                     System.err.println("Cannot instantiate pass " + passname + ": " + x);
358                     return index;
359                 } catch (java.lang.IllegalAccessException x) {
360                     System.err.println("Cannot access pass " + passname + ": " + x);
361                     System.err.println("Be sure that you made your class public?");
362                     return index;
363                 }
364                 // Sort classesToProcess
365                 Collection s = new TreeSet(new Comparator() {
366                     public int compare(Object o1, Object o2) {
367                         return o1.toString().compareTo(o2.toString());
368                     }
369                 });
370                 s.addAll(classesToProcess);
371                 for (Iterator i = s.iterator(); i.hasNext();) {
372                     jq_Type t = (jq_Type) i.next();
373                     try {
374                         t.accept(cv);
375                     } catch (LinkageError le) {
376                         if (!ignore_linkage_errors)
377                             throw le;
378                         System.err.println("Linkage error occurred while executing pass on " + t + " : " + le);
379                         le.printStackTrace(System.err);
380                     } catch (Exception x) {
381                         System.err.println("Runtime exception occurred while executing pass on " + t + " : " + x);
382                         x.printStackTrace(System.err);
383                     }
384                 }
385                 System.err.println("Completed pass! " + o);
386             } else if (commandBuffer[index].equalsIgnoreCase("run")) {
387                 String toRun = commandBuffer[++index];
388                 Runnable runnable = null;
389                 try {
390                     runnable = (Runnable)Class.forName(toRun).newInstance();
391                 } catch (InstantiationException e) {
392                     e.printStackTrace();
393                     System.err.println("Can't instantiate a " + toRun);
394                     return index;
395                 } catch (IllegalAccessException e) {
396                     // TODO Auto-generated catch block
397                     e.printStackTrace();
398                     System.err.println("Can't access a field");
399                     return index;
400                 } catch (ClassNotFoundException e) {
401                     e.printStackTrace();
402                     System.err.println("Class can't be found");
403                     return index;
404                 }
405                 Assert._assert(runnable != null);
406                 
407                 runnable.run();                
408             } else if (commandBuffer[index].equalsIgnoreCase("store")) {
409                 System.out.println(si.getStore());
410             } else if (commandBuffer[index].equalsIgnoreCase("loaderpath")) {
411                 try {
412                     si.setClassPath(new URL[] { new File(commandBuffer[++index]).toURL() });
413                 } catch (java.net.MalformedURLException e) {
414                     e.printStackTrace(System.err);
415                 }
416             } else if (commandBuffer[index].equalsIgnoreCase("new")) {    // new name Type arg0 arg1 arg2
417                 String name = commandBuffer[++index];
418                 String type = commandBuffer[++index];
419                 index = si.newObject(name, type, commandBuffer, index);
420                 printObjectInStore(si, name);
421             } else if (commandBuffer[index].indexOf(".") != -1) {              // name.method arg0 arg1 ...
422                 String fullName = commandBuffer[index];
423                 int b = fullName.lastIndexOf('.') + 1;
424                 String objectName = fullName.substring(0, b-1);
425                 String methodName = fullName.substring(b);
426                 index = si.invokeMethod(objectName, methodName, commandBuffer, index);
427                 printObjectInStore(si, "$last");
428             } else if (commandBuffer[index].equalsIgnoreCase("exit") || commandBuffer[index].equalsIgnoreCase("quit")) {
429                 System.exit(0);
430             } else if (commandBuffer[index].equalsIgnoreCase("help")) {
431                 printHelp();
432             } else {
433                 int index2 = TraceFlags.setTraceFlag(commandBuffer, index);
434                 if (index == index2)
435                     System.err.println("Unknown command " + commandBuffer[index]);
436                 else
437                     index = index2 - 1;
438             }
439         } catch (ArrayIndexOutOfBoundsException x) {
440             System.err.println("Incomplete command");
441             x.printStackTrace(System.err);
442         }
443         return index;
444     }
445 
446     private static void printObjectInStore(SimpleInterpreter si, Object name) {
447         Object newobj = si.getStore().get(name);
448         if (newobj != null) {
449             String s = newobj.toString();
450             if (s.length() > 1024) s = s.substring(0, 1024);
451             System.out.println(s);
452         } else {
453             System.err.println("object " + name + " not found - did the operation fail?");
454         }
455     }
456 
457     public static void printHelp() {
458         String nl = Strings.lineSep;
459         String helpMessage =
460                 nl+
461                 "Usage: command1 [args...] [command2 [args...]]..."+nl+nl +
462                 "1.  addtoclasspath   additional_classpath"+nl +
463                 "---->   add to the class path"+nl+nl +
464                 "2.  addpass   pass_class_name"+nl +
465                 "---->   run compiler pass on all code generated from this point"+nl+nl +
466                 "3.  class   class_name"+nl +
467                 "---->   add to the list of classes to process"+nl+nl +
468                 "4.  exit | quit"+nl +
469                 "---->   exit interactive mode"+nl+nl +
470                 "5.  help"+nl +
471                 "---->   print this message"+nl+nl +
472                 "6.  interpret   class_name.static_method_name param_list"+nl +
473                 "---->   interpret a static method with the given arguments"+nl+nl +
474                 "7.  method   method_name"+nl +
475                 "---->   only process methods of the given name"+nl+nl +
476                 "8.  package   package_name"+nl +
477                 "---->   add all the classes in the specified package to the list of classes to process"+nl+nl +
478                 "9.  packages   package_name"+nl +
479                 "---->   add all the classes in the specified package and all sub-packages recursively to the list of classes to process"+nl+nl +
480                 "10. runpass   pass_class_name"+nl +
481                 "---->   run compiler pass on classes in list"+nl+nl +
482                 "11. set   class_name.static_field_name value"+nl +
483                 "---->   set specified static field to specified value"+nl+nl +
484                 "12. trace   bb|cfg|method|type"+nl +
485                 "---->   enable tracing options when processing classes"+nl+nl +
486                 "Other trace options are available, see Main/TraceFlags.java."+
487                 nl;
488         System.out.println(helpMessage);
489     }
490 
491     public static String canonicalizeClassName(String s) {
492         if (s.endsWith(".class")) s = s.substring(0, s.length() - 6);
493         s = s.replace('.', '/');
494         String desc = "L" + s + ";";
495         return desc;
496     }
497 
498     public static int parseArg(Object[] args, int m, jq_Type type, String[] s_args, int j) {
499         if (type == PrimordialClassLoader.getJavaLangString())
500             args[m] = s_args[++j];
501         else if (type == jq_Primitive.BOOLEAN)
502             args[m] = Boolean.valueOf(s_args[++j]);
503         else if (type == jq_Primitive.BYTE)
504             args[m] = Byte.valueOf(s_args[++j]);
505         else if (type == jq_Primitive.SHORT)
506             args[m] = Short.valueOf(s_args[++j]);
507         else if (type == jq_Primitive.CHAR)
508             args[m] = new Character(s_args[++j].charAt(0));
509         else if (type == jq_Primitive.INT)
510             args[m] = Integer.valueOf(s_args[++j]);
511         else if (type == jq_Primitive.LONG) {
512             args[m] = Long.valueOf(s_args[++j]);
513         } else if (type == jq_Primitive.FLOAT)
514             args[m] = Float.valueOf(s_args[++j]);
515         else if (type == jq_Primitive.DOUBLE) {
516             args[m] = Double.valueOf(s_args[++j]);
517         } else if (type.isArrayType()) {
518             if (!s_args[++j].equals("{"))
519                 Assert.UNREACHABLE("array parameter doesn't start with {");
520             int count = 0;
521             while (!s_args[++j].equals("}")) ++count;
522             jq_Type elementType = ((jq_Array) type).getElementType();
523             if (elementType == PrimordialClassLoader.getJavaLangString()) {
524                 String[] array = new String[count];
525                 for (int k = 0; k < count; ++k)
526                     array[k] = s_args[j - count + k];
527                 args[m] = array;
528             } else if (elementType == jq_Primitive.BOOLEAN) {
529                 boolean[] array = new boolean[count];
530                 for (int k = 0; k < count; ++k)
531                     array[k] = Boolean.valueOf(s_args[j - count + k]).booleanValue();
532                 args[m] = array;
533             } else if (elementType == jq_Primitive.BYTE) {
534                 byte[] array = new byte[count];
535                 for (int k = 0; k < count; ++k)
536                     array[k] = Byte.parseByte(s_args[j - count + k]);
537                 args[m] = array;
538             } else if (elementType == jq_Primitive.SHORT) {
539                 short[] array = new short[count];
540                 for (int k = 0; k < count; ++k)
541                     array[k] = Short.parseShort(s_args[j - count + k]);
542                 args[m] = array;
543             } else if (elementType == jq_Primitive.CHAR) {
544                 char[] array = new char[count];
545                 for (int k = 0; k < count; ++k)
546                     array[k] = s_args[j - count + k].charAt(0);
547                 args[m] = array;
548             } else if (elementType == jq_Primitive.INT) {
549                 int[] array = new int[count];
550                 for (int k = 0; k < count; ++k)
551                     array[k] = Integer.parseInt(s_args[j - count + k]);
552                 args[m] = array;
553             } else if (elementType == jq_Primitive.LONG) {
554                 long[] array = new long[count];
555                 for (int k = 0; k < count; ++k)
556                     array[k] = Long.parseLong(s_args[j - count + k]);
557                 args[m] = array;
558             } else if (elementType == jq_Primitive.FLOAT) {
559                 float[] array = new float[count];
560                 for (int k = 0; k < count; ++k)
561                     array[k] = Float.parseFloat(s_args[j - count + k]);
562                 args[m] = array;
563             } else if (elementType == jq_Primitive.DOUBLE) {
564                 double[] array = new double[count];
565                 for (int k = 0; k < count; ++k)
566                     array[k] = Double.parseDouble(s_args[j - count + k]);
567                 args[m] = array;
568             } else
569                 Assert.UNREACHABLE("Parsing of type " + type + " is not implemented");
570         } else
571             Assert.UNREACHABLE("Parsing of type " + type + " is not implemented");
572         return j;
573     }
574 
575     public static int parseMethodArgs(Object[] args, jq_Type[] paramTypes, String[] s_args, int j) {
576         try {
577             for (int i = 0, m = 0; i < paramTypes.length; ++i, ++m) {
578                 j = parseArg(args, m, paramTypes[i], s_args, j);
579             }
580         } catch (ArrayIndexOutOfBoundsException x) {
581             x.printStackTrace();
582             Assert.UNREACHABLE("not enough method arguments");
583         }
584         return j;
585     }
586 }