Objectifying LSL
OSSL takes an object-oriented turn: instead of only LSL2-style function calls you can now write Prim.Position.x += 10 or set Prim.Text directly. A more modular approach to the scripting language.
19 articles in the notebook
OSSL takes an object-oriented turn: instead of only LSL2-style function calls you can now write Prim.Position.x += 10 or set Prim.Text directly. A more modular approach to the scripting language.
The ScriptEngine now mixes LSL and C# in the same script — and if a script starts with //C#, the LSL preprocessor is skipped entirely for 100% pure C# support. A few naming rules apply for events.
A summary for those who skip the techie details: LSL script support works, hundreds of scripts run simultaneously across multiple cores, events are queued, and the remaining gaps are clearly listed.
Some LL commands, like llSetTimerEvent and llHTTPRequest, don't return immediately — they come back later as events. LSLLongCmdHandler is a new class with a dedicated thread that keeps track of these long-running requests.
Proof in pixels: a screenshot of llSay() running for real.
Charles Krinkle contributed the interface and empty prototypes for all the LL builtin functions, so the compiler can now be tested against all kinds of scripts without erroring out. Thanks dude!
ScriptEngine is now implemented in OpenSim: a default script in every object, a touch_start event, and llSay writing to the server console. Now the 350+ builtin ll-functions can be implemented and tested in-world.
Quick status: the LSL-to-C# translator is close to complete, the compiler and script manager work, and what remains is the builtin commands and events.
Want to help with OpenSim scripting? LSL_BaseClass.cs contains a pile of empty llFunctions that all need implementing — here is how to get started.
Instead of compiling LSL directly, I first translate it to C# — simpler for other OpenSim developers to contribute to, and the same translator can double as a learning tool for people moving from LSL to C#. Written in less than a day with regex and a couple of passes.
After a meeting with Babbage Linden it is clear compilation moves to the server, and the LSO bytecode path goes away. So I'm changing course: a server-side LSL compiler working from the script text instead.
The full event pipeline works end to end: pressing a button in the test app sends an event through the ScriptEngine, into the queue, and out to the correct compiled script. Screenshot included.
Static and global variables, push/pop and simple scripts with math and llSay now work, and the internal state is ready for serializing so a running script can be moved between servers. Next up: local variables, custom functions, states and jumps.
A raw status table over the LSO opcodes: which ones the IL processor understands and which ones are implemented so far in the LSL-to-.NET translation.
LSL bytecode is full of pointers — static frames, heap, jump targets — all referring to positions inside a 16k LSO file. Here is my plan for mapping them onto dictionaries and two-pass MSIL label generation.
Direct translation from the LSO stack to the .NET stack falls apart: LSO doesn't always tell you the datatype, and .NET wants its stack served in a very particular order. The fix: my own stack in a base class the compiled scripts inherit from.
The converter can now take LSL bytecode all the way to a compiled .NET .dll on disk, with events visible in Visual Studio and llSay mapped to Console.WriteLine. Messy code, but the goal is simply "Version 1: Functional".
Found the "final bug" in the LSL bytecode parser and compiled my first small function to a working .dll. One opcode and one builtin command supported — it's a start, and it works!
The plan for OpenSim script support: read compiled LSL bytecode, convert it to .NET bytecode and let the JIT produce native code, with AppDomains providing the sandbox. Blazing fast execution inside the .NET VM.