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

📄 constants.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
字号:
/* Handle the constant pool of the Java(TM) Virtual Machine.   Copyright (C) 1997 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. Java and all Java-based marks are trademarks or registered trademarksof Sun Microsystems, Inc. in the United States and other countries.The Free Software Foundation is independent of Sun Microsystems, Inc.  */#include "config.h"#include "system.h"#include "jcf.h"#include "tree.h"#include "java-tree.h"#include "toplev.h"extern struct obstack permanent_obstack;static void set_constant_entry PROTO ((CPool *, int, int, jword));static int find_class_or_string_constant PROTO ((CPool *, int, tree));static int find_name_and_type_constant PROTO ((CPool *, tree, tree));static tree get_tag_node PROTO ((int));static tree build_constant_data_ref PROTO ((void));/* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */static voidset_constant_entry (cpool, index, tag, value)     CPool *cpool;     int index;     int tag;     jword value;{  if (cpool->data == NULL)    {      cpool->capacity = 100;      cpool->tags = (uint8*) xmalloc (sizeof(uint8) * cpool->capacity);      cpool->data = (jword*) xmalloc (sizeof(jword) * cpool->capacity);      cpool->count = 1;    }  if (index >= cpool->capacity)    {      cpool->capacity *= 2;      if (index >= cpool->capacity)	cpool->capacity = index + 10;      cpool->tags = (uint8*) xrealloc (cpool->tags,				       sizeof(uint8) * cpool->capacity);      cpool->data = (jword*) xrealloc (cpool->data,				       sizeof(jword) * cpool->capacity);    }  if (index >= cpool->count)    cpool->count = index + 1;  cpool->tags[index] = tag;  cpool->data[index] = value;}/* Find (or create) a constant pool entry matching TAG and VALUE. */intfind_constant1 (cpool, tag, value)     CPool *cpool;     int tag;     jword value;{  int i;  for (i = cpool->count;  --i > 0; )    {      if (cpool->tags[i] == tag && cpool->data[i] == value)	return i;    }  i = cpool->count == 0 ? 1 : cpool->count;  set_constant_entry (cpool, i, tag, value);  return i;}/* Find a double-word constant pool entry matching TAG and WORD1/WORD2. */intfind_constant2 (cpool, tag, word1, word2)     CPool *cpool;     int tag;     jword word1, word2;{  int i;  for (i = cpool->count - 1;  --i > 0; )    {      if (cpool->tags[i] == tag	  && cpool->data[i] == word1	  && cpool->data[i+1] == word2)	return i;    }  i = cpool->count == 0 ? 1 : cpool->count;  set_constant_entry (cpool, i, tag, word1);  set_constant_entry (cpool, i+1, 0, word2);  return i;}intfind_utf8_constant (cpool, name)     CPool *cpool;     tree name;{  if (name == NULL_TREE)    return 0;  return find_constant1 (cpool, CONSTANT_Utf8, (jword) name);}static intfind_class_or_string_constant (cpool, tag, name)     CPool *cpool;     int tag;     tree name;{  int j = find_utf8_constant (cpool, name);  int i;  for (i = cpool->count;  --i > 0; )    {      if (cpool->tags[i] == tag && cpool->data[i] == (jword) j)	return i;    }  i = cpool->count;  set_constant_entry (cpool, i, tag, (jword) j);  return i;}intfind_class_constant (cpool, type)     CPool *cpool;     tree type;{  return find_class_or_string_constant (cpool, CONSTANT_Class,					build_internal_class_name (type));}/* Allocate a CONSTANT_string entry given a STRING_CST. */intfind_string_constant (cpool, string)     CPool *cpool;     tree string;{  string = get_identifier (TREE_STRING_POINTER (string));  return find_class_or_string_constant (cpool, CONSTANT_String, string);}/* Find (or create) a CONSTANT_NameAndType matching NAME and TYPE.   Return its index in the constant pool CPOOL. */static intfind_name_and_type_constant (cpool, name, type)     CPool *cpool;     tree name;     tree type;{  int name_index = find_utf8_constant (cpool, name);  int type_index = find_utf8_constant (cpool, build_java_signature (type));  return find_constant1 (cpool, CONSTANT_NameAndType,			 (name_index << 16) | type_index);}/* Find (or create) a CONSTANT_Fieldref for DECL (a FIELD_DECL or VAR_DECL).   Return its index in the constant pool CPOOL. */intfind_fieldref_index (cpool, decl)     CPool *cpool;     tree decl;{  int class_index = find_class_constant (cpool, DECL_CONTEXT (decl));  int name_type_index    = find_name_and_type_constant (cpool, DECL_NAME (decl), TREE_TYPE (decl));  return find_constant1 (cpool, CONSTANT_Fieldref,			 (class_index << 16) | name_type_index);}/* Find (or create) a CONSTANT_Methodref for DECL (a FUNCTION_DECL).   Return its index in the constant pool CPOOL. */intfind_methodref_index (cpool, decl)     CPool *cpool;     tree decl;{  tree mclass = DECL_CONTEXT (decl);  int class_index = find_class_constant (cpool, mclass);  tree name = DECL_CONSTRUCTOR_P (decl) ? init_identifier_node    : DECL_NAME (decl);  int name_type_index    = find_name_and_type_constant (cpool, name, TREE_TYPE (decl));  return find_constant1 (cpool,			 CLASS_INTERFACE (TYPE_NAME (mclass))			 ? CONSTANT_InterfaceMethodref			 : CONSTANT_Methodref,			 (class_index << 16) | name_type_index);}#define PUT1(X)  (*ptr++ = (X))#define PUT2(X)  (PUT1((X) >> 8), PUT1(X))#define PUT4(X)  (PUT2((X) >> 16), PUT2(X))#define PUTN(P, N)  (bcopy(P, ptr, N), ptr += (N))/* Give the number of bytes needed in a .class file for the CPOOL   constant pool.  Includes the 2-byte constant_pool_count. */intcount_constant_pool_bytes (cpool)     CPool *cpool;{  int size = 2;  int i = 1;  for ( ;  i < cpool->count;  i++)    {      size++;      switch (cpool->tags[i])	{	case CONSTANT_NameAndType:	case CONSTANT_Fieldref:	case CONSTANT_Methodref:	case CONSTANT_InterfaceMethodref:	case CONSTANT_Float:	case CONSTANT_Integer:	  size += 4;	  break;	case CONSTANT_Class:	case CONSTANT_String:	  size += 2;	  break;	case CONSTANT_Long:	case CONSTANT_Double:	  size += 8;	  i++;	  break;	case CONSTANT_Utf8:	  {	    tree t = (tree) cpool->data[i];	    int len = IDENTIFIER_LENGTH (t);	    size += len + 2;	  }	  break;	default:	  /* Second word of CONSTANT_Long and  CONSTANT_Double. */	  size--;	}    }  return size;}/* Write the constant pool CPOOL into BUFFER.   The length of BUFFER is LENGTH, which must match the needed length. */voidwrite_constant_pool (cpool, buffer, length)     CPool *cpool;     unsigned char* buffer;     int length;{  unsigned char* ptr = buffer;  int i = 1;  jword *datap = &cpool->data[1];  PUT2 (cpool->count);  for ( ;  i < cpool->count;  i++, datap++)    {      int tag = cpool->tags[i];      PUT1 (tag);      switch (tag)	{	case CONSTANT_NameAndType:	case CONSTANT_Fieldref:	case CONSTANT_Methodref:	case CONSTANT_InterfaceMethodref:	case CONSTANT_Float:	case CONSTANT_Integer:	  PUT4 (*datap);	  break;	case CONSTANT_Class:	case CONSTANT_String:	  PUT2 (*datap);	  break;	  break;	case CONSTANT_Long:	case CONSTANT_Double:	  PUT4(*datap);	  i++;	  datap++;	  PUT4 (*datap);	  break;	case CONSTANT_Utf8:	  {	    tree t = (tree) *datap;	    int len = IDENTIFIER_LENGTH (t);	    PUT2 (len);	    PUTN (IDENTIFIER_POINTER (t), len);	  }	  break;	}    }  if (ptr != buffer + length)    fatal("internal error - incorrect constant pool");}CPool *outgoing_cpool;/* If non-NULL, an ADDR_EXPR referencing a VAR_DECL containing   the constant data array for the current class. */tree current_constant_pool_data_ref;/* A Cache for build_int_2 (CONSTANT_XXX, 0). */static tree tag_nodes[13];static treeget_tag_node (tag)     int tag;{  if (tag_nodes[tag] == NULL_TREE)    {      push_obstacks (&permanent_obstack, &permanent_obstack);      tag_nodes[tag] = build_int_2 (tag, 0);      pop_obstacks ();    }  return tag_nodes[tag];}/* Look for a constant pool entry that matches TAG and NAME.   Creates a new entry if not found.   TAG is one of CONSTANT_Utf8, CONSTANT_String or CONSTANT_Class.   NAME is an IDENTIFIER_NODE naming the Utf8 constant, string, or class.   Returns the index of the entry. */intalloc_name_constant (tag, name)     int tag;     tree name;{  return find_constant1 (outgoing_cpool, tag, (jword) name);}/* Build an identifier for the internal name of reference type TYPE. */treebuild_internal_class_name (type)     tree type;{  tree name;  if (TYPE_ARRAY_P (type))    name = build_java_signature (type);  else    {      name = TYPE_NAME (type);      if (TREE_CODE (name) != IDENTIFIER_NODE)	name = DECL_NAME (name);      name = identifier_subst (name, "", '.', '/', "");    }  return name;}/* Look for a CONSTANT_Class entry for CLAS, creating a new one if needed. */intalloc_class_constant (clas)     tree clas;{  tree class_name = build_internal_class_name (clas);    return alloc_name_constant (CONSTANT_Class,			      (unmangle_classname 			       (IDENTIFIER_POINTER(class_name),				IDENTIFIER_LENGTH(class_name))));}/* Return a reference to the data array of the current constant pool. */static treebuild_constant_data_ref (){  if (current_constant_pool_data_ref == NULL_TREE)    {      tree decl;      tree decl_name = mangled_classname ("_CD_", current_class);      push_obstacks (&permanent_obstack, &permanent_obstack);      decl = build_decl (VAR_DECL, decl_name,			 build_array_type (ptr_type_node,					   one_elt_array_domain_type));      TREE_STATIC (decl) = 1;      make_decl_rtl (decl, NULL, 1);      pop_obstacks ();      current_constant_pool_data_ref	= build1 (ADDR_EXPR, ptr_type_node, decl);    }  return current_constant_pool_data_ref;}/* Get the pointer value at the INDEX'th element of the constant pool. */treebuild_ref_from_constant_pool (index)     int index;{  tree t = build_constant_data_ref ();  index *= int_size_in_bytes (ptr_type_node);  t = fold (build (PLUS_EXPR, ptr_type_node,                              t, build_int_2 (index, 0)));  return build1 (INDIRECT_REF, ptr_type_node, t);}/* Build an initializer for the constants field of the current constal pool.   Should only be called at top-level, since it may emit declarations. */treebuild_constants_constructor (){  tree tags_value, data_value;  tree cons;  tree tags_list = NULL_TREE;  tree data_list = NULL_TREE;  int i;  for (i = outgoing_cpool->count;  --i > 0; )    {      tags_list	= tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),		     tags_list);      data_list	= tree_cons (NULL_TREE, build_utf8_ref ((tree)outgoing_cpool->data[i]),		     data_list);    }  if (outgoing_cpool->count > 0)    {      tree index_type;      tree data_decl, tags_decl, tags_type;      tree max_index = build_int_2 (outgoing_cpool->count - 1, 0);      TREE_TYPE (max_index) = sizetype;      index_type = build_index_type (max_index);      /* Add dummy 0'th element of constant pool. */      tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);      data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);        data_decl = TREE_OPERAND (build_constant_data_ref (), 0);      TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type),       DECL_INITIAL (data_decl) = build (CONSTRUCTOR, TREE_TYPE (data_decl),					NULL_TREE, data_list);      DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));      rest_of_decl_compilation (data_decl, (char*) 0, 1, 0);      data_value = build_address_of (data_decl);      tags_type = build_array_type (unsigned_byte_type_node, index_type);      tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_", 							   current_class),			      tags_type);      TREE_STATIC (tags_decl) = 1;      DECL_INITIAL (tags_decl) = build (CONSTRUCTOR, tags_type,					NULL_TREE, tags_list);      rest_of_decl_compilation (tags_decl, (char*) 0, 1, 0);      tags_value = build_address_of (tags_decl);    }  else    {      data_value = null_pointer_node;      tags_value = null_pointer_node;    }  START_RECORD_CONSTRUCTOR (cons, constants_type_node);  PUSH_FIELD_VALUE (cons, "size", build_int_2 (outgoing_cpool->count, 0));  PUSH_FIELD_VALUE (cons, "tags", tags_value);  PUSH_FIELD_VALUE (cons, "data", data_value);  FINISH_RECORD_CONSTRUCTOR (cons);  return cons;}

⌨️ 快捷键说明

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