diff options
Diffstat (limited to 'generic/tclCompile.h')
-rw-r--r-- | generic/tclCompile.h | 555 |
1 files changed, 320 insertions, 235 deletions
diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 4d8ed65..6171a49 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -455,266 +455,222 @@ typedef struct ByteCode { * tclExecute.c. */ -/* Opcodes 0 to 9 */ +/* Opcodes 0 to 7 */ #define INST_DONE 0 -#define INST_PUSH1 1 -#define INST_PUSH4 2 -#define INST_POP 3 -#define INST_DUP 4 -#define INST_CONCAT1 5 -#define INST_INVOKE_STK1 6 -#define INST_INVOKE_STK4 7 -#define INST_EVAL_STK 8 -#define INST_EXPR_STK 9 - -/* Opcodes 10 to 23 */ -#define INST_LOAD_SCALAR1 10 -#define INST_LOAD_SCALAR4 11 -#define INST_LOAD_SCALAR_STK 12 -#define INST_LOAD_ARRAY1 13 -#define INST_LOAD_ARRAY4 14 -#define INST_LOAD_ARRAY_STK 15 -#define INST_LOAD_STK 16 -#define INST_STORE_SCALAR1 17 -#define INST_STORE_SCALAR4 18 -#define INST_STORE_SCALAR_STK 19 -#define INST_STORE_ARRAY1 20 -#define INST_STORE_ARRAY4 21 -#define INST_STORE_ARRAY_STK 22 -#define INST_STORE_STK 23 - -/* Opcodes 24 to 33 */ -#define INST_INCR_SCALAR1 24 -#define INST_INCR_SCALAR_STK 25 -#define INST_INCR_ARRAY1 26 -#define INST_INCR_ARRAY_STK 27 -#define INST_INCR_STK 28 -#define INST_INCR_SCALAR1_IMM 29 -#define INST_INCR_SCALAR_STK_IMM 30 -#define INST_INCR_ARRAY1_IMM 31 -#define INST_INCR_ARRAY_STK_IMM 32 -#define INST_INCR_STK_IMM 33 - -/* Opcodes 34 to 39 */ -#define INST_JUMP1 34 -#define INST_JUMP4 35 -#define INST_JUMP_TRUE1 36 -#define INST_JUMP_TRUE4 37 -#define INST_JUMP_FALSE1 38 -#define INST_JUMP_FALSE4 39 - -/* Opcodes 40 to 64 */ -#define INST_LOR 40 -#define INST_LAND 41 -#define INST_BITOR 42 -#define INST_BITXOR 43 -#define INST_BITAND 44 -#define INST_EQ 45 -#define INST_NEQ 46 -#define INST_LT 47 -#define INST_GT 48 -#define INST_LE 49 -#define INST_GE 50 -#define INST_LSHIFT 51 -#define INST_RSHIFT 52 -#define INST_ADD 53 -#define INST_SUB 54 -#define INST_MULT 55 -#define INST_DIV 56 -#define INST_MOD 57 -#define INST_UPLUS 58 -#define INST_UMINUS 59 -#define INST_BITNOT 60 -#define INST_LNOT 61 -#define INST_CALL_BUILTIN_FUNC1 62 -#define INST_CALL_FUNC1 63 -#define INST_TRY_CVT_TO_NUMERIC 64 - -/* Opcodes 65 to 66 */ -#define INST_BREAK 65 -#define INST_CONTINUE 66 - -/* Opcodes 67 to 68 */ -#define INST_FOREACH_START4 67 -#define INST_FOREACH_STEP4 68 - -/* Opcodes 69 to 72 */ -#define INST_BEGIN_CATCH4 69 -#define INST_END_CATCH 70 -#define INST_PUSH_RESULT 71 -#define INST_PUSH_RETURN_CODE 72 - -/* Opcodes 73 to 78 */ -#define INST_STR_EQ 73 -#define INST_STR_NEQ 74 -#define INST_STR_CMP 75 -#define INST_STR_LEN 76 -#define INST_STR_INDEX 77 -#define INST_STR_MATCH 78 - -/* Opcodes 78 to 81 */ -#define INST_LIST 79 -#define INST_LIST_INDEX 80 -#define INST_LIST_LENGTH 81 - -/* Opcodes 82 to 87 */ -#define INST_APPEND_SCALAR1 82 -#define INST_APPEND_SCALAR4 83 -#define INST_APPEND_ARRAY1 84 -#define INST_APPEND_ARRAY4 85 -#define INST_APPEND_ARRAY_STK 86 -#define INST_APPEND_STK 87 - -/* Opcodes 88 to 93 */ -#define INST_LAPPEND_SCALAR1 88 -#define INST_LAPPEND_SCALAR4 89 -#define INST_LAPPEND_ARRAY1 90 -#define INST_LAPPEND_ARRAY4 91 -#define INST_LAPPEND_ARRAY_STK 92 -#define INST_LAPPEND_STK 93 +#define INST_PUSH 1 +#define INST_POP 2 +#define INST_DUP 3 +#define INST_CONCAT 4 +#define INST_INVOKE_STK 5 +#define INST_EVAL_STK 6 +#define INST_EXPR_STK 7 + +/* Opcodes 8 to 17: [set] */ +#define INST_LOAD_SCALAR 8 +#define INST_LOAD_SCALAR_STK 9 +#define INST_LOAD_ARRAY 10 +#define INST_LOAD_ARRAY_STK 11 +#define INST_LOAD_STK 12 +#define INST_STORE_SCALAR 13 +#define INST_STORE_SCALAR_STK 14 +#define INST_STORE_ARRAY 15 +#define INST_STORE_ARRAY_STK 16 +#define INST_STORE_STK 17 + +/* Opcodes 18 to 25: [incr] */ +#define INST_INCR_SCALAR 18 +#define INST_INCR_ARRAY 19 +#define INST_INCR_ARRAY_STK 20 +#define INST_INCR_STK 21 +#define INST_INCR_SCALAR_IMM 22 +#define INST_INCR_ARRAY_IMM 23 +#define INST_INCR_ARRAY_STK_IMM 24 +#define INST_INCR_STK_IMM 25 + +/* Opcodes 26 to 28 */ +#define INST_JUMP 26 +#define INST_JUMP_TRUE 27 +#define INST_JUMP_FALSE 28 + +/* Opcodes 29 to 54: operators */ +#define INST_LOR 29 +#define INST_LAND 30 +#define INST_BITOR 31 +#define INST_BITXOR 32 +#define INST_BITAND 33 +#define INST_EQ 34 +#define INST_NEQ 35 +#define INST_LT 36 +#define INST_GT 37 +#define INST_LE 38 +#define INST_GE 39 +#define INST_LSHIFT 40 +#define INST_RSHIFT 41 +#define INST_ADD 42 +#define INST_SUB 43 +#define INST_MULT 44 +#define INST_DIV 45 +#define INST_MOD 46 +#define INST_UPLUS 47 +#define INST_UMINUS 48 +#define INST_BITNOT 49 +#define INST_LNOT 50 +#define INST_TRY_CVT_TO_NUMERIC 51 +#define INST_EXPON 52 +#define INST_LIST_IN 53 +#define INST_LIST_NOT_IN 54 + +/* Opcodes 55 to 56: [foreach] */ +#define INST_FOREACH_START 55 +#define INST_FOREACH_STEP 56 + +/* Opcodes 57 to 66 */ +#define INST_BREAK 57 +#define INST_CONTINUE 58 +#define INST_BEGIN_CATCH 59 +#define INST_END_CATCH 60 +#define INST_PUSH_RESULT 61 +#define INST_PUSH_RETURN_CODE 62 +#define INST_PUSH_RETURN_OPTIONS 63 +#define INST_RETURN_STK 64 +#define INST_RETURN_IMM 65 +#define INST_RETURN_CODE_BRANCH 66 + +/* Opcodes 67 to 72 */ +#define INST_STR_EQ 67 +#define INST_STR_NEQ 68 +#define INST_STR_CMP 69 +#define INST_STR_LEN 70 +#define INST_STR_INDEX 71 +#define INST_STR_MATCH 72 + +/* Opcodes 73 to 75: list ops */ +#define INST_LIST 73 +#define INST_LIST_INDEX 74 +#define INST_LIST_LENGTH 75 + +/* Opcodes 76 to 79: [append] */ +#define INST_APPEND_SCALAR 76 +#define INST_APPEND_ARRAY 77 +#define INST_APPEND_ARRAY_STK 78 +#define INST_APPEND_STK 79 + +/* Opcodes 80 to 83: [lappend] */ +#define INST_LAPPEND_SCALAR 80 +#define INST_LAPPEND_ARRAY 81 +#define INST_LAPPEND_ARRAY_STK 82 +#define INST_LAPPEND_STK 83 /* TIP #22 - LINDEX operator with flat arg list */ +#define INST_LIST_INDEX_MULTI 84 -#define INST_LIST_INDEX_MULTI 94 - -/* - * TIP #33 - 'lset' command. Code gen also required a Forth-like - * OVER operation. - */ - -#define INST_OVER 95 -#define INST_LSET_LIST 96 -#define INST_LSET_FLAT 97 - -/* TIP#90 - 'return' command. */ - -#define INST_RETURN_IMM 98 - -/* TIP#123 - exponentiation operator. */ - -#define INST_EXPON 99 +/* TIP #33 - 'lset' command. */ +#define INST_LSET_LIST 85 +#define INST_LSET_FLAT 86 /* TIP #157 - {*}... (word expansion) language syntax support. */ - -#define INST_EXPAND_START 100 -#define INST_EXPAND_STKTOP 101 -#define INST_INVOKE_EXPANDED 102 +#define INST_EXPAND_START 87 +#define INST_EXPAND_STKTOP 88 +#define INST_INVOKE_EXPANDED 89 /* * TIP #57 - 'lassign' command. Code generation requires immediate * LINDEX and LRANGE operators. */ -#define INST_LIST_INDEX_IMM 103 -#define INST_LIST_RANGE_IMM 104 - -#define INST_START_CMD 105 - -#define INST_LIST_IN 106 -#define INST_LIST_NOT_IN 107 - -#define INST_PUSH_RETURN_OPTIONS 108 -#define INST_RETURN_STK 109 - -/* - * Dictionary (TIP#111) related commands. - */ - -#define INST_DICT_GET 110 -#define INST_DICT_SET 111 -#define INST_DICT_UNSET 112 -#define INST_DICT_INCR_IMM 113 -#define INST_DICT_APPEND 114 -#define INST_DICT_LAPPEND 115 -#define INST_DICT_FIRST 116 -#define INST_DICT_NEXT 117 -#define INST_DICT_DONE 118 -#define INST_DICT_UPDATE_START 119 -#define INST_DICT_UPDATE_END 120 +#define INST_LIST_INDEX_IMM 90 +#define INST_LIST_RANGE_IMM 91 + +#define INST_START_CMD 92 + +/* Dictionary (TIP#111) related commands. */ +#define INST_DICT_GET 93 +#define INST_DICT_SET 94 +#define INST_DICT_UNSET 95 +#define INST_DICT_INCR_IMM 96 +#define INST_DICT_APPEND 97 +#define INST_DICT_LAPPEND 98 +#define INST_DICT_FIRST 99 +#define INST_DICT_NEXT 100 +#define INST_DICT_UPDATE_START 101 +#define INST_DICT_UPDATE_END 102 +#define INST_DICT_EXPAND 103 +#define INST_DICT_RECOMBINE_STK 104 +#define INST_DICT_RECOMBINE_IMM 105 +#define INST_DICT_EXISTS 106 +#define INST_DICT_VERIFY 107 /* * Instruction to support jumps defined by tables (instead of the classic * [switch] technique of chained comparisons). */ -#define INST_JUMP_TABLE 121 +#define INST_JUMP_TABLE 108 /* * Instructions to support compilation of global, variable, upvar and * [namespace upvar]. */ -#define INST_UPVAR 122 -#define INST_NSUPVAR 123 -#define INST_VARIABLE 124 +#define INST_UPVAR 109 +#define INST_NSUPVAR 110 +#define INST_VARIABLE 111 -/* Instruction to support compiling syntax error to bytecode */ - -#define INST_SYNTAX 125 - -/* Instruction to reverse N items on top of stack */ - -#define INST_REVERSE 126 +/* Utilities */ +#define INST_OVER 112 +#define INST_SYNTAX 113 +#define INST_REVERSE 114 +#define INST_NOP 115 /* regexp instruction */ - -#define INST_REGEXP 127 +#define INST_REGEXP 116 /* For [info exists] compilation */ -#define INST_EXIST_SCALAR 128 -#define INST_EXIST_ARRAY 129 -#define INST_EXIST_ARRAY_STK 130 -#define INST_EXIST_STK 131 - -/* For [subst] compilation */ -#define INST_NOP 132 -#define INST_RETURN_CODE_BRANCH 133 +#define INST_EXIST_SCALAR 117 +#define INST_EXIST_ARRAY 118 +#define INST_EXIST_ARRAY_STK 119 +#define INST_EXIST_STK 120 /* For [unset] compilation */ -#define INST_UNSET_SCALAR 134 -#define INST_UNSET_ARRAY 135 -#define INST_UNSET_ARRAY_STK 136 -#define INST_UNSET_STK 137 - -/* For [dict with], [dict exists], [dict create] and [dict merge] */ -#define INST_DICT_EXPAND 138 -#define INST_DICT_RECOMBINE_STK 139 -#define INST_DICT_RECOMBINE_IMM 140 -#define INST_DICT_EXISTS 141 -#define INST_DICT_VERIFY 142 +#define INST_UNSET_SCALAR 121 +#define INST_UNSET_ARRAY 122 +#define INST_UNSET_ARRAY_STK 123 +#define INST_UNSET_STK 124 /* For [string map] and [regsub] compilation */ -#define INST_STR_MAP 143 -#define INST_STR_FIND 144 -#define INST_STR_FIND_LAST 145 -#define INST_STR_RANGE_IMM 146 -#define INST_STR_RANGE 147 +#define INST_STR_MAP 125 +#define INST_STR_FIND 126 +#define INST_STR_FIND_LAST 127 +#define INST_STR_RANGE_IMM 128 +#define INST_STR_RANGE 129 /* For operations to do with coroutines and other NRE-manipulators */ -#define INST_YIELD 148 -#define INST_COROUTINE_NAME 149 -#define INST_TAILCALL 150 +#define INST_YIELD 130 +#define INST_COROUTINE_NAME 131 +#define INST_TAILCALL 132 /* For compilation of basic information operations */ -#define INST_NS_CURRENT 151 -#define INST_INFO_LEVEL_NUM 152 -#define INST_INFO_LEVEL_ARGS 153 -#define INST_RESOLVE_COMMAND 154 -#define INST_TCLOO_SELF 155 -#define INST_TCLOO_CLASS 156 -#define INST_TCLOO_NS 157 -#define INST_TCLOO_IS_OBJECT 158 +#define INST_NS_CURRENT 133 +#define INST_INFO_LEVEL_NUM 134 +#define INST_INFO_LEVEL_ARGS 135 +#define INST_RESOLVE_COMMAND 136 +#define INST_TCLOO_SELF 137 +#define INST_TCLOO_CLASS 138 +#define INST_TCLOO_NS 139 +#define INST_TCLOO_IS_OBJECT 140 /* For compilation of [array] subcommands */ -#define INST_ARRAY_EXISTS_STK 159 -#define INST_ARRAY_EXISTS_IMM 160 -#define INST_ARRAY_MAKE_STK 161 -#define INST_ARRAY_MAKE_IMM 162 +#define INST_ARRAY_EXISTS_STK 141 +#define INST_ARRAY_EXISTS_IMM 142 +#define INST_ARRAY_MAKE_STK 143 +#define INST_ARRAY_MAKE_IMM 144 -#define INST_INVOKE_REPLACE 163 +#define INST_EXCH 145 +#define INST_UNDER 146 +#define INST_INVOKE_REPLACE 147 /* The last opcode */ -#define LAST_INST_OPCODE 163 +#define LAST_INST_OPCODE 147 /* * Table describing the Tcl bytecode instructions: their name (for displaying @@ -735,8 +691,6 @@ typedef enum InstOperandType { OPERAND_UINT4, /* Four byte unsigned integer. */ OPERAND_IDX4, /* Four byte signed index (actually an * integer, but displayed differently.) */ - OPERAND_LVT1, /* One byte unsigned index into the local - * variable table. */ OPERAND_LVT4, /* Four byte unsigned index into the local * variable table. */ OPERAND_AUX4 /* Four byte unsigned index into the aux data @@ -987,6 +941,11 @@ MODULE_SCOPE void TclPrintObject(FILE *outFile, Tcl_Obj *objPtr, int maxChars); MODULE_SCOPE void TclPrintSource(FILE *outFile, const char *string, int maxChars); +MODULE_SCOPE int TclPushVarName(Tcl_Interp *interp, + Tcl_Token *varTokenPtr, CompileEnv *envPtr, + int flags, int *localIndexPtr, + int *simpleVarNamePtr, int *isScalarPtr, + int line, int *clNext); MODULE_SCOPE void TclRegisterAuxDataType(const AuxDataType *typePtr); MODULE_SCOPE int TclRegisterLiteral(CompileEnv *envPtr, char *bytes, int length, int flags); @@ -1012,11 +971,11 @@ MODULE_SCOPE void TclVerifyLocalLiteralTable(CompileEnv *envPtr); MODULE_SCOPE int TclWordKnownAtCompileTime(Tcl_Token *tokenPtr, Tcl_Obj *valuePtr); MODULE_SCOPE void TclLogCommandInfo(Tcl_Interp *interp, - const char *script, - const char *command, int length, - const unsigned char *pc, Tcl_Obj **tosPtr); + const char *script, const char *command, + int length, const unsigned char *pc, + Tcl_Obj **tosPtr); MODULE_SCOPE Tcl_Obj *TclGetInnerContext(Tcl_Interp *interp, - const unsigned char *pc, Tcl_Obj **tosPtr); + const unsigned char *pc, Tcl_Obj **tosPtr); MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); @@ -1191,11 +1150,7 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); #define TclEmitPush(objIndex, envPtr) \ do { \ register int objIndexCopy = (objIndex); \ - if (objIndexCopy <= 255) { \ - TclEmitInstInt1(INST_PUSH1, objIndexCopy, (envPtr)); \ - } else { \ - TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \ - } \ + TclEmitInstInt4(INST_PUSH, objIndexCopy, (envPtr)); \ } while (0) /* @@ -1330,6 +1285,7 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); #define CompileTokens(envPtr, tokenPtr, interp) \ TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \ (envPtr)); + /* * Convenience macro for use when pushing literals. The ANSI C "prototype" for * this macro is: @@ -1362,11 +1318,10 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); ((envPtr)->codeNext - (envPtr)->codeStart) /* - * Note: the exceptDepth is a bit of a misnomer: TEBC only needs the - * maximal depth of nested CATCH ranges in order to alloc runtime - * memory. These macros should compute precisely that? OTOH, the nesting depth - * of LOOP ranges is an interesting datum for debugging purposes, and that is - * what we compute now. + * Note: the exceptDepth is a bit of a misnomer: TEBC only needs the maximal + * depth of nested CATCH ranges in order to alloc runtime memory. These macros + * should compute precisely that? OTOH, the nesting depth of LOOP ranges is an + * interesting datum for debugging purposes, and that is what we compute now. * * static int DeclareExceptionRange(CompileEnv *envPtr, int type); * static int ExceptionRangeStarts(CompileEnv *envPtr, int index); @@ -1389,12 +1344,16 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); ((envPtr)->exceptArrayPtr[(index)].targetType = CurrentOffset(envPtr)) /* - * Check if there is an LVT for compiled locals + * Check if there is an LVT for compiled locals, and issuing a new private + * variable. */ #define EnvHasLVT(envPtr) \ (envPtr->procPtr || envPtr->iPtr->varFramePtr->localCachePtr) +#define NewUnnamedLocal(envPtr) \ + TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1, (envPtr)) + /* * Macros for making it easier to deal with tokens and DStrings. */ @@ -1406,6 +1365,132 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); Tcl_DStringLength(dsPtr), /*flags*/ 0) /* + * Macro that encapsulates an efficiency trick that avoids a function call for + * the simplest of compiles. The ANSI C "prototype" for this macro is: + * + * static void CompileWord(CompileEnv *envPtr, Tcl_Token *tokenPtr, + * Tcl_Interp *interp, int word); + */ + +#define CompileWord(envPtr, tokenPtr, interp, word) \ + if ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD) { \ + TclEmitPush(TclRegisterNewLiteral((envPtr), (tokenPtr)[1].start, \ + (tokenPtr)[1].size), (envPtr)); \ + } else { \ + envPtr->line = mapPtr->loc[eclIndex].line[word]; \ + envPtr->clNext = mapPtr->loc[eclIndex].next[word]; \ + TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \ + (envPtr)); \ + } + +/* + * TIP #280: Remember the per-word line information of the current command. An + * index is used instead of a pointer as recursive compilation may reallocate, + * i.e. move, the array. This is also the reason to save the nuloc now, it may + * change during the course of the function. + * + * Macro to encapsulate the variable definition and setup. + */ + +#define DefineLineInformation \ + ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \ + int eclIndex = mapPtr->nuloc - 1 + +#define SetLineInformation(word) \ + do { \ + envPtr->line = mapPtr->loc[eclIndex].line[(word)]; \ + envPtr->clNext = mapPtr->loc[eclIndex].next[(word)]; \ + } while (0) + +#define PushVarNameWord(i,v,e,f,l,s,sc,word) \ + TclPushVarName(i,v,e,f,l,s,sc, \ + mapPtr->loc[eclIndex].line[(word)], \ + mapPtr->loc[eclIndex].next[(word)]) + +/* + * Flags bits used by TclPushVarName. + */ + +#define TCL_NO_LARGE_INDEX 1 /* Do not return localIndex value > 255 */ +#define TCL_NO_ELEMENT 2 /* Do not push the array element. */ + +/* + * Shorthand macros for instruction issuing. Note that these assume that there + * are variables in the current environment called 'envPtr' and 'interp', and + * also that there are no side effects in the arguments given. + */ + +#define OP(name) TclEmitOpcode(INST_##name, envPtr) +#define OP1(name,val) TclEmitInstInt1(INST_##name, (val), envPtr) +#define OP4(name,val) TclEmitInstInt4(INST_##name, (val), envPtr) +#define OP14(name,val1,val2) \ + do { \ + TclEmitInstInt1(INST_##name, (val1), envPtr); \ + TclEmitInt4((val2), envPtr); \ + } while (0) +#define OP41(name,val1,val2) \ + do { \ + TclEmitInstInt4(INST_##name, (val1), envPtr); \ + TclEmitInt1((val2), envPtr); \ + } while (0) +#define OP44(name,val1,val2) \ + do { \ + TclEmitInstInt4(INST_##name, (val1), envPtr); \ + TclEmitInt4((val2), envPtr); \ + } while (0) +#define BODY(token,index) \ + do { \ + SetLineInformation((index)); \ + CompileBody(envPtr, (token), interp); \ + } while (0) +#define PUSH(str) \ + PushLiteral(envPtr, (str), strlen(str)) +#define PUSH_SUBST_WORD(token,index) \ + do { \ + Tcl_Token *theTokenToCompile = (token); \ + int theIndex = (index); \ + CompileWord(envPtr, theTokenToCompile, interp, theIndex); \ + } while (0) +#define PUSH_EXPR_WORD(token,index) \ + do { \ + Tcl_Token *theTokenToCompile = (token); \ + int theIndex = (index); \ + SetLineInformation(theIndex); \ + TclCompileExprWords(interp, theTokenToCompile, 1, envPtr); \ + } while (0) +#define PUSH_VAR(v,word,l,s,sc) \ + TclPushVarName(interp,(v),envPtr,0,(l),(s),(sc), \ + mapPtr->loc[eclIndex].line[(word)], \ + mapPtr->loc[eclIndex].next[(word)]) +#define PUSH_OBJ(obj) \ + do { \ + int objLength; \ + char *objBytes = Tcl_GetStringFromObj((obj), &objLength); \ + PushLiteral(envPtr, objBytes, objLength); \ + } while (0) +#define PUSH_DSTRING(dsPtr) \ + PushLiteral(envPtr, Tcl_DStringValue((dsPtr)), Tcl_DStringLength((dsPtr))) +#define LABEL(var) \ + ((var) = CurrentOffset(envPtr)) +#define BACKJUMP(var,name) \ + do { \ + int theOffset = (var) - CurrentOffset(envPtr); \ + TclEmitInstInt4(INST_##name, theOffset, envPtr); \ + } while (0) +#define JUMP(var,name) \ + do { \ + (var) = CurrentOffset(envPtr); \ + TclEmitInstInt4(INST_##name, 0, envPtr); \ + } while (0) +#define FIXJUMP(var) \ + do { \ + if ((var) >= 0) { \ + TclStoreInt4AtPtr(CurrentOffset(envPtr)-(var), \ + envPtr->codeStart+(var)+1); \ + } \ + } while (0) + +/* * DTrace probe macros (NOPs if DTrace support is not enabled). */ |