Dan wrote: > Okay, here are some tasks for the interested. They're all related > (I expect you'll see the pattern), but independent anyway. > > 1) Dig through the perl source and find out all the opcodes. > (pp.c and friends) Document the opcodes and what they do. > > 2) The same as #1, only for Python > . . . > > Once we get these, the next task is to write an opcode library for > them...
The Tcl virtual machine is stack based. The stack contains only Tcl objects; these can contain just about anything. The usual stack ops are present. Ops leave their results on the stack. Many ops expect the Tcl object(s) they operate on to contain certain types of data, and will throw an exception if the constraints are violated. The operations are grouped into the following categories. (These groups are based mostly by op name in the source code, so blame the Tcl vm implementor if you disagree.) basic stack ops logical ops arithmetic and bitwise ops unary ops variable load/store/incr ops code control (function call/return; block setup/entry/exit) jump evaluation and invocation ------------------------------------------------------------------------ The Tcl VM Operations --------------------- basic stack ops: PUSH POP DUP CONCAT - concatenate strings (with no separators) from the top (n) stack items, starting with the deepest item. TRY_CVT_TO_NUMERIC - Try to convert the stack top object to an int or double object. logical ops: LOR LAND EQ NEQ LT GT LE GE arithmetic and bitwise ops: MOD - unlike C, Tcl guarantees that the remainder always has the same sign as the divisor and a smaller absolute value. DIV - ditto ADD SUB MULT RSHIFT - ensures that right shifts propagate the sign bit even on machines where ">>" won't do it by default. LSHIFT BITOR BITXOR BITAND BITOR BITXOR BITAND unary ops: (these do/honor COW for their operands) UPLUS UMINUS LNOT BITNOT variable load/store/incr ops (see NOTE 2 below): LOAD_ARRAY LOAD_ARRAY_STK LOAD_SCALAR LOAD_SCALAR_STK LOAD_STK STORE_ARRAY STORE_ARRAY_STK STORE_SCALAR STORE_SCALAR_STK STORE_STK INCR_ARRAY - increment by 1 INCR_ARRAY_STK INCR_SCALAR INCR_SCALAR_STK INCR_STK INCR_ARRAY_IMM - increment by specified "immediate" value INCR_ARRAY_STK_IMM INCR_SCALAR_IMM INCR_SCALAR_STK_IMM INCR_STK_IMM code control (function call/return; block setup/entry/exit): CALL_BUILTIN_FUNC - Call one of the built-in Tcl math functions. CALL_FUNC - Call a non-builtin Tcl math function previously registered by a call to Tcl_CreateMathFunc. BREAK - First reset the interpreter's result. Then find the closest enclosing loop or catch exception range, if any. If a loop is found, terminate its execution. If the closest is a catch exception range, jump to its catchOffset. If no enclosing range is found, stop execution and return TCL_BREAK. CONTINUE - Find the closest enclosing loop or catch exception range, if any. If a loop is found, skip to its next iteration. If the closest is a catch exception range, jump to [location of its handler]. If no enclosing range is found, stop execution and return TCL_CONTINUE result code. FOREACH_START4 FOREACH_STEP4 BEGIN_CATCH4 - Record start of the catch command with exception range index equal to the operand. Push the current stack depth onto the special catch stack. END_CATCH PUSH_RESULT PUSH_RETURN_CODE jump: JUMP JUMP_TRUE - conditional; jump if value on stack is true JUMP_FALSE evaluation and invocation: INVOKE_STK - invoke the command stored in stack top object; additional items on stack may be consumed as arguments. EVAL_STK - execute Tcl commands stored in stack top object. (These commands are compiled into bytecodes if necessary.) Stack top is replaced with result of evaluation. EXPR_STK - evaluate the expression stored in stack top object. Stack top is replaced with result. DONE - Pop the topmost object from the stack, set the interpreter's object result to point to it, and return. DONE is special; it causes the bytecode execution loop to exit. This opcode is emitted automatically at the end of compilation (you can think of it as encoding "EOF" on the source code stream.) ------------------------------------------------------------------------ NOTE 1: I have conflated versions of opcodes which were differentiated by the size or number of operands, e.g. Tcl actually defines distinct PUSH1 and PUSH4 operations. NOTE 2: SCALAR and ARRAY refer to two types of "simple" variables -- names that the compiler can resolve at compile time. In these cases, a reference to the resolved variable is used. Otherwise, the unresolved name is used (still contained in a Tcl object) and it will be resolved at run time. For example: LOAD_SCALAR - load immediate value from stack into resolved scalar variable LOAD_SCALAR_STK - load value, resulting from evaluation of expression on stack, into resolved scalar variable LOAD_ARRAY - ditto, but array variable (spec includes index) LOAD_ARRAY_STK LOAD_STK - stack contains expression for value and expression for location to load to. __________________________________________________ Do You Yahoo!? Sign up for SBC Yahoo! Dial - First Month Free http://sbc.yahoo.com