1 package gov.nasa.jpf.jvm; 20 21 import gov.nasa.jpf.JPFException; 22 23 import java.lang.reflect.Method ; 24 25 import org.apache.bcel.Constants; 26 27 28 31 public class Types implements Constants { 32 public static byte[] getArgumentTypes (String signature) { 33 int i; 34 int j; 35 int nArgs; 36 37 for (i = 1, nArgs = 0; signature.charAt(i) != ')'; nArgs++) { 38 i += getTypeLength(signature, i); 39 } 40 41 byte[] args = new byte[nArgs]; 42 43 for (i = 1, j = 0; j < nArgs; j++) { 44 int end = i + getTypeLength(signature, i); 45 String arg = signature.substring(i, end); 46 i = end; 47 48 args[j] = getBaseType(arg); 49 } 50 51 return args; 52 } 53 54 57 public static int getArgumentsSize (String signature) { 58 int i; 59 int n; 60 char c; 61 62 for (i = 1, n = 0; (c = signature.charAt(i)) != ')'; n++) { 63 switch (c) { 64 case 'L': 65 66 for (i++; signature.charAt(i) != ';'; i++) { 67 ; 68 } 69 70 break; 71 72 case '[': 73 74 while ((c = signature.charAt(++i)) == '[') { 75 ; 76 } 77 78 if (c == 'L') { 79 for (i++; signature.charAt(i) != ';'; i++) { 80 ; 81 } 82 } 83 84 break; 85 86 case 'J': 87 case 'D': 88 89 n++; 91 92 break; 93 94 default: 95 96 } 98 99 i++; 100 } 101 102 return n; 103 } 104 105 public static String getArrayElementType (String type) { 106 if (type.charAt(0) != '[') { 107 throw new JPFException("not an array type"); 108 } 109 110 return type.substring(1); 111 } 112 113 public static byte getBaseType (String type) { 114 switch (type.charAt(0)) { 115 case 'B': 116 return T_BYTE; 117 118 case 'C': 119 return T_CHAR; 120 121 case 'D': 122 return T_DOUBLE; 123 124 case 'F': 125 return T_FLOAT; 126 127 case 'I': 128 return T_INT; 129 130 case 'J': 131 return T_LONG; 132 133 case 'L': 134 return T_OBJECT; 136 case 'S': 137 return T_SHORT; 138 139 case 'V': 140 return T_VOID; 141 142 case 'Z': 143 return T_BOOLEAN; 144 145 case '[': 146 return T_ARRAY; 147 } 148 149 throw new JPFException("invalid type string: " + type); 150 } 151 152 159 public static String getJNIArgSignature (String mangledName) { 160 int i = mangledName.indexOf("__"); 161 String sig = null; 162 163 if (i > 0) { 164 int len = mangledName.length(); 165 char[] buf = new char[len + 1]; 166 int j; 167 int k = 0; 168 169 buf[k++] = '('; 170 171 for (j = i + 2; j < len; j++) { 172 char c = mangledName.charAt(j); 173 174 if (c == '_') { 175 j++; 176 177 if (j < len) { 178 c = mangledName.charAt(j); 179 180 switch (c) { 181 case '1': 182 buf[k++] = '_'; 183 184 break; 185 186 case '2': 187 buf[k++] = ';'; 188 189 break; 190 191 case '3': 192 buf[k++] = '['; 193 194 break; 195 196 default: 197 buf[k++] = '/'; 198 buf[k++] = c; 199 } 200 } else { 201 buf[k++] = '/'; 202 } 203 } else { 204 buf[k++] = c; 205 } 206 } 207 208 buf[k++] = ')'; 209 sig = new String (buf, 0, k); 210 } 211 212 return sig; 213 } 214 215 public static String getJNIMangledMethodName (Method m) { 216 String name = m.getName(); 217 Class [] pt = m.getParameterTypes(); 218 StringBuffer s = new StringBuffer (name.length() + (pt.length * 16)); 219 220 s.append(name); 221 s.append("__"); 222 223 for (int i = 0; i < pt.length; i++) { 225 s.append(getJNITypeCode(pt[i].getName())); 226 } 227 228 return s.toString(); 229 } 230 231 public static String getJNIMangledMethodName (String cls, String name, 232 String signature) { 233 StringBuffer s = new StringBuffer (signature.length() + 10); 234 int i; 235 char c; 236 237 if (cls != null) { 238 s.append(cls.replace('.', '_')); 239 } 240 241 s.append(name); 242 s.append("__"); 243 244 for (i = 1; (c = signature.charAt(i)) != ')'; i++) { 246 switch (c) { 247 case '/': 248 s.append("_"); 249 250 break; 251 252 case '_': 253 s.append("_1"); 254 255 break; 256 257 case ';': 258 s.append("_2"); 259 260 break; 261 262 case '[': 263 s.append("_3"); 264 265 break; 266 267 default: 268 s.append(c); 269 } 270 } 271 272 return s.toString(); 273 } 274 275 280 public static String getJNIMethodName (String mangledName) { 281 int i = mangledName.indexOf("__"); 282 283 if (i > 0) { 284 return mangledName.substring(0, i); 285 } else { 286 return mangledName; 287 } 288 } 289 290 public static String getJNITypeCode (String type) { 291 StringBuffer sb = new StringBuffer (32); 292 int l = type.length() - 1; 293 294 for (; type.charAt(l) == ']'; l -= 2) { 295 sb.append("_3"); 296 } 297 298 type = type.substring(0, l + 1); 299 300 if (type.equals("int")) { 301 sb.append('I'); 302 } else if (type.equals("long")) { 303 sb.append('J'); 304 } else if (type.equals("boolean")) { 305 sb.append('Z'); 306 } else if (type.equals("char")) { 307 sb.append('C'); 308 } else if (type.equals("byte")) { 309 sb.append('B'); 310 } else if (type.equals("short")) { 311 sb.append('S'); 312 } else if (type.equals("double")) { 313 sb.append('D'); 314 } else if (type.equals("float")) { 315 sb.append('F'); 316 } else { 317 sb.append('L'); 318 319 for (int i = 0; i < type.length(); i++) { 320 char c = type.charAt(i); 321 322 switch (c) { 323 case '.': 324 sb.append('_'); 325 326 break; 327 328 case '_': 329 sb.append("_1"); 330 331 break; 332 333 default: 334 sb.append(c); 335 } 336 } 337 338 sb.append("_2"); 339 } 340 341 return sb.toString(); 342 } 343 344 public static int getNumberOfArguments (String signature) { 345 int i; 346 int n; 347 char c; 348 349 for (i = 1, n = 0; (c = signature.charAt(i)) != ')'; n++) { 350 switch (c) { 351 case 'L': 352 353 for (i++; signature.charAt(i) != ';'; i++) { 354 ; 355 } 356 357 break; 358 359 case '[': 360 361 while ((c = signature.charAt(++i)) == '[') { 362 ; 363 } 364 365 if (c == 'L') { 366 for (i++; signature.charAt(i) != ';'; i++) { 367 ; 368 } 369 } 370 371 break; 372 373 default: 374 375 } 377 378 i++; 379 } 380 381 return n; 382 } 383 384 public static boolean isReference (String type) { 385 int t = getBaseType(type); 386 387 return (t == T_ARRAY) || (t == T_REFERENCE); 388 } 389 390 public static byte getReturnType (String signature) { 391 int i = signature.indexOf(')'); 392 393 return getBaseType(signature.substring(i + 1)); 394 } 395 396 public static String getTypeCode (String type) { 397 String t = null; 398 boolean isArray = type.endsWith("[]"); 399 400 if (isArray) { 401 type = type.substring(0, type.length() - 2); 402 } 403 404 if (type.equals("byte")) { 405 t = "B"; 406 } else if (type.equals("char")) { 407 t = "C"; 408 } else if (type.equals("short")) { 409 t = "S"; 410 } else if (type.equals("int")) { 411 t = "I"; 412 } else if (type.equals("float")) { 413 t = "F"; 414 } else if (type.equals("long")) { 415 t = "J"; 416 } else if (type.equals("double")) { 417 t = "D"; 418 } else if (type.equals("boolean")) { 419 t = "Z"; 420 } else if (type.equals("void")) { 421 t = "V"; 422 } 423 424 if (t != null) { 425 if (isArray) { 426 t = "[" + t; 427 } 428 } else { 429 t = "L"; 430 431 if (isArray) { 432 t += '['; 433 } 434 435 t += type.replace('.', '/'); 436 t += ';'; 437 } 438 439 return t; 440 } 441 442 public static boolean isTypeCode (String t) { 443 char c = t.charAt(0); 444 445 if (c == '[') { 446 return true; 447 } 448 449 if ((t.length() == 1) && 450 ((c == 'B') || (c == 'I') || (c == 'S') || (c == 'C') || 451 (c == 'F') || (c == 'J') || (c == 'D') || (c == 'Z'))) { 452 return true; 453 } 454 455 if (t.endsWith(";")) { 456 return true; 457 } 458 459 return false; 460 } 461 462 public static String getTypeName (String type) { 463 int len = type.length(); 464 char c = type.charAt(0); 465 466 if (len == 1) { 467 switch (c) { 468 case 'B': 469 return "byte"; 470 471 case 'C': 472 return "char"; 473 474 case 'D': 475 return "double"; 476 477 case 'F': 478 return "float"; 479 480 case 'I': 481 return "int"; 482 483 case 'J': 484 return "long"; 485 486 case 'S': 487 return "short"; 488 489 case 'V': 490 return "void"; 491 492 case 'Z': 493 return "boolean"; 494 } 495 } 496 497 if (c == '[') { 498 return getTypeName(type.substring(1)) + "[]"; 499 } 500 501 if (type.charAt(len - 1) == ';') { 502 return type.substring(1, type.indexOf(';')).replace('/', '.'); 503 } 504 505 throw new JPFException("invalid type string: " + type); 506 } 507 508 512 public static int getTypeSizeInBytes (String type) { 513 switch (type.charAt(0)) { 514 case 'V': 515 return 0; 516 517 case 'Z': case 'B': 519 return 1; 520 521 case 'S': 522 case 'C': 523 return 2; 524 525 case 'L': 526 case '[': 527 case 'F': 528 case 'I': 529 return 4; 530 531 case 'D': 532 case 'J': 533 return 8; 534 } 535 536 throw new JPFException("invalid type string: " + type); 537 } 538 539 public static int getTypeSize (String type) { 540 switch (type.charAt(0)) { 541 case 'V': 542 return 0; 543 544 case 'B': 545 case 'C': 546 case 'F': 547 case 'I': 548 case 'L': 549 case 'S': 550 case 'Z': 551 case '[': 552 return 1; 553 554 case 'D': 555 case 'J': 556 return 2; 557 } 558 559 throw new JPFException("invalid type string: " + type); 560 } 561 562 public static String asTypeName (String type) { 563 if (type.startsWith("[") || type.endsWith(";")) { 564 return getTypeName(type); 565 } 566 567 return type; 568 } 569 570 public static int booleanToInt (boolean b) { 571 return b ? 1 : 0; 572 } 573 574 public static long doubleToLong (double d) { 575 return Double.doubleToLongBits(d); 576 } 577 578 public static int floatToInt (float f) { 579 return Float.floatToIntBits(f); 580 } 581 582 public static int hiDouble (double d) { 583 return hiLong(Double.doubleToLongBits(d)); 584 } 585 586 public static int hiLong (long l) { 587 return (int) (l >> 32); 588 } 589 590 public static boolean instanceOf (String type, String ofType) { 591 int bType = getBaseType(type); 592 593 if ((bType == T_ARRAY) && ofType.equals("Ljava/lang/Object;")) { 594 return true; 595 } 596 597 int bOfType = getBaseType(ofType); 598 599 if (bType != bOfType) { 600 return false; 601 } 602 603 switch (bType) { 604 case T_ARRAY: 605 return instanceOf(type.substring(1), ofType.substring(1)); 606 607 case T_REFERENCE: 608 return ClassInfo.getClassInfo(getTypeName(type)) 609 .instanceOf(getTypeName(ofType)); 610 611 default: 612 return true; 613 } 614 } 615 616 public static boolean intToBoolean (int i) { 617 return i != 0; 618 } 619 620 public static float intToFloat (int i) { 621 return Float.intBitsToFloat(i); 622 } 623 624 public static double intsToDouble (int l, int h) { 625 return longToDouble(intsToLong(l, h)); 626 } 627 628 public static long intsToLong (int l, int h) { 629 return ((long) h << 32) | ((long) l & 0xFFFFFFFFL); 630 } 631 632 public static int loDouble (double d) { 633 return loLong(Double.doubleToLongBits(d)); 634 } 635 636 public static int loLong (long l) { 637 return (int) (l & 0xFFFFFFFFL); 638 } 639 640 public static double longToDouble (long l) { 641 return Double.longBitsToDouble(l); 642 } 643 644 private static int getTypeLength (String signature, int idx) { 645 switch (signature.charAt(idx)) { 646 case 'B': 647 case 'C': 648 case 'D': 649 case 'F': 650 case 'I': 651 case 'J': 652 case 'S': 653 case 'V': 654 case 'Z': 655 return 1; 656 657 case '[': 658 return 1 + getTypeLength(signature, idx + 1); 659 660 case 'L': 661 662 int semicolon = signature.indexOf(';', idx); 663 664 if (semicolon == -1) { 665 throw new JPFException("invalid type signature: " + 666 signature); 667 } 668 669 return semicolon - idx + 1; 670 } 671 672 throw new JPFException("invalid type signature"); 673 } 674 } 675 | Popular Tags |