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

📄 except.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
    return NULL_RTX;  }  /* 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 ();  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;  entry->finalization = NULL_TREE;  entry->context = current_function_decl;  node->entry = entry;  node->chain = stack->top;  stack->top = node;  enqueue_eh_entry (&eh_table_output_queue, copy_eh_entry (entry));  return entry->start_label;}static struct ehEntry *pop_eh_entry (stack)     struct ehStack *stack;{  struct ehNode *tempnode;  struct ehEntry *tempentry;  if (stack && (tempnode = stack->top)) {    tempentry = tempnode->entry;    stack->top = stack->top->chain;    free (tempnode);    return tempentry;  }  return NULL;}static struct ehEntry *copy_eh_entry (entry)     struct ehEntry *entry;{  struct ehEntry *newentry;  newentry = (struct ehEntry*)xmalloc (sizeof (struct ehEntry));  memcpy ((void*)newentry, (void*)entry, sizeof (struct ehEntry));  return newentry;}static voidenqueue_eh_entry (queue, entry)     struct ehQueue *queue;     struct ehEntry *entry;{  struct ehNode *node = (struct ehNode*)xmalloc (sizeof (struct ehNode));  node->entry = entry;  node->chain = NULL;  if (queue->head == NULL)    {      queue->head = node;    }  else    {      queue->tail->chain = node;    }  queue->tail = node;}static struct ehEntry *dequeue_eh_entry (queue)     struct ehQueue *queue;{  struct ehNode *tempnode;  struct ehEntry *tempentry;  if (queue->head == NULL)    return NULL;  tempnode = queue->head;  queue->head = queue->head->chain;  tempentry = tempnode->entry;  free (tempnode);  return tempentry;}static voidnew_eh_queue (queue)     struct ehQueue *queue;{  queue->head = queue->tail = NULL;}static voidnew_eh_stack (stack)     struct ehStack *stack;{  stack->top = NULL;}/* cheesyness to save some typing. returns the return value rtx */rtxdo_function_call (func, params, return_type)     tree func, params, return_type;{  tree func_call;  func_call = build_function_call (func, params);  expand_call (func_call, NULL_RTX, 0);  if (return_type != NULL_TREE)    return hard_function_value (return_type, func_call);  return NULL_RTX;}static voidexpand_internal_throw (pc)     rtx pc;{  tree params;  emit_move_insn (DECL_RTL (saved_pc), pc);#ifdef JUMP_TO_THROW  emit_indirect_jump (gen_rtx (SYMBOL_REF, Pmode, "__throw"));#else  do_function_call (Throw, NULL_TREE, NULL_TREE);#endif  throw_used = 1;}/* ========================================================================= */voidlang_interim_eh (finalization)     tree finalization;{  if (finalization)    end_protect (finalization);  else    start_protect ();}extern tree auto_function PROTO((tree, tree, enum built_in_function));/* sets up all the global eh stuff that needs to be initialized at the   start of compilation.   This includes:		- Setting up all the function call trees		- Initializing the ehqueue		- Initializing the eh_table_output_queue		- Initializing the ehstack*/voidinit_exception_processing (){  extern tree define_function ();  tree unexpected_fndecl, terminate_fndecl;  tree set_unexpected_fndecl, set_terminate_fndecl;  tree catch_match_fndecl;  tree find_first_exception_match_fndecl;  tree unwind_fndecl;  tree declspecs;  tree d;  /* void (*)() */  tree PFV = build_pointer_type (build_function_type				 (void_type_node, void_list_node));  /* arg list for the build_function_type call for set_terminate () and     set_unexpected () */  tree pfvlist = tree_cons (NULL_TREE, PFV, void_list_node);  /* void (*pfvtype (void (*) ()))() */  tree pfvtype = build_function_type (PFV, pfvlist);  /* void vtype () */  tree vtype = build_function_type (void_type_node, void_list_node);    set_terminate_fndecl = auto_function (get_identifier ("set_terminate"),					pfvtype, NOT_BUILT_IN);  set_unexpected_fndecl = auto_function (get_identifier ("set_unexpected"),					 pfvtype, NOT_BUILT_IN);  unexpected_fndecl = auto_function (get_identifier ("unexpected"),				     vtype, NOT_BUILT_IN);  terminate_fndecl = auto_function (get_identifier ("terminate"),				    vtype, NOT_BUILT_IN);  interim_eh_hook = lang_interim_eh;  push_lang_context (lang_name_c);  catch_match_fndecl =    define_function (flag_rtti		     ? "__throw_type_match_rtti"		     : "__throw_type_match",		     build_function_type (ptr_type_node,					  tree_cons (NULL_TREE, ptr_type_node,						     tree_cons (NULL_TREE, ptr_type_node,								tree_cons (NULL_TREE, ptr_type_node,									   void_list_node)))),		     NOT_BUILT_IN,		     pushdecl,		     0);  find_first_exception_match_fndecl =    define_function ("__find_first_exception_table_match",		     build_function_type (ptr_type_node,					  tree_cons (NULL_TREE, ptr_type_node,						     void_list_node)),		     NOT_BUILT_IN,		     pushdecl,		     0);  unwind_fndecl =    define_function ("__unwind_function",		     build_function_type (void_type_node,					  tree_cons (NULL_TREE, ptr_type_node,						     void_list_node)),		     NOT_BUILT_IN,		     pushdecl,		     0);  throw_fndecl =    define_function ("__throw",		     build_function_type (void_type_node, void_list_node),		     NOT_BUILT_IN,		     pushdecl,		     0);  DECL_EXTERNAL (throw_fndecl) = 0;  TREE_PUBLIC (throw_fndecl) = 0;  Unexpected = default_conversion (unexpected_fndecl);  Terminate = default_conversion (terminate_fndecl);  SetTerminate = default_conversion (set_terminate_fndecl);  SetUnexpected = default_conversion (set_unexpected_fndecl);  CatchMatch = default_conversion (catch_match_fndecl);  FirstExceptionMatch = default_conversion (find_first_exception_match_fndecl);  Unwind = default_conversion (unwind_fndecl);  Throw = default_conversion (throw_fndecl);  BuiltinReturnAddress = default_conversion (builtin_return_address_fndecl);  TerminateFunctionCall = build_function_call (Terminate, NULL_TREE);  pop_lang_context ();  new_eh_queue (&ehqueue);  new_eh_queue (&eh_table_output_queue);  new_eh_stack (&ehstack);  declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE);  d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_pc"));  d = start_decl (d, declspecs, 0, NULL_TREE);  DECL_COMMON (d) = 1;  cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0);  saved_pc = lookup_name (get_identifier ("__eh_pc"), 0);  declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE);  d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_type"));  d = start_decl (d, declspecs, 0, NULL_TREE);  DECL_COMMON (d) = 1;  cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0);  saved_throw_type = lookup_name (get_identifier ("__eh_type"), 0);  declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE);  d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_value"));  d = start_decl (d, declspecs, 0, NULL_TREE);  DECL_COMMON (d) = 1;  cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0);  saved_throw_value = lookup_name (get_identifier ("__eh_value"), 0);}/* call this to begin a block of unwind protection (ie: when an object is   constructed) */voidstart_protect (){  if (! doing_eh (0))    return;  emit_label (push_eh_entry (&ehstack));}   /* call this to end a block of unwind protection.  the finalization tree is   the finalization which needs to be run in order to cleanly unwind through   this level of protection. (ie: call this when a scope is exited)*/voidend_protect (finalization)     tree finalization;{  struct ehEntry *entry;  if (! doing_eh (0))    return;  entry = pop_eh_entry (&ehstack);  emit_label (entry->end_label);  /* Put in something that takes up space, as otherwise the end     address for the EH region could have the exact same address as     the outer region, causing us to miss the fact that resuming     exception handling with this PC value would be inside the outer     region.  */  emit_insn (gen_nop ());  entry->finalization = finalization;  enqueue_eh_entry (&ehqueue, entry);}/* call this on start of a try block. */voidexpand_start_try_stmts (){  if (! doing_eh (1))    return;  start_protect ();}voidexpand_end_try_stmts (){  end_protect (integer_zero_node);}/* call this to start processing of all the catch blocks. */voidexpand_start_all_catch (){  struct ehEntry *entry;  rtx label;  if (! doing_eh (1))    return;  emit_line_note (input_filename, lineno);  label = gen_label_rtx ();  /* The label for the exception handling block we will save.  This is     Lresume, in the documention.  */  emit_label (label);    /* Put in something that takes up space, as otherwise the end     address for the EH region could have the exact same address as     the outer region, causing us to miss the fact that resuming     exception handling with this PC value would be inside the outer     region.  */  emit_insn (gen_nop ());  push_label_entry (&caught_return_label_stack, label);  /* Start a new sequence for all the catch blocks.  We will add this     to the gloabl sequence catch_clauses, when we have completed all     the handlers in this handler-seq.  */  start_sequence ();  while (1)    {      entry = dequeue_eh_entry (&ehqueue);      emit_label (entry->exception_handler_label);      expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);      /* When we get down to the matching entry, stop.  */      if (entry->finalization == integer_zero_node)	break;      /* The below can be optimized away, and we could just fall into the	 next EH handler, if we are certain they are nested.  */      /* Code to throw out to outer context, if we fall off end of the	 handler.  */      expand_internal_throw (gen_rtx (LABEL_REF,				      Pmode,				      entry->end_label));      free (entry);    }}/* call this to end processing of all the catch blocks. */voidexpand_end_all_catch (){  rtx new_catch_clause;  if (! doing_eh (1))    return;  /* Code to throw out to outer context, if we fall off end of catch     handlers.  This is rethrow (Lresume, same id, same obj); in the     documentation.  */  expand_internal_throw (gen_rtx (LABEL_REF,				  Pmode,				  top_label_entry (&caught_return_label_stack)));  /* Now we have the complete catch sequence.  */  new_catch_clause = get_insns ();  end_sequence ();    /* this level of catch blocks is done, so set up the successful catch jump     label for the next layer of catch blocks. */  pop_label_entry (&caught_return_label_stack);  /* Add the new sequence of catchs to the main one for this     function.  */  push_to_sequence (catch_clauses);  emit_insns (new_catch_clause);  catch_clauses = get_insns ();  end_sequence ();    /* Here we fall through into the continuation code.  */}/* Build a type value for use at runtime for a type that is matched   against by the exception handling system.  */static tree

⌨️ 快捷键说明

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