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

📄 gjavah.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
    {      struct method_name *nn;      nn = (struct method_name *) malloc (sizeof (struct method_name));      nn->name = (char *) malloc (length);      memcpy (nn->name, str, length);      nn->length = length;      nn->next = method_name_list;      method_name_list = nn;    }  /* We can't generate a method whose name is a C++ reserved word.  We     can't just ignore the function, because that will cause incorrect     code to be generated if the function is virtual (not only for     calls to this function for for other functions after it in the     vtbl).  So we give it a dummy name instead.  */  override = cxx_keyword_subst (str, length);  if (override)    {      /* If the method is static or final, we can safely skip it.  If	 we don't skip it then we'll have problems since the mangling	 will be wrong.  FIXME.  */      if (METHOD_IS_FINAL (jcf->access_flags, flags)	  || (flags & ACC_STATIC))	return;    }  method_printed = 1;  generate_access (stream, flags);  fputs ("  ", out);  if ((flags & ACC_STATIC))    fputs ("static ", out);  else if (! METHOD_IS_FINAL (jcf->access_flags, flags))    {      /* Don't print `virtual' if we have a constructor.  */      if (! is_init)	fputs ("virtual ", out);    }  print_c_decl (out, jcf, name_index, sig_index, is_init, override);  if ((flags & ACC_ABSTRACT))    fputs (" = 0", out);  else    method_declared = 1;}/* Try to decompile a method body.  Right now we just try to handle a   simple case that we can do.  Expand as desired.  */static voiddecompile_method (out, jcf, code_len)     FILE *out;     JCF *jcf;     int code_len;{  unsigned char *codes = jcf->read_ptr;  int index;  uint16 name_and_type, name;  /* If the method is synchronized, don't touch it.  */  if ((method_access & ACC_SYNCHRONIZED))    return;  if (code_len == 5      && codes[0] == OPCODE_aload_0      && codes[1] == OPCODE_getfield      && (codes[4] == OPCODE_areturn	  || codes[4] == OPCODE_dreturn	  || codes[4] == OPCODE_freturn	  || codes[4] == OPCODE_ireturn	  || codes[4] == OPCODE_lreturn))    {      /* Found code like `return FIELD'.  */      fputs (" { return ", out);      index = (codes[2] << 8) | codes[3];      /* FIXME: ensure that tag is CONSTANT_Fieldref.  */      /* FIXME: ensure that the field's class is this class.  */      name_and_type = JPOOL_USHORT2 (jcf, index);      /* FIXME: ensure that tag is CONSTANT_NameAndType.  */      name = JPOOL_USHORT1 (jcf, name_and_type);      print_name (out, jcf, name);      fputs ("; }", out);      decompiled = 1;    }  else if (code_len == 2	   && codes[0] == OPCODE_aload_0	   && codes[1] == OPCODE_areturn)    {      /* Found `return this'.  */      fputs (" { return this; }", out);      decompiled = 1;    }  else if (code_len == 1 && codes[0] == OPCODE_return)    {      /* Found plain `return'.  */      fputs (" { }", out);      decompiled = 1;    }  else if (code_len == 2	   && codes[0] == OPCODE_aconst_null	   && codes[1] == OPCODE_areturn)    {      /* Found `return null'.  We don't want to depend on NULL being	 defined.  */      fputs (" { return 0; }", out);      decompiled = 1;    }}/* Print one piece of a signature.  Returns pointer to next parseable   character on success, NULL on error.  */static unsigned char *decode_signature_piece (stream, signature, limit, need_space)     FILE *stream;     unsigned char *signature, *limit;     int *need_space;{  const char *ctype;  switch (signature[0])    {    case '[':      for (signature++; (signature < limit			 && *signature >= '0'			 && *signature <= '9'); signature++)	;      switch (*signature)	{	case 'B': ctype = "jbyteArray";  goto printit;	case 'C': ctype = "jcharArray";  goto printit;	case 'D': ctype = "jdoubleArray";  goto printit;	case 'F': ctype = "jfloatArray";  goto printit;	case 'I': ctype = "jintArray";  goto printit;	case 'S': ctype = "jshortArray";  goto printit;	case 'J': ctype = "jlongArray";  goto printit;	case 'Z': ctype = "jbooleanArray";  goto printit;	case '[': ctype = "jobjectArray"; goto printit;	case 'L':	  /* We have to generate a reference to JArray here,	     so that our output matches what the compiler	     does.  */	  ++signature;	  fputs ("JArray<", stream);	  while (signature < limit && *signature != ';')	    {	      int ch = UTF8_GET (signature, limit);	      if (ch == '/')		fputs ("::", stream);	      else		jcf_print_char (stream, ch);	    }	  fputs (" *> *", stream);	  *need_space = 0;	  ++signature;	  break;	default:	  /* Unparseable signature.  */	  return NULL;	}      break;    case '(':    case ')':      /* This shouldn't happen.  */      return NULL;    case 'B': ctype = "jbyte";  goto printit;    case 'C': ctype = "jchar";  goto printit;    case 'D': ctype = "jdouble";  goto printit;    case 'F': ctype = "jfloat";  goto printit;    case 'I': ctype = "jint";  goto printit;    case 'J': ctype = "jlong";  goto printit;    case 'S': ctype = "jshort";  goto printit;    case 'Z': ctype = "jboolean";  goto printit;    case 'V': ctype = "void";  goto printit;    case 'L':      ++signature;      while (*signature && *signature != ';')	{	  int ch = UTF8_GET (signature, limit);	  /* `$' is the separator for an inner class.  */	  if (ch == '/' || ch == '$')	    fputs ("::", stream);	  else	    jcf_print_char (stream, ch);	}      fputs (" *", stream);      if (*signature == ';')	signature++;      *need_space = 0;      break;    default:      *need_space = 1;      jcf_print_char (stream, *signature++);      break;    printit:      signature++;      *need_space = 1;      fputs (ctype, stream);      break;    }  return signature;}static voidDEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,		     name_override),      FILE* stream AND JCF* jcf      AND int name_index AND int signature_index      AND int is_init AND const char *name_override){  if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)    {      fprintf (stream, "<not a UTF8 constant>");      found_error = 1;    }  else    {      int length = JPOOL_UTF_LENGTH (jcf, signature_index);      unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);      register  unsigned char *str = str0;      unsigned char *limit = str + length;      int need_space = 0;      int is_method = str[0] == '(';      unsigned char *next;      /* If printing a method, skip to the return signature and print	 that first.  However, there is no return value if this is a	 constructor.  */      if (is_method && ! is_init)	{	  while (str < limit)	    {	      int ch = *str++;	      if (ch == ')')		break;	    }	}      /* If printing a field or an ordinary method, then print the	 "return value" now.  */      if (! is_method || ! is_init)	{	  next = decode_signature_piece (stream, str, limit, &need_space);	  if (! next)	    {	      fprintf (stderr, "unparseable signature: `%s'\n", str0);	      found_error = 1;	      return;	    }	}      /* Now print the name of the thing.  */      if (need_space)	fputs (" ", stream);      if (name_override)	fputs (name_override, stream);      else if (name_index)	{	  /* Declare constructors specially.  */	  if (is_init)	    print_base_classname (stream, jcf, jcf->this_class);	  else	    print_name (stream, jcf, name_index);	}      if (is_method)	{	  /* Have a method or a constructor.  Print signature pieces	     until done.  */	  fputs (" (", stream);	  str = str0 + 1;	  while (str < limit && *str != ')')	    {	      next = decode_signature_piece (stream, str, limit, &need_space);	      if (! next)		{		  fprintf (stderr, "unparseable signature: `%s'\n", str0);		  found_error = 1;		  return;		}	      if (next < limit && *next != ')')		fputs (", ", stream);	      str = next;	    }	  fputs (")", stream);	}    }}voidDEFUN(print_mangled_classname, (stream, jcf, prefix, index),      FILE *stream AND JCF *jcf AND const char *prefix AND int index){  int name_index = JPOOL_USHORT1 (jcf, index);  fputs (prefix, stream);  jcf_print_utf8_replace (out,			  JPOOL_UTF_DATA (jcf, name_index),			  JPOOL_UTF_LENGTH (jcf, name_index),			  '/', '_');}/* Print PREFIX, then a class name in C++ format.  If the name refers   to an array, ignore it and don't print PREFIX.  Returns 1 if   something was printed, 0 otherwise.  */static intprint_cxx_classname (stream, prefix, jcf, index)     FILE *stream;     char *prefix;     JCF *jcf;     int index;{  int name_index = JPOOL_USHORT1 (jcf, index);  int len, c;  unsigned char *s, *p, *limit;  s = JPOOL_UTF_DATA (jcf, name_index);  len = JPOOL_UTF_LENGTH (jcf, name_index);  limit = s + len;  /* Explicitly omit arrays here.  */  p = s;  c = UTF8_GET (p, limit);  if (c == '[')    return 0;  fputs (prefix, stream);  while (s < limit)    {      c = UTF8_GET (s, limit);      if (c == '/')	fputs ("::", stream);      else	jcf_print_char (stream, c);    }  return 1;}int written_class_count = 0;/* Return name of superclass.  If LEN is not NULL, fill it with length   of name.  */static unsigned char *super_class_name (derived_jcf, len)     JCF *derived_jcf;     int *len;{  int supername_index = JPOOL_USHORT1 (derived_jcf, derived_jcf->super_class);  int supername_length = JPOOL_UTF_LENGTH (derived_jcf, supername_index);  unsigned char *supername = JPOOL_UTF_DATA (derived_jcf, supername_index);  if (len)    *len = supername_length;  return supername;}/* We keep track of all the `#include's we generate, so we can avoid   duplicates.  */struct include{  char *name;  struct include *next;};/* List of all includes.  */static struct include *all_includes = NULL;/* Generate a #include.  */static voidprint_include (out, utf8, len)     FILE *out;     unsigned char *utf8;     int len;{  struct include *incl;  if (! out)    return;  if (len == -1)    len = strlen (utf8);  for (incl = all_includes; incl; incl = incl->next)    {      /* We check the length because we might have a proper prefix.  */      if (len == (int) strlen (incl->name)	  && ! strncmp (incl->name, utf8, len))	return;    }  incl = (struct include *) malloc (sizeof (struct include));  incl->name = malloc (len + 1);  strncpy (incl->name, utf8, len);  incl->name[len] = '\0';  incl->next = all_includes;  all_includes = incl;  fputs ("#include <", out);  jcf_print_utf8 (out, utf8, len);  fputs (".h>\n", out);}/* This is used to represent part of a package or class name.  */struct namelet{  /* The text of this part of the name.  */  char *name;  /* True if this represents a class.  */  int is_class;  /* Linked list of all classes and packages inside this one.  */  struct namelet *subnamelets;  /* Pointer to next sibling.  */  struct namelet *next;};/* The special root namelet.  */static struct namelet root ={  NULL,  0,  NULL,  NULL};/* This extracts the next name segment from the full UTF-8 encoded   package or class name and links it into the tree.  It does this   recursively.  */static voidadd_namelet (name, name_limit, parent)     unsigned char *name, *name_limit;     struct namelet *parent;{  unsigned char *p;  struct namelet *n = NULL, *np;  /* We want to skip the standard namespaces that we assume the     runtime already knows about.  We only do this at the top level,     though, hence the check for `root'.  */  if (parent == &root)    {#define JAVALANG "java/lang/"#define JAVAIO "java/io/"#define JAVAUTIL "java/util/"      if ((name_limit - name >= (int) sizeof (JAVALANG) - 1	   && ! strncmp (name, JAVALANG, sizeof (JAVALANG) - 1))	  || (name_limit - name >= (int) sizeof (JAVAUTIL) - 1	      && ! strncmp (name, JAVAUTIL, sizeof (JAVAUTIL) - 1))	  || (name_limit - name >= (int) sizeof (JAVAIO) - 1	      && ! strncmp (name, JAVAIO, sizeof (JAVAIO) - 1)))	return;    }  for (p = name; p < name_limit && *p != '/' && *p != '$'; ++p)    ;  /* Search for this name beneath the PARENT node.  */  for (np = parent->subnamelets; np != NULL; np = np->next)    {      /* We check the length because we might have a proper prefix.  */      if ((int) strlen (np->name) == p - name &&	  ! strncmp (name, np->name, p - name))	{	  n = np;	  break;	}    }  if (n == NULL)    {      n = (struct namelet *) malloc (sizeof (struct namelet));      n->name = malloc (p - name + 1);      strncpy (n->name, name, p - name);      n->name[p - name] = '\0';      n->is_class = (p == name_limit || *p == '$');      n->subnamelets = NULL;      n->next = parent->subnamelets;      parent->subnamelets = n;    }  /* We recurse if there is more text, and if the trailing piece does     not represent an inner class. */  if (p < name_limit && *p != '$')    add_namelet (p + 1, name_limit, n);}/* Print a single namelet.  Destroys namelets while printing.  */static voidprint_namelet (out, name, depth)     FILE *out;     struct namelet *name;     int depth;{  int i, term = 0;  struct namelet *c;  if (name->name)    {      for (i = 0; i < depth; ++i)	fputc (' ', out);      fprintf (out, "%s %s", name->is_class ? "class" : "namespace",	       name->name);      if (name->is_class && name->subnamelets == NULL)	fputs (";\n", out);      else	{	  term = 1;	  fputs ("\n", out);	  for (i = 0; i < depth; ++i)	    fputc (' ', out);	  fputs ("{\n", out);	}    }  c = name->subnamelets;  while (c != NULL)    {      struct namelet *next = c->next;      print_namelet (out, c, depth + 2);      c = next;    }  if (name->name)    {      if (term)	{	  for (i = 0; i < depth; ++i)	    fputc (' ', out);	  fputs ("};\n", out);

⌨️ 快捷键说明

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