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

📄 codeattr.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
      emitLoad(catchVar);    emitThrow();    emitCatchEnd();    emitTryCatchEnd();  }  public void emitTryStart(boolean has_finally, Type result_type)  {    if (result_type != null && result_type.isVoid())      result_type = null;    Variable[] savedStack = null;    if (result_type != null || SP > 0)      pushScope();    if (SP > 0)      {	savedStack = new Variable[SP];	int i = 0;	while (SP > 0)	  {	    Variable var = addLocal(topType());	    emitStore(var);	    savedStack[i++] = var;	  }      }    TryState try_state = new TryState(this);    try_state.savedStack = savedStack;    if (result_type != null)      try_state.saved_result = addLocal(result_type);    if (has_finally)      try_state.finally_subr = new Label();  }  public void emitTryEnd()  {    if (try_stack.end_label == null)      {	if (try_stack.saved_result != null && reachableHere())	  emitStore(try_stack.saved_result);	try_stack.end_label = new Label();	if (reachableHere())	  {	    if (try_stack.finally_subr != null)	      emitJsr(try_stack.finally_subr);	    emitGoto(try_stack.end_label);	  }	try_stack.end_try = getLabel();      }  }  public void emitCatchStart(Variable var)  {    emitTryEnd();    SP = 0;    if (try_stack.try_type != null)      emitCatchEnd();    ClassType type = var == null ? null : (ClassType) var.getType();    try_stack.try_type = type;    addHandler(try_stack.start_try, try_stack.end_try, type);    if (var != null)      {	pushType(type);	emitStore(var);      }    else      pushType(Type.throwable_type);  }  public void emitCatchEnd()  {    if (reachableHere())      {	if (try_stack.saved_result != null)	  emitStore(try_stack.saved_result);	if (try_stack.finally_subr != null)	  emitJsr(try_stack.finally_subr);	emitGoto(try_stack.end_label);      }    try_stack.try_type = null;  }  public void emitFinallyStart()  {    emitTryEnd();    if (try_stack.try_type != null)      emitCatchEnd();    SP = 0;    try_stack.end_try = getLabel();    pushScope();    Type except_type = Type.pointer_type;    Variable except = addLocal(except_type);    emitCatchStart(null);    emitStore(except);    emitJsr(try_stack.finally_subr);    emitLoad(except);    emitThrow();        try_stack.finally_subr.define(this);    Type ret_addr_type = Type.pointer_type;    try_stack.finally_ret_addr = addLocal(ret_addr_type);    pushType(ret_addr_type);    emitStore(try_stack.finally_ret_addr);  }  public void emitFinallyEnd()  {    emitRet(try_stack.finally_ret_addr);    setUnreachable();    popScope();    try_stack.finally_subr = null;  }  public void emitTryCatchEnd()  {    if (try_stack.finally_subr != null)      emitFinallyEnd();    try_stack.end_label.define(this);    Variable[] vars = try_stack.savedStack;    if (vars != null)      {	for (int i = vars.length;  --i >= 0; )	  {	    Variable v = vars[i];	    if (v != null) {	      emitLoad(v);	    }	  }      }    if (try_stack.saved_result != null)	emitLoad(try_stack.saved_result);    if (try_stack.saved_result != null || vars != null)	popScope();    try_stack = try_stack.previous;  }  public final TryState getCurrentTry ()  {    return try_stack;  }  public final boolean isInTry()  {    // This also return true if we're in  a catch clause, but that is    // good enough for now.    return try_stack != null;  }  /** Compile a tail-call to position 0 of the current procedure.   * @param pop_args if true, copy argument registers (except this) from stack.   * @param scope Scope whose start we jump back to. */  public void emitTailCall (boolean pop_args, Scope scope)  {    if (pop_args)      {	Method meth = getMethod();	int arg_slots = ((meth.access_flags & Access.STATIC) != 0) ? 0 : 1;	for (int i = meth.arg_types.length;  --i >= 0; )	  arg_slots += meth.arg_types[i].size > 4 ? 2 : 1;	for (int i = meth.arg_types.length;  --i >= 0; )	  {	    arg_slots -= meth.arg_types[i].size > 4 ? 2 : 1;	    emitStore(locals.used [arg_slots]);	  }      }    emitGoto(scope.start);  }  public void processFixups ()  {    if (fixup_count == 0)      return;    // For each label, set it to its maximum limit, assuming all    // fixups causes the code the be expanded.  We need a prepass    // for this, since FIXUP_MOVEs can cause code to be reordered.    // Also, convert each FIXUP_MOVE_TO_END to FIXUP_MOVE.    int delta = 0;    int instruction_tail = fixup_count;    fixupAdd(CodeAttr.FIXUP_MOVE, 0, null);  loop1:   for (int i = 0;  ;  )      {	int offset = fixup_offsets[i];	int kind = offset & 15;	offset >>= 4;	Label label = fixup_labels[i];	switch (kind)	  {	  case FIXUP_TRY:	  case FIXUP_LINE_PC:	    i++;	  case FIXUP_NONE:	  case FIXUP_CASE:	  case FIXUP_DELETE3:	    break;	  case FIXUP_DEFINE:	    label.position += delta;	    break;	  case FIXUP_SWITCH:	    delta += 3;  // May need to add up to 3 padding bytes.	    break;	  case FIXUP_GOTO:	    // The first test fails in this case:  GOTO L2; L1: L2:  FIXME	    if (label.first_fixup == i + 1		&& fixupOffset(i+1) == offset + 3)	      {		// Optimize: GOTO L; L:		fixup_offsets[i] = (offset << 4) | FIXUP_DELETE3;		fixup_labels[i] = null;		delta -= 3;		break;	      }	    // ... else fall through ...	  case FIXUP_JSR:	    if (PC >= 0x8000)	      delta += 2;  // May need to convert goto->goto_w, jsr->jsr_w.	    break;	  case FIXUP_TRANSFER:	    if (PC >= 0x8000)	      delta += 5;  // May need to add a goto_w.	    break;	  case FIXUP_MOVE_TO_END:	    fixup_labels[instruction_tail] = fixup_labels[i+1];	    instruction_tail = offset;	    // ... fall through ...	  case FIXUP_MOVE:	    int cur_pc = ((i+1) >= fixup_count ? PC			  : fixupOffset(fixup_labels[i+1].first_fixup));	    fixup_offsets[i] = (cur_pc << 4) | FIXUP_MOVE;	    if (label == null)	      break loop1;	    else	      {		i = label.first_fixup;		int next_pc = fixupOffset(i);		delta = (cur_pc + delta) - next_pc;		continue;	      }	  default:	    throw new Error("unexpected fixup");	  }	i++;      }    // Next a loop to fix the position of each label, and calculate    // the exact number of code bytes.    // Number of bytes to be inserted or (if negative) removed, so far.    int new_size = PC;    // Current delta between final PC and offset in generate code array.    delta = 0;  loop2:    for (int i = 0;  i < fixup_count;  )      {	int offset = fixup_offsets[i];	int kind = offset & 15;	Label label = fixup_labels[i];	if (label != null && label.position < 0)	  throw new Error ("undefined label "+label);	while (label != null	       && kind >= FIXUP_GOTO && kind <= FIXUP_TRANSFER2	       && label.first_fixup + 1 < fixup_count	       && (fixup_offsets[label.first_fixup + 1]		   == ((fixup_offsets[label.first_fixup] & 15) | FIXUP_GOTO)))	  {	    // Optimize  JUMP L; ... L:  GOTO X	    // (where the JUMP is any GOTO or other transfer)	    // by changing the JUMP L to JUMP X.	    label = fixup_labels[label.first_fixup + 1];	    fixup_labels[i] = label;	  }	offset = offset >> 4;	switch (kind)	  {	  case FIXUP_TRY:	  case FIXUP_LINE_PC:	    i++;	  case FIXUP_NONE:	  case FIXUP_CASE:	    break;	  case FIXUP_DELETE3:	    delta -= 3;	    new_size -= 3;	    break;	  case FIXUP_DEFINE:	    label.position = offset + delta;	    break;	  case FIXUP_SWITCH:	    int padding = 3 - (offset+delta) & 3;	    delta += padding;	    new_size += padding;	    break;	  case FIXUP_GOTO:	  case FIXUP_JSR:	  case FIXUP_TRANSFER:	    int rel = label.position - (offset+delta);	    if ((short) rel == rel)	      {		fixup_offsets[i] = (offset << 4) | FIXUP_TRANSFER2;	      }	    else	      {		delta += kind == FIXUP_TRANSFER ? 5 : 2;  // need goto_w		new_size += kind == FIXUP_TRANSFER ? 5 : 2;  // need goto_w	      }	    break;	  case FIXUP_MOVE:	    if (label == null)	      break loop2;	    else	      {		i = label.first_fixup;		int next_pc = fixupOffset(i);		delta = (offset + delta) - next_pc;		continue;	      }	  default:	    throw new Error("unexpected fixup");	  }	i++;      }    byte[] new_code = new byte[new_size];    int new_pc = 0;    int next_fixup_index = 0;    int next_fixup_offset = fixupOffset(0);  loop3:    for (int old_pc = 0;  ;  )      {	if (old_pc < next_fixup_offset)	  {	  new_code[new_pc++] = code[old_pc++];	  }	else	  {	    int kind = fixup_offsets[next_fixup_index] & 15;	    Label label = fixup_labels[next_fixup_index];	    switch (kind)	      {	      case FIXUP_NONE:	      case FIXUP_DEFINE:		break;	      case FIXUP_DELETE3:		old_pc += 3;		break;	      case FIXUP_TRANSFER2:		delta = label.position - new_pc;		new_code[new_pc++] = code[old_pc];		new_code[new_pc++] = (byte) (delta >> 8);		new_code[new_pc++] = (byte) (delta & 0xFF);		old_pc += 3;		break;	      case FIXUP_GOTO:	      case FIXUP_JSR:	      case FIXUP_TRANSFER:		delta = label.position - new_pc;		byte opcode = code[old_pc];		if (kind == FIXUP_TRANSFER)		  {		    // convert: IF_xxx L to IF_NOT_xxx Lt; GOTO L; Lt:		    opcode = invert_opcode(opcode);		    new_code[new_pc++] = opcode;		    new_code[new_pc++] = 0;		    new_code[new_pc++] = 8;  // 8 byte offset to Lt.		    opcode = (byte) 200;  // goto_w		  }		else		  {		    // Change goto to goto_w; jsr to jsr_w:		    opcode = (byte) (opcode + (200-167));		  }		new_code[new_pc++] = opcode;		new_code[new_pc++] = (byte) (delta >> 24);		new_code[new_pc++] = (byte) (delta >> 16);		new_code[new_pc++] = (byte) (delta >> 8);		new_code[new_pc++] = (byte) (delta & 0xFF);		old_pc += 3;		break;	      case FIXUP_SWITCH:		int padding = 3 - new_pc & 3;		int switch_start = new_pc;		new_code[new_pc++] = code[old_pc++];		while (--padding >= 0)		  new_code[new_pc++] = 0;		while (next_fixup_index < fixup_count		       && fixupKind(next_fixup_index + 1) == FIXUP_CASE)		  {		    next_fixup_index++;		    int offset = fixupOffset(next_fixup_index);		    while (old_pc < offset)		      new_code[new_pc++] = code[old_pc++];		    delta = (fixup_labels[next_fixup_index].position			     - switch_start);		    new_code[new_pc++] = (byte) (delta >> 24);		    new_code[new_pc++] = (byte) (delta >> 16);		    new_code[new_pc++] = (byte) (delta >> 8);		    new_code[new_pc++] = (byte) (delta & 0xFF);		    old_pc += 4;		  }		break;	      case FIXUP_TRY:		addHandler(fixup_labels[next_fixup_index].position,			   fixup_labels[next_fixup_index+1].position,			   new_pc,			   fixupOffset(next_fixup_index+1));		next_fixup_index++;		break;	      case FIXUP_LINE_PC:		if (lines == null)		  lines = new LineNumbersAttr(this);		next_fixup_index++;		lines.put(fixupOffset(next_fixup_index), new_pc);		break;	      case FIXUP_MOVE:		if (label == null)		  break loop3;		else		  {		    next_fixup_index = label.first_fixup;		    old_pc = fixupOffset(next_fixup_index);		    next_fixup_offset = old_pc;		    if (label.position != new_pc)		      throw new Error("bad pc");		    continue;		  }	      default:		throw new Error("unexpected fixup");	      }	    next_fixup_index++;	    next_fixup_offset = fixupOffset(next_fixup_index);	  }      }    if (new_size != new_pc)      throw new Error("PC confusion new_pc:"+new_pc+" new_size:"+new_size);    PC = new_size;    code = new_code;    fixup_count = 0;    fixup_labels = null;    fixup_offsets = null;  }  public void assignConstants (ClassType cl)  {    super.assignConstants(cl);    if (locals != null && locals.container == null && ! locals.isEmpty())      locals.addToFrontOf(this);    processFixups();    Attribute.assignConstants(this, cl);  }  public final int getLength()  {    return 12 + getCodeLength() + 8 * exception_table_length      + Attribute.getLengthAll(this);  }  public void write (DataOutputStream dstr) throws java.io.IOException  {    dstr.writeShort (max_stack);    dstr.writeShort (max_locals);    dstr.writeInt (PC);    dstr.write (code, 0, PC);    dstr.writeShort (exception_table_length);    int count = exception_table_length;    for (int i = 0;  --count >= 0;  i += 4)      {	dstr.writeShort(exception_table[i]);	dstr.writeShort(exception_table[i+1]);	dstr.writeShort(exception_table[i+2]);	dstr.writeShort(exception_table[i+3]);      }    Attribute.writeAll(this, dstr);  }  public void print (ClassTypeWriter dst)   {    dst.print("Attribute \"");    dst.print(getName());    dst.print("

⌨️ 快捷键说明

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