我正在查看TCL源代码并尝试了解内部如何管理TCL变量的机制。例如,给定以下TCL脚本:
set a 1
set b 2
我查看了Tcl_SetObjCmd()函数,它将一个对象设置为解释器,就是这样。因此,当第一行运行时,有一个Tcl_Obj设置为解释器,值为“1”,但是我找不到这个对象的检索位置,这导致了我的最终目标,该对象在哪里存储?
非常感谢任何指针!
答案 0 :(得分:2)
它比它看起来更复杂。简单的版本是那里的Tcl表达式将Tcl_SetVar2Ex称为类Tcl_SetVar2Ex(interp, "a", NULL, Tcl_NewIntObj(1), 0)
,以在解释器中设置一个名为'a'的变量,并给出值。它还将使用Tcl_SetObjResult将此分配给解释器的结果。
然而,现代Tcl进行字节编译并执行其他操作。我们可以检查如下所示:
% tcl::unsupported::disassemble script {set a 1}
ByteCode 0x0x10e0110, refCt 1, epoch 3, interp 0x0xde9d00 (epoch 3)
Source "set a 1"
Cmds 1, src 7, inst 6, litObjs 2, aux 0, stkDepth 2, code/src 0.00
Commands 1:
1: pc 0-4, src 0-6
Command 1: "set a 1"
(0) push1 0 # "a"
(2) push1 1 # "1"
(4) storeScalarStk
(5) done
因此字节编译版本实际上将名称和值压入堆栈然后调用此storeScalarStk函数。在源代码中进行的一些挖掘表明,它在generic / tclExecute.c中以INST_STORE_SCALAR_STK
执行,它基本上只跳转到doCallPtrSetVar
,在那里调用TclPtrSetVar
,它执行与Tcl_SetVar2Ex函数类似的工作。公共API。字节编译的主要优点是重复运行,其中语法分析已经被处理,因此后续执行函数比第一次运行快得多。
您的基本问题似乎是关于如何将值返回给解释器。 interp结构有一个结果槽,由Tcl_SetObjResult
和Tcl_GetObjResult
操纵。想要将结果返回到脚本级别的函数将Tcl_Obj分配给interp结果。