annotate make/tools/GenerateCharacter/check_class.c.template @ 4338:9b8c96f96a0f

Added tag jdk7-b147 for changeset f097ca2434b1
author schien
date Mon, 27 Jun 2011 13:21:34 -0700
parents 3a4370604bab
children
rev   line source
duke@0 1 /*
ohair@2362 2 * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
ohair@2362 7 * published by the Free Software Foundation. Oracle designates this
duke@0 8 * particular file as subject to the "Classpath" exception as provided
ohair@2362 9 * by Oracle in the LICENSE file that accompanied this code.
duke@0 10 *
duke@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 15 * accompanied this code).
duke@0 16 *
duke@0 17 * You should have received a copy of the GNU General Public License version
duke@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 20 *
ohair@2362 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@2362 22 * or visit www.oracle.com if you need additional information or have any
ohair@2362 23 * questions.
duke@0 24 */
duke@0 25
duke@0 26 /* This file was generated AUTOMATICALLY from a template file Wed Jun 17 10:43:47 PDT 1998 */
duke@0 27
duke@0 28 /*-
duke@0 29 * code for verifying the date in a ClassClass structure for internal
duke@0 30 * consistency.
duke@0 31 */
duke@0 32
duke@0 33 #include <ctype.h>
duke@0 34
duke@0 35 #include "oobj.h"
duke@0 36 #include "interpreter.h"
duke@0 37 #include "bool.h"
duke@0 38 #include "utf.h"
duke@0 39 #include "tree.h"
duke@0 40
duke@0 41 extern bool_t verify_class_codes(ClassClass *cb);
duke@0 42
duke@0 43 static bool_t verify_constant_pool(ClassClass *cb);
duke@0 44
duke@0 45 static bool_t is_legal_fieldname(ClassClass *cb, char *name, int type);
duke@0 46 static bool_t is_legal_method_signature(ClassClass *cb, char *name, char *signature);
duke@0 47 static bool_t is_legal_field_signature(ClassClass *cb, char *name, char *signature);
duke@0 48
duke@0 49 static char *skip_over_fieldname(char *name, bool_t slash_okay);
duke@0 50 static char *skip_over_field_signature(char *name, bool_t void_okay);
duke@0 51
duke@0 52 static void CCerror (ClassClass *cb, char *format, ...);
duke@0 53
duke@0 54
duke@0 55 /* Argument for is_legal_fieldname */
duke@0 56 enum { LegalClass, LegalField, LegalMethod };
duke@0 57
duke@0 58
duke@0 59
duke@0 60
duke@0 61 bool_t
duke@0 62 VerifyClass(ClassClass *cb)
duke@0 63 {
duke@0 64 bool_t result = TRUE;
duke@0 65 struct methodblock *mb;
duke@0 66 struct fieldblock *fb;
duke@0 67 int i;
duke@0 68 if (CCIs(cb, Verified))
duke@0 69 return TRUE;
duke@0 70 if (!verify_constant_pool(cb))
duke@0 71 return FALSE;
duke@0 72 /* Make sure all the method names and signatures are okay */
duke@0 73 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
duke@0 74 char *name = mb->fb.name;
duke@0 75 char *signature = mb->fb.signature;
duke@0 76 if (! (is_legal_fieldname(cb, name, LegalMethod) &&
duke@0 77 is_legal_method_signature(cb, name, signature)))
duke@0 78 result = FALSE;
duke@0 79 }
duke@0 80 /* Make sure all the field names and signatures are okay */
duke@0 81 for (i = cbFieldsCount(cb), fb = cbFields(cb); --i >= 0; fb++) {
duke@0 82 if (! (is_legal_fieldname(cb, fb->name, LegalField) &&
duke@0 83 is_legal_field_signature(cb, fb->name, fb->signature)))
duke@0 84 result = FALSE;
duke@0 85 }
duke@0 86 /* Make sure we are not overriding any final methods or classes*/
duke@0 87 if (cbIsInterface(cb)) {
duke@0 88 struct methodblock *mb;
duke@0 89 if ((cbSuperclass(cb) == NULL) ||
duke@0 90 (cbSuperclass(cb) != classJavaLangObject)) {
duke@0 91 CCerror(cb, "Interface %s has bad superclass", cbName(cb));
duke@0 92 result = FALSE;
duke@0 93 }
duke@0 94 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
duke@0 95 if (mb->fb.access & ACC_STATIC) {
duke@0 96 if (mb->fb.name[0] != '<') {
duke@0 97 /* Only internal methods can be static */
duke@0 98 CCerror(cb, "Illegal static method %s in interface %s",
duke@0 99 mb->fb.name, cbName(cb));
duke@0 100 result = FALSE;
duke@0 101 }
duke@0 102 }
duke@0 103 }
duke@0 104 } else if (cbSuperclass(cb)) {
duke@0 105 ClassClass *super_cb;
duke@0 106 unsigned bitvector_size = (unsigned)(cbMethodTableSize(cb) + 31) >> 5;
duke@0 107 long *bitvector = sysCalloc(bitvector_size, sizeof(long));
duke@0 108 for (super_cb = cbSuperclass(cb); ; super_cb = cbSuperclass(super_cb)) {
duke@0 109 if (cbAccess(super_cb) & ACC_FINAL) {
duke@0 110 CCerror(cb, "Class %s is subclass of final class %s",
duke@0 111 cbName(cb), cbName(super_cb));
duke@0 112 result = FALSE;
duke@0 113 }
duke@0 114 mb = cbMethods(super_cb);
duke@0 115 for (i = cbMethodsCount(super_cb); --i >= 0; mb++) {
duke@0 116 if (mb->fb.access & ACC_FINAL) {
duke@0 117 unsigned offset = mb->fb.u.offset;
duke@0 118 bitvector[offset >> 5] |= (1 << (offset & 0x1F));
duke@0 119 }
duke@0 120 }
duke@0 121 if (cbSuperclass(super_cb) == NULL) break;
duke@0 122 }
duke@0 123 for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
duke@0 124 unsigned offset = mb->fb.u.offset;
duke@0 125 if ((offset > 0)
duke@0 126 && bitvector[offset >> 5] & (1 << (offset & 0x1F))) {
duke@0 127 CCerror(cb, "Class %s overrides final method %s.%s",
duke@0 128 cbName(cb), mb->fb.name, mb->fb.signature);
duke@0 129 result = FALSE;
duke@0 130 }
duke@0 131 }
duke@0 132 sysFree(bitvector);
duke@0 133 } else if (cb != classJavaLangObject) {
duke@0 134 CCerror(cb, "Class %s does not have superclass", cbName(cb));
duke@0 135 result = FALSE;
duke@0 136 }
duke@0 137
duke@0 138 if (result)
duke@0 139 result = verify_class_codes(cb);
duke@0 140 if (result)
duke@0 141 CCSet(cb, Verified);
duke@0 142 return result;
duke@0 143 }
duke@0 144
duke@0 145
duke@0 146 static bool_t
duke@0 147 verify_constant_pool(ClassClass *cb)
duke@0 148 {
duke@0 149 union cp_item_type *cp = cbConstantPool(cb);
duke@0 150 long cp_count = cbConstantPoolCount(cb);
duke@0 151 unsigned char *type_table;
duke@0 152 int i, type;
duke@0 153
duke@0 154 const int utf8_resolved = (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED);
duke@0 155
duke@0 156 if (cp_count == 0) /* Primitive classes */
duke@0 157 return TRUE;
duke@0 158 type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
duke@0 159 /* Let's make two quick passes over the constant pool. The first one
duke@0 160 * checks that everything is of the right type. */
duke@0 161 for (i = 1; i < cp_count; i++) {
duke@0 162 switch(type = type_table[i]) {
duke@0 163 case CONSTANT_String:
duke@0 164 case CONSTANT_Class: {
duke@0 165 int index = cp[i].i;
duke@0 166 if ( (index < 1)
duke@0 167 || (index >= cp_count)
duke@0 168 || (type_table[index] != utf8_resolved)) {
duke@0 169 CCerror(cb, "Bad index in constant pool #%d", i);
duke@0 170 return FALSE;
duke@0 171 }
duke@0 172 break;
duke@0 173 }
duke@0 174
duke@0 175 case CONSTANT_String | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 176 /* This can only happen if a string is the "initial" value of
duke@0 177 * some final static String. We assume that the checking has
duke@0 178 * already been done.
duke@0 179 */
duke@0 180 break;
duke@0 181
duke@0 182 case CONSTANT_Fieldref:
duke@0 183 case CONSTANT_Methodref:
duke@0 184 case CONSTANT_InterfaceMethodref:
duke@0 185 case CONSTANT_NameAndType: {
duke@0 186 unsigned index = (unsigned)(cp[i].i);
duke@0 187 int key1 = index >> 16;
duke@0 188 int key2 = index & 0xFFFF;
duke@0 189 if (key1 < 1 || key1 >= cp_count
duke@0 190 || key2 < 1 || key2 >= cp_count) {
duke@0 191 CCerror(cb, "Bad index in constant pool #%d", i);
duke@0 192 return FALSE;
duke@0 193 }
duke@0 194 if (type == CONSTANT_NameAndType) {
duke@0 195 if ( (type_table[key1] != utf8_resolved)
duke@0 196 || (type_table[key2] != utf8_resolved)) {
duke@0 197 CCerror(cb, "Bad index in constant pool.");
duke@0 198 return FALSE;
duke@0 199 }
duke@0 200 } else {
duke@0 201 if ( ((type_table[key1] & CONSTANT_POOL_ENTRY_TYPEMASK)
duke@0 202 != CONSTANT_Class)
duke@0 203 || ((type_table[key2] != CONSTANT_NameAndType))) {
duke@0 204 CCerror(cb, "Bad index in constant pool #%d", i);
duke@0 205 return FALSE;
duke@0 206 }
duke@0 207 }
duke@0 208 break;
duke@0 209 }
duke@0 210
duke@0 211 case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 212 case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 213 case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 214 case CONSTANT_NameAndType | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 215 CCerror(cb, "Improperly resolved constant pool #%d", i);
duke@0 216 return FALSE;
duke@0 217
duke@0 218
duke@0 219 case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 220 case CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 221 case CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 222 case CONSTANT_Float | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 223 break;
duke@0 224
duke@0 225 case CONSTANT_Long | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 226 case CONSTANT_Double | CONSTANT_POOL_ENTRY_RESOLVED:
duke@0 227 if ((i + 1 >= cp_count) ||
duke@0 228 (type_table[i + 1] != CONSTANT_POOL_ENTRY_RESOLVED)) {
duke@0 229 CCerror(cb, "Improper constant pool long/double #%d", i);
duke@0 230 return FALSE;
duke@0 231 } else {
duke@0 232 i++;
duke@0 233 break;
duke@0 234 }
duke@0 235
duke@0 236 case CONSTANT_Integer:
duke@0 237 case CONSTANT_Float:
duke@0 238 case CONSTANT_Long:
duke@0 239 case CONSTANT_Double:
duke@0 240 case CONSTANT_Utf8:
duke@0 241 CCerror(cb, "Improperly unresolved constant pool #%d", i);
duke@0 242 return FALSE;
duke@0 243
duke@0 244
duke@0 245 default:
duke@0 246 CCerror(cb, "Illegal constant pool type at #%d", i);
duke@0 247 return FALSE;
duke@0 248
duke@0 249
duke@0 250 }
duke@0 251 }
duke@0 252 for (i = 1; i < cp_count; i++) {
duke@0 253 switch(type = type_table[i]) {
duke@0 254 case CONSTANT_Class: {
duke@0 255 int index = cp[i].i;
duke@0 256 if (!is_legal_fieldname(cb, cp[index].cp, LegalClass))
duke@0 257 return FALSE;
duke@0 258 break;
duke@0 259 }
duke@0 260
duke@0 261 case CONSTANT_Fieldref:
duke@0 262 case CONSTANT_Methodref:
duke@0 263 case CONSTANT_InterfaceMethodref: {
duke@0 264 unsigned index = (unsigned)(cp[i].i);
duke@0 265 int name_type_index = index & 0xFFFF;
duke@0 266 int name_type_key = cp[name_type_index].i;
duke@0 267 int name_index = name_type_key >> 16;
duke@0 268 int signature_index = name_type_key & 0xFFFF;
duke@0 269 char *name = cp[name_index].cp;
duke@0 270 char *signature = cp[signature_index].cp;
duke@0 271
duke@0 272 if (type == CONSTANT_Fieldref) {
duke@0 273 if (! (is_legal_fieldname(cb, name, LegalField) &&
duke@0 274 is_legal_field_signature(cb, name, signature)))
duke@0 275 return FALSE;
duke@0 276 } else {
duke@0 277 if (! (is_legal_fieldname(cb, name, LegalMethod) &&
duke@0 278 is_legal_method_signature(cb, name, signature)))
duke@0 279 return FALSE;
duke@0 280 }
duke@0 281 break;
duke@0 282 }
duke@0 283 }
duke@0 284 }
duke@0 285 return TRUE;
duke@0 286 }
duke@0 287
duke@0 288
duke@0 289 /* Return true if the entire second argument consists of a legal fieldname
duke@0 290 * (or classname, if the third argument is LegalClass).
duke@0 291 */
duke@0 292
duke@0 293 static bool_t
duke@0 294 is_legal_fieldname(ClassClass *cb, char *name, int type)
duke@0 295 {
duke@0 296 bool_t result;
duke@0 297 if (name[0] == '<') {
duke@0 298 result = (type == LegalMethod) &&
duke@0 299 ((strcmp(name, "<init>") == 0) ||
duke@0 300 (strcmp(name, "<clinit>") == 0));
duke@0 301 } else {
duke@0 302 char *p;
duke@0 303 if (type == LegalClass && name[0] == SIGNATURE_ARRAY) {
duke@0 304 p = skip_over_field_signature(name, FALSE);
duke@0 305 } else {
duke@0 306 p = skip_over_fieldname(name, type == LegalClass);
duke@0 307 }
duke@0 308 result = (p != 0 && p[0] == '\0');
duke@0 309 }
duke@0 310 if (!result) {
duke@0 311 char *thing = (type == LegalField) ? "Field"
duke@0 312 : (type == LegalMethod) ? "Method" : "Class";
duke@0 313
duke@0 314 CCerror(cb, "Illegal %s name \"%s\"", thing, name);
duke@0 315 return FALSE;
duke@0 316 } else {
duke@0 317 return TRUE;
duke@0 318
duke@0 319 }
duke@0 320 }
duke@0 321
duke@0 322 /* Return true if the entire string consists of a legal field signature */
duke@0 323 static bool_t
duke@0 324 is_legal_field_signature(ClassClass *cb, char *fieldname, char *signature)
duke@0 325 {
duke@0 326 char *p = skip_over_field_signature(signature, FALSE);
duke@0 327 if (p != 0 && p[0] == '\0') {
duke@0 328 return TRUE;
duke@0 329 } else {
duke@0 330 CCerror(cb, "Field \"%s\" has illegal signature \"%s\"",
duke@0 331 fieldname, signature);
duke@0 332 return FALSE;
duke@0 333 }
duke@0 334 }
duke@0 335
duke@0 336
duke@0 337 static bool_t
duke@0 338 is_legal_method_signature(ClassClass *cb, char *methodname, char *signature)
duke@0 339 {
duke@0 340 char *p = signature;
duke@0 341 char *next_p;
duke@0 342 /* The first character must be a '(' */
duke@0 343 if (*p++ == SIGNATURE_FUNC) {
duke@0 344 /* Skip over however many legal field signatures there are */
duke@0 345 while ((next_p = skip_over_field_signature(p, FALSE)) != 0)
duke@0 346 p = next_p;
duke@0 347 /* The first non-signature thing better be a ')' */
duke@0 348 if (*p++ == SIGNATURE_ENDFUNC) {
duke@0 349 if (methodname[0] == '<') {
duke@0 350 /* All internal methods must return void */
duke@0 351 if ((p[0] == SIGNATURE_VOID) && (p[1] == '\0'))
duke@0 352 return TRUE;
duke@0 353 } else {
duke@0 354 /* Now, we better just have a return value. */
duke@0 355 next_p = skip_over_field_signature(p, TRUE);
duke@0 356 if (next_p && next_p[0] == '\0')
duke@0 357 return TRUE;
duke@0 358 }
duke@0 359 }
duke@0 360 }
duke@0 361 CCerror(cb, "Method \"%s\" has illegal signature \"%s\"",
duke@0 362 methodname, signature);
duke@0 363 return FALSE;
duke@0 364 }
duke@0 365
duke@0 366 $$Tables
duke@0 367
duke@0 368 /*
duke@0 369 * This code mirrors Character.isJavaIdentifierStart. It determines whether
duke@0 370 * the specified character is a legal start of a Java identifier as per JLS.
duke@0 371 *
duke@0 372 * The parameter ch is the character to be tested; return 1 if the
duke@0 373 * character is a letter, 0 otherwise.
duke@0 374 */
duke@0 375 #define isJavaIdentifierStart(ch) ($$Lookup(ch) & $$maskIsJavaIdentifierStart)
duke@0 376
duke@0 377 /*
duke@0 378 * This code mirrors Character.isJavaIdentifierPart. It determines whether
duke@0 379 * the specified character is a legal part of a Java identifier as per JLS.
duke@0 380 *
duke@0 381 * The parameter ch is the character to be tested; return 1 if the
duke@0 382 * character is a digit, 0 otherwise.
duke@0 383 */
duke@0 384 #define isJavaIdentifierPart(ch) ($$Lookup(ch) & $$maskIsJavaIdentifierPart)
duke@0 385
duke@0 386 /* Take pointer to a string. Skip over the longest part of the string that
duke@0 387 * could be taken as a fieldname. Allow '/' if slash_okay is TRUE.
duke@0 388 *
duke@0 389 * Return a pointer to just past the fieldname. Return NULL if no fieldname
duke@0 390 * at all was found, or in the case of slash_okay being true, we saw
duke@0 391 * consecutive slashes (meaning we were looking for a qualified path but
duke@0 392 * found something that was badly-formed).
duke@0 393 */
duke@0 394 static char *
duke@0 395 skip_over_fieldname(char *name, bool_t slash_okay)
duke@0 396 {
duke@0 397 bool_t first;
duke@0 398 char *p;
duke@0 399 unicode last_ch = 0;
duke@0 400 for (p = name, first = TRUE; ; first = FALSE) {
duke@0 401 char *old_p = p;
duke@0 402 unicode ch = next_utf2unicode(&p);
duke@0 403 if (isJavaIdentifierStart(ch) || (!first && isJavaIdentifierPart(ch))
duke@0 404 || (slash_okay && ch == '/' && !first)
duke@0 405 || ch == '_' || ch == '$') {
duke@0 406 if (ch == '/' && last_ch == '/') {
duke@0 407 return 0; /* Don't permit consecutive slashes */
duke@0 408 } else {
duke@0 409 last_ch = ch;
duke@0 410 }
duke@0 411 } else {
duke@0 412 return first ? 0 : old_p;
duke@0 413 }
duke@0 414 }
duke@0 415 }
duke@0 416
duke@0 417 /* Take pointer to a string. Skip over the longest part of the string that
duke@0 418 * could be taken as a field signature. Allow "void" if void_okay.
duke@0 419 *
duke@0 420 * Return a pointer to just past the signature. Return NULL if no legal
duke@0 421 * signature is found.
duke@0 422 */
duke@0 423
duke@0 424 static char *
duke@0 425 skip_over_field_signature(char *name, bool_t void_okay)
duke@0 426 {
duke@0 427 for (;;) {
duke@0 428 switch (name[0]) {
duke@0 429 case SIGNATURE_VOID:
duke@0 430 if (!void_okay) return 0;
duke@0 431 /* FALL THROUGH */
duke@0 432 case SIGNATURE_BOOLEAN:
duke@0 433 case SIGNATURE_BYTE:
duke@0 434 case SIGNATURE_CHAR:
duke@0 435 case SIGNATURE_SHORT:
duke@0 436 case SIGNATURE_INT:
duke@0 437 case SIGNATURE_FLOAT:
duke@0 438 case SIGNATURE_LONG:
duke@0 439 case SIGNATURE_DOUBLE:
duke@0 440 return name + 1;
duke@0 441
duke@0 442 case SIGNATURE_CLASS: {
duke@0 443 /* Skip over the classname, if one is there. */
duke@0 444 char *p = skip_over_fieldname(name + 1, TRUE);
duke@0 445 /* The next character better be a semicolon. */
duke@0 446 if (p && p[0] == ';')
duke@0 447 return p + 1;
duke@0 448 return 0;
duke@0 449 }
duke@0 450
duke@0 451 case SIGNATURE_ARRAY:
duke@0 452 /* The rest of what's there better be a legal signature. */
duke@0 453 name++;
duke@0 454 void_okay = FALSE;
duke@0 455 break;
duke@0 456
duke@0 457 default:
duke@0 458 return 0;
duke@0 459 }
duke@0 460 }
duke@0 461 }
duke@0 462
duke@0 463
duke@0 464 static void
duke@0 465 CCerror (ClassClass *cb, char *format, ...)
duke@0 466 {
duke@0 467 if (verbose) {
duke@0 468 va_list args;
duke@0 469 jio_fprintf(stderr, "VERIFIER CLASS ERROR %s:\n", cbName(cb));
duke@0 470 va_start(args, format);
duke@0 471 jio_vfprintf(stderr, format, args);
duke@0 472 va_end(args);
duke@0 473 jio_fprintf(stderr, "\n");
duke@0 474 }
duke@0 475 }
duke@0 476
duke@0 477 /* For use from outside the file. Determine if the specified name is legal
duke@0 478 * UTF name for a classname.
duke@0 479 *
duke@0 480 * Note that this routine expects the internal form of qualified classes:
duke@0 481 * the dots should have been replaced by slashes.
duke@0 482 */
duke@0 483 bool_t IsLegalClassname(char *name, bool_t allowArrayClass)
duke@0 484 {
duke@0 485 char *p;
duke@0 486 if (name[0] == SIGNATURE_ARRAY) {
duke@0 487 if (!allowArrayClass) {
duke@0 488 return FALSE;
duke@0 489 } else {
duke@0 490 /* Everything that's left better be a field signature */
duke@0 491 p = skip_over_field_signature(name, FALSE);
duke@0 492 }
duke@0 493 } else {
duke@0 494 /* skip over the fieldname. Slashes are okay */
duke@0 495 p = skip_over_fieldname(name, TRUE);
duke@0 496 }
duke@0 497 return (p != 0 && p[0] == '\0');
duke@0 498 }