⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jannotate.c

📁 一个开源的JAVA虚拟机
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <jpr/type.h>#include <jpr/log.h>#include <jpr/system.h>#include <jpr/io.h>#include <jpr/arena.h>#include <prelude/parse.h>#include <prelude/verify.h>#include <prelude/pretty_print.h>#include "parser.tab.h"#include "globals.h"//#define JAN_DEBUGconst char *attribute_name = 0;const char *class_annotation = 0;ju2 constants_count = 0;const char **constant_annotations = 0;ju2 fields_count = 0;const char **field_annotations = 0;ju2 methods_count = 0;const char **method_annotations = 0;voiddefine_attribute_name(const char *name) {  if (attribute_name != 0) {    free((void*) attribute_name);  }  attribute_name = name;}voiddefine_class_annotation(const char *annotation) {  class_annotation = annotation;}voiddefine_constant_annotation(ju2 index, const char *annotation) {  if (index < constants_count) {    if (constant_annotations[index] != 0)      free((void *) constant_annotations[index]);    constant_annotations[index] = annotation;  }}voiddefine_field_annotation(ju2 index, const char *annotation) {  if (index < fields_count) {    if (field_annotations[index] != 0)      free((void *) field_annotations[index]);    field_annotations[index] = annotation;  }}voiddefine_method_annotation(ju2 index, const char *annotation) {  if (index < methods_count) {    if (method_annotations[index] != 0)      free((void *) method_annotations[index]);    method_annotations[index] = annotation;  }}void init_constant_annotations(ju2 count) {  constants_count = count;  constant_annotations = calloc(count, sizeof(const char *));}void init_field_annotations(ju2 count) {  fields_count = count;  field_annotations = calloc(count, sizeof(const char *));}void init_method_annotations(ju2 count) {  methods_count = count;  method_annotations = calloc(count, sizeof(const char *));}boolcheck_constant_annotations(const PREClassFile *classfile) {  const PREConstantPool *constant_pool =     pre_classfile_constant_pool(classfile);  ju2 i;  if (constant_annotations[0] != 0)    return false;  for (i = 1; i < constants_count; i++) {    const void *cp = pre_classfile_constant_pool_entry(classfile, i);    if (cp == 0) {      if (constant_annotations[i] != 0)	return false;    } else {      ju1 tag = pre_cp_tag(cp);      if (tag == J_CONSTANT_NameAndType ||	  tag == J_CONSTANT_Utf8) {	if (constant_annotations[i] != 0)	  return false;      }    }  }  return true;}voidyyerror(char *s) {  fprintf(stderr, "%s\n", s);}void *yy_create_buffer(void *file, size_t size);struct id_index_map_t {  ju2 id;  ju2 index;};intmain(int argc,     const char * const * argv) {  int result;  FILE *spec_file, *outfile;  JFile infile;  void *yy_buffer_state;  int errno;  if (argc != 3) {    fprintf(stderr, "usage: %s specfile infile\n", argv[0]);    exit(1);  }  spec_file = fopen(argv[1], "r");  if (spec_file == NULL) {    fprintf(stderr, "%s: unable to open %s\n", argv[0], argv[1]);    exit(1);  }  if (j_load_file(argv[2], &infile) < 0) {    fprintf(stderr, "%s: unable to open %s\n", argv[0], argv[2]);    exit(1);  }  JArena *arena = j_arena_new();  if (arena == 0) {    fprintf(stderr, "%s: memory allocation failure\n", argv[0]);    exit(1);  }  PREClassFile *classfile = pre_parse_classfile(arena, j_file_data(&infile),						j_file_size(&infile), &errno);  if (classfile == 0) {    fprintf(stderr, "%s: unable to parse %s: %d\n", argv[0], argv[2], errno);    exit(1);  }  if (pre_verify_classfile(classfile) < 0) {    fprintf(stderr, "%s: unable to verify %s\n", argv[0], argv[2]);    exit(1);  }  yy_buffer_state = yy_create_buffer(spec_file, 16384);  yy_switch_to_buffer(yy_buffer_state);  init_constant_annotations(pre_classfile_constant_pool_count(classfile));  init_field_annotations(pre_classfile_fields_count(classfile));  init_method_annotations(pre_classfile_methods_count(classfile));  if ((result = yyparse()) != 0)    return result;  yy_delete_buffer(yy_buffer_state);#ifdef JAN_DEBUG  fprintf(stderr, "attribute \"%s\"\n", attribute_name);    if (class_annotation != 0)    fprintf(stderr, "class \"%s\"\n", class_annotation);  {    ju2 i;    for (i = 0; i < pre_classfile_constant_pool_count(classfile); i++) {      if (constant_annotations[i] != 0)	fprintf(stderr, "constant [%i] \"%s\"\n", i, constant_annotations[i]);    }  }  {    ju2 i;    for (i = 0; i < pre_classfile_fields_count(classfile); i++) {      if (field_annotations[i] != 0)	fprintf(stderr, "field [%i] \"%s\"\n", i, field_annotations[i]);    }  }  {    ju2 i;    for (i = 0; i < pre_classfile_methods_count(classfile); i++) {      if (method_annotations[i] != 0)	fprintf(stderr, "method [%i] \"%s\"\n", i, method_annotations[i]);    }  }#endif  /* Check constant annotations */  if (! check_constant_annotations(classfile)) {    fprintf(stderr, "%s: invalid constant annotation(s)\n", argv[0]);    exit(1);  }  /* Create cp entry for attribute name */  PREConstantPool *constant_pool = pre_classfile_constant_pool(classfile);  ju2 attribute_name_index =    pre_constant_pool_define_utf8(arena, constant_pool, attribute_name);  if (attribute_name_index == 0) {    fprintf(stderr, "%s: unable to create cp entry for attribute name: %s\n",	    argv[0], attribute_name);    exit(1);  }  /* Create cp entry for class annotation */  ju2 class_annotation_index;  if (class_annotation == 0) {    class_annotation_index = 0;  } else {    class_annotation_index =      pre_constant_pool_define_utf8(arena, constant_pool, class_annotation);    if (class_annotation_index == 0) {      fprintf(stderr, "%s: unable to create cp entry class annotation\n",	      argv[0]);      exit(1);    }  }  /* Create mapping from constant id to index of cp entry holding      corresponding annotation */  ju2 constant_annotations_count = 0;  ju2 i;  struct id_index_map_t con_map[constants_count];  for (i = 0; i < constants_count; i++) {    if (constant_annotations[i] != 0) {      ju2 index = pre_constant_pool_define_utf8(arena, constant_pool,						constant_annotations[i]);      if (index == 0) {	fprintf(stderr, "%s: unable to create cp entry for annotation "		"of field %d: %s\n", argv[0], i, constant_annotations[i]);	exit(1);      }      con_map[constant_annotations_count].id = i;      con_map[constant_annotations_count].index = index;      ++constant_annotations_count;    }  }  /* Create mapping from field id to index of cp entry holding      corresponding annotation */  ju2 field_annotations_count = 0;  struct id_index_map_t fld_map[fields_count];  for (i = 0; i < fields_count; i++) {    if (field_annotations[i] != 0) {      ju2 index = pre_constant_pool_define_utf8(arena, constant_pool,						field_annotations[i]);      if (index == 0) {	fprintf(stderr, "%s: unable to create cp entry for annotation "		"of field %d: %s\n", argv[0], i, field_annotations[i]);	exit(1);      }      fld_map[field_annotations_count].id = i;      fld_map[field_annotations_count].index = index;      ++field_annotations_count;    }  }  /* Create mapping from method id to index of cp entry holding      corresponding annotation */  ju2 method_annotations_count = 0;  struct id_index_map_t mth_map[methods_count];  for (i = 0; i < methods_count; i++) {    if (method_annotations[i] != 0) {      ju2 index = pre_constant_pool_define_utf8(arena, constant_pool,						method_annotations[i]);      if (index == 0) {	fprintf(stderr, "%s: unable to create cp entry for annotation "		"of method %d: %s\n", argv[0], i, method_annotations[i]);	exit(1);      }      mth_map[method_annotations_count].id = i;      mth_map[method_annotations_count].index = index;      ++method_annotations_count;    }  }  /* Estimate attribute length */  ju4 attribute_length =    sizeof(ju2) + /* class_annotation_index */    sizeof(ju2) + /* constant_annotations_count */    sizeof(ju2) + /* field_annotations_count */    sizeof(ju2) + /* method_annotations_count */    constant_annotations_count * (sizeof(ju2) + sizeof(ju2)) +    field_annotations_count * (sizeof(ju2) + sizeof(ju2)) +    method_annotations_count * (sizeof(ju2) + sizeof(ju2));#ifdef JAN_DEBUG  fprintf(stderr, "attribute_name_index = %d \"%s\"\n",	  attribute_name_index,	  pre_constant_pool_utf8_bytes(constant_pool, attribute_name_index));  fprintf(stderr, "attribute_length = %d\n", attribute_length);  if (class_annotation_index != 0) {    fprintf(stderr, "class_annotation_index = %d \"%s\"\n",	    class_annotation_index,	    pre_constant_pool_utf8_bytes(constant_pool,					 class_annotation_index));  } else {    fprintf(stderr, "class_annotation_index = 0\n");  }  fprintf(stderr, "Constant Mapping (x%d):\n", constant_annotations_count);  for (i = 0; i < constant_annotations_count; i++)    fprintf(stderr, "<%d, %d \"%s\">\n",	    con_map[i].id, con_map[i].index,	    pre_constant_pool_utf8_bytes(constant_pool, con_map[i].index));  fprintf(stderr, "Field Mapping (x%d):\n", field_annotations_count);  for (i = 0; i < field_annotations_count; i++)    fprintf(stderr, "<%d, %d \"%s\">\n",	    fld_map[i].id, fld_map[i].index,	    pre_constant_pool_utf8_bytes(constant_pool, fld_map[i].index));  fprintf(stderr, "Method Mapping (x%d)\n", method_annotations_count);  for (i = 0; i < method_annotations_count; i++)    fprintf(stderr, "<%d, %d \"%s\">\n",	    mth_map[i].id, mth_map[i].index,	    pre_constant_pool_utf8_bytes(constant_pool, mth_map[i].index));#endif  /* Create info for generic attribute */  ju1 *info = j_arena_alloc(arena, attribute_length);  if (info == 0) {    fprintf(stderr, "%s: unable to create info for attribute\n", argv[0]);    exit(1);  }  ju1 *p = info;  j_encode_u2(class_annotation_index, &p);  j_encode_u2(constant_annotations_count, &p);  j_encode_u2(field_annotations_count, &p);  j_encode_u2(method_annotations_count, &p);  for (i = 0; i < constant_annotations_count; i++) {    j_encode_u2(con_map[i].id, &p);    j_encode_u2(con_map[i].index, &p);  }  for (i = 0; i < field_annotations_count; i++) {    j_encode_u2(fld_map[i].id, &p);    j_encode_u2(fld_map[i].index, &p);  }  for (i = 0; i < method_annotations_count; i++) {    j_encode_u2(mth_map[i].id, &p);    j_encode_u2(mth_map[i].index, &p);  }#ifdef JAN_DEBUG  fprintf(stderr, "info = ");  ju4 j;  for (j = 0; j < attribute_length; j++)    fprintf(stderr, "%02x ", info[j]);  fprintf(stderr, "\n");#endif  /* Append attribute */  void *attr = pre_make_attribute_generic(arena, attribute_name_index,					  attribute_length, info);  if (attr == 0) {    fprintf(stderr, "%s: unable to create attribute\n", argv[0]);    exit(1);  }  pre_classfile_append_attribute(classfile, attr);  /* Output modified classfile */  size_t length = pre_classfile_length(classfile);  ju1 buf[length];  ju1 *q = buf;  pre_gencode_classfile(&q, classfile);  const char *r = buf;  const char *s = buf + length;  for (; r != s; ++r)    putchar(*r);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -