LSO

From Second Life Wiki
Revision as of 16:20, 27 August 2024 by Garfield Linden (talk | contribs) (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!)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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 "Wikipedia logo"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
Type Size
dword 4
short 2
byte 1
type 1 upper 4 bits are type.Left
lower 4 bits are type.Right
Value Type Size
0 void ?
1 integer 4
2 float 4
3 string 4
Value Type Size
4 key 4
5 vector 12
6 rotation 16
7 list 4

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