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

📄 verify.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
	      /* FIXME: If we exit a subroutine via a throw, we might		 have returned to an earlier caller.  Obviously a		 "ret" can only return one level, but a throw may		 return many levels.*/	      current_subr = caller;	      if (RETURN_MAP_ADJUSTED (ret_map))		{		  /* Since we are done with this subroutine , set up		     the (so far known) return address as pending -		     with the merged type state. */		  for ( ; tmp != NULL_TREE;  tmp = TREE_CHAIN (tmp))		    {		      tree return_label = TREE_VALUE (tmp);		      tree return_state = LABEL_TYPE_STATE (return_label);		      if (return_state == NULL_TREE)			{			  /* This means means we had not verified the			     subroutine earlier, so this is the first jsr to			     call it.  In this case, the type_map of the return			     address is just the current type_map - and that			     is handled by the following PUSH_PENDING. */			}		      else			{			  /* In this case we have to do a merge.  But first			     restore the type_map for unused slots to those			     that were in effect at the jsr. */			  for (index = size;  --index >= 0; )			    {			      type_map[index] = TREE_VEC_ELT (ret_map, index);			      if (type_map[index] == TYPE_UNUSED)				type_map[index]				  = TREE_VEC_ELT (return_state, index);			    }			}		      PUSH_PENDING (return_label);		    }		}	    }	}      if (PC == INVALID_PC)	{	  label = pending_blocks;	  if (label == NULL_TREE)	    break;  /* We're done! */	  pending_blocks = LABEL_PENDING_CHAIN (label);	  LABEL_CHANGED (label) = 0;	  if (LABEL_IN_SUBR (label))	    current_subr = LABEL_SUBR_START (label);	  else	    current_subr = NULL_TREE;	  /* Restore type_map and stack_pointer from	     LABEL_TYPE_STATE (label), and continue	     compiling from there. */	  load_type_state (label);	  PC = LABEL_PC (label);	}      else if (PC >= length)	VERIFICATION_ERROR ("falling through end of method");      /* fprintf (stderr, "** %d\n", PC); */      oldpc = PC;      if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)	VERIFICATION_ERROR ("PC not at instruction start");      instruction_bits[PC] |= BCODE_VERIFIED;      eh_ranges = find_handler (oldpc);      op_code = byte_ops[PC++];      switch (op_code)	{	  int is_static, is_putting;	case OPCODE_nop:	  break;	case OPCODE_iconst_m1:	case OPCODE_iconst_0:	case OPCODE_iconst_1:	case OPCODE_iconst_2:	case OPCODE_iconst_3:	case OPCODE_iconst_4:	case OPCODE_iconst_5:	  i = op_code - OPCODE_iconst_0;	  goto push_int;	push_int:	  if (byte_ops[PC] == OPCODE_newarray	      || byte_ops[PC] == OPCODE_newarray)	    int_value = i;	  push_type (int_type_node);  break;	case OPCODE_lconst_0:	case OPCODE_lconst_1:	  push_type (long_type_node);  break;	case OPCODE_fconst_0:	case OPCODE_fconst_1:	case OPCODE_fconst_2:	  push_type (float_type_node);  break;	case OPCODE_dconst_0:	case OPCODE_dconst_1:	  push_type (double_type_node);  break;	case OPCODE_bipush:	  i = IMMEDIATE_s1;	  goto push_int;	case OPCODE_sipush:	  i = IMMEDIATE_s2;	  goto push_int;	case OPCODE_iload:  type = int_type_node;  goto general_load;	case OPCODE_lload:  type = long_type_node;  goto general_load;	case OPCODE_fload:  type = float_type_node;  goto general_load;	case OPCODE_dload:  type = double_type_node;  goto general_load;	case OPCODE_aload:  type = ptr_type_node;  goto general_load;	general_load:	index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;	wide = 0;	goto load;	case OPCODE_iload_0:  type = int_type_node;  index = 0; goto load;	case OPCODE_iload_1:  type = int_type_node;  index = 1; goto load;	case OPCODE_iload_2:  type = int_type_node;  index = 2; goto load;	case OPCODE_iload_3:  type = int_type_node;  index = 3; goto load;	case OPCODE_lload_0:  type = long_type_node; index = 0; goto load;	case OPCODE_lload_1:  type = long_type_node; index = 1; goto load;	case OPCODE_lload_2:  type = long_type_node; index = 2; goto load;	case OPCODE_lload_3:  type = long_type_node; index = 3; goto load;	case OPCODE_fload_0:  type = float_type_node; index = 0; goto load;	case OPCODE_fload_1:  type = float_type_node; index = 1; goto load;	case OPCODE_fload_2:  type = float_type_node; index = 2; goto load;	case OPCODE_fload_3:  type = float_type_node; index = 3; goto load;	case OPCODE_dload_0: type = double_type_node; index = 0; goto load;	case OPCODE_dload_1: type = double_type_node; index = 1; goto load;	case OPCODE_dload_2: type = double_type_node; index = 2; goto load;	case OPCODE_dload_3: type = double_type_node; index = 3; goto load;	case OPCODE_aload_0:  type = ptr_type_node;  index = 0;  goto load;	case OPCODE_aload_1:  type = ptr_type_node;  index = 1;  goto load;	case OPCODE_aload_2:  type = ptr_type_node;  index = 2;  goto load;	case OPCODE_aload_3:  type = ptr_type_node;  index = 3;  goto load;	load:	if (index < 0	    || (index + TYPE_IS_WIDE (type)		>= DECL_MAX_LOCALS (current_function_decl)))	  VERIFICATION_ERROR ("invalid local variable index in load");	tmp = type_map[index];	if (tmp == TYPE_UNKNOWN || tmp == TYPE_SECOND	    || (TYPE_IS_WIDE (type)		&& type_map[index+1] != void_type_node)	    || (type == ptr_type_node		? TREE_CODE (tmp) != POINTER_TYPE		: type == int_type_node		? (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)		: type != tmp))	  VERIFICATION_ERROR("invalid local variable type in load");	push_type (tmp);	goto note_used;	case OPCODE_istore:  type = int_type_node;  goto general_store;	case OPCODE_lstore:  type = long_type_node;  goto general_store;	case OPCODE_fstore:  type = float_type_node;  goto general_store;	case OPCODE_dstore:  type = double_type_node;  goto general_store;	case OPCODE_astore:  type = ptr_type_node;  goto general_store;	general_store:	index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;	wide = 0;	goto store;	case OPCODE_istore_0:  type = int_type_node; index = 0; goto store;	case OPCODE_istore_1:  type = int_type_node; index = 1; goto store;	case OPCODE_istore_2:  type = int_type_node; index = 2; goto store;	case OPCODE_istore_3:  type = int_type_node; index = 3; goto store;	case OPCODE_lstore_0:  type = long_type_node; index=0; goto store;	case OPCODE_lstore_1:  type = long_type_node; index=1; goto store;	case OPCODE_lstore_2:  type = long_type_node; index=2; goto store;	case OPCODE_lstore_3:  type = long_type_node; index=3; goto store;	case OPCODE_fstore_0:  type=float_type_node; index=0; goto store;	case OPCODE_fstore_1:  type=float_type_node; index=1; goto store;	case OPCODE_fstore_2:  type=float_type_node; index=2; goto store;	case OPCODE_fstore_3:  type=float_type_node; index=3; goto store;	case OPCODE_dstore_0:  type=double_type_node; index=0; goto store;	case OPCODE_dstore_1:  type=double_type_node; index=1; goto store;	case OPCODE_dstore_2:  type=double_type_node; index=2; goto store;	case OPCODE_dstore_3:  type=double_type_node; index=3; goto store;	case OPCODE_astore_0:  type = ptr_type_node; index = 0; goto store;	case OPCODE_astore_1:  type = ptr_type_node; index = 1; goto store;	case OPCODE_astore_2:  type = ptr_type_node; index = 2; goto store;	case OPCODE_astore_3:  type = ptr_type_node; index = 3; goto store;	store:	if (index < 0	    || (index + TYPE_IS_WIDE (type)		>= DECL_MAX_LOCALS (current_function_decl)))	  {	    VERIFICATION_ERROR ("invalid local variable index in store");	    return 0;	  }	type = pop_type (type);	type_map[index] = type;	/* If local variable changed, we need to reconsider eh handlers. */	prev_eh_ranges = NULL_EH_RANGE;	/* Allocate decl and rtx for this variable now, so if we're not	   optmizing, we get a temporary that survives the whole method. */	find_local_variable (index, type, oldpc);        if (TYPE_IS_WIDE (type))          type_map[index+1] = TYPE_SECOND;	/* ... fall through to note_used ... */	note_used:	  /* For store or load, note that local variable INDEX is used.	     This is needed to verify try-finally sub-routines. */	  if (current_subr)	    {	      tree vec = LABEL_RETURN_TYPE_STATE (current_subr);	      tree subr_vec = LABEL_TYPE_STATE (current_subr);	      int len = 1 + TYPE_IS_WIDE (type);	      while (--len >= 0)		{		  if (TREE_VEC_ELT (vec, index) == TYPE_UNUSED)		    TREE_VEC_ELT (vec, index) = TREE_VEC_ELT (subr_vec, index);		}	    }	break;	case OPCODE_iadd:	case OPCODE_iand:	case OPCODE_idiv:	case OPCODE_imul:	case OPCODE_ior:	case OPCODE_irem:	case OPCODE_ishl:	case OPCODE_ishr:	case OPCODE_isub:	case OPCODE_iushr:	case OPCODE_ixor:	  type = int_type_node;  goto binop;	case OPCODE_ineg:	case OPCODE_i2c:	case OPCODE_i2b:	case OPCODE_i2s:	  type = int_type_node;  goto unop;	case OPCODE_ladd:	case OPCODE_land:	case OPCODE_ldiv:	case OPCODE_lsub:	case OPCODE_lmul:	case OPCODE_lrem:	case OPCODE_lor:	case OPCODE_lxor:	  type = long_type_node;  goto binop;	case OPCODE_lneg:	  type = long_type_node;  goto unop;	case OPCODE_fadd:	case OPCODE_fsub:	case OPCODE_fmul:	case OPCODE_fdiv:	case OPCODE_frem:	  type = float_type_node;  goto binop;	case OPCODE_fneg:	  type = float_type_node;  goto unop;	case OPCODE_dadd:	case OPCODE_dsub:	case OPCODE_dmul:	case OPCODE_ddiv:	case OPCODE_drem:	  type = double_type_node;  goto binop;	case OPCODE_dneg:	  type = double_type_node;  goto unop;	unop:	  pop_type (type);	  push_type (type);	  break;	binop:	  pop_type (type);	  pop_type (type);	  push_type (type);	  break;	case OPCODE_lshl:	case OPCODE_lshr:	case OPCODE_lushr:	  pop_type (int_type_node);	  pop_type (long_type_node);	  push_type (long_type_node);	  break;	case OPCODE_iinc:	  index = wide ? IMMEDIATE_u2 : IMMEDIATE_u1;	  PC += wide + 1;	  wide = 0;	  if (index < 0 || index >= DECL_MAX_LOCALS (current_function_decl))	    VERIFICATION_ERROR ("invalid local variable index in iinc");	  tmp = type_map[index];	  if (! INTEGRAL_TYPE_P (tmp) || TYPE_PRECISION (tmp) > 32)	    VERIFICATION_ERROR ("invalid local variable type in iinc");	  break;	case OPCODE_i2l:	  pop_type (int_type_node);    push_type (long_type_node);   break;	case OPCODE_i2f:	  pop_type (int_type_node);    push_type (float_type_node);  break;	case OPCODE_i2d:	  pop_type (int_type_node);    push_type (double_type_node); break;	case OPCODE_l2i:	  pop_type (long_type_node);   push_type (int_type_node);    break;	case OPCODE_l2f:	  pop_type (long_type_node);   push_type (float_type_node);  break;	case OPCODE_l2d:	  pop_type (long_type_node);   push_type (double_type_node); break;	case OPCODE_f2i:	  pop_type (float_type_node);  push_type (int_type_node);    break;	case OPCODE_f2l:	  pop_type (float_type_node);  push_type (long_type_node);   break;	case OPCODE_f2d:	  pop_type (float_type_node);  push_type (double_type_node); break;	case OPCODE_d2i:	  pop_type (double_type_node); push_type (int_type_node);    break;	case OPCODE_d2l:	  pop_type (double_type_node); push_type (long_type_node);   break;	case OPCODE_d2f:	  pop_type (double_type_node); push_type (float_type_node);  break;	case OPCODE_lcmp:	  type = long_type_node;  goto compare;	case OPCODE_fcmpl:	case OPCODE_fcmpg:	  type = float_type_node;  goto compare;	case OPCODE_dcmpl:	case OPCODE_dcmpg:	  type = double_type_node;  goto compare;	compare:	  pop_type (type);  pop_type (type);	  push_type (int_type_node);  break;	case OPCODE_ifeq:	case OPCODE_ifne:	case OPCODE_iflt:	case OPCODE_ifge:	case OPCODE_ifgt:	case OPCODE_ifle:	  pop_type (int_type_node);  goto cond;	case OPCODE_ifnull:	case OPCODE_ifnonnull:	  pop_type (ptr_type_node ); goto cond;	case OPCODE_if_icmpeq:	case OPCODE_if_icmpne:	case OPCODE_if_icmplt:	case OPCODE_if_icmpge:	case OPCODE_if_icmpgt:	case OPCODE_if_icmple:	  pop_type (int_type_node);  pop_type (int_type_node);  goto cond;	case OPCODE_if_acmpeq:	case OPCODE_if_acmpne:	  pop_type (object_ptr_type_node);  pop_type (object_ptr_type_node);	  goto cond;	cond:	  PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));	  break;	case OPCODE_goto:	  PUSH_PENDING (lookup_label (oldpc + IMMEDIATE_s2));	  INVALIDATE_PC;	  break;	case OPCODE_wide:	  switch (byte_ops[PC])	    {	    case OPCODE_iload:  case OPCODE_lload:	    case OPCODE_fload:  case OPCODE_dload:  case OPCODE_aload:	    case OPCODE_istore:  case OPCODE_lstore:	    case OPCODE_fstore:  case OPCODE_dstore:  case OPCODE_astore:	    case OPCODE_iinc:	    case OPCODE_ret:	      wide = 1;	      break;	    default:	      VERIFICATION_ERROR ("invalid use of wide instruction");	    }	  break;	case OPCODE_return:   type = void_type_node;   goto ret;	case OPCODE_ireturn:	  if ((TREE_CODE (return_type) == BOOLEAN_TYPE	       || TREE_CODE (return_type) == CHAR_TYPE	       || TREE_CODE (return_type) == INTEGER_TYPE)	      && TYPE_PRECISION (return_type) <= 32)	    type = return_type;	  else	    type = NULL_TREE;	  goto ret;	case OPCODE_lreturn:  type = long_type_node;   goto ret;	case OPCODE_freturn:  type = float_type_node;  goto ret;	case OPCODE_dreturn:  type = double_type_node; goto ret;	case OPCODE_areturn:	  if (TREE_CODE (return_type) == POINTER_TYPE)	    type = return_type;	  else	    type = NULL_TREE;	  goto ret;	ret:	  if (type != return_type)	    VERIFICATION_ERROR ("incorrect ?return opcode");	  if (type != void_type_node)	    {	      if (pop_type_0 (type) == NULL_TREE)		VERIFICATION_ERROR ("return value has wrong type");	    }	  INVALIDATE_PC;	  break;	case OPCODE_getstatic: is_putting = 0;  is_static = 1;  goto field;	case OPCODE_putstatic: is_putting = 1;  is_static = 1;  goto field;	case OPCODE_getfield:  is_putting = 0;  is_static = 0;  goto field;	case OPCODE_putfield:  is_putting = 1;  is_static = 0;  goto field;	field:	  {	    int index = IMMEDIATE_u2;	    tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, index);	    tree field_type = get_type_from_signature (field_signature);	    if (is_putting)	      pop_type (field_type);	    if (! is_static)	      {		int clindex = COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,							index);		tree self_type = get_class_constant (current_jcf, clindex);		/* Defer actual checking until next pass. */		if (pop_type_0 (self_type) == NULL_TREE)		  VERIFICATION_ERROR ("incorrect type for field reference");	      }	    if (! is_putting)	      push_type (field_type);	    break;	  }	case OPCODE_new:	  push_type (get_class_constant (jcf, IMMEDIATE_u2));	  break;	case OPCODE_dup:     type_stack_dup (1, 0);  break;	case OPCODE_dup_x1:  type_stack_dup (1, 1);  break;	case OPCODE_dup_x2:  type_stack_dup (1, 2);  break;	case OPCODE_dup2:    type_stack_dup (2, 0);  break;	case OPCODE_dup2_x1: type_stack_dup (2, 1);  break;	case OPCODE_dup2_x2: type_stack_dup (2, 2);  break;	case OPCODE_pop:  index = 1;  goto pop;	case OPCODE_pop2: index = 2;  goto pop;	pop:	  if (stack_pointer < index)	    VERIFICATION_ERROR ("stack underflow");	  stack_pointer -= index;	  break;	case OPCODE_swap:	  if (stack_pointer < 2)	    VERIFICATION_ERROR ("stack underflow (in swap)");	  else	    {	      tree type1 = stack_type_map[stack_pointer - 1];	      tree type2 = stack_type_map[stack_pointer - 2];	      if (type1 == void_type_node || type2 == void_type_node)		VERIFICATION_ERROR ("verifier (swap):  double or long value");	      stack_type_map[stack_pointer - 2] = type1;	      stack_type_map[stack_pointer - 1] = type2;	    }	  break;	case OPCODE_ldc:   index = IMMEDIATE_u1;  goto ldc;	case OPCODE_ldc2_w:	case OPCODE_ldc_w:	  index = IMMEDIATE_u2;  goto ldc;	ldc:	  if (index <= 0 || index >= JPOOL_SIZE(current_jcf))	    VERIFICATION_ERROR ("bad constant pool index in ldc");	  int_value = -1;	  switch (JPOOL_TAG (current_jcf, index) & ~CONSTANT_ResolvedFlag)	    {	    case CONSTANT_Integer:  type = int_type_node;  goto check_ldc;	    case CONSTANT_Float:    type = float_type_node;  goto check_ldc;

⌨️ 快捷键说明

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