Difference between revisions of "LSO"
m (Added some abbreviations/Wikipedia links...) |
(openmetaverse.co is gone, and so is its wiki article on LSO. An older version of this page linked to a similar page on libsecondlife.org's wiki, which archive.org thankfully indexed. Let's link to that!) |
||
Line 3: | Line 3: | ||
Second Life has two LSL compilers, one which compiles into LSO bytecode and is executed by the simulator in the LSO {{Abbr|VM|Virtual machine}}, the other which compiles to {{Wikipedia|Common Intermediate Language|CIL}} and is executed by the simulator in the [[Mono]] VM. This article is about the LSO bytecode. | Second Life has two LSL compilers, one which compiles into LSO bytecode and is executed by the simulator in the LSO {{Abbr|VM|Virtual machine}}, the other which compiles to {{Wikipedia|Common Intermediate Language|CIL}} and is executed by the simulator in the [[Mono]] VM. This article is about the LSO bytecode. | ||
LSO is mostly a stack-based language with a reference-counted heap and a very odd function calling convention in which the caller allocates storage for the callee's local variables. All the gory details can be found at | LSO is mostly a stack-based language with a reference-counted heap and a very odd function calling convention in which the caller allocates storage for the callee's local variables. All the gory details can be found at https://web.archive.org/web/20080430044527/https://www.libsecondlife.org/wiki/LSO, including some opcodes that are implemented in the interpreter but never outputted by the compiler (such as the handy DUP family of instructions for Forth-style programming, and PUSHIP/POPIP for implementing custom function calls/function pointers, jumptable-based switch statements and the like). | ||
It's actually a reasonably powerful instruction set in some ways, but the compiler doesn't make use of it very well. | It's actually a reasonably powerful instruction set in some ways, but the compiler doesn't make use of it very well. |
Latest revision as of 16:20, 27 August 2024
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Second Life has two LSL compilers, one which compiles into LSO bytecode and is executed by the simulator in the LSO VM, the other which compiles to CIL and is executed by the simulator in the Mono VM. This article is about the LSO bytecode.
LSO is mostly a stack-based language with a reference-counted heap and a very odd function calling convention in which the caller allocates storage for the callee's local variables. All the gory details can be found at https://web.archive.org/web/20080430044527/https://www.libsecondlife.org/wiki/LSO, including some opcodes that are implemented in the interpreter but never outputted by the compiler (such as the handy DUP family of instructions for Forth-style programming, and PUSHIP/POPIP for implementing custom function calls/function pointers, jumptable-based switch statements and the like).
It's actually a reasonably powerful instruction set in some ways, but the compiler doesn't make use of it very well.
With the release of the Mono VM, LSO has been maintained for backwards compatibility.
Bytecodes
Argument Types | Variable type codes | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
By Task
Pop Value
Name | Value | Description | arg0 size |
---|---|---|---|
POP | 0x01 | Pops a dword from the stack. | |
POPS | 0x02 | Pops a dword from the stack and deallocates it from the heap as a string | |
POPL | 0x03 | Pops a dword from the stack and deallocates it from the heap as a list | |
POPV | 0x04 | Pops 3 dwords from the stack. | |
POPQ | 0x05 | Pops 4 dwords from the stack. | |
POPARG | 0x06 | Pops arg0 bytes from the stack. | dword |
Duplicate Value
Name | Value | Description |
---|---|---|
DUP | 0x20 | Copy dword from stack and push the copy onto the stack. |
DUPS | 0x21 | Copy string from stack and push the copy onto the stack. |
DUPL | 0x22 | Copy list from stack and push the copy onto the stack. |
DUPV | 0x23 | Copy 3 dwrods from stack and push the copy onto the stack. |
DUPQ | 0x24 | Copy 4 dwrods from stack and push the copy onto the stack. |
Store to Local
Name | Value | Description | arg0 size |
---|---|---|---|
STORE | 0x30 | Copy a dword from the stack and store to local arg0 address. | dword |
STORES | 0x31 | Copy a string from the stack and store to local arg0 address. | dword |
STOREL | 0x32 | Copy a list from the stack and store to local arg0 address. | dword |
STOREV | 0x33 | Copy 3 dwords from the stack and store to local arg0 address. | dword |
STOREQ | 0x34 | Copy 4 dwords from the stack and store to local arg0 address. | dword |
Store to Global
Name | Value | Description | arg0 size |
---|---|---|---|
STOREG | 0x35 | Copy a dword from the stack and store to global arg0 address. | dword |
STOREGS | 0x36 | Copy a string from the stack and store to global arg0 address. | dword |
STOREGL | 0x37 | Copy a list from the stack and store to global arg0 address. | dword |
STOREGV | 0x38 | Copy 3 dwords from the stack and store to global arg0 address. | dword |
STOREGQ | 0x39 | Copy 4 dwords from the stack and store to global arg0 address. | dword |
Load to Local
Name | Value | Description | arg0 size |
---|---|---|---|
LOADP | 0x3A | Pop a dword from the stack and store to local arg0 address. | dword |
LOADSP | 0x3B | Pop a string from the stack and store to local arg0 address. | dword |
LOADLP | 0x3C | Pop a list from the stack and store to local arg0 address. | dword |
LOADVP | 0x3D | Pop 3 dwords from the stack and store to local arg0 address. | dword |
LOADQP | 0x3E | Pop 4 dwords from the stack and store to local arg0 address. | dword |
Load to Global
Name | Value | Description | arg0 size |
---|---|---|---|
LOADGP | 0x3F | Pop a dword from the stack and store to global arg0 address. | dword |
LOADGSP | 0x40 | Pop a string from the stack and store to global arg0 address. | dword |
LOADGLP | 0x41 | Pop a list from the stack and store to global arg0 address. | dword |
LOADGVP | 0x42 | Pop 3 dwords from the stack and store to global arg0 address. | dword |
LOADGQP | 0x43 | Pop 4 dwords from the stack and store to global arg0 address. | dword |
Push Local
Name | Value | Description | arg0 size |
---|---|---|---|
PUSH | 0x50 | Push a dword from the local address arg0 to the stack. | dword |
PUSHS | 0x51 | Push a string from the local address arg0 to the stack. | dword |
PUSHL | 0x52 | Push a list from the local address arg0 to the stack. | dword |
PUSHV | 0x53 | Push 3 dwords from the local address arg0 to the stack. | dword |
PUSHQ | 0x54 | Push 4 dwords from the local address arg0 to the stack. | dword |
Push Global
Name | Value | Description | arg0 size |
---|---|---|---|
PUSHG | 0x55 | Push a dword from the global address arg0 to the stack. | dword |
PUSHGS | 0x56 | Push a string from the global address arg0 to the stack. | dword |
PUSHGL | 0x57 | Push a list from the global address arg0 to the stack. | dword |
PUSHGV | 0x58 | Push 3 dwords from the global address arg0 to the stack. | dword |
PUSHGQ | 0x59 | Push 4 dwords from the global address arg0 to the stack. | dword |
Push into List
Name | Value | Description | arg0 size |
---|---|---|---|
PUSHARGB | 0x5D | Pop type <byte> from the stack and push into buffer for list (use to prepare list entries) | Type |
PUSHARGI | 0x5E | Push the following dword onto the stack (used for integer or float) | |
PUSHARGF | 0x5F | Push the following dword onto the stack (used for float) | |
PUSHARGS | 0x60 | Push the following null terminated string onto the stack (used for string or key) | |
PUSHARGV | 0x61 | Push the following 3 dwords onto the stack (used for vector) | |
PUSHARGQ | 0x62 | Push the following 4 dwords onto the stack (used for rotation/quaternion) |
Push Zero Values
Name | Value | Description | arg0 size |
---|---|---|---|
PUSHE | 0x63 | Push a zero dword onto the stack | |
PUSHEV | 0x64 | Push 3 zero dwords onto the stack | |
PUSHEQ | 0x65 | Push 4 zero dwords onto the stack | |
PUSHARGE | 0x66 | Push arg0 zero bytes onto the stack. | dword |
Operators
Name | Value | Description | arg0 size |
---|---|---|---|
CAST | 0xA0 | Pop type.Left, convert Left to type.Right and push the result onto the stack. | type |
NEG | 0x80 | Pop type.Right, push result of (-Right) onto the stack. | type |
ADD | 0x70 | Pop type.Right then type.Left, push result of (Left + Right) onto the stack. | type |
SUB | 0x71 | Pop type.Right then type.Left, push result of (Left - Right) onto the stack. | type |
MUL | 0x72 | Pop type.Right then type.Left, push result of (Left * Right) onto the stack. | type |
DIV | 0x73 | Pop type.Right then type.Left, push result of (Left / Right) onto the stack. | type |
MOD | 0x74 | Pop type.Right then type.Left, push result of (Left % Right) onto the stack. | type |
EQ | 0x75 | Pop type.Right then type.Left, push result of (Left == Right) onto the stack. | type |
NEQ | 0x76 | Pop type.Right then type.Left, push result of (Left != Right) onto the stack. | type |
LEQ | 0x77 | Pop type.Right then type.Left, push result of (Left <= Right) onto the stack. | type |
GEQ | 0x78 | Pop type.Right then type.Left, push result of (Left >= Right) onto the stack. | type |
LESS | 0x79 | Pop type.Right then type.Left, push result of (Left < Right) onto the stack. | type |
GREATER | 0x7A | Pop type.Right then type.Left, push result of (Left > Right) onto the stack. | type |
BITAND | 0x7B | Pop dword (Right) then dword (Left), push result of (Left & Right) onto the stack. | |
BITOR | 0x7C | Pop dword (Right) then dword (Left), push result of (Left | Right) onto the stack. | |
BITXOR | 0x7D | Pop dword (Right) then dword (Left), push result of (Left ^ Right) onto the stack. | |
BOOLAND | 0x7E | Pop dword (Right) then dword (Left), push result of (Left && Right) onto the stack. | |
BOOLOR | 0x7F | Pop dword (Right) then dword (Left), push result of (Left || Right) onto the stack. | |
BITNOT | 0x81 | Pop dword (Right), push result of (~Right) onto the stack. | |
BOOLNOT | 0x82 | Pop dword (Right), push result of (!Right) onto the stack. | |
SHL | 0xE0 | Pop dword (Right) then dword (Left), push result of (Left << Right) onto the stack. | |
SHR | 0xE1 | Pop dword (Right) then dword (Left), push result of (Left >> Right) onto the stack. |
Jump
Name | Value | Description | arg0 size | arg1 size |
---|---|---|---|---|
JUMP | 0x90 | Jump to offset arg0 local to this instruction. arg0 is signed. | dword | |
JUMPIF | 0x91 | Pop type.Right, if Right is executes to true jump to offset arg1 local to this instruction. arg1 is signed. | type | dword |
JUMPNIF | 0x92 | Pop type.Right, if Right is executes to false jump to offset arg1 local to this instruction. arg1 is signed. | type | dword |
Return
Name | Value | Description | arg0 size |
---|---|---|---|
STATE | 0x93 | Change state to arg0 and return (see RETURN) | dword |
RETURN | 0x95 | Revert the Instruction and Stack pointers. |
Stack to Heap
Name | Value | Description | arg0 size |
---|---|---|---|
STACKTOS | 0xB0 | Pop arg0 bytes from the stack, store them as a string on the heap and push a string pointer onto the stack. | dword |
STACKTOL | 0xB1 | Pop arg0 objects from the stack, store them as a list on the heap and push a list pointer onto the stack. | dword |
Call Functions
Name | Value | Description | arg0 size |
---|---|---|---|
CALL | 0x94 | Execute user function arg0. | dword |
CALLLIB | 0xD0 | Execute built-in function arg0 | byte |
CALLLIB_TWO_BYTE | 0xD1 | Execute built-in function arg0 | word |
Special Registers
Name | Value | Description |
---|---|---|
PUSHIP | 0x5A | Push InstructionPointer onto the stack |
PUSHBP | 0x5B | Push BasePointer onto the stack |
PUSHSP | 0x5C | Push StackPointer onto the stack |
POPIP | 0x07 | Pop dword and set it to InstructionPointer |
POPBP | 0x08 | Pop dword and set it to BasePointer |
POPSP | 0x09 | Pop dword and set it to StackPointer |
POPSLR | 0x0A | Pop dword and set it to the SleepRegister |
Miscellaneous
Name | Value | Description | arg0 size |
---|---|---|---|
NOOP | 0x00 | Does nothing | |
0xC0 | Pop type.Right from the stack and send it to stdout. | type |
All Bytecodes
Name | Value | Description | arg0 size | arg1 size |
---|---|---|---|---|
NOOP | 0x00 | Does nothing | ||
0xC0 | Pop type.Right from the stack and send it to stdout. | type | ||
POP | 0x01 | Pops a dword from the stack. | ||
POPS | 0x02 | Pops a dword from the stack and deallocates it from the heap as a string | ||
POPL | 0x03 | Pops a dword from the stack and deallocates it from the heap as a list | ||
POPV | 0x04 | Pops 3 dwords from the stack. | ||
POPQ | 0x05 | Pops 4 dwords from the stack. | ||
POPARG | 0x06 | Pops arg0 bytes from the stack. | dword | |
POPIP | 0x07 | Pop dword and set it to InstructionPointer | ||
POPBP | 0x08 | Pop dword and set it to BasePointer | ||
POPSP | 0x09 | Pop dword and set it to StackPointer | ||
POPSLR | 0x0A | Pop dword and set it to the SleepRegister | ||
DUP | 0x20 | Copy dword from stack and push the copy onto the stack. | ||
DUPS | 0x21 | Copy string from stack and push the copy onto the stack. | ||
DUPL | 0x22 | Copy list from stack and push the copy onto the stack. | ||
DUPV | 0x23 | Copy 3 dwrods from stack and push the copy onto the stack. | ||
DUPQ | 0x24 | Copy 4 dwrods from stack and push the copy onto the stack. | ||
STORE | 0x30 | Copy a dword from the stack and store to local arg0 address. | dword | |
STORES | 0x31 | Copy a string from the stack and store to local arg0 address. | dword | |
STOREL | 0x32 | Copy a list from the stack and store to local arg0 address. | dword | |
STOREV | 0x33 | Copy 3 dwords from the stack and store to local arg0 address. | dword | |
STOREQ | 0x34 | Copy 4 dwords from the stack and store to local arg0 address. | dword | |
STOREG | 0x35 | Copy a dword from the stack and store to global arg0 address. | dword | |
STOREGS | 0x36 | Copy a string from the stack and store to global arg0 address. | dword | |
STOREGL | 0x37 | Copy a list from the stack and store to global arg0 address. | dword | |
STOREGV | 0x38 | Copy 3 dwords from the stack and store to global arg0 address. | dword | |
STOREGQ | 0x39 | Copy 4 dwords from the stack and store to global arg0 address. | dword | |
LOADP | 0x3A | Pop a dword from the stack and store to local arg0 address. | dword | |
LOADSP | 0x3B | Pop a string from the stack and store to local arg0 address. | dword | |
LOADLP | 0x3C | Pop a list from the stack and store to local arg0 address. | dword | |
LOADVP | 0x3D | Pop 3 dwords from the stack and store to local arg0 address. | dword | |
LOADQP | 0x3E | Pop 4 dwords from the stack and store to local arg0 address. | dword | |
LOADGP | 0x3F | Pop a dword from the stack and store to global arg0 address. | dword | |
LOADGSP | 0x40 | Pop a string from the stack and store to global arg0 address. | dword | |
LOADGLP | 0x41 | Pop a list from the stack and store to global arg0 address. | dword | |
LOADGVP | 0x42 | Pop 3 dwords from the stack and store to global arg0 address. | dword | |
LOADGQP | 0x43 | Pop 4 dwords from the stack and store to global arg0 address. | dword | |
PUSH | 0x50 | Push a dword from the local address arg0 to the stack. | dword | |
PUSHS | 0x51 | Push a string from the local address arg0 to the stack. | dword | |
PUSHL | 0x52 | Push a list from the local address arg0 to the stack. | dword | |
PUSHV | 0x53 | Push 3 dwords from the local address arg0 to the stack. | dword | |
PUSHQ | 0x54 | Push 4 dwords from the local address arg0 to the stack. | dword | |
PUSHG | 0x55 | Push a dword from the global address arg0 to the stack. | dword | |
PUSHGS | 0x56 | Push a string from the global address arg0 to the stack. | dword | |
PUSHGL | 0x57 | Push a list from the global address arg0 to the stack. | dword | |
PUSHGV | 0x58 | Push 3 dwords from the global address arg0 to the stack. | dword | |
PUSHGQ | 0x59 | Push 4 dwords from the global address arg0 to the stack. | dword | |
PUSHIP | 0x5A | Push InstructionPointer onto the stack | ||
PUSHBP | 0x5B | Push BasePointer onto the stack | ||
PUSHSP | 0x5C | Push StackPointer onto the stack | ||
PUSHARGB | 0x5D | Pop type <byte> from the stack and push into buffer for list (use to prepare list entries) | Type | |
PUSHARGI | 0x5E | Push the following dword onto the stack (used for integer or float) | ||
PUSHARGF | 0x5F | Push the following dword onto the stack (used for float) | ||
PUSHARGS | 0x60 | Push the following null terminated string onto the stack (used for string or key) | ||
PUSHARGV | 0x61 | Push the following 3 dwords onto the stack (used for vector) | ||
PUSHARGQ | 0x62 | Push the following 4 dwords onto the stack (used for rotation/quaternion) | ||
PUSHE | 0x63 | Push a zero dword onto the stack | ||
PUSHEV | 0x64 | Push 3 zero dwords onto the stack | ||
PUSHEQ | 0x65 | Push 4 zero dwords onto the stack | ||
PUSHARGE | 0x66 | Push arg0 zero bytes onto the stack. | dword | |
CAST | 0xA0 | Pop type.Left, convert Left to type.Right and push the result onto the stack. | type | |
NEG | 0x80 | Pop type.Right, push result of (-Right) onto the stack. | type | |
ADD | 0x70 | Pop type.Right then type.Left, push result of (Left + Right) onto the stack. | type | |
SUB | 0x71 | Pop type.Right then type.Left, push result of (Left - Right) onto the stack. | type | |
MUL | 0x72 | Pop type.Right then type.Left, push result of (Left * Right) onto the stack. | type | |
DIV | 0x73 | Pop type.Right then type.Left, push result of (Left / Right) onto the stack. | type | |
MOD | 0x74 | Pop type.Right then type.Left, push result of (Left % Right) onto the stack. | type | |
EQ | 0x75 | Pop type.Right then type.Left, push result of (Left == Right) onto the stack. | type | |
NEQ | 0x76 | Pop type.Right then type.Left, push result of (Left != Right) onto the stack. | type | |
LEQ | 0x77 | Pop type.Right then type.Left, push result of (Left <= Right) onto the stack. | type | |
GEQ | 0x78 | Pop type.Right then type.Left, push result of (Left >= Right) onto the stack. | type | |
LESS | 0x79 | Pop type.Right then type.Left, push result of (Left < Right) onto the stack. | type | |
GREATER | 0x7A | Pop type.Right then type.Left, push result of (Left > Right) onto the stack. | type | |
BITAND | 0x7B | Pop dword (Right) then dword (Left), push result of (Left & Right) onto the stack. | ||
BITOR | 0x7C | Pop dword (Right) then dword (Left), push result of (Left | Right) onto the stack. | ||
BITXOR | 0x7D | Pop dword (Right) then dword (Left), push result of (Left ^ Right) onto the stack. | ||
BOOLAND | 0x7E | Pop dword (Right) then dword (Left), push result of (Left && Right) onto the stack. | ||
BOOLOR | 0x7F | Pop dword (Right) then dword (Left), push result of (Left || Right) onto the stack. | ||
BITNOT | 0x81 | Pop dword (Right), push result of (~Right) onto the stack. | ||
BOOLNOT | 0x82 | Pop dword (Right), push result of (!Right) onto the stack. | ||
SHL | 0xE0 | Pop dword (Right) then dword (Left), push result of (Left << Right) onto the stack. | ||
SHR | 0xE1 | Pop dword (Right) then dword (Left), push result of (Left >> Right) onto the stack. | ||
JUMP | 0x90 | Jump to offset arg0 local to this instruction. arg0 is signed. | dword | |
JUMPIF | 0x91 | Pop type.Right, if Right is executes to true jump to offset arg1 local to this instruction. arg1 is signed. | type | dword |
JUMPNIF | 0x92 | Pop type.Right, if Right is executes to false jump to offset arg1 local to this instruction. arg1 is signed. | type | dword |
STATE | 0x93 | Change state to arg0 and return (see RETURN) | dword | |
RETURN | 0x95 | Revert the Instruction and Stack pointers. | ||
STACKTOS | 0xB0 | Pop arg0 bytes from the stack, store them as a string on the heap and push a string pointer onto the stack. | dword | |
STACKTOL | 0xB1 | Pop arg0 objects from the stack, store them as a list on the heap and push a list pointer onto the stack. | dword | |
CALL | 0x94 | Execute user function arg0. | dword | |
CALLLIB | 0xD0 | Execute built-in function arg0 | byte | |
CALLLIB_TWO_BYTE | 0xD1 | Execute built-in function arg0 | word |