ccebinger / SWPSoSe14

2 stars 1 forks source link

Backend: Fully understand conditionals in Bytecode #80

Closed kretzschi closed 10 years ago

kretzschi commented 10 years ago

Also, ich weiß nun zumindest erst einmal, was die zwei Bytes hinter dem if (bzw. goto) bedeuten.

Folgendes Beispiel: [...] 8: if_icmpne 16 11: iconst_1
12: istore_3
13: goto 18 16: iconst_0
17: istore_3 [...]

Dieses erzeugt in der Class Datei folgenden Stream: A0 00 08 04 3E A7 00 05 03 3E

Wobei A0 für if_icmpne und A7 für goto steht. Die nachfolgenden zwei Bytes (also 0008 für if und 0005 für goto) sagen dir, wie viele Schritte (Bytes) du nach vorn schieben musst:

Für if_icmpne: (->00->08->04->3E->A7->00->05->03) würden wir also bei 03 bzw. iconst_0 landen.

Wir (oder nur ich) dachten ja, dass diese die Sprungadresse repräsentieren würde.

PS: Ich hoffe, ihr hattet das noch nicht rausgefunden, sonst wären die letzten Stunden sinnlos gewesen :O

Zelldon commented 10 years ago

Ah ok naja das dahinter die Bytes war mir klar aber das das die laenge ist wusst ich nicht! Das ist ja schon mal interessant zu wissen. Sehr cool :) Aber problem ist ja dann woher wissen wir wieviele schritte wir machen wollen? Weil wir muessen es ja direkt danach setzen aber wissen ja nicht was danach noch alles kommt oder ?

ccebinger commented 10 years ago

moment… habe das beispiel nicht verstanden. du gehst im bytecde nur noch auf 8: und 13: ein. was passiert mit 11: 12:

Zelldon commented 10 years ago

Die werden ausgefuehrt wenn das IF Statement nicht zutrifft ;)

EDIT Bzw bei diesem IF statment wenn die ints gleich sind

kretzschi commented 10 years ago

Man müsste das in zwei Schritten machen, erst die Bytes zählen bis zum Goto, und dann erst die eigentliche Sequenz ab dem IF schreiben ..

Zelldon commented 10 years ago

Hab denke auch noch ein gutes Beispiel:

  public static void main(String[] args) {
    Integer i = 0;
    if (!(i instanceof Integer))
      throw new IllegalArgumentException();

    int test = 0;
    test++;

  }
public class javabytecode.IfInstanceOf {
  public javabytecode.IfInstanceOf();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return        
  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       4: astore_1      
       5: aload_1       
       6: instanceof    #3                  // class java/lang/Integer
       9: ifne          20
      12: new           #4                  // class java/lang/IllegalArgumentException
      15: dup           
      16: invokespecial #5                  // Method java/lang/IllegalArgumentException."":()V
      19: athrow        
      20: iconst_0      
      21: istore_2      
      22: iinc          2, 1
      25: return        
}

Dazugehoerige If zeile:

0000210: 1a03 b800 024c 2bc1 0003 9a00 0bbb 0004  .....L+.........
0000220: 59b7 0005 bf03 3d84 0201 b100 0000 0300  Y.....=.........

9a -> ist IFNE dann 000b Schritte (also 11) 00 0b mit eingezaehlt zudem muss man von 1 anfangen zu zaehlen dann kommt man auf 03 was iconst_0 ist.

Also deine Theorie stimmt aufjedenfall Sascha, ich werde dann mal ne Methode implementieren mit der man eine If instruction erstellt die den If body mitbekomm sodass man geeignete branchbytes erstellen kann.