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

📄 pvmjac.c

📁 一个开源的JAVA虚拟机
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <jpr/utf8.h>#include <aegisvm/pvm.h>#include "jac.h"//#define JAC_PVM_DEBUGintjac_pvm_init(void) {  return 0;}intjac_pvm_finish(void) {  return 0;}const void *jac_find_jac_attribute(const PREClassFile *classfile) {  const PREConstantPool *constant_pool;  const void *attr;  const void *the_attr = 0;  constant_pool = pre_classfile_constant_pool(classfile);  for (attr = pre_classfile_attributes(classfile);       attr != 0;       attr = pre_attribute_next(attr)) {    if (pre_attribute_type(attr) != PRE_ATTR_Generic)      continue;    ju2 attribute_name_index = pre_attribute_attribute_name_index(attr);    const char *attribute_name =      pre_constant_pool_utf8_bytes(constant_pool, attribute_name_index);    if (! j_utf8_eq(attribute_name, "JAC"))      continue;    if (the_attr != 0)      return 0;    the_attr = attr;  }  return the_attr;}static inlinebooljac_valid_type_annotation(char c) {  return c == 'R' || c == '.';}static inlinebooljac_valid_primitive_type_annotation(char c) {  return c == '.';}booljac_validate_field_annotation(const PREConstantPool *constant_pool,			      ju2 descriptor_index,			      ju2 annotation_index) {  /* Check if annotation_index refers to a valid utf8 cp entry */  if (!pre_cp_index_is_valid(constant_pool, annotation_index, J_CONSTANT_Utf8))    return false;  /* Fetch descriptor and annotation string */  const char *descriptor =    pre_constant_pool_utf8_bytes(constant_pool, descriptor_index);  const char *annotation =    pre_constant_pool_utf8_bytes(constant_pool, annotation_index);  /* Annotation should consist of one character only */  if (j_strlen(annotation) != 1)    return false;  /* Annotation should be consistent with descriptor */  switch (*descriptor) {  case J_ASCII_reference:  case J_ASCII_array:    return jac_valid_type_annotation(*annotation);  default:    return jac_valid_primitive_type_annotation(*annotation);  }}booljac_validate_method_annotation(const PREConstantPool *constant_pool,			       ju2 descriptor_index,			       ju2 annotation_index,			       bool known_to_be_static) {  /* Check if annotation_index refers to a valid utf8 cp entry */  if (!pre_cp_index_is_valid(constant_pool, annotation_index, J_CONSTANT_Utf8))    return false;  /* Fetch descriptor and annotation string */  const char *descriptor =    pre_constant_pool_utf8_bytes(constant_pool, descriptor_index);  const char *annotation =    pre_constant_pool_utf8_bytes(constant_pool, annotation_index);  /* Annotation for 'this' */  if (known_to_be_static) {    if (! jac_valid_primitive_type_annotation(*annotation))      return false;  } else {    if (! jac_valid_type_annotation(*annotation))      return false;  }  ++annotation;  /* Skip over left bracket */  if (*annotation != J_ASCII_lbracket)    return false;  ++annotation;  ++descriptor;  /* Annotations for argument list */  while (*descriptor != J_ASCII_rbracket) {    switch (*descriptor) {    case J_ASCII_boolean:    case J_ASCII_byte:    case J_ASCII_char:    case J_ASCII_short:    case J_ASCII_int:    case J_ASCII_float:      if (! jac_valid_primitive_type_annotation(*annotation))	return false;      ++annotation;      ++descriptor;      break;    case J_ASCII_long:    case J_ASCII_double:      if (! jac_valid_primitive_type_annotation(*annotation))	return false;      ++annotation;      if (! jac_valid_primitive_type_annotation(*annotation))	return false;      ++annotation;      ++descriptor;      break;    case J_ASCII_reference:      if (! jac_valid_type_annotation(*annotation))	return false;      ++annotation;      do {	++descriptor;      } while (*descriptor != J_ASCII_terminator);      ++descriptor;      break;    case J_ASCII_array:      if (! jac_valid_type_annotation(*annotation))	return false;      ++annotation;      do {	++descriptor;      } while (*descriptor == J_ASCII_array);      switch (*descriptor) {      case J_ASCII_boolean:      case J_ASCII_byte:      case J_ASCII_char:      case J_ASCII_short:      case J_ASCII_int:      case J_ASCII_float:      case J_ASCII_long:      case J_ASCII_double:	++descriptor;	break;      case J_ASCII_reference:	do {	  ++descriptor;	} while (*descriptor != J_ASCII_terminator);	++descriptor;	break;      default:	j_assert_not_reached();      }      break;    default:      j_assert_not_reached();    }  }  /* Skip over right bracket */  if (*annotation != J_ASCII_rbracket)    return false;  ++annotation;  ++descriptor;  /* Annotation for return type */  switch (*descriptor) {  case J_ASCII_reference:  case J_ASCII_array:    if (! jac_valid_type_annotation(*annotation))      return false;    break;  default:    if (! jac_valid_primitive_type_annotation(*annotation))      return false;    break;  }  ++annotation;  /* Annotation should terminate at this point */  if (*annotation != '\0')    return false;  /* Annotation is properly validated */  return true;}booljac_parse_constant_annotations(JArena *arena,			       const void **begin,			       const PREClassFile *classfile,			       ju2 constant_annotations_count,			       ju2 **result) {  /* Allocate memory for annotations */  ju2 constant_pool_count = pre_classfile_constant_pool_count(classfile);  ju2 *annotations =    j_arena_alloc_array(arena, constant_pool_count, sizeof(ju2));  if (annotations == 0)    return false;  /* Initialize annotation array to zero */  j_memset(annotations, 0, constant_pool_count * sizeof(ju2));  /* Parsing loop */  ju2 i, last;  const PREConstantPool *constant_pool =    pre_classfile_constant_pool(classfile);  for (i = 0; i < constant_annotations_count; i++) {    /* Read id and index */    ju2 id = j_parse_u2(begin);    ju2 index = j_parse_u2(begin);    /* Validate id */    if (i != 0) {      if (id <= last)	return false; /* constant id must be strictly increasing */    } else {      last = id;    }    if (! pre_cp_index_is_in_range(constant_pool, id))      return false;    /* Validate index */    const void *cp = pre_constant_pool_entry(constant_pool, id);        ju1 tag = pre_cp_tag(cp);    ju2 descriptor_index;    switch (tag) {    case J_CONSTANT_Fieldref:      descriptor_index =	pre_constant_pool_fieldref_descriptor_index(constant_pool, id);      if (! jac_validate_field_annotation(constant_pool, descriptor_index,					  index))	return false;      break;    case J_CONSTANT_Methodref:      descriptor_index =	pre_constant_pool_methodref_descriptor_index(constant_pool, id);      if (! jac_validate_method_annotation(constant_pool, descriptor_index,					   index, false))	return false;      break;    case J_CONSTANT_InterfaceMethodref:      descriptor_index =	pre_constant_pool_interface_methodref_descriptor_index(constant_pool,							       id);      if (! jac_validate_method_annotation(constant_pool, descriptor_index,					   index, false))	return false;      break;    default:      return false;    }    /* Install annotation */    annotations[id] = index;  }  /* Return result */  *result = annotations;  return true;}booljac_parse_field_annotations(JArena *arena,			    const void **begin,			    const PREClassFile *classfile,			    ju2 field_annotations_count,			    ju2 **result) {  /* Allocate memory for annotations */  ju2 fields_count = pre_classfile_fields_count(classfile);  ju2 *annotations = j_arena_alloc_array(arena, fields_count, sizeof(ju2));  if (annotations == 0)    return false;  /* Initialize annotation array to zero */  j_memset(annotations, 0, fields_count * sizeof(ju2));  /* Parsing loop */  ju2 i, last;  const PREConstantPool *constant_pool =    pre_classfile_constant_pool(classfile);  for (i = 0; i < field_annotations_count; i++) {    /* Read id and index */    ju2 id = j_parse_u2(begin);    ju2 index = j_parse_u2(begin);    /* Validate id */    if (i != 0) {      if (id <= last)	return false; /* field id must be strictly increasing */    } else {      last = id;    }    if (id >= fields_count)      return false;    /* Validate index */    ju2 descriptor_index = pre_classfile_field_descriptor_index(classfile, id);    if (! jac_validate_field_annotation(constant_pool, descriptor_index,					index))      return false;    /* Install annotation */    annotations[id] = index;  }  /* Return result */  *result = annotations;  return true;}booljac_parse_method_annotations(JArena *arena,			     const void **begin,			     const PREClassFile *classfile,			     ju2 method_annotations_count,			     ju2 **result) {  /* Allocate memory for annotations */  ju2 methods_count = pre_classfile_methods_count(classfile);  ju2 *annotations = j_arena_alloc_array(arena, methods_count, sizeof(ju2));  if (annotations == 0)    return false;  /* Initialize annotation array to zero */  j_memset(annotations, 0, methods_count * sizeof(ju2));  /* Parsing loop */  ju2 i, last;  const PREConstantPool *constant_pool =    pre_classfile_constant_pool(classfile);  for (i = 0; i < method_annotations_count; i++) {    /* Read id and index */    ju2 id = j_parse_u2(begin);    ju2 index = j_parse_u2(begin);    /* Validate id */    if (i != 0) {      if (id <= last) /* method id must be strictly increasing */	return false;    } else {      last = id;    }    if (id >= methods_count)      return false;    /* Validate index */    ju2 descriptor_index =      pre_classfile_method_descriptor_index(classfile, id);    bool known_to_be_static =      pre_method_is_static(pre_classfile_method(classfile, id));    if (! jac_validate_method_annotation(constant_pool, descriptor_index,					 index, known_to_be_static))      return false;    /* Install annotation */    annotations[id] = index;  }  /* Return result */  *result = annotations;  return true;}static inlineconst char *jac_get_constant_annotation(const struct jac_commitments *commitments,			    const PREConstantPool *constant_pool,			    ju2 cp_index) {  ju2 index = jac_get_constant_annotation_index(commitments, cp_index);  if (index != 0)    return pre_constant_pool_utf8_bytes(constant_pool, index);  else    return 0;}static inlineconst char *jac_get_field_annotation(const struct jac_commitments *commitments,			 const PREConstantPool *constant_pool,			 ju2 field_index) {  ju2 index = jac_get_method_annotation_index(commitments, field_index);  if (index != 0)    return pre_constant_pool_utf8_bytes(constant_pool, index);  else    return 0;}static inlineconst char *jac_get_method_annotation(const struct jac_commitments *commitments,			  const PREConstantPool *constant_pool,			  ju2 method_index) {  ju2 index = jac_get_method_annotation_index(commitments, method_index);  if (index != 0)    return pre_constant_pool_utf8_bytes(constant_pool, index);  else    return 0;}booljac_parse_jac_attribute(JArena *arena,			const PREClassFile *classfile,			const void *attr,			struct jac_commitments **result) {  const void *check_point = j_arena_check_point(arena);  ju4 attribute_length = pre_attribute_attribute_length(attr);  const void *begin = pre_attribute_generic_info(attr);  const void *end = begin + attribute_length;  /* Enough bytes left in input? */  if (end - begin < sizeof(ju2) * 4)    goto ErrorExit;  /* Read header */  ju2 class_annotation_index = j_parse_u2(&begin);  ju2 constant_annotations_count = j_parse_u2(&begin);  ju2 field_annotations_count = j_parse_u2(&begin);  ju2 method_annotations_count = j_parse_u2(&begin);  /* Validate class_annotation_index */  if (class_annotation_index != 0)    goto ErrorExit;  /* Enough bytes left in input? */  if (end - begin <      constant_annotations_count * (sizeof(ju2) + sizeof(ju2)) +      field_annotations_count * (sizeof(ju2) + sizeof(ju2)) +      method_annotations_count * (sizeof(ju2) + sizeof(ju2)))    goto ErrorExit;  /* Parse constant annotations */  ju2 *constant_annotations;  if (! jac_parse_constant_annotations(arena, &begin, classfile,				       constant_annotations_count,				       &constant_annotations))    goto ErrorExit;  /* Parse field annotations */  ju2 *field_annotations;  if (! jac_parse_field_annotations(arena, &begin, classfile,				    field_annotations_count,				    &field_annotations))    goto ErrorExit;  /* Parse method annotations */  ju2 *method_annotations;  if (! jac_parse_method_annotations(arena, &begin, classfile,				     method_annotations_count,				     &method_annotations))    goto ErrorExit;  j_assert(begin == end);  /* Refrain from allocating memory if no annotation is found */  if (constant_annotations == 0 &&      field_annotations == 0 &&      method_annotations == 0) {    *result = 0;    return true;  }  /* Allocate memory for commitment structure */  struct jac_commitments *commitments =    j_arena_alloc(arena, sizeof(struct jac_commitments));  if (commitments == 0)    goto ErrorExit;  /* Install annotations into commitment structure */  commitments->class_annotation = 0;  commitments->constant_annotations = constant_annotations;  commitments->field_annotations = field_annotations;  commitments->method_annotations = method_annotations;  /* Return result */  *result = commitments;  return true; ErrorExit:  j_arena_free(arena, check_point);  return false;}static inlinebooljac_meet(char *des, const char *src, bool *updated) {  if (jac_subtype(*src, *des))    return true;  if (*src == JAC_TYP_ReadOnly)    return false;  *des = *src;  *updated = true;  return true;}typedef struct JACState JACState;struct JACState {  ju2 max_locals;  ju2 max_stack;  char *locals;  char *stack;  char *top;};JACState *jac_allocate_state(JArena *arena,		   ju2 max_locals,		   ju2 max_stack) {  const void *check_point = j_arena_check_point(arena);  JACState *state = j_arena_alloc(arena, sizeof(JACState));  if (state == 0)    goto ErrorExit;  state->locals = j_arena_alloc(arena, max_locals);  if (state->locals == 0)    goto ErrorExit;  state->stack = j_arena_alloc(arena, max_stack);  if (state->stack == 0)    goto ErrorExit;  state->max_locals = max_locals;  state->max_stack = max_stack;  return state; ErrorExit:  j_arena_free(arena, check_point);  return 0;}voidjac_copy_state(JACState *des,	       const JACState *src) {  j_memcpy(des->locals, src->locals, src->max_locals);  j_memcpy(des->stack, src->stack, src->max_stack);  des->top = des->stack + (src->top - src->stack);}voidjac_initialize_first_state(const PREAnalysis *analysis,			   const struct jac_commitments *commitments,			   JACState *state) {  const PREClassFile *classfile = pre_analysis_classfile(analysis);  const PREConstantPool *constant_pool =    pre_classfile_constant_pool(classfile);  ju2 method_index = pre_analysis_method_index(analysis);  const PREMethod *method = pre_classfile_method(classfile, method_index);

⌨️ 快捷键说明

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