Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001863opensim[REGION] Scripting Enginepublic2008-07-29 15:492008-12-26 21:39
Reportermjm 
Assigned To 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionwon't fix 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0001863: Three minor script compilion errors
DescriptionJust tried to copy and paste some of my really big scripts from SL to OpenSim, and ran only into 3 minor issues, that were easy to work around. Great job, I love the new compiler! :-)

Nevertheless here is a simple example, reproducing all three errors:

--- CUT ---

// this initialization gives:
// Error Number: CS0120, 'An object reference is required...
vector TEST = ZERO_VECTOR;

integer isZero(integer x)
{
    // this gives:
    // Error Number: CS0029, 'Cannot implicitly convert...
    return (x == 0);
}

default
{
    state_entry()
    {
       list l = ["hello"];
       // typical LSL hack gives syntax error
       l = (l=[]) + l + "world";
    }
}

--- CUT ---
TagsNo tags attached.
Git Revision or version number
Run Mode Grid (Multiple Regions per Sim)
Physics EngineODE
Script Engine
Environment.NET / Windows64
Mono VersionNone
Viewer
Attached Files

- Relationships
related to 0001862closedmikem LSL assignment in if statement recently broke 
related to 0003187closedmelanie popular list memory saving hack does not work in LSL 
related to 0003269closedFly-Man- LSL : Syntax error 

-  Notes
(0004157)
mikem (developer)
2008-07-31 00:16

Since r5718 the example script above compiles. Two of the problems are fixed, the list hack is not.

The code:

        list l = ["hello"];
        l = (l=[]) + l + "world";
        llSay(0, (string) l);

prints the text "helloworld" in SL. In OpenSim, the printed text is "world". This is because, when translated into C#, we get this:

        LSL_Types.list l = new LSL_Types.list("hello");
        l = (l = new LSL_Types.list()) + l + "world";
        llSay(0, (LSL_Types.LSLString) l);

Obviously the LSL implementation in SL works differently than the C# code above.

I don't quite understand the point of the code, what is happening under the hood in SL and how this could be re-implemented in C#. Perhaps someone can provide further insights.
(0004161)
mjm (reporter)
2008-07-31 03:03
edited on: 2008-07-31 03:16

1.) Why would someone write code like this?

This is a well known LSL hack to save memory. If you keep adding to lists in LSL, you will soon get a stack/heap collision - out of memory. Using this hack allows you to store significantly more data in one script.

2.) How does it work in LSL?

Well, I can only give my best guess. AFAIK LSL is executed on a stack machine. I assume, all arguments of an expression are pushed onto the stack, before the operations are executed. Now, if inside of an expression a variable is modified, either by direct assignment or implicitly like (i++), all other references to that variable still give the old value that was pushed onto the stack before.

3.) Why is C# different?

Honestly, I am no expert for C#, but let me show what would happen in C. There any variable modification is effective immediately. References in the same expression might give the old or the new value, depending on the order of evaluation. Hence, an expression like (++i + i) is ill defined in C. The result might differ between different compilers or even between different optimization options in the same compiler.

4.) How to make it work in C#?

The only way I can see to make it work in C# is introducing an additional temporary variable:

    LSL_Types.list l = new LSL_Types.list("hello");
    LSL_Types.list __tmp_001 = l;
    l = (l = new LSL_Types.list()) + __tmp_001 + "world";
    llSay(0, (LSL_Types.LSLString) l);

5.) How to put this in a compiler?

One option is to create temporary variables for all variables referenced in expressions. That would result in ugly code, but hey, it is only for the C# compiler. If the C# optimizer is any good, it will not impact performance.

The other option would be to generate the temporary variables only for those variables, that are modified AND additionally referenced inside of one expression. Here "modified" includes direct assignment or implicit assignments like (i++).

A third option is to simply detect the case, when a variable is both modified and additionally referenced in the same expression, and issue a warning. Then the hacker can make the LSL code more beautiful. :-)

(0004199)
mikem (developer)
2008-08-03 19:55

For the time being, the list hack won't be addressed. It may be revisited again in the future.

- Issue History
Date Modified Username Field Change
2008-07-29 15:50 mjm New Issue
2008-07-29 15:50 mjm SVN Revision => 5707
2008-07-29 15:50 mjm Run Mode => Grid (Multiple Regions per Sim)
2008-07-29 15:50 mjm Physics Engine => ODE
2008-07-29 15:50 mjm Environment => .NET / Windows64
2008-07-29 17:39 matth Relationship added related to 0001862
2008-07-31 00:16 mikem Note Added: 0004157
2008-07-31 03:03 mjm Note Added: 0004161
2008-07-31 03:05 mjm Note Edited: 0004161
2008-07-31 03:08 mjm Note Edited: 0004161
2008-07-31 03:16 mjm Note Edited: 0004161
2008-08-03 19:55 mikem Note Added: 0004199
2008-12-26 21:39 sdague Mono Version => None
2008-12-26 21:39 sdague Status new => closed
2008-12-26 21:39 sdague Resolution open => won't fix
2009-02-17 20:17 mikem Relationship added related to 0003187
2009-03-08 04:24 idb Relationship added related to 0003269


Copyright © 2000 - 2012 MantisBT Group
Powered by Mantis Bugtracker