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

📄 except.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
  t = build_modify_expr (saved_pc, NOP_EXPR, make_tree (ptr_type_node, return_val_rtx));  expand_expr (t, const0_rtx, VOIDmode, 0);  do_unwind (gen_rtx (LABEL_REF, Pmode, top_of_loop));  emit_jump (top_of_loop);  /* no it didn't --> therefore we need to call terminate */  emit_label (gotta_call_terminate);  do_function_call (Terminate, NULL_TREE, NULL_TREE);  assemble_external (TREE_OPERAND (Terminate, 0));  {    rtx ret_val, return_val_rtx;    emit_label (unwind_first);    ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,					  0, hard_frame_pointer_rtx);    /* Set it up so that we continue inside, at the top of the loop.  */    emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, top_of_loop));#ifdef NORMAL_RETURN_ADDR_OFFSET  return_val_rtx = plus_constant (ret_val, -NORMAL_RETURN_ADDR_OFFSET);    if (return_val_rtx != ret_val)      emit_move_insn (ret_val, return_val_rtx);#endif    /* Fall into epilogue to unwind prologue. */  }  expand_end_bindings (getdecls(), 1, 0);  poplevel (1, 0, 0);  pop_momentary ();  finish_function (lineno, 0, 0);}voidexpand_start_eh_spec (){  start_protect ();}voidexpand_end_eh_spec (raises)     tree raises;{  tree expr, second_try;  rtx check = gen_label_rtx ();  rtx cont;  rtx ret = gen_reg_rtx (Pmode);  rtx flag = gen_reg_rtx (TYPE_MODE (integer_type_node));  rtx end = gen_label_rtx ();  expr = make_node (RTL_EXPR);  TREE_TYPE (expr) = void_type_node;  RTL_EXPR_RTL (expr) = const0_rtx;  TREE_SIDE_EFFECTS (expr) = 1;  start_sequence_for_rtl_expr (expr);  cont = gen_label_rtx ();  emit_move_insn (ret, gen_rtx (LABEL_REF, Pmode, cont));  emit_jump (check);  emit_label (cont);  jumpif (make_tree (integer_type_node, flag), end);  do_function_call (Terminate, NULL_TREE, NULL_TREE);  assemble_external (TREE_OPERAND (Terminate, 0));  emit_barrier ();  RTL_EXPR_SEQUENCE (expr) = get_insns ();  end_sequence ();    second_try = expr;  expr = make_node (RTL_EXPR);  TREE_TYPE (expr) = void_type_node;  RTL_EXPR_RTL (expr) = const0_rtx;  TREE_SIDE_EFFECTS (expr) = 1;  start_sequence_for_rtl_expr (expr);  cont = gen_label_rtx ();  emit_move_insn (ret, gen_rtx (LABEL_REF, Pmode, cont));  emit_jump (check);  emit_label (cont);  jumpif (make_tree (integer_type_node, flag), end);  start_protect ();  do_function_call (Unexpected, NULL_TREE, NULL_TREE);  assemble_external (TREE_OPERAND (Unexpected, 0));  emit_barrier ();  end_protect (second_try);    emit_label (check);  emit_move_insn (flag, const1_rtx);  cont = gen_label_rtx ();  while (raises)    {      tree exp;      tree match_type = TREE_VALUE (raises);            if (match_type)	{	  /* check TREE_VALUE (raises) here */	  exp = saved_throw_value;	  exp = tree_cons (NULL_TREE,			   build_eh_type_type (match_type),			   tree_cons (NULL_TREE,				      saved_throw_type,				      tree_cons (NULL_TREE, exp, NULL_TREE)));	  exp = build_function_call (CatchMatch, exp);	  assemble_external (TREE_OPERAND (CatchMatch, 0));	  jumpif (exp, cont);	}      raises = TREE_CHAIN (raises);    }  emit_move_insn (flag, const0_rtx);  emit_label (cont);  emit_indirect_jump (ret);  emit_label (end);    RTL_EXPR_SEQUENCE (expr) = get_insns ();  end_sequence ();    end_protect (expr);}/* This is called to expand all the toplevel exception handling   finalization for a function.  It should only be called once per   function.  */voidexpand_exception_blocks (){  static rtx funcend;  rtx insns;  start_sequence ();  funcend = gen_label_rtx ();  emit_jump (funcend);  /* expand_null_return (); */  start_sequence ();  /* Add all the catch clauses here.  */  emit_insns (catch_clauses);  catch_clauses = NULL_RTX;  expand_leftover_cleanups ();  insns = get_insns ();  end_sequence ();    /* Do this after we expand leftover cleanups, so that the end_protect     that expand_end_eh_spec does will match the right start_protect,     and make sure it comes out before the terminate protected region.  */  if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))    {      expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));      push_to_sequence (insns);      /* Now expand any new ones.  */      expand_leftover_cleanups ();      insns = get_insns ();      end_sequence ();    }  if (insns)    {      struct ehEntry entry;      /* These are saved for the exception table.  */      push_rtl_perm ();      entry.start_label = gen_label_rtx ();      entry.end_label = gen_label_rtx ();      entry.exception_handler_label = gen_label_rtx ();      entry.finalization = TerminateFunctionCall;      entry.context = current_function_decl;      assemble_external (TREE_OPERAND (Terminate, 0));      pop_rtl_from_perm ();      LABEL_PRESERVE_P (entry.start_label) = 1;      LABEL_PRESERVE_P (entry.end_label) = 1;      LABEL_PRESERVE_P (entry.exception_handler_label) = 1;      emit_label (entry.start_label);      emit_insns (insns);      enqueue_eh_entry (&eh_table_output_queue, copy_eh_entry (&entry));      emit_label (entry.exception_handler_label);      expand_expr (entry.finalization, const0_rtx, VOIDmode, 0);      emit_label (entry.end_label);      emit_barrier ();    }  {    /* Mark the end of the stack unwinder.  */    rtx unwind_insns;    start_sequence ();    end_eh_unwinder (funcend);    expand_leftover_cleanups ();    unwind_insns = get_insns ();    end_sequence ();    if (unwind_insns)      {	insns = unwind_insns;	emit_insns (insns);      }  }  emit_label (funcend);  /* Only if we had previous insns do we want to emit the jump around     them.  If there weren't any, then insns will remain NULL_RTX.  */  if (insns)    insns = get_insns ();  end_sequence ();  emit_insns (insns);}/* call this to expand a throw statement.  This follows the following   algorithm:	1. Allocate space to save the current PC onto the stack.	2. Generate and emit a label and save its address into the		newly allocated stack space since we can't save the pc directly.	3. If this is the first call to throw in this function:		generate a label for the throw block	4. jump to the throw block label.  */voidexpand_throw (exp)     tree exp;{  rtx label;  if (! doing_eh (1))    return;  /* This is the label that represents where in the code we were, when     we got an exception.  This needs to be updated when we rethrow an     exception, so that the matching routine knows to search out.  */  label = gen_label_rtx ();  emit_label (label);  if (exp)    {      tree throw_type;      tree e;      /* throw expression */      /* First, decay it. */      exp = decay_conversion (exp);      if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)	{	  throw_type = build_eh_type (exp);	  exp = build_reinterpret_cast (ptr_type_node, exp);	}      else	{	  /* Make a copy of the thrown object.  WP 15.1.5  */	  exp = build_new (NULL_TREE, TREE_TYPE (exp),			   build_tree_list (NULL_TREE, exp),			   0);	  if (exp == error_mark_node)	    error ("  in thrown expression");	  throw_type = build_eh_type (build_indirect_ref (exp, NULL_PTR));	}      e = build_modify_expr (saved_throw_type, NOP_EXPR, throw_type);      expand_expr (e, const0_rtx, VOIDmode, 0);      e = build_modify_expr (saved_throw_value, NOP_EXPR, exp);      e = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (e), e);      expand_expr (e, const0_rtx, VOIDmode, 0);    }  else    {      /* rethrow current exception */      /* This part is easy, as we don't have to do anything else.  */    }  expand_internal_throw (gen_rtx (LABEL_REF, Pmode, label));}voidend_protect_partials () {  while (protect_list)    {      end_protect (TREE_VALUE (protect_list));      protect_list = TREE_CHAIN (protect_list);    }}intmight_have_exceptions_p (){  if (eh_table_output_queue.head)    return 1;  return 0;}/* Output the exception table. Return the number of handlers.  */voidemit_exception_table (){  int count = 0;  extern FILE *asm_out_file;  struct ehEntry *entry;  tree eh_node_decl;  if (! doing_eh (0))    return;  exception_section ();  /* Beginning marker for table. */  assemble_align (GET_MODE_ALIGNMENT (Pmode));  assemble_label ("__EXCEPTION_TABLE__");  output_exception_table_entry (asm_out_file,				const0_rtx, const0_rtx, const0_rtx); while (entry = dequeue_eh_entry (&eh_table_output_queue))   {     tree context = entry->context;     if (context && ! TREE_ASM_WRITTEN (context))       continue;     count++;     output_exception_table_entry (asm_out_file,				   entry->start_label, entry->end_label,				   entry->exception_handler_label);  }  /* Ending marker for table. */  assemble_label ("__EXCEPTION_END__");  output_exception_table_entry (asm_out_file,				constm1_rtx, constm1_rtx, constm1_rtx);}voidregister_exception_table (){  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__register_exceptions"), 0,		     VOIDmode, 1,		     gen_rtx (SYMBOL_REF, Pmode, "__EXCEPTION_TABLE__"),		     Pmode);}/* Build a throw expression.  */treebuild_throw (e)     tree e;{  if (e != error_mark_node)    {      e = build1 (THROW_EXPR, void_type_node, e);      TREE_SIDE_EFFECTS (e) = 1;      TREE_USED (e) = 1;    }  return e;}start_eh_unwinder (){  start_protect ();}end_eh_unwinder (end)     rtx end;{  tree expr;  rtx return_val_rtx, ret_val, label;  if (! doing_eh (0))    return;  expr = make_node (RTL_EXPR);  TREE_TYPE (expr) = void_type_node;  RTL_EXPR_RTL (expr) = const0_rtx;  TREE_SIDE_EFFECTS (expr) = 1;  start_sequence_for_rtl_expr (expr);  ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,					0, hard_frame_pointer_rtx);  return_val_rtx = copy_to_reg (ret_val);#ifdef NORMAL_RETURN_ADDR_OFFSET  return_val_rtx = plus_constant (return_val_rtx, NORMAL_RETURN_ADDR_OFFSET-1);#else  return_val_rtx = plus_constant (return_val_rtx, -1);#endif  emit_move_insn (DECL_RTL (saved_pc), return_val_rtx);  #ifdef JUMP_TO_THROW  emit_move_insn (ret_val, gen_rtx (SYMBOL_REF, Pmode, "__throw"));#else  label = gen_label_rtx ();  emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, label));#endif#ifdef NORMAL_RETURN_ADDR_OFFSET  return_val_rtx = plus_constant (ret_val, -NORMAL_RETURN_ADDR_OFFSET);  if (return_val_rtx != ret_val)    emit_move_insn (ret_val, return_val_rtx);#endif    emit_jump (end);  #ifndef JUMP_TO_THROW  emit_label (label);  do_function_call (Throw, NULL_TREE, NULL_TREE);#endif    RTL_EXPR_SEQUENCE (expr) = get_insns ();  end_sequence ();  end_protect (expr);}

⌨️ 快捷键说明

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