2010-06-17 10 views
2

Longue histoire courte: J'ai utilisé réflecteur sur la classe System.Security.Util.Tokenizer, et il y a des tas d'instructions goto là-dedans.Erreur de réflecteur ou optimisation?

Voici un bref exemple extrait:

Label_0026: 
     if (this._inSavedCharacter != -1) 
     { 
      num = this._inSavedCharacter; 
      this._inSavedCharacter = -1; 
     } 
     else 
     { 
      switch (this._inTokenSource) 
      { 
       case TokenSource.UnicodeByteArray: 
        if ((this._inIndex + 1) < this._inSize) 
        { 
         break; 
        } 
        stream.AddToken(-1); 
        return; 

       case TokenSource.UTF8ByteArray: 
        if (this._inIndex < this._inSize) 
        { 
         goto Label_00CF; 
        } 
        stream.AddToken(-1); 
        return; 

       case TokenSource.ASCIIByteArray: 
        if (this._inIndex < this._inSize) 
        { 
         goto Label_023C; 
        } 
        stream.AddToken(-1); 
        return; 

       case TokenSource.CharArray: 
        if (this._inIndex < this._inSize) 
        { 
         goto Label_0272; 
        } 
        stream.AddToken(-1); 
        return; 

       case TokenSource.String: 
        if (this._inIndex < this._inSize) 
        { 
         goto Label_02A8; 
        } 
        stream.AddToken(-1); 
        return; 

       case TokenSource.NestedStrings: 
        if (this._inNestedSize == 0) 
        { 
         goto Label_030D; 
        } 
        if (this._inNestedIndex >= this._inNestedSize) 
        { 
         goto Label_0306; 
        } 
        num = this._inNestedString[this._inNestedIndex++]; 
        goto Label_0402; 

       default: 
        num = this._inTokenReader.Read(); 
        if (num == -1) 
        { 
         stream.AddToken(-1); 
         return; 
        } 
        goto Label_0402; 
      } 
      num = (this._inBytes[this._inIndex + 1] << 8) + this._inBytes[this._inIndex]; 
      this._inIndex += 2; 
     } 
     goto Label_0402; 
    Label_00CF: 
     num = this._inBytes[this._inIndex++]; 
     if ((num & 0x80) != 0) 
     { 
      switch (((num & 240) >> 4)) 
      { 
       case 8: 
       case 9: 
       case 10: 
       case 11: 
        throw new XmlSyntaxException(this.LineNo); 

       case 12: 
       case 13: 
        num &= 0x1f; 
        num3 = 2; 
        break; 

       case 14: 
        num &= 15; 
        num3 = 3; 
        break; 

       case 15: 
        throw new XmlSyntaxException(this.LineNo); 
      } 
      if (this._inIndex >= this._inSize) 
      { 
       throw new XmlSyntaxException(this.LineNo, Environment.GetResourceString("XMLSyntax_UnexpectedEndOfFile")); 
      } 
      byte num2 = this._inBytes[this._inIndex++]; 
      if ((num2 & 0xc0) != 0x80) 
      { 
       throw new XmlSyntaxException(this.LineNo); 
      } 
      num = (num << 6) | (num2 & 0x3f); 
      if (num3 != 2) 
      { 
       if (this._inIndex >= this._inSize) 
       { 
        throw new XmlSyntaxException(this.LineNo, Environment.GetResourceString("XMLSyntax_UnexpectedEndOfFile")); 
       } 
       num2 = this._inBytes[this._inIndex++]; 
       if ((num2 & 0xc0) != 0x80) 
       { 
        throw new XmlSyntaxException(this.LineNo); 
       } 
       num = (num << 6) | (num2 & 0x3f); 
      } 
     } 
     goto Label_0402; 
    Label_023C: 
     num = this._inBytes[this._inIndex++]; 
     goto Label_0402; 
    Label_0272: 
     num = this._inChars[this._inIndex++]; 
     goto Label_0402; 
    Label_02A8: 
     num = this._inString[this._inIndex++]; 
     goto Label_0402; 
    Label_0306: 
     this._inNestedSize = 0; 

Je voulais essentiellement savoir comment la classe a travaillé, mais le nombre de GOTO rend impossible. Peut-être que quelque chose comme une classe Tokenizer doit être fortement optimisé, donc ma question est: est-ce que Reflector se trompe, ou goto une optimisation pour cette classe?

Répondre

0

Reflector est incapable de déterminer la structure de la boucle d'origine.

En tant que point d'intérêt (et pourquoi cela est parfois le cas) il n'y a pas IL opcodes pour des choses comme while et for boucles et break et continue. L'équivalent IL est juste if tests combinés avec des sauts (c'est-à-dire gotos).

+0

J'ai soupçonné une erreur de réflecteur - j'espère que Redgate améliorera le moteur sous-jacent ... –