User:Pedro Oval/Mono code memory usage/CIL

From Second Life Wiki
Jump to navigation Jump to search

Here's the CIL code generated by the script below, which gives some insight of what's happening under the hood.

Compilation was done using the viewer's built-in compiler as suggested by User:Becky Pippen/LSL Performance. Assembly was done using ilasm from the Mono suite.

Script that gets compiled:

integer i;
u(){}

default
{
    state_entry()
    {
        integer x;
        integer y = 0;
        integer z;
        float f;
        float g;
        vector v;
        list a;

        ;;;;;;;;;{{{{{{{{}}}}}}}}
        return;
        x;
        (x);
        (integer)x;
        (float)x;
        f;
        (float)f;
        (integer)f;
        v;
        v.z;
        -x;
        ~x;
        !x;
        --x;
        ++x;
        x--;
        x++;
        x=y;
        x==y;
        x=y=z;
        f=x;
        f=(float)x;
        x!=y;
        x+y;
        x-y;
        x+-y;
        x*y;
        x/y;
        x%y;
        x&y;
        x&&y;
        x|y;
        x||y;
        x^y;
        x<<y;
        x>>y;
        x<y;
        x>y;
        x<=y;
        x>=y;
        x+=y;
        x-=y;
        x+=-y;
        x*=y;
        x/=y;
        x%=y;
        if (x) ;
        if (x) ; else ;
        0;
        x^x;
        1;
        -1;
        0xffffffff;
        ALL_SIDES;
        x|~x;
        x+1;
        -~x;
        x-1;
        x+-1;
        ~-x;
        x*y+y-1;
        (x+1)*y-1;
        ~(~x*y)
        while (x) ;
        do ; while (x);
        for (;x;) ;
        @label; if (x) jump label;
        0.0;
        f=0.0;
        f=0;
        <0.0, 0.0, 0.0>;
        ZERO_VECTOR;
        <0, 0, 0>;
        <-1.0, -1.0, 0.0>;
        TOUCH_INVALID_TEXCOORD;
        <-1, -1, 0>;
        <0xffffffff, 0xffffffff, 0>;
        v+v;
        v-v;
        v*v;
        v%v;
        [];
        a=[];
        a+[x];
        a+x;
        [x]+a;
        x+a;
        [x];
        []+x;
        (list)x;
        [x,y];
        []+x+y;
        (string)a;
        i;
        u();
    }
}

Compiled and annotated result:

          .assembly extern mscorlib {.ver 1:0:5000:0}
          .assembly extern LslLibrary {.ver 0:1:0:0}
          .assembly extern LslUserScript {.ver 0:1:0:0}
          .assembly extern ScriptTypes {.ver 0:1:0:0}
          .assembly 'LSL_y' {.ver 0:0:0:0}
          .class public auto ansi serializable beforefieldinit LSL_y extends [LslUserScript]LindenLab.SecondLife.LslUserScript
          {
              .field public int32 'i'
              .method public hidebysig  specialname  rtspecialname instance default void .ctor ()  cil managed
              {
                  .maxstack 500

                  // Globals initialization

                  // integer i;
02                ldarg.0
16                ldc.i4.0
7D 01 00 00 04    stfld int32 LSL_y::'i'

02                ldarg.0
28 01 00 00 0A    call instance void [LslUserScript]LindenLab.SecondLife.LslUserScript::.ctor()
2A                ret
              }
              .method public hidebysig instance default void 'gu'() cil managed
              {
                  .maxstack 500
2A                ret
              }


              .method public hidebysig instance default void edefaultstate_entry() cil managed
              {
                  .maxstack 500
                  .locals init (int32, int32, int32, float32, float32, class [ScriptTypes]LindenLab.SecondLife.Vector, class [mscorlib]System.Collections.ArrayList)
                  // integer x;
16                ldc.i4.0
13 00             stloc.s 0

                  // integer y = 0;
20 00 00 00 00    ldc.i4 0
13 01             stloc.s 1

                  // integer z;
16                ldc.i4.0
13 02             stloc.s 2

                  // float f;
23 00 00 00 00    ldc.r8 0
00 00 00 00
13 03             stloc.s 3

                  // float g;
23 00 00 00 00    ldc.r8 0
00 00 00 00
13 04             stloc.s 4

                  // vector v;
23 00 00 00 00    ldc.r8 0
00 00 00 00
23 00 00 00 00    ldc.r8 0
00 00 00 00
23 00 00 00 00    ldc.r8 0
00 00 00 00
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
13 05             stloc.s 5

                  // list a;
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
13 06             stloc.s 6

                  // ;;; {{{ }}} generate no code

                  // return;
2A                ret

                  // x;
11 00             ldloc.s 0
26                pop

                  // (x);
11 00             ldloc.s 0
26                pop

                  // (integer)x;
11 00             ldloc.s 0
26                pop

                  // (float)x;
11 00             ldloc.s 0
6C                conv.r8
26                pop

                  // f;
11 03             ldloc.s 3
26                pop

                  // (float)f;
11 03             ldloc.s 3
26                pop

                  // (integer)f;
11 03             ldloc.s 3
28 04 00 00 0A    call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)
26                pop

                  // v;
11 05             ldloc.s 5
26                pop

                  // v.z;
12 05             ldloca.s 5
78 05 00 00 0A    ldfld float32 class [ScriptTypes]LindenLab.SecondLife.Vector::z
26                pop

                  // -x;
11 00             ldloc.s 0
65                neg
26                pop

                  // ~x;
11 00             ldloc.s 0
66                not
26                pop

                  // !x;
11 00             ldloc.s 0
16                ldc.i4.0
FE 01             ceq
26                pop

                  // --x;
11 00             ldloc.s 0
17                ldc.i4.1
59                sub
25                dup
13 00             stloc.s 0
26                pop

                  // ++x;
11 00             ldloc.s 0
17                ldc.i4.1
58                add
25                dup
13 00             stloc.s 0
26                pop

                  // x--;
11 00             ldloc.s 0
11 00             ldloc.s 0
17                ldc.i4.1
59                sub
25                dup
13 00             stloc.s 0
26                pop
26                pop

                  // x++;
11 00             ldloc.s 0
11 00             ldloc.s 0
17                ldc.i4.1
58                add
25                dup
13 00             stloc.s 0
26                pop
26                pop

                  // x = y;
11 01             ldloc.s 1
25                dup
13 00             stloc.s 0
26                pop

                  // x == y;
11 01             ldloc.s 1
11 00             ldloc.s 0
FE 01             ceq
26                pop

                  // x = y = z;
11 02             ldloc.s 2
25                dup
13 01             stloc.s 1
25                dup
13 00             stloc.s 0
26                pop

                  // f = x;
11 00             ldloc.s 0
6C                conv.r8
25                dup
13 03             stloc.s 3
26                pop

                  // f = (float)x;
11 00             ldloc.s 0
6C                conv.r8
25                dup
13 03             stloc.s 3
26                pop

                  // x != y; implemented as: !(x==y)
11 01             ldloc.s 1  // this part is x == y
11 00             ldloc.s 0
FE 01             ceq
16                ldc.i4.0   // this part is 'not'
FE 01             ceq
26                pop

                  // x + y;
11 01             ldloc.s 1
11 00             ldloc.s 0
58                add
26                pop

                  // x - y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 06 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
26                pop

                  // x + -y;
11 01             ldloc.s 1
65                neg
11 00             ldloc.s 0
58                add
26                pop

                  // x * y;
11 01             ldloc.s 1
11 00             ldloc.s 0
5A                mul
26                pop

                  // x / y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 07 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(int32, int32)
26                pop

                  // x % y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 08 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)
26                pop

                  // x & y;
11 01             ldloc.s 1
11 00             ldloc.s 0
5F                and
26                pop

                  // x && y; implemented as: !(!x | !y)
11 01             ldloc.s 1    // !x
16                ldc.i4.0
FE 01             ceq
11 00             ldloc.s 0    // !y
16                ldc.i4.0
FE 01             ceq
60                or           // !x | !y
16                ldc.i4.0     // !(!x | !y)
FE 01             ceq
26                pop

                  // x | y;
11 01             ldloc.s 1
11 00             ldloc.s 0
60                or
26                pop

                  // x || y; implemented as: !!(x | y)
11 01             ldloc.s 1    // x | y
11 00             ldloc.s 0
60                or
16                ldc.i4.0     // !(x | y)
FE 01             ceq
16                ldc.i4.0     // !!(x | y)
FE 01             ceq
26                pop

                  // x ^ y;
11 01             ldloc.s 1
11 00             ldloc.s 0
61                xor
26                pop

                  // x << y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 09 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftLeft(int32, int32)
26                pop

                  // x >> y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 0A 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftRight(int32, int32)
26                pop

                  // x < y; implemented as: y > x
11 01             ldloc.s 1
11 00             ldloc.s 0
FE 02             cgt
26                pop

                  // x > y; implemented as: y < x;
11 01             ldloc.s 1
11 00             ldloc.s 0
FE 04             clt
26                pop

                  // x <= y; implemented as: !(y < x)
11 01             ldloc.s 1
11 00             ldloc.s 0
FE 04             clt
16                ldc.i4.0
FE 01             ceq
26                pop

                  // x >= y; implemented as: !(y > x)
11 01             ldloc.s 1
11 00             ldloc.s 0
FE 02             cgt
16                ldc.i4.0
FE 01             ceq
26                pop

                  // x += y;
11 01             ldloc.s 1
11 00             ldloc.s 0
58                add
25                dup
13 00             stloc.s 0
26                pop

                  // x -= y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 06 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
25                dup
13 00             stloc.s 0
26                pop

                  // x += -y;
11 01             ldloc.s 1
65                neg
11 00             ldloc.s 0
58                add
25                dup
13 00             stloc.s 0
26                pop

                  // x *= y;
11 01             ldloc.s 1
11 00             ldloc.s 0
5A                mul
25                dup
13 00             stloc.s 0
26                pop

                  // x /= y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 07 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Divide(int32, int32)
25                dup
13 00             stloc.s 0
26                pop

                  // x %= y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 08 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)
25                dup
13 00             stloc.s 0
26                pop

                  // if (x) ;
11 00             ldloc.s 0
39 00 00 00 00    brfalse LabelTempJump0
                  // THEN branch code goes here
              LabelTempJump0:

                  // if (x) ; else ;
11 00             ldloc.s 0
39 05 00 00 00    brfalse LabelTempJump1
                  // THEN branch code would go here
38 00 00 00 00    br LabelTempJump2
                  // ELSE branch code would go here
              LabelTempJump1:
              LabelTempJump2:

                  // 0;
20 00 00 00 00    ldc.i4 0
26                pop

                  // x ^ x;
11 00             ldloc.s 0
11 00             ldloc.s 0
61                xor
26                pop

                  // 1;
20 01 00 00 00    ldc.i4 1
26                pop

                  // -1; note the negative sign takes code memory
20 01 00 00 00    ldc.i4 1
65                neg
26                pop

                  // 0xffffffff; note it equals -1 without the sign taking memory
20 FF FF FF FF    ldc.i4 -1
26                pop

                  // ALL_SIDES; ditto
20 FF FF FF FF    ldc.i4 -1
26                pop

                  // x | ~x;
11 00             ldloc.s 0
66                not
11 00             ldloc.s 0
60                or
26                pop

                  // x + 1;
20 01 00 00 00    ldc.i4 1
11 00             ldloc.s 0
58                add
26                pop

                  // -~x;
11 00             ldloc.s 0
66                not
65                neg
26                pop

                  // x - 1;
20 01 00 00 00    ldc.i4 1
11 00             ldloc.s 0
28 06 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
26                pop

                  // x + -1;
20 01 00 00 00    ldc.i4 1
65                neg
11 00             ldloc.s 0
58                add
26                pop

                  // ~-x;
11 00             ldloc.s 0
65                neg
66                not
26                pop

                  // x*y + y - 1;
20 01 00 00 00    ldc.i4 1
11 01             ldloc.s 1
11 01             ldloc.s 1
11 00             ldloc.s 0
5A                mul
58                add
28 06 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
26                pop

                  // (x + 1)*y - 1;
20 01 00 00 00    ldc.i4 1
11 01             ldloc.s 1
20 01 00 00 00    ldc.i4 1
11 00             ldloc.s 0
58                add
5A                mul
28 06 00 00 0A    call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Subtract(int32, int32)
26                pop

                  // ~(~x*y);
11 01             ldloc.s 1
11 00             ldloc.s 0
66                not
5A                mul
66                not
26                pop

                  // while (x) ;
              LabelTempJump3:
11 00             ldloc.s 0
39 05 00 00 00    brfalse LabelTempJump4
                  // Looped code would go here
38 F4 FF FF FF    br LabelTempJump3
              LabelTempJump4:

                  // do ; while (x);
              LabelTempJump5:
                  // Looped code would go here
11 00             ldloc.s 0
3A F9 FF FF FF    brtrue LabelTempJump5

                  // for (; x; ) ;
              LabelTempJump6:
11 00             ldloc.s 0
39 05 00 00 00    brfalse LabelTempJump7
                  // Looped code would go here
38 F4 FF FF FF    br LabelTempJump6
              LabelTempJump7:

                  // @label; if (x) jump label;
              'label':
                  // Looped code would go here
11 00             ldloc.s 0
39 05 00 00 00    brfalse LabelTempJump8
38 F4 FF FF FF    br 'label'
              LabelTempJump8:

                  // 0.0;
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
26                pop

                  // f = 0.0;
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
25                dup
13 03             stloc.s 3
26                pop

                  // f = 0;
20 00 00 00 00    ldc.i4 0
6C                conv.r8
25                dup
13 03             stloc.s 3
26                pop

                  // <0.0, 0.0, 0.0>;
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
26                pop

                  // ZERO_VECTOR;
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
26                pop

                  // <0, 0, 0>;
20 00 00 00 00    ldc.i4 0
6C                conv.r8
20 00 00 00 00    ldc.i4 0
6C                conv.r8
20 00 00 00 00    ldc.i4 0
6C                conv.r8
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
26                pop

                  // <-1.0, -1.0, 0.0>;
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 f0 3f)
00 00 F0 3F
65                neg
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 f0 3f)
00 00 F0 3F
65                neg
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
26                pop

                  // TOUCH_INVALID_TEXCOORD;
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 f0 bf)
00 00 F0 BF
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 f0 bf)
00 00 F0 BF
23 00 00 00 00    ldc.r8 (00 00 00 00 00 00 00 00)
00 00 00 00
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
26                pop

                  // <-1, -1, 0>;
20 01 00 00 00    ldc.i4 1
65                neg
6C                conv.r8
20 01 00 00 00    ldc.i4 1
65                neg
6C                conv.r8
20 00 00 00 00    ldc.i4 0
6C                conv.r8
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
26                pop

                  // <0xffffffff, 0xffffffff, 0>;
20 FF FF FF FF    ldc.i4 -1
6C                conv.r8
20 FF FF FF FF    ldc.i4 -1
6C                conv.r8
20 00 00 00 00    ldc.i4 0
6C                conv.r8
28 02 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)
26                pop

                  // v + v;
11 05             ldloc.s 5
11 05             ldloc.s 5
28 0B 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Add'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
26                pop

                  // v - v;
11 05             ldloc.s 5
11 05             ldloc.s 5
28 0C 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Subtract'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
26                pop

                  // v * v;
11 05             ldloc.s 5
11 05             ldloc.s 5
28 0D 00 00 0A    call float32 class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Multiply'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
26                pop

                  // v % v;
11 05             ldloc.s 5
11 05             ldloc.s 5
28 0E 00 00 0A    call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Modulo'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)
26                pop

                  // [];
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
26                pop

                  // a = [];
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
25                dup
13 06             stloc.s 6
26                pop

                  // a + [x];
11 00             ldloc.s 0
8C 01 00 00 1B    box [mscorlib]System.Int32
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
28 0F 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
11 06             ldloc.s 6
28 10 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)
26                pop

                  // a + x;
11 00             ldloc.s 0
11 06             ldloc.s 6
28 11 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
26                pop

                  // [x] + a;
11 06             ldloc.s 6
11 00             ldloc.s 0
8C 01 00 00 1B    box [mscorlib]System.Int32
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
28 0F 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
28 10 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)
26                pop

                  // x + a;
11 06             ldloc.s 6
11 00             ldloc.s 0
8C 01 00 00 1B    box [mscorlib]System.Int32
28 12 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(class [mscorlib]System.Collections.ArrayList, object)
26                pop

                  // [x];
11 00             ldloc.s 0
8C 01 00 00 1B    box [mscorlib]System.Int32
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
28 0F 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
26                pop

                  // []+x;
11 00             ldloc.s 0
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
28 11 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
26                pop

                  // (list)x;
11 00             ldloc.s 0
8C 01 00 00 1B    box [mscorlib]System.Int32
28 13 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList(object)
26                pop

                  // [x, y];
11 00             ldloc.s 0
8C 01 00 00 1B    box [mscorlib]System.Int32
11 01             ldloc.s 1
8C 01 00 00 1B    box [mscorlib]System.Int32
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
28 0F 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
28 0F 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)
26                pop

                  // []+x+y;
11 01             ldloc.s 1
11 00             ldloc.s 0
28 03 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()
28 11 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
28 11 00 00 0A    call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Append(int32, class [mscorlib]System.Collections.ArrayList)
26                pop

                  // (string)a;
11 06             ldloc.s 6
28 14 00 00 0A    call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ListToString(class [mscorlib]System.Collections.ArrayList)
26                pop

                  // i;
02                ldarg.0
7B 01 00 00 04    ldfld int32 LSL_y::'i'
26                pop

                  // u();
02                ldarg.0
28 02 00 00 06    call instance void class LSL_y::'gu'()

                  // end of event
2A                ret
              }

          }
Important notes:
  • ldloc.s 0 (opcode 11, argument 00) is probably contracted to the abbreviation ldloc.0 (opcode 06) at assembly time, resulting in the length of 2 obtained in the memory usage tests. Or possibly the server-side compiler added an optimization of this case (!). Either way, the evidence for this is confirmed by the fact that x; takes 2 bytes if it's one of the first four local variables (there are 1-byte opcodes for ldloc.0 through ldloc.3), and 3 bytes otherwise. This applies to all appearances of this opcode and the similar stloc.s.
  • Local variable definitions seem to take a variable and big number of bytes (averaging about 47 bytes for local integers) if there is a function call anywhere in the event in which they are defined. Reason unknown.
  • Backward jumps seem to take many more bytes than what the CIL result above suggests. Forward jumps, however, seem predictable enough.
  • As things are now, having more than 256 local variables in a single function or event causes wraparound, making the 257th be an alias to the 1st, and so on. If they aren't the same type, the script crashes at runtime with an uncaught exception. That's a consequence of using ldloc.s / stloc.s without switching to the long version (ldloc / stloc) when the argument is greater than 255.
Additional memory usage notes:
  • Global variable, function, and function parameter names do take code memory from the script (as part of some symbol table). Fortunately they take 1 byte per character only, as opposed to Mono strings, which take at least 2 bytes per character (they are UTF-16). That extra code is only taken once per variable, regardless of how many times it is used.
  • In addition to the state code and state change command code, the state names themselves take code memory from the script, as follows:
    • The state name by itself takes no code memory, but internally, each event name includes the state name. The internal name for the event is e.g. edefaultstate_entry (for state default, event state_entry), eblahtimer (for state blah, event timer). These names take 1 byte per character.
    • If a state switch statement appears in the code, the state name takes additionally 2 bytes per character. (But these strings are reused, so multiple state switch statements don't take additional space for the strings.)

Although not mentioned above, every single-byte string needs an additional terminating zero byte, and every UTF-16 string needs an additional length prefix byte (or more if longer than 127 bytes, i.e. 63 characters if in the ASCII range) plus an additional terminating zero byte.