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

📄 pvmjac.c

📁 一个开源的JAVA虚拟机
💻 C
📖 第 1 页 / 共 4 页
字号:
  const void *attr = pre_method_code(method);  const char *annotation =    jac_get_method_annotation(commitments, constant_pool, method_index);  ju2 max_locals = pre_attribute_code_max_locals(attr);  ju2 i = 0;  if (annotation != 0) {    /* Type for this */    if (! pre_method_is_static(method)) {      state->locals[i] = *annotation;      ++i;    }    ++annotation;    /* Skip left bracket */    ++annotation;    /* Initialize arguments */    while (*annotation != J_ASCII_rbracket) {      state->locals[i] = *annotation;      ++annotation;      ++i;    }  } else {    const char *descriptor =      pre_classfile_method_descriptor(classfile, method_index);    /* Type for this */    if (! pre_method_is_static(method)) {      state->locals[i] = JAC_TYP_Writable;      ++i;    }    /* Skip left bracket */    ++descriptor;    /* Initialize arguments */    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:	state->locals[i] = JAC_TYP_Writable;	++i;	++descriptor;	break;      case J_ASCII_long:      case J_ASCII_double:	state->locals[i] = JAC_TYP_Writable;	++i;	state->locals[i] = JAC_TYP_Writable;	++i;	++descriptor;	break;      case J_ASCII_reference:	state->locals[i] = JAC_TYP_Writable;	++i;	do {	  ++descriptor;	} while (*descriptor != J_ASCII_terminator);	++descriptor;	break;      case J_ASCII_array:	state->locals[i] = JAC_TYP_Writable;	++i;	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();      }    }  }  /* The rest are uninitialized values */  while (i < max_locals) {    state->locals[i] = JAC_TYP_Writable;    ++i;  }  /* Stack is initially empty */  state->top = state->stack;}booljac_compute_state_meet(JArena *arena,		       JACState **des,		       const JACState *src,		       bool *updated) {  j_assert(arena != 0 && src != 0 && des != 0 && updated != 0);  if (*des == 0) {    /* Destination state is not initialized at all */    /* Create new state */    *des = jac_allocate_state(arena, src->max_locals, src->max_stack);    if (*des == 0)      return false;    /* Copy source state content to destination state */    jac_copy_state(*des, src);    /* Indicate that destination state is updated */    *updated = true;  } else {    /* Destination state has been initialized */    j_assert((*des)->max_locals == src->max_locals);    j_assert((*des)->max_stack == src->max_stack);    j_assert((*des)->top - (*des)->stack == src->top - src->stack);    /* Compute meet values for local variables */    char *p = (*des)->locals;    const char *q = src->locals;    const char *r = q + src->max_locals;    while (q != r) {      if (! jac_meet(p, q, updated))	return false;      ++p;      ++q;    }    /* Compute meet values for stack */    p = (*des)->stack;    q = src->stack;    r = src->top;    while (q != r) {      if (! jac_meet(p, q, updated))	return false;      ++p;      ++q;    }  }  /* Return successfully */  return true;}booljac_compute_routine_meet(JArena *arena,			 JACState **des,			 const JACState *jsr,			 const JACState *ret,			 const PRERoutine *routine,			 bool *updated) {  ju2 i;  if (*des == 0) {    /* Destination state has not been initialized yet */    /* Create destination state */    *des = jac_allocate_state(arena, jsr->max_locals, jsr->max_stack);    if (*des == 0)      return false;    /* Initialize destination state with content of the state       at the ret instruction */    jac_copy_state(*des, ret);    /* Overwrite the non-parameter local variables with content of       the state at the jsr instruction */    for (i = 0; i < ret->max_locals; i++)      if (! pre_routine_locals_is_marked(routine, i))	(*des)->locals[i] = jsr->locals[i];    /* Indicate that the destination state has been changed */    *updated = true;  } else {    /* Compute content of local variables */    for (i = 0; i < ret->max_locals; i++) {      char *p = (*des)->locals + i;      const char *q;      /* Select where the local variable values come from */      if (pre_routine_locals_is_marked(routine, i))	/* Ret state if local variable is a subroutine parameter */	q = ret->locals + i;      else	/* Jsr state if local variable is not a subroutine parameter */	q = jsr->locals + i;      /* Compute meet value */      if (! jac_meet(p, q, updated))	return false;    }    /* Compute stack content by taking the meet of original values       with those from the jsr state */    char *p = (*des)->stack;    const char *q = jsr->stack;    const char *r = jsr->top;    while (q != r) {      if (! jac_meet(p, q, updated))	return false;      ++p;      ++q;    }  }  return true;}//	pre_merge_all_handler_states(context, analysis, &flag, next, S);booljac_compute_handler_meet(JArena *arena,			 const void *attr,			 JACState **states,			 ju2 addr,			 bool *updated) {  const JACState *src = states[addr];  ju2 handlers_count = pre_attribute_code_exception_table_length(attr);  ju2 i;  for (i = 0; i < handlers_count; i++) {    const PREHandler *H =      pre_attribute_code_exception_table_entry(attr, i);    ju2 start_pc = pre_handler_start_pc(H);    ju2 end_pc = pre_handler_end_pc(H);    ju2 handler_pc = pre_handler_handler_pc(H);    if (addr >= start_pc && addr < end_pc) {      JACState *des = states[handler_pc];      if (des == 0) {	/* Destination state has not been initialized yet */	/* Create destination state */	des = states[handler_pc] =	  jac_allocate_state(arena, src->max_locals, src->max_stack);	if (des == 0)	  return false;	/* Initialize destination locals */	j_memcpy(des->locals, src->locals, src->max_locals);	/* Destination stack contains a writable */	des->stack[0] = JAC_TYP_Writable;	des->top = des->stack + 1;      } else {	/* Destination already there */	/* Check destination locals */	ju2 j;	for (j = 0; j < src->max_locals; j++) {	  if (! jac_meet(des->locals + j, src->locals + j, updated))	    return false;	}	/* Check destination stack */	if (des->stack[0] != JAC_TYP_Writable)	  return false;      }    }  }  return true;}static inlinevoidjac_microcode_stack_push_type(JACState *S, char type) {  *(S->top) = type;  S->top++;}static inlinecharjac_microcode_stack_pop_type(JACState *S) {  S->top--;  return *(S->top);}static inlinevoidjac_microcode_stack_pop(JACState *S, unsigned delta) {  S->top -= delta;}static inlinevoidjac_microcode_stack_empty(JACState *S) {  S->top = S->stack;}static inlinevoidjac_microcode_stack_write(JACState *S, int offset, char type) {  S->top[offset] = type;}static inlinecharjac_microcode_stack_read(JACState *S, int offset) {  return S->top[offset];}static inlinevoidjac_microcode_load(JACState *S, ju2 index) {  *(S->top) = S->locals[index];  S->top++;}static inlinevoidjac_microcode_store(JACState *S, ju2 index) {  S->top--;  S->locals[index] = *(S->top);}voidjac_print_state(FILE *file,		const JACState *state) {  ju2 i, depth;  fprintf(file, "locals = \"");  for (i = 0; i < state->max_locals; i++)    fprintf(file, "%c", state->locals[i]);  fprintf(file, "\"\nstack = \"");  depth = state->top - state->stack;  for (i = 0; i < depth; i++)    fprintf(file, "%c", state->stack[i]);  fprintf(file, "\"\n");}booljac_run_flow_analysis(JArena *arena,		      const PREAnalysis *analysis,		      const struct jac_commitments *commitments,		      JACState **states) {  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);  const void *attr = pre_method_code(method);  ju4 code_length = pre_attribute_code_length(attr);  /* Cache return type annotation */  const char *annotation =    jac_get_method_annotation(commitments, constant_pool, method_index);  char return_type;  if (annotation != 0) {    do /* look for right bracket */      ++annotation;    while (*annotation != J_ASCII_rbracket);    return_type = annotation[1]; /* skip right bracket */  } else {    return_type = JAC_TYP_Writable;  }  /* Construct local state struct */  ju2 max_locals = pre_attribute_code_max_locals(attr);  ju2 max_stack = pre_attribute_code_max_stack(attr);  char locals[max_locals];  char stack[max_stack];  JACState state = {    max_locals,    max_stack,    locals,    stack,    stack  };  register JACState *S = &state;  /* Loop until no change */  bool flag = true;  while (flag) {    ju4 j;    const void *instr;    flag = false;    for (j = 0; j < code_length; j += pre_instr_len(instr)) {      instr = pre_attribute_code_code(attr, j);      if (states[j] == 0)	continue;      jac_copy_state(S, states[j]);      ju2 index;      ju1 opcode = pre_instr_opcode(instr);#ifdef JAC_PVM_DEBUG      fprintf(stderr, "========\n");      fprintf(stderr, "%08x: %s\n", j, j_opcode_mnemonic(opcode));      fprintf(stderr, "Before:\n");      jac_print_state(stderr, states[j]);#endif      /*       * Compute state change       */      switch (opcode) {	/*	  no-op	*/      case J_OPC_nop:      case J_OPC_goto:      case J_OPC_goto_w:      case J_OPC_ineg:      case J_OPC_lneg:      case J_OPC_fneg:      case J_OPC_dneg:      case J_OPC_i2b:      case J_OPC_i2c:      case J_OPC_i2s:      case J_OPC_i2f:      case J_OPC_f2i:      case J_OPC_d2l:      case J_OPC_l2d:      case J_OPC_iinc:      case J_OPC_checkcast:      case J_OPC_anewarray:      case J_OPC_ret:	break;	/*	  push one writable	*/      case J_OPC_aconst_null:      case J_OPC_iconst_m1:      case J_OPC_iconst_0:      case J_OPC_iconst_1:      case J_OPC_iconst_2:      case J_OPC_iconst_3:      case J_OPC_iconst_4:      case J_OPC_iconst_5:      case J_OPC_bipush:      case J_OPC_sipush:      case J_OPC_fconst_0:      case J_OPC_fconst_1:      case J_OPC_fconst_2:      case J_OPC_ldc:      case J_OPC_ldc_w:      case J_OPC_new:      case J_OPC_newarray:      case J_OPC_i2l:      case J_OPC_i2d:      case J_OPC_f2l:      case J_OPC_f2d:      case J_OPC_iload:      case J_OPC_iload_0:      case J_OPC_iload_1:      case J_OPC_iload_2:      case J_OPC_iload_3:      case J_OPC_fload:      case J_OPC_fload_0:      case J_OPC_fload_1:      case J_OPC_fload_2:      case J_OPC_fload_3:      case J_OPC_jsr:      case J_OPC_jsr_w:	jac_microcode_stack_push_type(S, JAC_TYP_Writable);	break;	/*	  push two writables	*/      case J_OPC_lconst_0:      case J_OPC_lconst_1:      case J_OPC_dconst_0:      case J_OPC_dconst_1:      case J_OPC_ldc2_w:      case J_OPC_lload:      case J_OPC_lload_0:      case J_OPC_lload_1:      case J_OPC_lload_2:      case J_OPC_lload_3:      case J_OPC_dload:      case J_OPC_dload_0:      case J_OPC_dload_1:      case J_OPC_dload_2:      case J_OPC_dload_3:	jac_microcode_stack_push_type(S, JAC_TYP_Writable);	jac_microcode_stack_push_type(S, JAC_TYP_Writable);	break;	/*	  pop one and dispose	*/      case J_OPC_pop:      case J_OPC_iadd:      case J_OPC_isub:      case J_OPC_imul:      case J_OPC_idiv:      case J_OPC_irem:      case J_OPC_ishl:      case J_OPC_ishr:      case J_OPC_iushr:      case J_OPC_iand:      case J_OPC_ior:      case J_OPC_ixor:      case J_OPC_fadd:      case J_OPC_fsub:      case J_OPC_fmul:      case J_OPC_fdiv:      case J_OPC_frem:      case J_OPC_l2i:      case J_OPC_l2f:      case J_OPC_d2i:      case J_OPC_d2f:      case J_OPC_lshl:      case J_OPC_lshr:      case J_OPC_lushr:      case J_OPC_monitorenter:      case J_OPC_monitorexit:      case J_OPC_ifeq:      case J_OPC_ifne:      case J_OPC_iflt:      case J_OPC_ifge:      case J_OPC_ifgt:      case J_OPC_ifle:      case J_OPC_tableswitch:      case J_OPC_lookupswitch:      case J_OPC_fcmpl:      case J_OPC_fcmpg:      case J_OPC_ifnull:      case J_OPC_ifnonnull:      case J_OPC_aaload:	jac_microcode_stack_pop(S, 1);	break;	/*	  pop two and dispose	*/      case J_OPC_pop2:      case J_OPC_ladd:      case J_OPC_lsub:      case J_OPC_lmul:      case J_OPC_ldiv:      case J_OPC_lrem:      case J_OPC_land:      case J_OPC_lor:      case J_OPC_lxor:      case J_OPC_dadd:      case J_OPC_dsub:      case J_OPC_dmul:      case J_OPC_ddiv:      case J_OPC_drem:      case J_OPC_if_icmpeq:      case J_OPC_if_icmpne:      case J_OPC_if_icmplt:      case J_OPC_if_icmpge:      case J_OPC_if_icmpgt:      case J_OPC_if_icmple:

⌨️ 快捷键说明

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