【问题标题】:Where/how do the TCL variables saved?TCL 变量在哪里/如何保存?
【发布时间】:2013-11-19 22:31:05
【问题描述】:

我正在查看 TCL 源代码并试图了解如何在内部管理 TCL 变量的机制。例如,给定以下 TCL 脚本:

set a 1
set b 2

我查看了 Tcl_SetObjCmd() 函数,它将一个对象设置为解释器,就是这样。因此,当第一行运行时,有一个 Tcl_Obj 被设置为值为“1”的解释器,但我没有找到该对象的检索位置,这导致了我的最终目标,该对象存储在哪里?

非常感谢任何指针!

【问题讨论】:

    标签: tcl


    【解决方案1】:

    它比看起来更复杂。简单的版本是那里的 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_SetObjResultTcl_GetObjResult 操作的结果槽。想要将结果返回到脚本级别的函数将 Tcl_Obj 分配给 interp 结果。

    【讨论】:

    • 谢谢。这有帮助。我正在处理的问题是,当 TCL 无法分配内存(ckalloc 失败)时,TCL 就会出现恐慌。我喜欢使用 setjmp/longjmp 尽可能干净地退出,这需要取消分配已经分配的变量。我将跟踪 tclExecute.c 以获取线索。但我们很感谢您的建议!
    • @my_question 如果 ckalloc 因少量分配而失败,您将完全陷入困境:没有剩余内存。不要太担心清理工作,因为你的资源太少了,恢复的可能性非常小。这是在交付给客户的实时代码中发生的,还是仅仅在测试中发生的?
    猜你喜欢
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    • 2020-03-16
    • 1970-01-01
    • 2010-12-17
    • 2017-03-26
    • 2010-10-02
    • 1970-01-01
    相关资源
    最近更新 更多