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

📄 jcf-parse.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
   - and then perhaps rename read_class to load_class.  FIXME */voidload_class (class_or_name, verbose)     tree class_or_name;     int verbose;{  tree name;  /* class_or_name can be the name of the class we want to load */  if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)    name = class_or_name;  /* In some cases, it's a dependency that we process earlier that     we though */  else if (TREE_CODE (class_or_name) == TREE_LIST)    name = TYPE_NAME (TREE_PURPOSE (class_or_name));  /* Or it's a type in the making */  else    name = DECL_NAME (TYPE_NAME (class_or_name));  if (read_class (name) == 0 && verbose)    {      error ("Cannot find file for class %s.",	     IDENTIFIER_POINTER (name));      if (TREE_CODE (class_or_name) == RECORD_TYPE)	TYPE_SIZE (class_or_name) = error_mark_node;#if 0      /* FIXME: what to do here?  */      if (!strcmp (classpath, DEFAULT_CLASS_PATH))	fatal ("giving up");#endif      return;    }}/* Parse a source file when JCF refers to a source file.  */static voidjcf_parse_source (){  tree file;  java_parser_context_save_global ();  java_push_parser_context ();  input_filename = current_jcf->filename;  file = get_identifier (input_filename);  if (!HAS_BEEN_ALREADY_PARSED_P (file))    {      if (!(finput = fopen (input_filename, "r")))	fatal ("input file `%s' just disappeared - jcf_parse_source",	       input_filename);      parse_source_file (file);      if (fclose (finput))	fatal ("can't close input file `%s' stream - jcf_parse_source",	       input_filename);    }  java_pop_parser_context (IS_A_COMMAND_LINE_FILENAME_P (file));  java_parser_context_restore_global ();}/* Parse the .class file JCF. */voidjcf_parse (jcf)     JCF* jcf;{  int i, code;  if (jcf_parse_preamble (jcf) != 0)    fatal ("Not a valid Java .class file.\n");  code = jcf_parse_constant_pool (jcf);  if (code != 0)    fatal ("error while parsing constant pool");  code = verify_constant_pool (jcf);  if (code > 0)    fatal ("error in constant pool entry #%d\n", code);  jcf_parse_class (jcf);  if (main_class == NULL_TREE)    main_class = current_class;  if (! quiet_flag && TYPE_NAME (current_class))    fprintf (stderr, " class %s",	     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));  if (CLASS_LOADED_P (current_class))    return;  CLASS_LOADED_P (current_class) = 1;  for (i = 1; i < JPOOL_SIZE(jcf); i++)    {      switch (JPOOL_TAG (jcf, i))	{	case CONSTANT_Class:	  get_class_constant (jcf, i);	  break;	}    }    code = jcf_parse_fields (jcf);  if (code != 0)    fatal ("error while parsing fields");  code = jcf_parse_methods (jcf);  if (code != 0)    fatal ("error while parsing methods");  code = jcf_parse_final_attributes (jcf);  if (code != 0)    fatal ("error while parsing final attributes");  /* The fields of class_type_node are already in correct order. */  if (current_class != class_type_node && current_class != object_type_node)    TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));  push_obstacks (&permanent_obstack, &permanent_obstack);  layout_class (current_class);  if (current_class == object_type_node)    layout_class_methods (object_type_node);  else    all_class_list = tree_cons (NULL_TREE, 				TYPE_NAME (current_class), all_class_list );  pop_obstacks ();}voidinit_outgoing_cpool (){  current_constant_pool_data_ref = NULL_TREE;   if (outgoing_cpool == NULL)    {      static CPool outgoing_cpool_buffer;      outgoing_cpool = &outgoing_cpool_buffer;      CPOOL_INIT(outgoing_cpool);    }  else    {      CPOOL_REINIT(outgoing_cpool);    }}static voidparse_class_file (){  tree method;  char *save_input_filename = input_filename;  int save_lineno = lineno;  java_layout_seen_class_methods ();  input_filename = DECL_SOURCE_FILE (TYPE_NAME (current_class));  lineno = 0;  debug_start_source_file (input_filename);  init_outgoing_cpool ();  for ( method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));	method != NULL_TREE; method = TREE_CHAIN (method))    {      JCF *jcf = current_jcf;      if (METHOD_NATIVE (method) || METHOD_ABSTRACT (method))	continue;      if (DECL_CODE_OFFSET (method) == 0)	{	  error ("missing Code attribute");	  continue;	}      lineno = 0;      if (DECL_LINENUMBERS_OFFSET (method))	{	  register int i;	  register unsigned char *ptr;	  JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));	  linenumber_count = i = JCF_readu2 (jcf);	  linenumber_table = ptr = jcf->read_ptr;	  for (ptr += 2; --i >= 0; ptr += 4)	    {	      int line = GET_u2 (ptr);	      /* Set initial lineno lineno to smallest linenumber.	       * Needs to be set before init_function_start. */	      if (lineno == 0 || line < lineno)		lineno = line;	    }  	}      else	{	  linenumber_table = NULL;	  linenumber_count = 0;	}      start_java_method (method);      give_name_to_locals (jcf);      /* Actually generate code. */      expand_byte_code (jcf, method);      end_java_method ();    }  if (flag_emit_class_files)    write_classfile (current_class);  finish_class (current_class);  debug_end_source_file (save_lineno);  input_filename = save_input_filename;  lineno = save_lineno;}/* Parse a source file, as pointed by the current value of INPUT_FILENAME. */static voidparse_source_file (file)     tree file;{  int save_error_count = java_error_count;  /* Mark the file as parsed */  HAS_BEEN_ALREADY_PARSED_P (file) = 1;  lang_init_source (1);		    /* Error msgs have no method prototypes */  java_init_lex ();		    /* Initialize the parser */  java_parse_abort_on_error ();  java_parse ();		    /* Parse and build partial tree nodes. */  java_parse_abort_on_error ();  java_complete_class ();	    /* Parse unsatisfied class decl. */  java_parse_abort_on_error ();  java_check_circular_reference (); /* Check on circular references */  java_parse_abort_on_error ();}static intpredefined_filename_p (node)     tree node;{  int i;  for (i = 0; i < predef_filenames_size; i++)    if (predef_filenames [i] == node)      return 1;  return 0;}intyyparse (){  int several_files = 0;  char *list = strdup (input_filename), *next;  tree node, current_file_list = NULL_TREE;  do     {      next = strchr (list, '&');      if (next)	{	  *next++ = '\0';	  several_files = 1;	}      if (list[0]) 	{	  char *value;	  tree id;	  int twice = 0;	  int len = strlen (list);	  /* FIXME: this test is only needed until our .java parser is	     fully capable.  */	  if (len > 5 && ! strcmp (&list[len - 5], ".java"))	    saw_java_source = 1;	  if (*list != '/' && several_files)	    obstack_grow (&temporary_obstack, "./", 2);	  obstack_grow0 (&temporary_obstack, list, len);	  value = obstack_finish (&temporary_obstack);	  /* Exclude file that we see twice on the command line. For	     all files except {Class,Error,Object,RuntimeException,String,	     Throwable}.java we can rely on maybe_get_identifier. For	     these files, we need to do a linear search of	     current_file_list. This search happens only for these	     files, presumably only when we're recompiling libgcj. */	     	  if ((id = maybe_get_identifier (value)))	    {	      if (predefined_filename_p (id))		{		  tree c;		  for (c = current_file_list; c; c = TREE_CHAIN (c))		    if (TREE_VALUE (c) == id)		      twice = 1;		}	      else		twice = 1;	    }	  if (twice)	    {	      char *saved_input_filename = input_filename;	      input_filename = value;	      warning ("source file seen twice on command line and will be "		       "compiled only once.");	      input_filename = saved_input_filename;	    }	  else	    {	      node = get_identifier (value);	      IS_A_COMMAND_LINE_FILENAME_P (node) = 1;	      current_file_list = tree_cons (NULL_TREE, node, 					     current_file_list);	    }	}      list = next;    }  while (next);  current_jcf = main_jcf;  current_file_list = nreverse (current_file_list);  for (node = current_file_list; node; node = TREE_CHAIN (node))    {      tree name = TREE_VALUE (node);      /* Skip already parsed files */      if (HAS_BEEN_ALREADY_PARSED_P (name))	continue;            /* Close previous descriptor, if any */      if (main_jcf->read_state && fclose (main_jcf->read_state))	fatal ("failed to close input file `%s' - yyparse",	       (main_jcf->filename ? main_jcf->filename : "<unknown>"));            /* Set jcf up and open a new file */      JCF_ZERO (main_jcf);      main_jcf->read_state = fopen (IDENTIFIER_POINTER (name), "rb");      if (main_jcf->read_state == NULL)	pfatal_with_name (IDENTIFIER_POINTER (name));            /* Set new input_filename and finput */      finput = main_jcf->read_state;#ifdef IO_BUFFER_SIZE      setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE),	       _IOFBF, IO_BUFFER_SIZE);#endif      input_filename = IDENTIFIER_POINTER (name);      main_jcf->filbuf = jcf_filbuf_from_stdio;      switch (jcf_figure_file_type (current_jcf))	{	case JCF_ZIP:	  parse_zip_file_entries ();	  break;	case JCF_CLASS:	  jcf_parse (current_jcf);	  parse_class_file ();	  break;	case JCF_SOURCE:	  java_push_parser_context ();	  java_parser_context_save_global ();	  parse_source_file (name);	  java_parser_context_restore_global ();	  java_pop_parser_context (1);	  break;	}    }  java_expand_classes ();  if (!java_report_errors () && !flag_syntax_only)    emit_register_classes ();  return 0;}static struct ZipFileCache *localToFile;/* Process all class entries found in the zip file.  */static voidparse_zip_file_entries (void){  struct ZipDirectory *zdir;  int i;  for (i = 0, zdir = (ZipDirectory *)localToFile->z.central_directory;       i < localToFile->z.count; i++, zdir = ZIPDIR_NEXT (zdir))    {      tree class;            /* We don't need to consider those files.  */      if (!zdir->size || !zdir->filename_offset)	continue;      class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir)));      current_jcf = TYPE_LANG_SPECIFIC (class)->jcf;      current_class = class;      if ( !CLASS_LOADED_P (class))	{          fseek (current_jcf->read_state, current_jcf->zip_offset, SEEK_SET);	  jcf_parse (current_jcf);	}      if (TYPE_SIZE (current_class) != error_mark_node)	{	  input_filename = current_jcf->filename;	  parse_class_file ();	  FREE (current_jcf->buffer); /* No longer necessary */	  /* Note: there is a way to free this buffer right after a	     class seen in a zip file has been parsed. The idea is the	     set its jcf in such a way that buffer will be reallocated	     the time the code for the class will be generated. FIXME. */	}    }}/* Read all the entries of the zip file, creates a class and a JCF. Sets the   jcf up for further processing and link it to the created class.  */static void process_zip_dir(){  int i;  ZipDirectory *zdir;  for (i = 0, zdir = (ZipDirectory *)localToFile->z.central_directory;       i < localToFile->z.count; i++, zdir = ZIPDIR_NEXT (zdir))    {      char *class_name, *file_name, *class_name_in_zip_dir;      tree class;      JCF  *jcf;      int   j;      class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);      /* We choose to not to process entries with a zero size or entries	 not bearing the .class extention.  */      if (!zdir->size || !zdir->filename_offset ||	  strncmp (&class_name_in_zip_dir[zdir->filename_length-6], 		   ".class", 6))	{	  /* So it will be skipped in parse_zip_file_entries  */	  zdir->size = 0;  	  continue;	}      class_name = ALLOC (zdir->filename_length+1-6);      file_name  = ALLOC (zdir->filename_length+1);      jcf = ALLOC (sizeof (JCF));      JCF_ZERO (jcf);      strncpy (class_name, class_name_in_zip_dir, zdir->filename_length-6);      class_name [zdir->filename_length-6] = '\0';      strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);      file_name [zdir->filename_length] = '\0';      for (j=0; class_name[j]; j++)        class_name [j] = (class_name [j] == '/' ? '.' : class_name [j]);      /* Yes, we write back the true class name into the zip directory.  */      strcpy (class_name_in_zip_dir, class_name);      zdir->filename_length = j;      class = lookup_class (get_identifier (class_name));      jcf->read_state  = finput;      jcf->filbuf      = jcf_filbuf_from_stdio;      jcf->seen_in_zip = 1;      jcf->java_source = 0;      jcf->zip_offset  = zdir->filestart;      jcf->classname   = class_name;      jcf->filename    = file_name;      TYPE_LANG_SPECIFIC (class) =         (struct lang_type *) perm_calloc (1, sizeof (struct lang_type));      TYPE_LANG_SPECIFIC (class)->jcf = jcf;    }}/* Lookup class NAME and figure whether is a class already found in the current   zip file.  */static intDEFUN(find_in_current_zip, (name, length, jcf),      char *name AND JCF **jcf){  JCF *local_jcf;  tree class_name = maybe_get_identifier (name), class, icv;  if (!class_name)    return 0;  if (!(icv = IDENTIFIER_CLASS_VALUE (class_name)))    return 0;  class = TREE_TYPE (icv);  /* Doesn't have jcf specific info ? It's not ours */  if (!TYPE_LANG_SPECIFIC (class) || !TYPE_LANG_SPECIFIC (class)->jcf)    return 0;  *jcf = local_jcf = TYPE_LANG_SPECIFIC (class)->jcf;  fseek (local_jcf->read_state, local_jcf->zip_offset, SEEK_SET);  return 1;}/* Figure what kind of file we're dealing with */static intDEFUN(jcf_figure_file_type, (jcf),      JCF *jcf){  unsigned char magic_string[4];  uint32 magic;  if (fread (magic_string, 1, 4, jcf->read_state) != 4)    jcf_unexpected_eof (jcf, 4);  fseek (jcf->read_state, 0L, SEEK_SET);  magic = GET_u4 (magic_string);  if (magic == 0xcafebabe)    return JCF_CLASS;  /* FIXME: is it a system file?  */  if (magic ==  (JCF_u4)ZIPMAGIC      && !open_in_zip (jcf, input_filename, NULL, 0))    {      localToFile = ALLOC (sizeof (struct ZipFileCache));      bcopy ((PTR) SeenZipFiles, (PTR) localToFile, sizeof (struct ZipFileCache));      process_zip_dir ();	/* Register all the class defined there */      return JCF_ZIP;    }  return JCF_SOURCE;}

⌨️ 快捷键说明

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