diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2023-12-05 15:48:03 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2023-12-05 15:48:03 (GMT) |
commit | 345dcdfb8ad2fa31e53650c111342f7888d8cb8a (patch) | |
tree | 3ee27d8891ba30e7903b9579ae80d1825aded9dd /generic/tclExecute.c | |
parent | 4d0ad9c0f93437f64fa9450ad43fd8f6c17e7f85 (diff) | |
download | tcl-345dcdfb8ad2fa31e53650c111342f7888d8cb8a.zip tcl-345dcdfb8ad2fa31e53650c111342f7888d8cb8a.tar.gz tcl-345dcdfb8ad2fa31e53650c111342f7888d8cb8a.tar.bz2 |
Bytecode implementation
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 8149532..8cce3ba 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3926,6 +3926,77 @@ TEBCresume( /* * End of INST_UNSET instructions. * ----------------------------------------------------------------- + * Start of INST_CONST instructions. + */ + { + const char *msgPart; + + case INST_CONST_IMM: + opnd = TclGetUInt4AtPtr(pc+1); + pcAdjustment = 5; + cleanup = 1; + part1Ptr = NULL; + objPtr = OBJ_AT_TOS; + TRACE(("%u "\"%.30s\" => \n", opnd, O2S(objPtr))); + varPtr = LOCAL(opnd); + arrayPtr = NULL; + while (TclIsVarLink(varPtr)) { + varPtr = varPtr->value.linkPtr; + } + goto doConst; + case INST_CONST_STK: + opnd = -1; + pcAdjustment = 1; + cleanup = 2; + part1Ptr = OBJ_UNDER_TOS; + objPtr = OBJ_AT_TOS; + TRACE(("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(objPtr))); + varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL, + /*createPart1*/1, /*createPart2*/0, &arrayPtr); + doConst: + if (TclIsVarConstant(varPtr)) { + TRACE_APPEND(("\n")); + NEXT_INST_V(pcAdjustment, cleanup, 0); + } + if (TclIsVarArray(varPtr)) { + msgPart = "variable is array"; + goto constError; + } else if (TclIsVarArrayElement(varPtr)) { + msgPart = "name refers to an element in an array"; + goto constError; + } else if (!TclIsVarUndefined(varPtr)) { + msgPart = "variable already exists"; + goto constError; + } + if (TclIsVarDirectModifyable(varPtr)) { + varPtr->value.objPtr = objPtr; + Tcl_IncrRefCount(objPtr); + } else { + Tcl_Obj *resPtr; + + DECACHE_STACK_INFO(); + resPtr = TclPtrSetVarIdx(interp, varPtr, arrayPtr, part1Ptr, NULL, + objPtr, TCL_LEAVE_ERR_MSG, opnd); + CACHE_STACK_INFO(); + if (resPtr == NULL) { + TRACE_ERROR(interp); + goto gotError; + } + } + TclSetVarConstant(varPtr); + TRACE_APPEND(("\n")); + NEXT_INST_V(pcAdjustment, cleanup, 0); + + constError: + TclObjVarErrMsg(interp, part1Ptr, NULL, "make constant", msgPart, opnd); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CONST", (void *)NULL); + TRACE_ERROR(interp); + goto gotError; + } + + /* + * End of INST_CONST instructions. + * ----------------------------------------------------------------- * Start of INST_ARRAY instructions. */ |