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

📄 codeattr.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
  { emitGotoIfCompare2(label, 157); }  public final void emitGotoIfLe(Label label)  { emitGotoIfCompare2(label, 158); }  /** Compile start of a conditional:   *   <tt>if (!(<var>x</var> opcode 0)) ...</tt>.   * The value of <var>x</var> must already have been pushed. */  public final void emitIfCompare1 (int opcode)  {    IfState new_if = new IfState(this);    if (popType().promote() != Type.int_type)      throw new Error ("non-int type to emitIfCompare1");    reserve(3);    emitTransfer (new_if.end_label, opcode);    new_if.start_stack_size = SP;  }  /** Compile start of conditional:  <tt>if (x != 0) ...</tt>.   * Also use this if you have pushed a boolean value:  if (b) ... */  public final void emitIfIntNotZero()  {    emitIfCompare1(153); // ifeq  }  /** Compile start of conditional:  <tt>if (x == 0) ...</tt>.   * Also use this if you have pushed a boolean value:  if (!b) ... */  public final void emitIfIntEqZero()  {    emitIfCompare1(154); // ifne  }  /** Compile start of conditional:  <tt>if (x <= 0)</tt>. */  public final void emitIfIntLEqZero()  {    emitIfCompare1(157); // ifgt  }  /** Compile start of a conditional:  <tt>if (!(x opcode null)) ...</tt>.   * The value of <tt>x</tt> must already have been pushed and must be of   * reference type. */  public final void emitIfRefCompare1 (int opcode)  {    IfState new_if = new IfState(this);    if (! (popType() instanceof ObjectType))      throw new Error ("non-ref type to emitIfRefCompare1");    reserve(3);    emitTransfer (new_if.end_label, opcode);    new_if.start_stack_size = SP;  }      /** Compile start of conditional:  if (x != null) */  public final void emitIfNotNull()  {    emitIfRefCompare1(198); // ifnull  }  /** Compile start of conditional:  if (x == null) */  public final void emitIfNull()  {    emitIfRefCompare1(199); // ifnonnull  }      /** Compile start of a conditional:  if (!(x OPCODE y)) ...   * The value of x and y must already have been pushed. */  public final void emitIfIntCompare(int opcode)  {    IfState new_if = new IfState(this);    popType();    popType();    reserve(3);    emitTransfer(new_if.end_label, opcode);    new_if.start_stack_size = SP;  }  /* Compile start of a conditional:  if (x < y) ... */  public final void emitIfIntLt()  {    emitIfIntCompare(162);  // if_icmpge  }  /** Compile start of a conditional:  if (x != y) ...   * The values of x and y must already have been pushed. */  public final void emitIfNEq ()  {    IfState new_if = new IfState (this);    emitGotoIfEq(new_if.end_label);    new_if.start_stack_size = SP;  }  /** Compile start of a conditional:  if (x == y) ...   * The values of x and y must already have been pushed. */  public final void emitIfEq ()  {    IfState new_if = new IfState (this);    emitGotoIfNE(new_if.end_label);    new_if.start_stack_size = SP;  }  /** Compile start of a conditional:  if (x < y) ...   * The values of x and y must already have been pushed. */  public final void emitIfLt ()  {    IfState new_if = new IfState (this);    emitGotoIfGe(new_if.end_label);    new_if.start_stack_size = SP;  }  /** Compile start of a conditional:  if (x >= y) ...   * The values of x and y must already have been pushed. */  public final void emitIfGe ()  {    IfState new_if = new IfState (this);    emitGotoIfLt(new_if.end_label);    new_if.start_stack_size = SP;  }  /** Compile start of a conditional:  if (x > y) ...   * The values of x and y must already have been pushed. */  public final void emitIfGt ()  {    IfState new_if = new IfState (this);    emitGotoIfLe(new_if.end_label);    new_if.start_stack_size = SP;  }  /** Compile start of a conditional:  if (x <= y) ...   * The values of x and y must already have been pushed. */  public final void emitIfLe ()  {    IfState new_if = new IfState (this);    emitGotoIfGt(new_if.end_label);    new_if.start_stack_size = SP;  }  /** Emit a 'ret' instruction.    * @param var the variable containing the return address */  public void emitRet (Variable var)  {    int offset = var.offset;    if (offset < 256)      {	reserve(2);	put1(169);  // ret	put1(offset);      }    else      {	reserve(4);	put1(196);  // wide	put1(169);  // ret	put2(offset);      }  }  public final void emitThen()  {    if_stack.start_stack_size = SP;  }  public final void emitIfThen ()  {    new IfState(this, null);  }  /** Compile start of else clause. */  public final void emitElse ()  {    Label else_label = if_stack.end_label;    Label end_label = new Label (this);    if_stack.end_label = end_label;    if (reachableHere ())      {	int growth = SP-if_stack.start_stack_size;	if_stack.stack_growth = growth;	if (growth > 0)	  {	    if_stack.then_stacked_types = new Type[growth];	    System.arraycopy (stack_types, if_stack.start_stack_size,			      if_stack.then_stacked_types, 0, growth);	  }	else	  if_stack.then_stacked_types = new Type[0];  // ???	emitGoto (end_label);      }    while (SP > if_stack.start_stack_size)      popType();    SP = if_stack.start_stack_size;    if (else_label != null)      else_label.define (this);    if_stack.doing_else = true;      }  /** Compile end of conditional. */  public final void emitFi ()  {    boolean make_unreachable = false;    if (! if_stack.doing_else)      { // There was no 'else' clause.	if (reachableHere ()	    && SP != if_stack.start_stack_size)	  throw new Error("at PC "+PC+" then clause grows stack with no else clause");      }    else if (if_stack.then_stacked_types != null)      {	int then_clause_stack_size	  = if_stack.start_stack_size + if_stack.stack_growth;	if (! reachableHere ())	  {	    if (if_stack.stack_growth > 0)	      System.arraycopy (if_stack.then_stacked_types, 0,				stack_types, if_stack.start_stack_size,				if_stack.stack_growth);	    SP = then_clause_stack_size;	  }	else if (SP != then_clause_stack_size)	  throw new Error("at PC "+PC+": SP at end of 'then' was " +			  then_clause_stack_size			  + " while SP at end of 'else' was " + SP);      }    else if (unreachable_here)      make_unreachable = true;    if (if_stack.end_label != null)      if_stack.end_label.define (this);    if (make_unreachable)      setUnreachable();    // Pop the if_stack.    if_stack = if_stack.previous;  }  public final void emitConvert (Type from, Type to)  {    String to_sig = to.getSignature();    String from_sig = from.getSignature();    int op = -1;    if (to_sig.length() == 1 || from_sig.length() == 1)      {	char to_sig0 = to_sig.charAt(0);	char from_sig0 = from_sig.charAt(0);	if (from_sig0 == to_sig0)	  return;	if (from.size < 4)	  from_sig0 = 'I';	if (to.size < 4)	  {	    emitConvert(from, Type.int_type);	    from_sig0 = 'I';	  }	if (from_sig0 == to_sig0)	  return;	switch (from_sig0)	  {	  case 'I':	    switch (to_sig0)	      {	        case 'B':  op = 145;  break;  // i2b	        case 'C':  op = 146;  break;  // i2c	        case 'S':  op = 147;  break;  // i2s		case 'J':  op = 133;  break;  // i2l		case 'F':  op = 134;  break;  // i2f		case 'D':  op = 135;  break;  // i2d	      }	    break;	  case 'J':	    switch (to_sig0)	      {		case 'I':  op = 136;  break;  // l2i		case 'F':  op = 137;  break;  // l2f		case 'D':  op = 138;  break;  // l2d	      }	    break;	  case 'F':	    switch (to_sig0)	      {		case 'I':  op = 139;  break;  // f2i		case 'J':  op = 140;  break;  // f2l		case 'D':  op = 141;  break;  // f2d	      }	    break;	  case 'D':	    switch (to_sig0)	      {		case 'I':  op = 142;  break;  // d2i		case 'J':  op = 143;  break;  // d2l		case 'F':  op = 144;  break;  // d2f	      }	    break;	  }      }    if (op < 0)      throw new Error ("unsupported CodeAttr.emitConvert");    reserve(1);    popType();    put1(op);    pushType(to);  }  private void emitCheckcast (Type type, int opcode)  {    reserve(3);    popType();    put1(opcode);    if (type instanceof ArrayType)      {	ArrayType atype = (ArrayType) type;	CpoolUtf8 name = getConstants().addUtf8(atype.signature);	putIndex2(getConstants().addClass(name));      }    else if (type instanceof ClassType)      {	putIndex2(getConstants().addClass((ClassType) type));      }    else      throw new Error ("unimplemented type " + type		       + " in emitCheckcast/emitInstanceof");  }   public void emitCheckcast (Type type)  {    if (type instanceof ClassType)      {	Type top = topType();	if (top instanceof ClassType	    && ((ClassType) top).isSubclass((ClassType) type))	  return;      }    emitCheckcast(type, 192);    pushType(type);  }  public void emitInstanceof (Type type)  {    emitCheckcast(type, 193);    pushType(Type.boolean_type);  }  public final void emitThrow ()  {    popType();    reserve(1);    put1 (191);  // athrow    setUnreachable();  }  public final void emitMonitorEnter ()  {    popType();    reserve(1);    put1 (194);  // monitorenter  }  public final void emitMonitorExit ()  {    popType();    reserve(1);    put1 (195);  // monitorexit  }  /** Call pending finalizer functions.   * @param limit Only call finalizers more recent than this.   */  public void doPendingFinalizers (TryState limit)  {    TryState stack = try_stack;    /* If a value is returned, it must be saved to a local variable,       to prevent a verification error because of inconsistent stack sizes.    */    boolean saveResult = ! getMethod().getReturnType().isVoid();    Variable result = null;    while (stack != limit)      {	if (stack.finally_subr != null         // there is a finally block	    && stack.finally_ret_addr == null) // 'return' is not inside it	  {	    if (saveResult && result == null)	      {		result = addLocal(topType());		emitStore(result);	      }	    emitJsr(stack.finally_subr);	  }	stack = stack.previous;      }    if (result != null)      emitLoad(result);    // We'd like to do freeLocal on the result Variable, but then we risk    // it being re-used in a finalizer, which would trash its value.  We    // don't have any convenient way to to do that (the pending Scope    // mechanism is over-kill), we for now we just leak the Variable.  }  /**   * Compile a method return.   * If inside a 'catch' clause, first call 'finally' clauses.   * The return value (unless the return type is void) must be on the stack,   * and have the correct type.   */  public final void emitReturn ()  {    doPendingFinalizers(null);    if (getMethod().getReturnType().size == 0)      {	reserve(1);	put1(177); // return      }    else      emitTypedOp (172, popType().promote());    setUnreachable();  }  /** Add an exception handler. */  public void addHandler (int start_pc, int end_pc,			  int handler_pc, int catch_type)  {    int index = 4 * exception_table_length;    if (exception_table == null)      {	exception_table = new short[20];      }    else if (exception_table.length <= index)      {	short[] new_table = new short[2 * exception_table.length];	System.arraycopy(exception_table, 0, new_table, 0, index);	exception_table = new_table;      }    exception_table[index++] = (short) start_pc;    exception_table[index++] = (short) end_pc;    exception_table[index++] = (short) handler_pc;    exception_table[index++] = (short) catch_type;    exception_table_length++;  }  /** Add an exception handler. */  public void addHandler (Label start_try, Label end_try,			  ClassType catch_type)  {    ConstantPool constants = getConstants();    int catch_type_index;    if (catch_type == null)      catch_type_index = 0;    else      catch_type_index = constants.addClass(catch_type).index;    fixupAdd(FIXUP_TRY, start_try);    fixupAdd(FIXUP_CATCH, catch_type_index, end_try);  }  /** Beginning of code that has a cleanup handler.   * This is similar to a try-finally, but the cleanup is only   * done in the case of an exception.  Alternatively, the try clause   * has to manually do the cleanup with code duplication.   * Equivalent to: <code>try <var>body</var> catch (Throwable ex) { <var>cleanup</var>; throw ex; }</code>   * Call <code>emitWithCleanupStart</code> before the <code><var>body</var></code>.   */  public void emitWithCleanupStart ()  {    new TryState(this);  }  /** Called after a <code><var>body</var></code> that has a <code><var>cleanup</var></code> clause.   * Followed by the <code><var>cleanup</var></code> code.   */  public void emitWithCleanupCatch (Variable catchVar)  {    emitTryEnd();    try_stack.saved_result = catchVar;    int save_SP = SP;    emitCatchStart(catchVar);    // Don't trash stack_types, and set things up so the SP has the    // right value after emitWithCleanupDone (assuming the handler leaves    // the stack empty after the throw).  The + 1 for the incoming exception.    SP = save_SP + 1;  }  /** Called after generating a <code><var>cleanup</var></code> handler. */  public void emitWithCleanupDone ()  {    Variable catchVar = try_stack.saved_result;    try_stack.saved_result = null;    if (catchVar != null)

⌨️ 快捷键说明

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