Reflector error or optimisation?

Posted by David_001 on Stack Overflow See other posts from Stack Overflow or by David_001
Published on 2010-06-17T07:48:35Z Indexed on 2010/06/17 7:53 UTC
Read the original article Hit count: 138

Long story short: I used reflector on the System.Security.Util.Tokenizer class, and there's loads of goto statements in there.

Here's a brief example snippet:

    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;

I essentially wanted to know how the class worked, but the number of goto's makes it impossible. Arguably something like a Tokenizer class needs to be heavily optimised, so my question is: is Reflector getting it wrong, or is goto an optimisation for this class?

© Stack Overflow or respective owner

Related posts about optimization

Related posts about .net-reflector