diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2011-10-03 10:45:35 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2011-10-03 10:45:35 (GMT) |
commit | f5da66af9b1d20982f24f809029662cdf55fe3b0 (patch) | |
tree | 50130e480fa011b6a08d1873587e28d09ec541af /generic/tclCompCmds.c | |
parent | 12b24fa2fb8f381005e95bb52ab317ccfaae110e (diff) | |
download | tcl-f5da66af9b1d20982f24f809029662cdf55fe3b0.zip tcl-f5da66af9b1d20982f24f809029662cdf55fe3b0.tar.gz tcl-f5da66af9b1d20982f24f809029662cdf55fe3b0.tar.bz2 |
Added support for having the dict var itself referenced by LVT index.
Diffstat (limited to 'generic/tclCompCmds.c')
-rw-r--r-- | generic/tclCompCmds.c | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 172a58d..0b6b76b 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1245,7 +1245,7 @@ TclCompileDictWithCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ - int i, range, varNameTmp, pathTmp, keysTmp, gotPath; + int i, range, varNameTmp, pathTmp, keysTmp, gotPath, dictVar = -1; Tcl_Token *dictVarTokenPtr, *tokenPtr; int savedStackDepth = envPtr->currStackDepth; JumpFixup jumpFixup; @@ -1281,7 +1281,32 @@ TclCompileDictWithCmd( */ gotPath = (parsePtr->numWords > 3); - varNameTmp = TclFindCompiledLocal(NULL, 0, 1, envPtr); + if (dictVarTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { + const char *ptr = dictVarTokenPtr[1].start; + const char *end = ptr + dictVarTokenPtr[1].size; + int notArray = 1; + + /* + * A conservative check for if we're working with an array since we + * have a reasonable fallback if things are tricky. + */ + + for (; ptr<end ; ptr++) { + if (*ptr == '(' || *ptr == ')') { + notArray = 0; + break; + } + } + if (notArray) { + dictVar = TclFindCompiledLocal(dictVarTokenPtr[1].start, + dictVarTokenPtr[1].size, 1, envPtr); + } + } + if (dictVar == -1) { + varNameTmp = TclFindCompiledLocal(NULL, 0, 1, envPtr); + } else { + varNameTmp = -1; + } if (gotPath) { pathTmp = TclFindCompiledLocal(NULL, 0, 1, envPtr); } else { @@ -1294,11 +1319,13 @@ TclCompileDictWithCmd( */ tokenPtr = dictVarTokenPtr; - CompileWord(envPtr, tokenPtr, interp, 0); - if (varNameTmp <= 255) { - TclEmitInstInt1( INST_STORE_SCALAR1, varNameTmp, envPtr); - } else { - TclEmitInstInt4( INST_STORE_SCALAR4, varNameTmp, envPtr); + if (varNameTmp > -1) { + CompileWord(envPtr, tokenPtr, interp, 0); + if (varNameTmp <= 255) { + TclEmitInstInt1( INST_STORE_SCALAR1, varNameTmp, envPtr); + } else { + TclEmitInstInt4( INST_STORE_SCALAR4, varNameTmp, envPtr); + } } tokenPtr = TokenAfter(tokenPtr); if (gotPath) { @@ -1314,7 +1341,13 @@ TclCompileDictWithCmd( } TclEmitOpcode( INST_POP, envPtr); } - TclEmitOpcode( INST_LOAD_STK, envPtr); + if (dictVar == -1) { + TclEmitOpcode( INST_LOAD_STK, envPtr); + } else if (dictVar <= 255) { + TclEmitInstInt1( INST_LOAD_SCALAR1, dictVar, envPtr); + } else { + TclEmitInstInt4( INST_LOAD_SCALAR4, dictVar, envPtr); + } if (gotPath) { if (pathTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, pathTmp, envPtr); @@ -1351,9 +1384,9 @@ TclCompileDictWithCmd( */ TclEmitOpcode( INST_END_CATCH, envPtr); - if (varNameTmp <= 255) { + if (varNameTmp > -1 && varNameTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, varNameTmp, envPtr); - } else { + } else if (varNameTmp > -1) { TclEmitInstInt4( INST_LOAD_SCALAR4, varNameTmp, envPtr); } if (gotPath) { @@ -1370,7 +1403,11 @@ TclCompileDictWithCmd( } else { TclEmitInstInt4( INST_LOAD_SCALAR4, keysTmp, envPtr); } - TclEmitOpcode( INST_DICT_RECOMBINE, envPtr); + if (dictVar == -1) { + TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr); + } else { + TclEmitInstInt4( INST_DICT_RECOMBINE_IMM, dictVar, envPtr); + } TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup); /* @@ -1381,9 +1418,9 @@ TclCompileDictWithCmd( TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr); TclEmitOpcode( INST_PUSH_RESULT, envPtr); TclEmitOpcode( INST_END_CATCH, envPtr); - if (varNameTmp <= 255) { + if (varNameTmp > -1 && varNameTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, varNameTmp, envPtr); - } else { + } else if (varNameTmp > -1) { TclEmitInstInt4( INST_LOAD_SCALAR4, varNameTmp, envPtr); } if (parsePtr->numWords > 3) { @@ -1400,7 +1437,11 @@ TclCompileDictWithCmd( } else { TclEmitInstInt4( INST_LOAD_SCALAR4, keysTmp, envPtr); } - TclEmitOpcode( INST_DICT_RECOMBINE, envPtr); + if (dictVar == -1) { + TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr); + } else { + TclEmitInstInt4( INST_DICT_RECOMBINE_IMM, dictVar, envPtr); + } TclEmitOpcode( INST_RETURN_STK, envPtr); /* |