LSL scripting support – Progress report

By | 2007.07.14

Ok, time for status update again…

Status

Code is currently able to convert from LSL ByteCode to .Net IL, compile it and save it to disk.
I’ve moved the code from a quick and dirty hack (that compiled the first script) to a bit more organized. It’s still a mess, but that can be fixed later. The goal is simply “Version 1: Functional.”.

So basically I’m able to convert simple LSL ByteCode-files into .Net .dll. If you load the script (.dll) into Visual Studio you will see the events (from server to script). If you provide the script (.dll) with an object with the righ inheritance the script (.dll) will use that objects LL-functions. Currently only llSay(); is implemented (mapped to Console.WriteLine). This is how the script communicated with the server.

I’ve added support for a few more OPCODES, so we support basic math and most PUSH/POP functions. Because LSL ByteCode based itself on pure memory addressing and .Net CLR/IL is object oriented a few of the functions will be tricky to implement. For example LSL wants to push a string followed by xx 0x000’s to memory, then perform an operation and remove two bytes.

Server to script

For each event in the script I create one function that the server can execute. These functions needs to be late bound during load of .dll. I’m dynamically creating functions for each state+event combination. Because of the naming scheme, and the fact that a script seldonly listen on all events, I’ve not used any interface for this. The available events can be fetched through a GetEvents() functions that is hardcoded into the assembly when script is converted.
Also the required parameters for each function is created dynamically from the information in the LSO-file.

The naming scheme will be different once I’m done. Maybe something like a switch() inside each event to determine what code chunk should be executed based on what state number we are in.

UInt32 LSLObj.State; // Contains current state number
public void 0_event_state_entry() {} // state_entry event in state number 0
public void 1_event_state_entry() {} // state_entry event in state number 1
public void 0_event_touch_start() {} // touch_start event instate number 0

Script to server

I’ve created an interface for all LSL builtin commands, and another class that inherits the interface. All the functions are there, but they are empty and don’t have the correct arguments. Anyone can help to add commands by changing this class. This is probably the single remaining area that requires most work. (not sure though)

Since most PUSH/POP and math commands are supported already, we just need to map the builtin function calls to the above mentioned class. This is a simple Switch()-case hardcoding issue.

TODO:
From the top of my head, not in any particular order.

  • Support custom functions (currently only LL server events gets compiled)
    • Compiling them is easy, but I need to be able to bind them to Call OPCODE somehow. (IL issue)
  • Figure out how to reference the LSL builtin commands C# class from IL (IL issue)
    • Then bind all ll* functions
  • Add support for remaining OPCODES (IL issue)
    • This can be a bit tricky since LSL uses memory addressing in stack while .Net IL is object oriented. One possible solution is to implement same memory scheme as LL is using. Either way it’s not a big problem, just a bit of work.
  • Figure out what OPCODES needs special (custom) commands in order to support interregional transfers and user space multitasking – instead of running CLR/IL OPCODE we run a C# function that does the required work.
  • Figure out how one can cast an element in CLR/IL stack without knowing its type, or – keeping track of all types in stack.
    • LSL is a bit like “push string, push long, convert to string, concat, push long(channel id), llSay()“. Its asking me to cast whatever is on the stack, but CLR/IL requires me to know what type I’m casting from.
  • Figure out how to clear CLR/IL stack. CLR/IL requires stack to be empty on return. LSL sometimes leaves items in the stack. For now a Try:Catch is handling the issue.

The full source is here: http://www.konge.net/OpenSim/OpenSim.Region.Scripting_r1.zip.
Please note that this source belongs to OpenSim project (http://opensecondlife.org/wiki/OpenMetaverse) and is licensed thereafter.

Download, run project, choose a LSO-file (for example CloseToDefault.LSO), then process it.

LSL running in .Net

Leave a Reply