LSO
| 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 |