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

📄 jcf-write.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
      struct jcf_block *label = gen_jcf_label (state);      define_jcf_label (label, state);      return label;    }}/* Note a line number entry for the current PC and given LINE. */static voidput_linenumber (line, state)     int line;     struct jcf_partial *state;{  struct jcf_block *label = get_jcf_label_here (state);  if (label->linenumber > 0)    {      label = gen_jcf_label (state);      define_jcf_label (label, state);    }  label->linenumber = line;  state->linenumber_count++;}/* Allocate a new jcf_handler, for a catch clause that catches exceptions   in the range (START_LABEL, END_LABEL). */static struct jcf_handler *alloc_handler (start_label, end_label, state)     struct jcf_block *start_label;     struct jcf_block *end_label;     struct jcf_partial *state;{  struct jcf_handler *handler = (struct jcf_handler *)    obstack_alloc (state->chunk_obstack, sizeof (struct jcf_handler));  handler->start_label = start_label;  handler->end_label = end_label;  handler->handler_label = get_jcf_label_here (state);  if (state->handlers == NULL)    state->handlers = handler;  else    state->last_handler->next = handler;  state->last_handler = handler;  handler->next = NULL;  state->num_handlers++;  return handler;}/* The index of jvm local variable allocated for this DECL.   This is assigned when generating .class files;   contrast DECL_LOCAL_SLOT_NUMBER which is set when *reading* a .class file.   (We don't allocate DECL_LANG_SPECIFIC for locals from Java sourc code.) */#define DECL_LOCAL_INDEX(DECL) DECL_ALIGN(DECL)struct localvar_info{  struct localvar_info *next;  tree decl;  struct jcf_block *start_label;  struct jcf_block *end_label;};#define localvar_buffer ((struct localvar_info**) state->localvars.data)#define localvar_max \  ((struct localvar_info**) state->localvars.ptr - localvar_buffer)static voidlocalvar_alloc (decl, state)     tree decl;     struct jcf_partial *state;{  struct jcf_block *start_label = get_jcf_label_here (state);  int wide = TYPE_IS_WIDE (TREE_TYPE (decl));  int index;  register struct localvar_info *info;  register struct localvar_info **ptr = localvar_buffer;  register struct localvar_info **limit    = (struct localvar_info**) state->localvars.ptr;  for (index = 0;  ptr < limit;  index++, ptr++)    {      if (ptr[0] == NULL	  && (! wide || ((ptr+1) < limit && ptr[1] == NULL)))	break;    }  if (ptr == limit)    {      buffer_grow (&state->localvars, 2 * sizeof (struct localvar_info*));      ptr = (struct localvar_info**) state->localvars.data + index;      state->localvars.ptr = (unsigned char *) (ptr + 1 + wide);    }  info = (struct localvar_info *)    obstack_alloc (state->chunk_obstack, sizeof (struct localvar_info));  ptr[0] = info;  if (wide)    ptr[1] = (struct localvar_info *)(~0);  DECL_LOCAL_INDEX (decl) = index;  info->decl = decl;  info->start_label = start_label;  if (debug_info_level > DINFO_LEVEL_TERSE      && DECL_NAME (decl) != NULL_TREE)    {      /* Generate debugging info. */      info->next = NULL;      if (state->last_lvar != NULL)	state->last_lvar->next = info;      else	state->first_lvar = info;      state->last_lvar = info;      state->lvar_count++;    }}static intlocalvar_free (decl, state)     tree decl;          struct jcf_partial *state;{  struct jcf_block *end_label = get_jcf_label_here (state);  int index = DECL_LOCAL_INDEX (decl);  register struct localvar_info **ptr = &localvar_buffer [index];  register struct localvar_info *info = *ptr;  int wide = TYPE_IS_WIDE (TREE_TYPE (decl));  info->end_label = end_label;  if (info->decl != decl)    abort ();  ptr[0] = NULL;  if (wide)    {      if (ptr[1] !=  (struct localvar_info *)(~0))	abort ();      ptr[1] = NULL;    }}#define STACK_TARGET 1#define IGNORE_TARGET 2/* Get the access flags of a class (TYPE_DECL), a method (FUNCTION_DECL), or   a field (FIELD_DECL or VAR_DECL, if static), as encoded in a .class file. */static intget_access_flags (decl)    tree decl;{  int flags = 0;  int isfield = TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL;  if (CLASS_PUBLIC (decl))  /* same as FIELD_PUBLIC and METHOD_PUBLIC */    flags |= ACC_PUBLIC;  if (CLASS_FINAL (decl))  /* same as FIELD_FINAL and METHOD_FINAL */    flags |= ACC_FINAL;  if (isfield || TREE_CODE (decl) == FUNCTION_DECL)    {      if (TREE_PROTECTED (decl))	flags |= ACC_PROTECTED;      if (TREE_PRIVATE (decl))	flags |= ACC_PRIVATE;    }  else if (TREE_CODE (decl) == TYPE_DECL)    {      if (CLASS_SUPER (decl))	flags |= ACC_SUPER;      if (CLASS_ABSTRACT (decl))	flags |= ACC_ABSTRACT;      if (CLASS_INTERFACE (decl))	flags |= ACC_INTERFACE;    }  else    fatal ("internal error - bad argument to get_access_flags");  if (TREE_CODE (decl) == FUNCTION_DECL)    {      if (METHOD_NATIVE (decl))	flags |= ACC_NATIVE;      if (METHOD_STATIC (decl))	flags |= ACC_STATIC;      if (METHOD_SYNCHRONIZED (decl))	flags |= ACC_SYNCHRONIZED;      if (METHOD_ABSTRACT (decl))	flags |= ACC_ABSTRACT;    }  if (isfield)    {      if (FIELD_STATIC (decl))	flags |= ACC_STATIC;      if (FIELD_VOLATILE (decl))	flags |= ACC_VOLATILE;      if (FIELD_TRANSIENT (decl))	flags |= ACC_TRANSIENT;    }  return flags;}/* Write the list of segments starting at CHUNKS to STREAM. */static voidwrite_chunks (stream, chunks)     FILE* stream;     struct chunk *chunks;{  for (;  chunks != NULL;  chunks = chunks->next)    fwrite (chunks->data, chunks->size, 1, stream);}/* Push a 1-word constant in the constant pool at the given INDEX.   (Caller is responsible for doing NOTE_PUSH.) */static voidpush_constant1 (index, state)     int index;     struct jcf_partial *state;{  RESERVE (3);  if (index < 256)    {      OP1 (OPCODE_ldc);      OP1 (index);    }  else    {      OP1 (OPCODE_ldc_w);      OP2 (index);    }}/* Push a 2-word constant in the constant pool at the given INDEX.   (Caller is responsible for doing NOTE_PUSH.) */static voidpush_constant2 (index, state)     int index;     struct jcf_partial *state;{  RESERVE (3);  OP1 (OPCODE_ldc2_w);  OP2 (index);}/* Push 32-bit integer constant on VM stack.   Caller is responsible for doing NOTE_PUSH. */static voidpush_int_const (i, state)     HOST_WIDE_INT i;     struct jcf_partial *state;{  RESERVE(3);  if (i >= -1 && i <= 5)    OP1(OPCODE_iconst_0 + i);  else if (i >= -128 && i < 128)    {      OP1(OPCODE_bipush);      OP1(i);    }  else if (i >= -32768 && i < 32768)    {      OP1(OPCODE_sipush);      OP2(i);    }  else    {      i = find_constant1 (&state->cpool, CONSTANT_Integer, i & 0xFFFFFFFF);      push_constant1 (i, state);    }}static intfind_constant_wide (lo, hi, state)     HOST_WIDE_INT lo, hi;     struct jcf_partial *state;{  HOST_WIDE_INT w1, w2;  lshift_double (lo, hi, -32, 64, &w1, &w2, 1);  return find_constant2 (&state->cpool, CONSTANT_Long,			 w1 & 0xFFFFFFFF, lo & 0xFFFFFFFF);}/* Find or allocate a constant pool entry for the given VALUE.   Return the index in the constant pool. */static intfind_constant_index (value, state)     tree value;     struct jcf_partial *state;{  if (TREE_CODE (value) == INTEGER_CST)    {      if (TYPE_PRECISION (TREE_TYPE (value)) <= 32)	return find_constant1 (&state->cpool, CONSTANT_Integer,			       TREE_INT_CST_LOW (value) & 0xFFFFFFFF);      else	return find_constant_wide (TREE_INT_CST_LOW (value),				   TREE_INT_CST_HIGH (value), state);    }  else if (TREE_CODE (value) == REAL_CST)    {      long words[2];      if (TYPE_PRECISION (TREE_TYPE (value)) == 32)	{	  words[0] = etarsingle (TREE_REAL_CST (value)) & 0xFFFFFFFF;	  return find_constant1 (&state->cpool, CONSTANT_Float, words[0]);	}      else	{	  etardouble (TREE_REAL_CST (value), words);	  return find_constant2 (&state->cpool, CONSTANT_Double,				 words[1-FLOAT_WORDS_BIG_ENDIAN] & 0xFFFFFFFF,				 words[FLOAT_WORDS_BIG_ENDIAN] & 0xFFFFFFFF);	}    }  else if (TREE_CODE (value) == STRING_CST)    {      return find_string_constant (&state->cpool, value);    }  else    fatal ("find_constant_index - bad type");}/* Push 64-bit long constant on VM stack.   Caller is responsible for doing NOTE_PUSH. */static voidpush_long_const (lo, hi, state)     HOST_WIDE_INT lo, hi;     struct jcf_partial *state;{  if (hi == 0 && lo >= 0 && lo <= 1)    {      RESERVE(1);      OP1(OPCODE_lconst_0 + lo);    }  else if ((hi == 0 && lo < 32768) || (hi == -1 && lo >= -32768))      {        push_int_const (lo, state);        RESERVE (1);        OP1 (OPCODE_i2l);      }  else    push_constant2 (find_constant_wide (lo, hi, state), state);}static voidfield_op (field, opcode, state)     tree field;     int opcode;     struct jcf_partial *state;{  int index = find_fieldref_index (&state->cpool, field);  RESERVE (3);  OP1 (opcode);  OP2 (index);}/* Returns an integer in the range 0 (for 'int') through 4 (for object   reference) to 7 (for 'short') which matches the pattern of how JVM   opcodes typically depend on the operand type. */static intadjust_typed_op (type, max)     tree type;     int max;{  switch (TREE_CODE (type))    {    case POINTER_TYPE:    case RECORD_TYPE:   return 4;    case BOOLEAN_TYPE:      return TYPE_PRECISION (type) == 32 || max < 5 ? 0 : 5;    case CHAR_TYPE:      return TYPE_PRECISION (type) == 32 || max < 6 ? 0 : 6;    case INTEGER_TYPE:      switch (TYPE_PRECISION (type))	{	case  8:       return max < 5 ? 0 : 5;	case 16:       return max < 7 ? 0 : 7;	case 32:       return 0;	case 64:       return 1;	}      break;    case REAL_TYPE:      switch (TYPE_PRECISION (type))	{	case 32:       return 2;	case 64:       return 3;	}      break;    default:      break;    }  abort ();}static voidmaybe_wide (opcode, index, state)     int opcode, index;     struct jcf_partial *state;{  if (index >= 256)    {      RESERVE (4);      OP1 (OPCODE_wide);      OP1 (opcode);      OP2 (index);    }  else    {      RESERVE (2);      OP1 (opcode);      OP1 (index);    }}/* Compile code to duplicate with offset, where   SIZE is the size of the stack item to duplicate (1 or 2), abd   OFFSET is where to insert the result (must be 0, 1, or 2).   (The new words get inserted at stack[SP-size-offset].) */static voidemit_dup (size, offset, state)     int size, offset;     struct jcf_partial *state;{  int kind;  if (size == 0)    return;  RESERVE(1);  if (offset == 0)    kind = size == 1 ? OPCODE_dup : OPCODE_dup2;  else if (offset == 1)    kind = size == 1 ? OPCODE_dup_x1 : OPCODE_dup2_x1;  else if (offset == 2)    kind = size == 1 ? OPCODE_dup_x2 : OPCODE_dup2_x2;  else    abort();  OP1 (kind);  NOTE_PUSH (size);}static voidemit_pop (size, state)     int size;     struct jcf_partial *state;{  RESERVE (1);  OP1 (OPCODE_pop - 1 + size);}static voidemit_iinc (var, value, state)     tree var;

⌨️ 快捷键说明

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