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

📄 objc-actions.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
static voidgenerate_ivar_lists (){  tree initlist, ivar_list_template, chain;  tree cast, variable_length_type;  int size;  if (!objc_ivar_template)    objc_ivar_template = build_ivar_template ();  cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,							    get_identifier (_TAG_IVAR_LIST))), NULLT);  variable_length_type = groktypename (cast);  /* only generate class variables for the root of the inheritance     hierarchy since these will be the same for every class */  if (CLASS_SUPER_NAME (implementation_template) == NULLT      && (chain = TYPE_FIELDS (objc_class_template)))    {      size = 0;      initlist = build_ivar_list_initializer (chain, &size);      ivar_list_template = build_ivar_list_template (objc_ivar_template, size);      _OBJC_CLASS_VARIABLES_decl =	generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",			     size, initlist);      /* cast! */      TREE_TYPE (_OBJC_CLASS_VARIABLES_decl) = variable_length_type;    }  else    _OBJC_CLASS_VARIABLES_decl = 0;  chain = CLASS_IVARS (implementation_template);  if (chain)    {      size = 0;      initlist = build_ivar_list_initializer (chain, &size);      ivar_list_template = build_ivar_list_template (objc_ivar_template, size);      _OBJC_INSTANCE_VARIABLES_decl =	generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",			     size, initlist);      /* cast! */      TREE_TYPE (_OBJC_INSTANCE_VARIABLES_decl) = variable_length_type;    }  else    _OBJC_INSTANCE_VARIABLES_decl = 0;}static treebuild_dispatch_table_initializer (entries, size)     tree entries;     int *size;{  tree initlist = NULLT;  do    {      int offset = add_objc_string (METHOD_SEL_NAME (entries));      initlist = tree_cons (NULLT, init_selector (offset), initlist);      offset = add_objc_string (METHOD_ENCODING (entries));      initlist = tree_cons (NULLT, build_msg_pool_reference (offset), initlist);      initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist);      (*size)++;      entries = TREE_CHAIN (entries);    }  while (entries);  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));}/* * To accomplish method prototyping without generating all kinds of * inane warnings, the definition of the dispatch table entries were * changed from: * * 	struct objc_method { SEL _cmd; id (*_imp)(); }; * to: * 	struct objc_method { SEL _cmd; void *_imp; }; */static treebuild_method_template (){  tree _SLT_record;  tree decl_specs, field_decl, field_decl_chain, parms;  _SLT_record = start_struct (RECORD_TYPE, get_identifier (_TAG_METHOD));#ifdef OBJC_INT_SELECTORS  /* unsigned int _cmd; */  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT);  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs);  field_decl = get_identifier ("_cmd");#else /* not OBJC_INT_SELECTORS */  /* struct objc_selector *_cmd; */  decl_specs = tree_cons (NULLT,			  xref_tag (RECORD_TYPE,				    get_identifier (TAG_SELECTOR)),			  NULLT);  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd"));#endif /* not OBJC_INT_SELECTORS */  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);  field_decl_chain = field_decl;  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT);  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types"));  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);  chainon (field_decl_chain, field_decl);  /* void *_imp; */  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT);  field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp"));  field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT);  chainon (field_decl_chain, field_decl);  finish_struct (_SLT_record, field_decl_chain);  return _SLT_record;}static treegenerate_dispatch_table (type, name, size, list)     tree type;     char *name;     int size;     tree list;{  tree sc_spec, decl_specs, decl, initlist;  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);  decl_specs = tree_cons (NULLT, type, sc_spec);  decl = start_decl (synth_id_with_class_suffix (name), decl_specs, 1);  initlist = build_tree_list (NULLT, build_int_2 (0, 0));  initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist);  initlist = tree_cons (NULLT, list, initlist);  finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT);  return decl;}static voidgenerate_dispatch_tables (){  tree initlist, chain, method_list_template;  tree cast, variable_length_type;  int size;  if (!objc_method_template)    objc_method_template = build_method_template ();  cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE,							    get_identifier (_TAG_METHOD_LIST))), NULLT);  variable_length_type = groktypename (cast);  chain = CLASS_CLS_METHODS (implementation_context);  if (chain)    {      size = 0;      initlist = build_dispatch_table_initializer (chain, &size);      method_list_template = build_method_list_template (objc_method_template,							 size);      if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)	_OBJC_CLASS_METHODS_decl = 	    generate_dispatch_table (method_list_template,				     "_OBJC_CLASS_METHODS", 				     size, initlist);      else	/* we have a category */	_OBJC_CLASS_METHODS_decl = 	    generate_dispatch_table (method_list_template,				     "_OBJC_CATEGORY_CLASS_METHODS", 				     size, initlist);      /* cast! */      TREE_TYPE (_OBJC_CLASS_METHODS_decl) = variable_length_type;    }  else    _OBJC_CLASS_METHODS_decl = 0;  chain = CLASS_NST_METHODS (implementation_context);  if (chain)    {      size = 0;      initlist = build_dispatch_table_initializer (chain, &size);      method_list_template = build_method_list_template (objc_method_template,							 size);      if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)	_OBJC_INSTANCE_METHODS_decl = 	    generate_dispatch_table (method_list_template,				     "_OBJC_INSTANCE_METHODS", 				     size, initlist);      else	/* we have a category */	_OBJC_INSTANCE_METHODS_decl = 	    generate_dispatch_table (method_list_template,				     "_OBJC_CATEGORY_INSTANCE_METHODS", 				     size, initlist);      /* cast! */      TREE_TYPE (_OBJC_INSTANCE_METHODS_decl) = variable_length_type;    }  else    _OBJC_INSTANCE_METHODS_decl = 0;}static treebuild_category_initializer (cat_name, class_name,			    instance_methods, class_methods)     tree cat_name;     tree class_name;     tree instance_methods;     tree class_methods;{  tree initlist = NULLT, expr;  initlist = tree_cons (NULLT, cat_name, initlist);  initlist = tree_cons (NULLT, class_name, initlist);  if (!instance_methods)    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);  else    {      expr = build_unary_op (ADDR_EXPR, instance_methods, 0);      initlist = tree_cons (NULLT, expr, initlist);    }  if (!class_methods)    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);  else    {      expr = build_unary_op (ADDR_EXPR, class_methods, 0);      initlist = tree_cons (NULLT, expr, initlist);    }  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));}/* *  struct objc_class { *    struct objc_class *isa; *    struct objc_class *super_class; *    char *name; *    long version; *    long info; *    long instance_size; *    struct objc_ivar_list *ivars; *    struct objc_method_list *methods; *    struct objc_cache *cache; *  }; */static treebuild_shared_structure_initializer (isa, super, name, size, status,				    dispatch_table, ivar_list)     tree isa;     tree super;     tree name;     tree size;     int status;     tree dispatch_table;     tree ivar_list;{  tree initlist = NULLT, expr;  /* isa = */  initlist = tree_cons (NULLT, isa, initlist);  /* super_class = */  initlist = tree_cons (NULLT, super, initlist);  /* name = */  initlist = tree_cons (NULLT, name, initlist);  /* version = */  initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);  /* info = */  initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist);  /* instance_size = */  initlist = tree_cons (NULLT, size, initlist);  /* objc_ivar_list = */  if (!ivar_list)    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);  else    {      expr = build_unary_op (ADDR_EXPR, ivar_list, 0);      initlist = tree_cons (NULLT, expr, initlist);    }  /* objc_method_list = */  if (!dispatch_table)    initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);  else    {      expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);      initlist = tree_cons (NULLT, expr, initlist);    }  /* method_cache = */  initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);  return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));}/* * static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */static voidgenerate_category (cat)     tree cat;{  tree sc_spec, decl_specs, decl;  tree initlist, cat_name_expr, class_name_expr;  int offset;  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);  decl_specs = tree_cons (NULLT, objc_category_template, sc_spec);  decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY"),		     decl_specs, 1);  offset = add_objc_string (CLASS_SUPER_NAME (cat));  cat_name_expr = build_msg_pool_reference (offset);  offset = add_objc_string (CLASS_NAME (cat));  class_name_expr = build_msg_pool_reference (offset);  initlist = build_category_initializer (					 cat_name_expr, class_name_expr,					 _OBJC_INSTANCE_METHODS_decl, _OBJC_CLASS_METHODS_decl);  finish_decl (decl, initlist, NULLT);}/* * static struct objc_class _OBJC_METACLASS_Foo={ ... }; * static struct objc_class _OBJC_CLASS_Foo={ ... }; */static voidgenerate_shared_structures (){  tree sc_spec, decl_specs, expr_decl, decl;  tree name_expr, super_expr, root_expr;  tree my_root_id = NULLT, my_super_id = NULLT;  tree cast_type, initlist;  int offset;  my_super_id = CLASS_SUPER_NAME (implementation_template);  if (my_super_id)    {      add_class_reference (my_super_id);      /* compute "my_root_id" - this is required for code generation.       * the "isa" for all meta class structures points to the root of       * the inheritance hierarchy (e.g. "__Object")...       */      my_root_id = my_super_id;      do	{	  tree my_root_int = lookup_interface (my_root_id);	  if (my_root_int && CLASS_SUPER_NAME (my_root_int))	    my_root_id = CLASS_SUPER_NAME (my_root_int);	  else	    break;	}      while (1);    }  else				/* no super class */    {      my_root_id = CLASS_NAME (implementation_template);    }  cast_type = groktypename (build_tree_list (build_tree_list (NULLT,							      objc_class_template), build1 (INDIRECT_REF, NULLT, NULLT)));  offset = add_objc_string (CLASS_NAME (implementation_template));  name_expr = build_msg_pool_reference (offset);  /* install class `isa' and `super' pointers at runtime */  if (my_super_id)    {      offset = add_objc_string (my_super_id);      super_expr = build_msg_pool_reference (offset);      TREE_TYPE (super_expr) = cast_type; /* cast! */    }  else    super_expr = build_int_2 (0, 0);  offset = add_objc_string (my_root_id);  root_expr = build_msg_pool_reference (offset);  TREE_TYPE (root_expr) = cast_type; /* cast! */  /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */  sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);  decl_specs = tree_cons (NULLT, objc_class_template, sc_spec);  decl = start_decl (DECL_NAME (_OBJC_METACLASS_decl), decl_specs, 1);  initlist = build_shared_structure_initializer (						 root_expr, super_expr, name_expr,						 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) / BITS_PER_UNIT, 0),						 2 /*CLS_META*/,						 _OBJC_CLASS_METHODS_decl, _OBJC_CLASS_VARIABLES_decl);  finish_decl (decl, initlist, NULLT);  /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */  decl = start_decl (DECL_NAME (_OBJC_CLASS_decl), decl_specs, 1);  initlist = build_shared_structure_initializer (						 build_unary_op (ADDR_EXPR, _OBJC_METACLASS_decl, 0),						 super_expr, name_expr,						 build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) / BITS_PER_UNIT, 0),						 1 /*CLS_FACTORY*/,						 _OBJC_INSTANCE_METHODS_decl, _OBJC_INSTANCE_VARIABLES_decl);  finish_decl (decl, initlist, NULLT);}static treesynth_id_with_class_suffix (preamble)     char *preamble;{  char *string;  if (TREE_CODE (implementation_context) == IMPLEMENTATION_TYPE)    {      string = (char *) alloca (strlen (preamble)				+ strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))				+ 3);      sprintf (string, "%s_%s", preamble,	       IDENTIFIER_POINTER (CLASS_NAME (implementation_context)));    }  else    {      /* we have a category */      string = (char *) alloca (strlen (preamble)				+ strlen (IDENTIFIER_POINTER (CLASS_NAME (implementation_context)))				+ strlen (IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)))				+ 3);      sprintf (string, "%s_%s_%s", preamble,	       IDENTIFIER_POINTER (CLASS_NAME (implementation_context)),	       IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)));    }  return get_identifier (string);}/* *   usage: *		keyworddecl: *			selector ':' '(

⌨️ 快捷键说明

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