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

📄 jcf-write.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    case EXIT_BLOCK_EXPR:      {	struct jcf_block *label = state->labeled_blocks;	if (TREE_OPERAND (exp, 1) != NULL) goto notimpl;	while (label->u.labeled_block != TREE_OPERAND (exp, 0))	  label = label->next;	call_cleanups (label, state);	emit_goto (label, state);      }      break;    case PREDECREMENT_EXPR:  value = -1; post_op = 0;  goto increment;    case PREINCREMENT_EXPR:  value =  1; post_op = 0;  goto increment;    case POSTDECREMENT_EXPR: value = -1; post_op = 1;  goto increment;    case POSTINCREMENT_EXPR: value =  1; post_op = 1;  goto increment;    increment:      exp = TREE_OPERAND (exp, 0);      type = TREE_TYPE (exp);      size = TYPE_IS_WIDE (type) ? 2 : 1;      if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)	  && ! TREE_STATIC (exp)	  && TREE_CODE (type) == INTEGER_TYPE	  && TYPE_PRECISION (type) == 32)	{	  if (target != IGNORE_TARGET && post_op)	    emit_load (exp, state);	  emit_iinc (exp, value, state);	  if (target != IGNORE_TARGET && ! post_op)	    emit_load (exp, state);	  break;	}      if (TREE_CODE (exp) == COMPONENT_REF)	{	  generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);	  emit_dup (1, 0, state);	  /* Stack:  ..., objectref, objectref. */	  field_op (TREE_OPERAND (exp, 1), OPCODE_getfield, state);	  NOTE_PUSH (size-1);	  /* Stack:  ..., objectref, oldvalue. */	  offset = 1;	}      else if (TREE_CODE (exp) == ARRAY_REF)	{	  generate_bytecode_insns (TREE_OPERAND (exp, 0), STACK_TARGET, state);	  generate_bytecode_insns (TREE_OPERAND (exp, 1), STACK_TARGET, state);	  emit_dup (2, 0, state);	  /* Stack:  ..., array, index, array, index. */	  jopcode = OPCODE_iaload + adjust_typed_op (TREE_TYPE (exp), 7);	  RESERVE(1);	  OP1 (jopcode);	  NOTE_POP (2-size);	  /* Stack:  ..., array, index, oldvalue. */	  offset = 2;	}      else if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)	{	  generate_bytecode_insns (exp, STACK_TARGET, state);	  /* Stack:  ..., oldvalue. */	  offset = 0;	}      else	abort ();      if (target != IGNORE_TARGET && post_op)	emit_dup (size, offset, state);      /* Stack, if ARRAY_REF:  ..., [result, ] array, index, oldvalue. */      /* Stack, if COMPONENT_REF:  ..., [result, ] objectref, oldvalue. */      /* Stack, otherwise:  ..., [result, ] oldvalue. */      if (size == 1)	push_int_const (value, state);      else	push_long_const (value, value >= 0 ? 0 : -1, state);      NOTE_PUSH (size);      emit_binop (OPCODE_iadd + adjust_typed_op (type, 3), type, state);      if (target != IGNORE_TARGET && ! post_op)	emit_dup (size, offset, state);      /* Stack, if ARRAY_REF:  ..., [result, ] array, index, newvalue. */      /* Stack, if COMPONENT_REF:  ..., [result, ] objectref, newvalue. */      /* Stack, otherwise:  ..., [result, ] newvalue. */      goto finish_assignment;    case MODIFY_EXPR:      {	tree lhs = TREE_OPERAND (exp, 0);	tree rhs = TREE_OPERAND (exp, 1);	int offset = 0;	/* See if we can use the iinc instruction. */	if ((TREE_CODE (lhs) == VAR_DECL || TREE_CODE (lhs) == PARM_DECL)	    && ! TREE_STATIC (lhs)	    && TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE	    && TYPE_PRECISION (TREE_TYPE (lhs)) == 32	    && (TREE_CODE (rhs) == PLUS_EXPR || TREE_CODE (rhs) == MINUS_EXPR))	  {	    tree arg0 = TREE_OPERAND (rhs, 0);	    tree arg1 = TREE_OPERAND (rhs, 1);	    HOST_WIDE_INT min_value = -32768;	    HOST_WIDE_INT max_value = 32767;	    if (TREE_CODE (rhs) == MINUS_EXPR)	      {		min_value++;		max_value++;	      }	    else if (arg1 == lhs)	      {		arg0 = arg1;		arg1 = TREE_OPERAND (rhs, 0);	      }	    if (lhs == arg0 && TREE_CODE (arg1) == INTEGER_CST)	      {		HOST_WIDE_INT hi_value = TREE_INT_CST_HIGH (arg1);		value = TREE_INT_CST_LOW (arg1);		if ((hi_value == 0 && value <= max_value)		    || (hi_value == -1 && value >= min_value))		  {		    if (TREE_CODE (rhs) == MINUS_EXPR)		      value = -value;		    emit_iinc (lhs, value, state);		    break;		  }	      }	  }	if (TREE_CODE (lhs) == COMPONENT_REF)	  {	    generate_bytecode_insns (TREE_OPERAND (lhs, 0),				     STACK_TARGET, state);	    offset = 1;	  }	else if (TREE_CODE (lhs) == ARRAY_REF)	  {	    generate_bytecode_insns (TREE_OPERAND(lhs, 0),				     STACK_TARGET, state);	    generate_bytecode_insns (TREE_OPERAND(lhs, 1),				     STACK_TARGET, state);	    offset = 2;	  }	else	  offset = 0;	generate_bytecode_insns (rhs, STACK_TARGET, state);	if (target != IGNORE_TARGET)	  emit_dup (TYPE_IS_WIDE (type) ? 2 : 1 , offset, state);	exp = lhs;      }      /* FALLTHOUGH */    finish_assignment:      if (TREE_CODE (exp) == COMPONENT_REF)	{	  tree field = TREE_OPERAND (exp, 1);	  if (! FIELD_STATIC (field))	    NOTE_POP (1);	  field_op (field,		    FIELD_STATIC (field) ? OPCODE_putstatic : OPCODE_putfield,		    state);	  NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (field)) ? 2 : 1);	}      else if (TREE_CODE (exp) == VAR_DECL	       || TREE_CODE (exp) == PARM_DECL)	{	  if (FIELD_STATIC (exp))	    {	      field_op (exp, OPCODE_putstatic, state);	      NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 2 : 1);	    }	  else	    emit_store (exp, state);	}      else if (TREE_CODE (exp) == ARRAY_REF)	{	  jopcode = OPCODE_iastore + adjust_typed_op (TREE_TYPE (exp), 7);	  RESERVE(1);	  OP1 (jopcode);	  NOTE_POP (TYPE_IS_WIDE (TREE_TYPE (exp)) ? 4 : 3);	}      else	fatal ("internal error (bad lhs to MODIFY_EXPR)");      break;    case PLUS_EXPR:      jopcode = OPCODE_iadd;      goto binop;    case MINUS_EXPR:      jopcode = OPCODE_isub;      goto binop;    case MULT_EXPR:      jopcode = OPCODE_imul;      goto binop;    case TRUNC_DIV_EXPR:    case RDIV_EXPR:      jopcode = OPCODE_idiv;      goto binop;    case TRUNC_MOD_EXPR:      jopcode = OPCODE_irem;      goto binop;    case LSHIFT_EXPR:   jopcode = OPCODE_ishl;   goto binop;    case RSHIFT_EXPR:   jopcode = OPCODE_ishr;   goto binop;    case URSHIFT_EXPR:  jopcode = OPCODE_iushr;  goto binop;    case TRUTH_AND_EXPR:    case BIT_AND_EXPR:  jopcode = OPCODE_iand;   goto binop;    case TRUTH_OR_EXPR:    case BIT_IOR_EXPR:  jopcode = OPCODE_ior;    goto binop;    case TRUTH_XOR_EXPR:    case BIT_XOR_EXPR:  jopcode = OPCODE_ixor;   goto binop;    binop:    {      tree arg0 = TREE_OPERAND (exp, 0);      tree arg1 = TREE_OPERAND (exp, 1);      jopcode += adjust_typed_op (type, 3);      if (arg0 == arg1 && TREE_CODE (arg0) == SAVE_EXPR)	{	  /* fold may (e.g) convert 2*x to x+x. */	  generate_bytecode_insns (TREE_OPERAND (arg0, 0), target, state);	  emit_dup (TYPE_PRECISION (TREE_TYPE (arg0)) > 32 ? 2 : 1, 0, state);	}      else	{	  generate_bytecode_insns (arg0, target, state);	  generate_bytecode_insns (arg1, target, state);	}      /* For most binary operations, both operands and the result have the	 same type.  Shift operations are different.  Using arg1's type	 gets us the correct SP adjustment in all casesd. */      if (target == STACK_TARGET)	emit_binop (jopcode, TREE_TYPE (arg1), state);      break;    }    case TRUTH_NOT_EXPR:    case BIT_NOT_EXPR:      generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);      if (target == STACK_TARGET)	{	  int is_long = TYPE_PRECISION (TREE_TYPE (exp)) > 32;	  push_int_const (TREE_CODE (exp) == BIT_NOT_EXPR ? -1 : 1, state); 	  RESERVE (2);	  if (is_long)	    OP1 (OPCODE_i2l);	  NOTE_PUSH (1 + is_long);	  OP1 (OPCODE_ixor + is_long);	  NOTE_POP (1 + is_long);	}      break;    case NEGATE_EXPR:      jopcode = OPCODE_ineg;      jopcode += adjust_typed_op (type, 3);      generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);      if (target == STACK_TARGET)	emit_unop (jopcode, type, state);      break;    case INSTANCEOF_EXPR:      {	int index = find_class_constant (&state->cpool, TREE_OPERAND (exp, 1));	generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);	RESERVE (3);	OP1 (OPCODE_instanceof);	OP2 (index);      }      break;    case CONVERT_EXPR:    case NOP_EXPR:    case FLOAT_EXPR:    case FIX_TRUNC_EXPR:      {	tree src = TREE_OPERAND (exp, 0);	tree src_type = TREE_TYPE (src);	tree dst_type = TREE_TYPE (exp);	generate_bytecode_insns (TREE_OPERAND (exp, 0), target, state);	if (target == IGNORE_TARGET || src_type == dst_type)	  break;	if (TREE_CODE (dst_type) == POINTER_TYPE)	  {	    if (TREE_CODE (exp) == CONVERT_EXPR)	      {		int index = find_class_constant (&state->cpool, TREE_TYPE (dst_type));		RESERVE (3);		OP1 (OPCODE_checkcast);		OP2 (index);	      }	  }	else /* Convert numeric types. */	  {	    int wide_src = TYPE_PRECISION (src_type) > 32;	    int wide_dst = TYPE_PRECISION (dst_type) > 32;	    NOTE_POP (1 + wide_src);	    RESERVE (1);	    if (TREE_CODE (dst_type) == REAL_TYPE)	      {		if (TREE_CODE (src_type) == REAL_TYPE)		  OP1 (wide_dst ? OPCODE_f2d : OPCODE_d2f);		else if (TYPE_PRECISION (src_type) == 64)		  OP1 (OPCODE_l2f + wide_dst);		else		  OP1 (OPCODE_i2f + wide_dst);	      }	    else /* Convert to integral type. */	      {		if (TREE_CODE (src_type) == REAL_TYPE)		  OP1 (OPCODE_f2i + wide_dst + 3 * wide_src);		else if (wide_dst)		  OP1 (OPCODE_i2l);		else if (wide_src)		  OP1 (OPCODE_l2i);		if (TYPE_PRECISION (dst_type) < 32)		  {		    RESERVE (1);		    /* Already converted to int, if needed. */		    if (TYPE_PRECISION (dst_type) <= 8)		      OP1 (OPCODE_i2b);		    else if (TREE_UNSIGNED (dst_type))		      OP1 (OPCODE_i2c);		    else		      OP1 (OPCODE_i2s);		  }	      }	    NOTE_PUSH (1 + wide_dst);	  }      }      break;    case CLEANUP_POINT_EXPR:      {	struct jcf_block *save_labeled_blocks = state->labeled_blocks;	int can_complete = CAN_COMPLETE_NORMALLY (TREE_OPERAND (exp, 0));	generate_bytecode_insns (TREE_OPERAND (exp, 0), IGNORE_TARGET, state);	if (target != IGNORE_TARGET)	  abort ();	while (state->labeled_blocks != save_labeled_blocks)	  {	    struct jcf_block *finished_label = NULL;	    tree return_link;	    tree exception_type = build_pointer_type (throwable_type_node);	    tree exception_decl = build_decl (VAR_DECL, NULL_TREE,					      exception_type);	    struct jcf_block *end_label = get_jcf_label_here (state);	    struct jcf_block *label = state->labeled_blocks;	    struct jcf_handler *handler;	    tree cleanup = label->u.labeled_block;	    state->labeled_blocks = label->next;	    state->num_finalizers--;	    if (can_complete)	      {		finished_label = gen_jcf_label (state);		emit_jsr (label, state);		emit_goto (finished_label, state);		if (! CAN_COMPLETE_NORMALLY (cleanup))		  can_complete = 0;	      }	    handler = alloc_handler (label->v.start_label, end_label, state);	    handler->type = NULL_TREE;	    localvar_alloc (exception_decl, state);	    NOTE_PUSH (1);            emit_store (exception_decl, state);	    emit_jsr (label, state);	    emit_load (exception_decl, state);	    RESERVE (1);	    OP1 (OPCODE_athrow);	    NOTE_POP (1);	    /* The finally block. */	    return_link = build_decl (VAR_DECL, NULL_TREE,				      return_address_type_node);	    define_jcf_label (label, state);	    NOTE_PUSH (1);	    localvar_alloc (return_link, state);	    emit_store (return_link, state);	    generate_bytecode_insns (cleanup, IGNORE_TARGET, state);	    maybe_wide (OPCODE_ret, DECL_LOCAL_INDEX (return_link), state);	    localvar_free (return_link, state);	    localvar_free (exception_decl, state);	    if (finished_label != NULL)	      define_jcf_label (finished_label, state);	  }      }      break;    case WITH_CLEANUP_EXPR:      {	struct jcf_block *label;	generate_bytecode_insns (TREE_OPERAND (exp, 0), IGNORE_TARGET, state);	label = gen_jcf_label (state);	label->pc = PENDING_CLEANUP_PC;	label->next = state->labeled_blocks;	state->labeled_blocks = label;	state->num_finalizers++;	label->u.labeled_block = TREE_OPERAND (exp, 2);	label->v.start_label = get_jcf_label_here (state);	if (target != IGNORE_TARGET)	  abort ();      }      break;    case TRY_EXPR:      {	tree try_clause = TREE_OPERAND (exp, 0);	struct jcf_block *start_label = get_jcf_label_here (state);	struct jcf_block *end_label;  /* End of try clause. */	struct jcf_block *finished_label = gen_jcf_label (state);	tree clause = TREE_OPERAND (exp, 1);	if (target != IGNORE_TARGET)	  abort ();	generate_bytecode_insns (try_clause, IGNORE_TARGET, state);	end_label = get_jcf_label_here (state);	if (CAN_COMPLETE_NORMALLY (try_clause))	  emit_goto (finished_label, state);	while (clause != NULL_TREE)	  {	    tree catch_clause = TREE_OPERAND (clause, 0);	    tree exception_decl = BLOCK_EXPR_DECLS (catch_clause);	    struct jcf_handler *handler = alloc_handler (start_label, end_label, state);	    if (exception_decl == NULL_TREE)	      handler->type = NULL_TREE;	    else	      handler->type = TREE_TYPE (TREE_TYPE (exception_decl));	    generate_bytecode_insns (catch_clause, IGNORE_TARGET, state);	    clause = TREE_CHAIN (clause);	    if (CAN_COMPLETE_NORMALLY (catch_clause) && clause != NULL_TREE)	      emit_goto (finished_label, state);	  }	define_jcf_label (finished_label, state);      }      break;    case TRY_FINALLY_EXPR:      {	tree try_block = TREE_OPERAND (exp, 0);	tree finally = TREE_OPERAND (exp, 1);	struct jcf_block *finished_label = gen_jcf_label (state);	struct jcf_block *finally_label = gen_jcf_label (state);	struct jcf_block *start_label = get_jcf_label_here (state);	tree return_link = build_decl (VAR_DECL, NULL_TREE,				       return_address_type_node);	tree exception_type = build_pointer_type (throwable_type_node);	tree exception_decl = build_decl (VAR_DECL, NULL_TREE, exception_type);	struct jcf_handler *handler;	finally_label->pc = PENDING_CLEANUP_PC;	finally_label->next = state->labeled_blocks;	state->labeled_blocks = finally_label;	state->num_finalizers++;	generate_bytecode_insns (try_block, target, state);	if (state->labeled_blocks != finally_label)	  abort();	state->labeled_blocks = finally_label->next;	emit_jsr (finally_label, state);	if (CAN_COMPLETE_NORMALLY (try_block))	  emit_goto (finished_label, state);	/* Handle exceptions. */	localvar_alloc (return_link, state);	handler = alloc_handler (start_label, NULL_TREE, state);	handler->end_

⌨️ 快捷键说明

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