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

📄 except.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
voidpop_handler (used)     int used;{  action_nesting_level--;  if (pass == 1)    {      struct handler_state *old = current_handler;      if (old == NULL)	fatal ("internal error: on stack out of sync");      current_handler = old->next;      if (used)	{ /* Push unto global_handler_list. */	  old->next = global_handler_list;	  global_handler_list = old;	}      else	{	  /* Push onto free_handlers free list. */	  old->next = free_handlers;	  free_handlers = old;	}    }  else if (used)    {      current_handler = current_handler->next;    }}/* Emit code before an action that has an ON-handler. */static voidemit_setup_handler (){  tree handler_decl, handler_addr, t;  /* Field references. */  tree jbuf_ref, handlers_ref,prev_ref;  if (!exceptions_initialized)    {      /* We temporarily reset the maximum_field_alignment to zero so the	 compiler's exception data structures can be compatible with the	 run-time system, even when we're compiling with -fpack. */      extern int maximum_field_alignment;      int save_maximum_field_alignment = maximum_field_alignment;      maximum_field_alignment = 0;      push_obstacks_nochange ();      end_temporary_allocation ();      initialize_exceptions ();      pop_obstacks ();      maximum_field_alignment = save_maximum_field_alignment;    }  push_momentary ();  handler_decl = build_lang_decl (VAR_DECL,				  get_unique_identifier ("handler"),				  handler_link_type);  push_obstacks_nochange ();  pushdecl(handler_decl);  expand_decl (handler_decl);  finish_decl (handler_decl);  jbuf_ref = build_component_ref (handler_decl, jbuf_ident);  jbuf_ref = build_chill_arrow_expr (jbuf_ref, 1);  handlers_ref = build_component_ref (handler_decl, handlers_ident);  prev_ref = build_component_ref (handler_decl, prev_ident);  /* Emit code to link in handler in __exceptionStack chain. */  mark_addressable (handler_decl);  handler_addr = build1 (ADDR_EXPR, handler_link_pointer_type, handler_decl);  if (inline_exception_stack_ops)    {      expand_expr_stmt (build_chill_modify_expr (prev_ref,						 exception_stack_decl));      expand_expr_stmt (build_chill_modify_expr (exception_stack_decl,						 handler_addr));      current_handler->handler_ref = prev_ref;    }  else    {      expand_expr_stmt (build_chill_function_call (link_handler_decl,					     build_tree_list (NULL_TREE,							      handler_addr)));      current_handler->handler_ref = handler_addr;    }  /* Expand:  handler->__handlers = { <<array mapping names to ints } */  t =  build1 (NOP_EXPR, build_pointer_type (handler_element_type),	       build_chill_arrow_expr (start_handler_array (), 1));  expand_expr_stmt (build_chill_modify_expr (handlers_ref, t));  /* Emit code to unlink handler. */  if (inline_exception_stack_ops)    current_handler->unlink_cleanup      = build_chill_modify_expr (exception_stack_decl,				 current_handler->handler_ref);  else    current_handler->unlink_cleanup      = build_chill_function_call (unlink_handler_decl,				   build_tree_list(NULL_TREE,					       current_handler->handler_ref));  cleanup_chain = tree_cons (build_int_2 (action_nesting_level, 0),			     current_handler->unlink_cleanup,			     cleanup_chain);  /* Emit code for setjmp. */    current_handler->setjmp_expr =    build_chill_function_call (BISJ, build_tree_list (NULL_TREE, jbuf_ref));  expand_start_case (1, current_handler->setjmp_expr,		     integer_type_node, "on handler");  chill_handle_case_label (integer_zero_node, current_handler->setjmp_expr);}/* Start emitting code for: <actions> ON <handlers> END.   Assume we've parsed <actions>, and the setup needed for it. */voidchill_start_on (){  expand_expr_stmt (current_handler->unlink_cleanup);  /* Emit code to jump past the handlers. */  current_handler->end_label = gen_label_rtx ();  current_handler->compiling = 1;  emit_jump (current_handler->end_label);}voidchill_finish_on (){  expand_end_case (current_handler->setjmp_expr);    finish_handler_array ();  emit_label (current_handler->end_label);  pop_momentary ();  cleanup_chain = TREE_CHAIN (cleanup_chain);}voidchill_handle_on_labels (labels)     tree labels;{  int alternative = ++current_handler->prev_on_alternative;  if (pass == 1)    {      tree handler_number = build_int_2 (alternative, 0);      current_handler->on_alt_list =	tree_cons (handler_number, labels, current_handler->on_alt_list);    }  else    {      /* Find handler_number saved in pass 1. */      tree tmp = current_handler->on_alt_list;      while (TREE_INT_CST_LOW (TREE_PURPOSE (tmp)) != alternative)	tmp = TREE_CHAIN (tmp);      if (expand_exit_needed)	expand_exit_something (), expand_exit_needed = 0;      chill_handle_case_label (TREE_PURPOSE (tmp),			       current_handler->setjmp_expr);    }}voidchill_start_default_handler (){  current_handler->else_handler = ++current_handler->prev_on_alternative;  if (!ignoring)    {      chill_handle_case_default ();    }}voidchill_check_no_handlers (){  if (current_handler != NULL)    fatal ("internal error: on stack not empty when done");}static voidinitialize_exceptions (){  tree jmp_buf_type = build_array_type (integer_type_node,					build_index_type (build_int_2 (_JBLEN_2-1, 0)));  tree setjmp_fndecl, link_ftype;  tree parmtypes    = tree_cons (NULL_TREE, build_pointer_type (jmp_buf_type), void_list_node);  setjmp_fndecl = builtin_function ("setjmp",				    build_function_type (integer_type_node,							 parmtypes),				    NOT_BUILT_IN,				    SETJMP_LIBRARY_NAME);  BISJ = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (setjmp_fndecl)),		 setjmp_fndecl);   char_pointer_type_for_handler    = build_pointer_type (build_type_variant (char_type_node, 1, 0));  handler_element_type =    build_chill_struct_type (chainon			     (build_decl (FIELD_DECL,					  get_identifier("__exceptid"),					  char_pointer_type_for_handler),			      build_decl (FIELD_DECL,					  get_identifier("__handlerno"),					  integer_type_node)));  jbuf_ident = get_identifier("__jbuf");  prev_ident = get_identifier("__prev");  handlers_ident = get_identifier("__handlers");  handler_link_type =    build_chill_struct_type      (chainon       (build_decl (FIELD_DECL, prev_ident, ptr_type_node),	chainon	(build_decl (FIELD_DECL, handlers_ident,		     build_pointer_type (handler_element_type)),	 build_decl (FIELD_DECL, jbuf_ident, jmp_buf_type))));  handler_link_pointer_type = build_pointer_type (handler_link_type);  if (inline_exception_stack_ops)    {      exception_stack_decl =	build_lang_decl (VAR_DECL,			 get_identifier("__exceptionStack"),			 handler_link_pointer_type);      TREE_STATIC (exception_stack_decl) = 1;      TREE_PUBLIC (exception_stack_decl) = 1;      DECL_EXTERNAL (exception_stack_decl) = 1;      push_obstacks_nochange ();      pushdecl(exception_stack_decl);      make_decl_rtl (exception_stack_decl, NULL_PTR, 1);      finish_decl (exception_stack_decl);    }  link_ftype = build_function_type (void_type_node,				    tree_cons (NULL_TREE,					       handler_link_pointer_type,					       void_list_node));  link_handler_decl = builtin_function ("__ch_link_handler", link_ftype,					NOT_BUILT_IN, NULL_PTR);  unlink_handler_decl = builtin_function ("__ch_unlink_handler", link_ftype,					  NOT_BUILT_IN, NULL_PTR);  exceptions_initialized = 1;}/* Do the cleanup(s) needed for a GOTO label.   We only need to do the last of the cleanups. */voidexpand_goto_except_cleanup (label_level)     int label_level;{  tree list = cleanup_chain;  tree last = NULL_TREE;  for ( ; list != NULL_TREE; list = TREE_CHAIN (list))    {      if (TREE_INT_CST_LOW (TREE_PURPOSE (list)) > label_level)	last = list;      else	break;    }  if (last)    expand_expr_stmt (TREE_VALUE (last));}/* Returns true if there is a valid handler for EXCEPT_NAME   in the current static scope.   0 ... no handler found   1 ... local handler available   2 ... function may propagate this exception*/intis_handled (except_name)     tree except_name;{  tree t;  struct handler_state *h = current_handler;  /* if we are are currently compiling this handler     we have to start at the next level */  if (h && h->compiling)    h = h->next;  while (h != NULL)    {      if (h->function != current_function_decl)	break;      if (h->else_handler > 0)	return 1;      for (t = h->on_alt_list; t != NULL_TREE; t = TREE_CHAIN (t))	{	  if (value_member (except_name, TREE_VALUE (t)))	    return 1;	}      h = h->next;    }  t = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl));  if (value_member (except_name, t))    return 2;  return 0;}/* function generates code to reraise exceptions   for PROC's propagating exceptions. */voidchill_reraise_exceptions (exceptions)     tree exceptions;{  tree wrk;  if (exceptions == NULL_TREE)    return; /* just in case */  if (pass == 1)    {      for (wrk = exceptions; wrk != NULL_TREE; wrk = TREE_CHAIN (wrk))	chill_handle_on_labels (build_tree_list (NULL_TREE, TREE_VALUE (wrk)));    }  else /* pass == 2 */    {      chill_start_on ();      expand_exit_needed = 0;      for (wrk = exceptions; wrk != NULL_TREE; wrk = TREE_CHAIN (wrk))	{	  chill_handle_on_labels (TREE_VALUE (wrk));	  /* do a CAUSE exception */	  expand_expr_stmt (build_cause_exception (TREE_VALUE (wrk), 0));	  expand_exit_needed = 1;	}      chill_finish_on ();    }  pop_handler (1);}

⌨️ 快捷键说明

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