load help; @[name] daovm.spec @[name] @[title] Various Specifications @[title] @[name] daovm.spec.instruction @[name] @[title] VM Instructions @[title] @[text] @[code] DVM_NOP # No operation, Dao VM assumes at most one NOP between two effective codes; DVM_DATA # Create primitive data: C = B; A: data type id; B: direct value; DVM_GETCL # Get local const: C = A:::B; B, index; A=0, implicit; A=1, explicit; DVM_GETCK # Get class const: C = A:::B; B, index; A=0; DVM_GETCG # Get global const: C = A:::B; B, index; A=0; DVM_GETVH # Get host variable: C = A:::B; B, index; A, section level; DVM_GETVS # Get closure variable: C = A:::B; B, index; A=0; DVM_GETVO # Get instance object variable: C = A:::B; B, index; A=0; DVM_GETVK # Get class static variable: C = A:::B; B, index; A=0; DVM_GETVG # Get global variable: C = A:::B; B, index; A=0; DVM_GETI # Get item(s): C = A[B]; A, register; B, register; DVM_GETDI # Get item(s): C = A[B]; A, register; B, direct index; DVM_GETMI # Get item(s): C = A[A+1, ..., A+B]; DVM_GETF # Get field: C = A.B or C = A::B; DVM_SETVH # Set host variable: C:::B = A; B, index; C, section level; DVM_SETVS # Set closure variable: C:::B = A; B, index; C=0; DVM_SETVO # Set instance object variable: C:::B = A; B, index; C=0; DVM_SETVK # Set class static variable: C:::B = A; B, index; C=0; DVM_SETVG # Set global variable: C:::B = A; C: Bit1, zero; Bit2, decl; Bit3, invar; DVM_SETI # Set item(s): C[B] = A; DVM_SETDI # Set item(s): C[B] = A; B, direct index; DVM_SETMI # Set item(s): C[C+1, ..., C+B] = A; DVM_SETF # Set field: C.B = A or C::B = A; DVM_LOAD # Put local value A as reference at C; DVM_MOVE # Move A to C: C = A; C: Bit1, explicit; Bit2, decl; Bit3, invar; DVM_UNTAG # Untag A of type X|none to X type at C; DVM_CAST # Cast A to B and store at C: C = (B)A; B, local const index; DVM_NOT # Not: C = ! A; DVM_MINUS # Unary minus: C = - A; DVM_TILDE # Bitwise not: C = ~ A DVM_SIZE # Size: C = % A; DVM_ADD # Addition: C = A + B; DVM_SUB # Subtraction: C = A - B; DVM_MUL # Multiplication: C = A * B; DVM_DIV # Division: C = A / B; DVM_MOD # Modulo: C = A % B; DVM_POW # Power: C = A ** B; DVM_AND # And: C = A && B; DVM_OR # Or: C = A || B; DVM_LT # Less than: C = A < B; DVM_LE # Less or equal: C = A <= B; DVM_EQ # Equal: C = A == B; DVM_NE # Not equal: C = A != B; DVM_IN # In: C = A in B; DVM_BITAND # Bit and: C = A & B DVM_BITOR # Bit or: C = A | B DVM_BITXOR # Bit xor: C = A ^ B DVM_BITLFT # Bit shift left: C = A << B DVM_BITRIT # Bit shift right: C = A >> B DVM_SAME # Same: C = A ?= B, same type; A, B, both are data objects or type objects; DVM_ISA # Isa: C = A ?< B; B, type; A (data) is a B; A (type) is a sub type of B; DVM_NAMEVA # C = (A = B): name A, local constant, value B, local register DVM_PAIR # C = A : B; create a pair of index, as a tuple; DVM_TUPLE # tuple: C = ( A, A+1, ..., A+B-1 ); B>=2, items can be: name=value DVM_LIST # list: C = { A, A+1, ..., A+B-1 }; DVM_MAP # map: C = { A => A+1, ..., A+B-2 => A+B-1 }; if B==0, empty; DVM_HASH # hash: C = { A -> A+1, ..., A+B-2 -> A+B-1 }; if B==0, empty; DVM_VECTOR # vector: C = [ A, A+1, ..., A+B-1 ]; DVM_MATRIX # matrix: C=[A,..,A+c-1;..;A+c*(r-1),..,A+c*r-1]; B=rc;r,c:8-bits each. DVM_APLIST # arithmetic progression list: C = { A : ... : A+B-1 }, B = 2 or 3; DVM_APVECTOR # arithmetic progression vector: C = [ A : ... : A+B-1 ], B = 2 or 3; DVM_PACK # packing: A::{ A+1, ..., A+B }; A, routine, class or type object; DVM_MPACK # packing: (A+1).A::{ A+2, ..., A+B }; (A+1).A, routine, class or type; DVM_ROUTINE # create a function, possibly with closure DVM_GOTO # go to B; DVM_SWITCH # A: variable, B: location of default block, C: number of cases DVM_CASE # A: constant of the case, B: location of the case block, C: case mode DVM_ITER # create an iterator at C for A if B==0, else test an array of iterators; DVM_TEST # if A, go to the next one; else, goto B-th instruction; DVM_MATH # C = A( B ); A: sin,cos,...; B: double,complex DVM_CALL # function call: C = A( A+1, A+2, ..., A+B ); If B==0, no parameters; DVM_MCALL # method call: x.y(...), pass x as the first parameter; DVM_RETURN # return A,A+1,..,A+B-1; B==0: no returns; C==1: return from functional; DVM_YIELD # yield A, A+1,.., A+B-1; return data at C when resumed; DVM_SECT # code section label, parameters: A,A+1,...,A+B-1; C, ID|(#explicit params); DVM_JITC # run Just-In-Time compiled Code A, and skip the next B instructions; DVM_DEBUG # prompt to debugging mode; @[code] @[text] @[name] daovm.spec.bytecode @[name] @[title] Bytecode Format @[title] @[text] This document contains specifications of the bytecode format for Dao virtual machine. In this bytecode format, integers are always stored in big endian. In the following specifications or examples, each byte is represented by two hexadecimal digits, unless it is quoted by quotation marks. @[section] Header Section @[section] The header section contains 32 bytes, which are divided as the following: @[code] Byte # ESC, 0x1B; Byte # 0x44, namely 'D'; Byte # 0x61, namely 'a'; Byte # 0x6F, namely 'o'; Byte # major version number, 0x2; Byte # minor version number, 0x0; Byte # Carriage Return (CR), 0x0D; Byte # Line Feed (LF), 0x0A; Byte # format class, 0x0 for the official one; Byte # size of integer type, default 0x4; Byte[4] # format hash (rotating hash of the ASM tags and VM opcodes); Byte[16] # 16 reserved bytes; Byte # Carriage Return (CR), 0x0D; Byte # Line Feed (LF), 0x0A; @[code] The ninth byte is for format class, where 0x0 is reserved for the official format, and 0x1 for encrypted format (only the main section is encrypted, see below for more information). The four bytes for format hash serves as a signature for the format in which the bytecode is encoded. It is the rotating hash value of a string that is constructed from the bytecode tag indices and names, and virtual machine opcode indices and names: @[code] TagIndex1:TagName1;TagIndex2:TagName2;...; OpcodeIndex1:OpcodeName1;... @[code] Each index is separated with its corresponding name by a colon; and each pair of index and name is followed by a semicolon. The substrings for bytecode tags and opcodes are seperated by a blank space. The rotating hash is computed by @[code] var hash = length( text ); for(byte in text) hash = ((hash<<4)^(hash>>28)^byte)&0x7fffffff; return hash; @[code] @[section] Source Path Section @[section] @[code] Byte[2] # length of the source path; Byte[] # source path (null-terminated); Byte # Carriage Return (CR), 0x0D; Byte # Line Feed (LF), 0x0A; @[code] @[section] Main Section @[section] The main section is encoded as structured blocks. Each block is divided into chunks of 9 bytes, where the first byte always stores a tag which identifies the chunk type. The remaining 8 bytes are used to store data. There are the following type of chunks: @[code] ASM_COPY # ASM_TYPEOF # ASM_TYPEDEF # ASM_TYPEINVAR # ASM_ROUTINE # ASM_CLASS # ASM_INTERFACE # ASM_ENUM # ASM_TYPE # ASM_VALUE # ASM_EVAL # ASM_BASES # ASM_DECOS # ASM_PATTERNS # ASM_CONSTS # ASM_TYPES # ASM_CODE # ASM_END # ASM_LOAD # ASM_IMPORT # ASM_VERBATIM # ASM_CONST # ASM_STATIC # ASM_GLOBAL # ASM_VAR # ASM_DATA # ASM_DATA2 # ASM_SEEK # @[code] @[section] Chunk Specifications: @[section] @[subsection] Values: @[subsection] @[code] int: ASM_VALUE(1Byte): DAO_INTEGER(1Bytes), Zeros(7Bytes); ASM_END(1B): Value(4B/8B), Zeros(4B/0B); float: ASM_VALUE(1B): DAO_FLOAT(1B), Zeros(7B); ASM_END(1B): Value(4B), Zeros(4B); double: ASM_VALUE(1B): DAO_DOUBLE(1B), Zeros(7B); ASM_END(1B): Value(8B); complex: ASM_VALUE(1B): DAO_COMPLEX(1B), Zeros(7B); ASM_DATA(1B): Real(8B); ASM_END(1B): Imag(8B); string: ASM_VALUE(1B): DAO_STRING(1B), SizeMod16(1B), Bytes(6B); ASM_DATA(1B); Bytes(8B); ASM_END(1B): Bytes(8B); enum symbol: ASM_VALUE(1B): DAO_ENUM(1B), Zeros(1B), Type-Index(2B), Zeros(4B); ASM_END(1B): Value(4B), Zeros(0); @[code] Notes: The "Type-Index" reference previous blocks which are located backwardly by a such "index" offset. Only blocks that represent values are indexed, and such index is stored as a two-byte short. In case short is not sufficient to represent such index, an intermediate indexing chunk can be used: @[code] ASM_SEEK(1B): New-Index(2B), Zeros(6B); @[code] When "New-Index" is also seeked backwardly, and is relative to the seek chunk. @[code] array: ASM_VALUE(1B): DAO_ARRAY(1B), Numeric-Type(1B), Dimensions(2B), Size(4B); ASM_DATA(1B); Dim1(4B), Dim2(4B); ASM_DATA(1B); More dimensions; ASM_DATA(1B); Data(4B), Data(4B); Or Data(8B); ASM_DATA(1B); More Data; ASM_END(1B): Data(8B); list: ASM_VALUE(1B): DAO_LIST(1B), Zeros(1B), Type-Index(2B), Size(4B); ASM_DATA(1B); Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ASM_END(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); map: ASM_VALUE(1B): DAO_MAP(1B), Zeros(1B), Type-Index(2B), Hash-Seed(4B); ASM_DATA(1B); Key-Index(2B), Value-Index(2B), Key-Index(2B), Value-Index(2B); ASM_END(1B): Key-Index(2B), Value-Index(2B), Key-Index(2B), Value-Index(2B); A pair of "Value-Index"s is for a pair of key-value, zero marks the end. tuple: ASM_VALUE(1B): DAO_TUPLE(1B), SubTypeID(1B), Type-Index(2B), Size(2B), Value-Index(2B); ASM_DATA(1B); Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ASM_END(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); namevalue: ASM_VALUE(1B): DAO_PAR_NAMED(1B), Zeros(1B), Name-Index(2B), Value-Index(2B), Type-Index(2B); ASM_END(1B): Zeros(8B); specialized ctype: ASM_VALUE(1B): DAO_CTYPE(1B), Zeros(1B), Value-Index(2B), Type-Index(2B) X 2; ASM_DATA(1B): Type-Index(2B) X 4; ASM_END(1B): Type-Index(2B) X 4; @[code] @[subsection] Other Values @[subsection] @[code] copied value: ASM_COPY(1B): Value-Index(2B), Zeros(6B); type of a value: ASM_TYPEOF(1B): Value-Index(2B), Zeros(6B); const/invar type: ASM_TYPEINVAR(1B): Type-Index(2B), SubType(2B), Zeros(4B); type alias: ASM_TYPEDEF(1B): Name-Index(2B), Type-Index(2B), Zeros(4B); @[code] @[subsection] Structures: @[subsection] @[code] routine: ASM_ROUTINE(1B): Name-Index(2B), Type-Index(2B), Host-Index(2B), Attrib(2B); ... ASM_END: RegCount(2B), Zeros(4B), DefaultConstructor(1B), Permission(1B); class: ASM_CLASS(1B): Name/Decl-Index(2B), Parent-Index(2B), Attrib(4B); ASM_BASES(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ... ASM_END(1B): LineDef(2B), Zeros(5B), Permission(1B); interface: ASM_INTERFACE(1B): Name/Decl-Index(2B), Parent-Count(2B), Zeros(4B); ASM_BASES(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ... ASM_END(1B): LineDef(2B), Zeros(5B), Permission(1B); enum: ASM_ENUM(1B): Name-Index(2B), Enum/Flag(2B), Count(4B); ASM_DATA(1B): Name-Index(2B), Value(4B), Zeros(2B); ASM_END(1B): Name-Index(2B), Value(4B), Zeros(2B); type: ASM_TYPE(1B): Name-Index(2B), TypeID(2B), Aux-Index(2B), CodeBlockType-Index(2B); ASM_DATA(1B): Type-Index(2B) X 4; ASM_END(1B): Type-Index(2B) X 4; Note 1: the nested types are zero Type-Index terminated; Note 2: "Aux-Index" could be index to returned type or class block etc; value: See above; evaluation: ASM_EVAL(1B): Opcode(2B), OpB(2B), Type-Index(2B), Zeros(2B); ASM_DATA(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ASM_END(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); bases (mixin components or interface parents): ASM_BASES(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ASM_DATA(1B): Value-Index(2B) X 4; ASM_END(1B): Value-Index(2B) X 4; decorators for the current routine: ASM_DECOS(1B): Func-Index(2B), ParList-Index(2B), Func-Index(2B), ParList-Index(2B); ASM_DATA(1B): Func-Index(2B), ParList-Index(2B), Func-Index(2B), ParList-Index(2B); ASM_END(1B): Func-Index(2B), ParList-Index(2B), Func-Index(2B), ParList-Index(2B); patterns for automatic decorator application: ASM_PATTERNS(1B): PatternString-Index(2B) X 4; ASM_DATA(1B): PatternString-Index(2B) X 4; ASM_END(1B): PatternString-Index(2B) X 4; consts: ASM_CONSTS(1B): Count(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ASM_DATA(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); ASM_END(1B): Value-Index(2B), Value-Index(2B), Value-Index(2B), Value-Index(2B); types: ASM_TYPES(1B): Count(2B), Zeros(2B), Var-Index(2B), Type-Index(2B); ASM_DATA(1B): Var-Index(2B), Type-Index(2B), Var-Index(2B), Type-Index(2B); ASM_END(1B): Var-Index(2B), Type-Index(2B), Var-Index(2B), Type-Index(2B); code: ASM_CODE(1B): CodeNum(2B), Line-Num-Count(2B), LineNum(2B), Count(2B); ASM_DATA(1B): LineDiff(2B), Count(2B), LineDiff(2B), Count(2B); ASM_DATA(1B): Opcode(2B), A(2B), B(2B), C(2B); ASM_END(1B): Opcode(2B), A(2B), B(2B), C(2B); @[code] @[subsection] Statement: @[subsection] @[code] load statement: ASM_LOAD(1B): File-Path-Index(2B), Optional-Name-Index(2B), Zeros(4B); import from namespace/module: ASM_IMPORT(1B): Mod-Index(2B), Name-Index(2B), Scope(2B), Offset(2B); verbatim: ASM_VERBATIM(1B): Tag-Index(2B), Mode-Index(2B), Text-Index(2B), LineNum(2B); var declaration: ASM_VAR(1B): Name-Index(2B), Value-Index(2B), Type-Index(2B), Scope(1B), Perm(1B); const declaration: ASM_CONST(1B): Name-Index(2B), Value-Index(2B), Zeros(2B), Scope(1B), Permission(1B); static declaration: ASM_STATIC(1B): Name-Index(2B), Value-Index(2B), Type-Index(2B), Scope(1B), Perm(1B); global declaration: ASM_GLOBAL(1B): Name-Index(2B), Value-Index(2B), Type-Index(2B), Scope(1B), Perm(1B); seek: ASM_SEEK(1B): New-Index(2B), Zeros(6B); @[code] @[section] Samples @[section] Input code: @[code] io.writeln( 'Hello Dao!' ); @[code] Output disassembled bytecode: @[code] ASM_ROUTINE: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 2, 'io'; ASM_END: ''; ASM_EVAL: GETCG, 1, 0, 0; ASM_END: 1, 0, 0, 0; ASM_VALUE: DAO_STRING, 7, 'writel'; ASM_END: 'n'; ASM_EVAL: GETF, 2, 0, 0; ASM_END: 2, 1, 0, 0; ASM_VALUE: DAO_STRING, 10, 'Hello '; ASM_END: 'Dao!'; ASM_CONSTS: 2, 2, 1, 0; ASM_END: 0, 0, 0, 0; ASM_TYPES: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_CODE: 6, 1, 1, 6; ASM_DATA: GETCG , 1, 5, 0; ASM_DATA: GETCL , 0, 0, 1; ASM_DATA: LOAD , 0, 0, 2; ASM_DATA: GETCL , 0, 1, 3; ASM_DATA: MCALL , 1, 2, 4; ASM_END: RETURN , 4, 1, 0; ASM_END: ; @[code] Input code: @[code] load web.cgi as cgi import cgi.random_string enum Bool { False, True } static abc = random_string( 100 ) var index = 123 + %abc class Klass { const name = "abc"; var index = 123; routine Method( a :int ){ } } routine Func() { var name = index } var klass = Klass() @[code] Output disassembled bytecode: @[code] ASM_ROUTINE: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 7, 'web/cg'; ASM_END: 'i'; ASM_VALUE: DAO_STRING, 3, 'cgi'; ASM_END: ''; ASM_LOAD: 2, 1, 0, 0; ASM_EVAL: GETCG, 1, 0, 0; ASM_END: 1, 0, 0, 0; ASM_VALUE: DAO_STRING, 13, 'random'; ASM_END: '_string'; ASM_IMPORT: 2, 1, 0, 28; ASM_VALUE: DAO_STRING, 4, 'Bool'; ASM_END: ''; ASM_VALUE: DAO_STRING, 5, 'False'; ASM_END: ''; ASM_VALUE: DAO_STRING, 4, 'True'; ASM_END: ''; ASM_VALUE: DAO_STRING, 0, 'enum'; ASM_ENUM: 1, 68, 2; ASM_DATA: 3, 0; ASM_END: 2, 1; ASM_TYPEINVAR: 5, 1, 0, 0; ASM_EVAL: GETCG, 1, 0, 0; ASM_END: 7, 0, 0, 0; ASM_VALUE: DAO_INTEGER; ASM_END: 100 ; ASM_VALUE: DAO_STRING, 1, '?'; ASM_END: ''; ASM_TYPE: 1, 66, 0, 0; ASM_END: 0, 0, 0, 0; ASM_EVAL: CALL, 1, 0, 1; ASM_END: 4, 3, 0, 0; ASM_TYPEOF: 1, 0, 0, 0; ASM_VALUE: DAO_STRING, 3, 'abc'; ASM_END: ''; ASM_GLOBAL: 1, 3, 2, 3; ASM_VALUE: DAO_STRING, 5, 'index'; ASM_END: ''; ASM_GLOBAL: 1, 0, 5, 3; ASM_VALUE: DAO_STRING, 5, 'Klass'; ASM_END: ''; ASM_CLASS: 1, 0, 0, 0; ASM_END: ; ASM_VALUE: DAO_STRING, 12, 'class<'; ASM_END: 'Klass>'; ASM_TYPE: 1, 14, 2, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 7, 'interf'; ASM_DATA: 'ace'; ASM_END: '>'; ASM_INTERFACE: 2, 0, 0, 0; ASM_END: ; ASM_TYPE: 6, 11, 5, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 0, 'interf'; ASM_DATA: 'ace'; ASM_INTERFACE: 2, 0, 0, 0; ASM_END: ; ASM_CLASS: 8, 0, 0, 1; ASM_BASES: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 4, 'name'; ASM_END: ''; ASM_CONST: 1, 13, 0, 3; ASM_VALUE: DAO_INTEGER; ASM_END: 123 ; ASM_VALUE: DAO_STRING, 3, 'int'; ASM_END: ''; ASM_TYPE: 1, 1, 0, 0; ASM_END: 0, 0, 0, 0; ASM_VAR: 15, 3, 1, 3; ASM_VALUE: DAO_STRING, 10, 'self:K'; ASM_END: 'lass'; ASM_TYPE: 1, 28, 9, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 5, 'a:int'; ASM_END: ''; ASM_TYPE: 1, 28, 4, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 7, '@Metho'; ASM_END: 'd'; ASM_TYPE: 1, 65, 0, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 2, 'routin'; ASM_DATA: 'e@Met'; ASM_END: 'hod>'; ASM_TYPE: 1, 17, 2, 0; ASM_END: 6, 4, 0, 0; ASM_VALUE: DAO_STRING, 6, 'Method'; ASM_END: ''; ASM_ROUTINE: 1, 2, 17, 1; ASM_END: ; ASM_ROUTINE: 1, 3, 18, 1; ASM_CONSTS: 2, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_TYPES: 2, 0, 0, 10; ASM_END: 1, 12, 0, 0; ASM_CODE: 1, 1, 0, 1; ASM_END: RETURN , 0, 0, 0; ASM_END: ; ASM_VALUE: DAO_STRING, 0, 'routin'; ASM_DATA: 'e<=>Klas'; ASM_END: 's>'; ASM_TYPE: 1, 17, 20, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 12, 'Klass:'; ASM_END: ':Klass'; ASM_ROUTINE: 1, 2, 22, 512; ASM_CONSTS: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_TYPES: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_CODE: 1, 1, 0, 1; ASM_END: RETURN , 0, 0, 0; ASM_END: ; ASM_END: ; ASM_VALUE: DAO_STRING, 5, '@Func'; ASM_END: ''; ASM_TYPE: 1, 65, 0, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 0, 'routin'; ASM_DATA: 'e<=>@Fun'; ASM_END: 'c>'; ASM_TYPE: 1, 17, 2, 0; ASM_END: 0, 0, 0, 0; ASM_VALUE: DAO_STRING, 4, 'Func'; ASM_END: ''; ASM_ROUTINE: 1, 2, 0, 0; ASM_CONSTS: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_TYPES: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_CODE: 3, 1, 26, 3; ASM_DATA: GETVG , 0, 36, 0; ASM_DATA: MOVE_XX , 0, 3, 1; ASM_END: RETURN , 0, 0, 0; ASM_END: ; ASM_CONSTS: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_TYPES: 0, 0, 0, 0; ASM_END: 0, 0, 0, 0; ASM_CODE: 10, 3, 3, 1; ASM_DATA: 10, 5, 16, 4; ASM_DATA: GETCG , 0, 52, 0; ASM_DATA: DATA_I , 1, 123, 1; ASM_DATA: GETVG , 0, 37, 2; ASM_DATA: SIZE , 2, 0, 3; ASM_DATA: ADD_III , 1, 3, 4; ASM_DATA: SETVG_II , 4, 36, 2; ASM_DATA: GETCG , 0, 35, 5; ASM_DATA: CALL , 5, 0, 6; ASM_DATA: MOVE_PP , 6, 3, 7; ASM_END: RETURN , 0, 0, 0; ASM_END: ; @[code] @[text] @[name] daovm.struct @[name] @[title] The Structures of the Dao Virtual Machine @[title] @[name] daovm.struct.vmspace @[name] @[title] VM Space @[title] @[name] daovm.struct.namespace @[name] @[title] Namespace @[title] @[name] daovm.struct.class @[name] @[title] Class @[title] @[name] daovm.struct.routine @[name] @[title] Routine @[title] @[name] daovm.struct.process @[name] @[title] VM Process @[title]