【发布时间】:2013-11-19 22:31:05
【问题描述】:
我正在查看 TCL 源代码并试图了解如何在内部管理 TCL 变量的机制。例如,给定以下 TCL 脚本:
set a 1
set b 2
我查看了 Tcl_SetObjCmd() 函数,它将一个对象设置为解释器,就是这样。因此,当第一行运行时,有一个 Tcl_Obj 被设置为值为“1”的解释器,但我没有找到该对象的检索位置,这导致了我的最终目标,该对象存储在哪里?
非常感谢任何指针!
【问题讨论】:
标签: tcl
我正在查看 TCL 源代码并试图了解如何在内部管理 TCL 变量的机制。例如,给定以下 TCL 脚本:
set a 1
set b 2
我查看了 Tcl_SetObjCmd() 函数,它将一个对象设置为解释器,就是这样。因此,当第一行运行时,有一个 Tcl_Obj 被设置为值为“1”的解释器,但我没有找到该对象的检索位置,这导致了我的最终目标,该对象存储在哪里?
非常感谢任何指针!
【问题讨论】:
标签: tcl
它比看起来更复杂。简单的版本是那里的 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,它与公共API 中的Tcl_SetVar2Ex 函数执行类似的工作。字节编译的主要优点是重复运行,其中已经处理了句法解析,因此函数的后续执行比第一次运行快得多。
您的基本问题似乎是关于如何将值返回给解释器。 interp 结构有一个使用Tcl_SetObjResult 和Tcl_GetObjResult 操作的结果槽。想要将结果返回到脚本级别的函数将 Tcl_Obj 分配给 interp 结果。
【讨论】: