Jump to content

"Internal server compile error"


Wulfie Reanimator
 Share

You are about to reply to a thread that has been inactive for 1503 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

A friend of mine just showed me something weird.

This code, which is 1040 lines long, compiles fine. But if you add one extra element to the test list, it refuses to compile with the error "Internal server compile error."

  • The working code reports 14628 bytes of used memory before and after touching the object, so there's no stack-heap collision or impossible memory requirements.
  • There are 43278 characters in the code, so it's not hitting the viewer's default limit.
  • I don't know whether this "internal server" is internal to the viewer or internal to the actual server-server (technical term).

Pre-post edit:

  • The working test list has 1023 elements (last index is 1022). 1024 elements seem to break it.
  • If you start another list, you can keep going just fine.
  • Appending an element to test list in the touch_start event works just fine, even though the list starts at 1023 elements.

I'm posting this because 1) it started as an interesting problem and 2) it turned out to be a seemingly undocumented quirk. It's not listed in the Limits page of the wiki.

Real edit:

Yeah, there are no hard limits beyond that besides the memory limit itself. It's actually possible to compile a script that will run out of memory immediately on state_entry.

The maximum predefined list length may vary based on the data type, obviously this code only used strings.

Edited by Wulfie Reanimator
  • Like 1
Link to comment
Share on other sites

what i remember is that a predefined list has a maximum number of elements, while adding elements to the list through the script only maxes out when you run out of memory, i think this is by design.

looking to find it on the lsl page, will get back when i find it

 

Dargo... ;)

*edit:  this is what i found on the old lslwiki:


Note: while the LSL compiler will only accept code with a maximum of 72 items in a list, lists can actually support as many items as a script's memory will allow. If a list of more than 72 predefined items is needed, just concatenate (combine) two predefined lists into a new one: longlist = firstpart + secondpart;
As of 1.20.4, this no longer seems to be true. A list with at least 100 is possible, though I haven't tested to see just how many elements I can initialize a list to. - BlueJeansAndRain
June 5, 2008 - Server 1.22.1.88473 | Client 1.19.1 (4): I was able to create a global list containing 1,081 null integers and a local list containing 2,318 null integers before receiving "(0, 0) : Byte code assembly failed -- out of memory".

so it seems there's still a maximum of predefined objects in a list, but it was gradually increased over time, however you found the maximum again.. :)

you can still do a longlist = list1 + list2

 

Edited by Kardargo Adamczyk
  • Like 1
Link to comment
Share on other sites

On 3/12/2020 at 12:57 AM, Kardargo Adamczyk said:

this is what i found on the old lslwiki:

Note: while the LSL compiler will only accept code with a maximum of 72 items in a list, lists can actually support as many items as a script's memory will allow. If a list of more than 72 predefined items is needed, just concatenate (combine) two predefined lists into a new one: longlist = firstpart + secondpart;

As of 1.20.4, this no longer seems to be true. A list with at least 100 is possible, though I haven't tested to see just how many elements I can initialize a list to. - BlueJeansAndRain

June 5, 2008 - Server 1.22.1.88473 | Client 1.19.1 (4): I was able to create a global list containing 1,081 null integers and a local list containing 2,318 null integers before receiving "(0, 0) : Byte code assembly failed -- out of memory".

I looked into this, and found more weird things.

If a global list has more than 4998 elements or a local list has more than 4995 elements, you will get a syntax error before the next comma. (Of course, the script crashes long before these limits are reached, due to stack-heap collisions on or before state_entry.) Here's a reference script.

If you stay within that limit, but too many for a predefined list, you'll get the internal server error. That said, I have no idea what exactly causes the internal server error. It doesn't happen when I have 4800 integers (75KB) in a single list. I can't say if it's caused by some kind of memory limit or another problem.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

You said you have a list of 4800 integers.

What is the maximum number of bits actually used per integer?

If each integer is only using 1 - 16 bits, you can XOR those integers, each shifted the number of bits used into a larger bit integer, thus freeing up memory.

The less bits used the more integers you can "combine".

Think "Endianness".

Just remember when "extracting" or "expanding" that SL doesn't allow logical right shifting. 😉

Edited by Lucia Nightfire
Link to comment
Share on other sites

34 minutes ago, Lucia Nightfire said:

You said you have a list of 4800 integers.

What is the maximum number of bits actually used per integer?

If each integer is only using 1 - 16 bits, you can XOR those integers, each shifted the number of bits used into a larger bit integer, thus freeing up memory.

The less bits used the more integers you can "combine".

Think "Endianness".

Just remember when "extracting" or "expanding" that SL doesn't allow logical right shifting. 😉

Firstly: SL definitely allows logical right shifting.

integer i = 4;          // Binary: 0100
i = (i >> 1);           // Binary: 0010
llOwnerSay((string)i);  // Output: 2

Secondly: You've entirely missed the point of the exercise.

I'm not trying to have a practical solution -- a working script -- with any number of integers or any large lists. I'm very aware of everything you've mentioned and pretty experienced with bit-twiddling.

This is a purely technical examination. I was trying to figure out "at which point does the internal server compile error happen?" The more things I try, the more convoluted the error gets. For example if I add a function call into state_entry, the internal error shows up until the predefined list length is satisfied. Otherwise it doesn't show up, except for the syntax error at the limit I originally found.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

58 minutes ago, Lucia Nightfire said:

It does the exact same thing as regular C/C++ compilers. You can try this in any online compiler for example.

If the value is signed and negative, it pads with 1s.

integer i = -777;       // Binary: 11111111111111111111110011110111
i = (i >> 1);           // Binary: 11111111111111111111111001111011
llOwnerSay((string)i);  // Output: -389
#include <stdio.h>

int main()
{
    printf("%d\n", -777);       // "-777"
    printf("%d\n", -777 >> 1);  // "-389"

    return 0;
}

If you have more questions, make a new thread (or PM me) and I'll be happy to answer them.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

1 hour ago, Wulfie Reanimator said:

If the value is signed and negative, it pads with 1s.

That padding of 1's is specific to Arithmetic right shifting, and only optional in Logical right shifting, which typically pads with 0's.

SL uses Arithmetic right shifting. You have to use other bitwise functions to emulate Logical right shifting in SL.

1 hour ago, Wulfie Reanimator said:

If you have more questions, make a new thread and I'll be happy to answer them.

My "question" was more rhetorical than genuine. 😉

Link to comment
Share on other sites

6 minutes ago, Lucia Nightfire said:

That padding of 1's is specific to Arithmetic right shifting, and only optional in Logical right shifting, which typically pads with 0's.

SL uses Arithmetic right shifting. You have to use other bitwise functions to emulate Logical right shifting in SL.

My "question" was more rhetorical than genuine. 😉

I am actually curious. Can you show an example of logical right shift in LSL?

Link to comment
Share on other sites

1 hour ago, ItHadToComeToThis said:

I am actually curious. Can you show an example of logical right shift in LSL?

string integer2hex(integer in, integer keep_leading_zeros)
{
    string ret;
    integer i = ~8;
    while(++i)
    {
        ret = llGetSubString("0123456789abcdef",in & 0xF,in & 0xF) + ret;
        in = in >> 4;
    }
    return "0x" + llList2String(llParseString2List("0x" + ret,["0x0000000","0x000000","0x00000","0x0000","0x000","0x00","0x0","0x"],[]) + [ret],!!keep_leading_zeros); //parsing eval'd left to right
}
default
{
    state_entry()
    {
        llSetObjectName("Logical Left or Right Shift Test (<<<,>>>)");
        llSetObjectDesc("1 <<< 0");
    }
    on_rez(integer i)
    {
        llResetScript();
    }
    touch_end(integer i)
    {
        if (llDetectedKey(0) == llGetOwner())
        {
            list T = llParseString2List(llGetObjectDesc(),[" ","\n"],["<<<",">>>"]);
            if (llGetListLength(T) == 3)
            {
                integer a = (integer)llList2String(T,0); //hex notation is not typecasted to integer format with llList2Integer()
                integer b = llAbs((integer)llList2String(T,2)) % 32; //hex notation is not typecasted to integer format with llList2Integer()
                if (~(i = llListFindList(["<<<",">>>"],[llList2String(T,1)])))
                {
                    integer c = llList2Integer([a << b,((a & ~0x80000000) >> b) | (!!(a & 0x80000000) << (31 - b))],i);
                    llOwnerSay((string)a + "(" + integer2hex(a,0) + ") " + llList2String(["<<<",">>>"],i) + " " + (string)b + " = " + (string)c + "(" + integer2hex(c,0) + ")");
                    return;
                }
            }
            llOwnerSay("Object description must contain two integers, separated by a logical left shift operator, '<<<' or a logical right shift operator, '>>>'. Bitwise input is accepted.");
        }
    }
}

I made this example years ago. IDK if I thoroughly tested it. It may or may not have redundancies. It doesn't do more than 31 bits as it's assumed greater than that will yield 0 with any input.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1503 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...