代码之家  ›  专栏  ›  技术社区  ›  Oak

在squak中,我在哪里找到消息处理算法的代码?

  •  4
  • Oak  · 技术社区  · 14 年前

    当以吱吱声向对象发送消息时,运行时调用算法类似于

    1. curr<-接收器的类
    2. 当货币不是零时重复
      1. 在该类的方法中搜索选择器;如果存在,则调用它并返回
      2. curr<-curr的超类
    3. 呼叫 doesNotUnderstand: self

    现在,一个非常相似的算法被用于 respondsTo: 方法,确实可以通过检查 答: 的代码。 我想找到的是用于调用的上述算法的代码位置 .

    我知道 perform: 做了一些类似的事情,但我相信它不是用于常规方法调用,而是作为一种类似于反射的方法调用机制(例如,当方法名直到运行时才为程序员所知时)。

    如果上面的代码也作为原始指令隐藏,那么在哪里可以找到原始调用?如果不是,我在哪里可以找到代码本身?

    3 回复  |  直到 14 年前
        1
  •  2
  •   Frank Shearar    14 年前

    你可能想看看 VMMaker . 它的解释器类是执行compiledMethod的字节码的人,它实际上会将消息发送到您的对象。

    例如,如果您查看对象的字节码>>respondsto:

    17 <70> self
    18 <C7> send: class
    19 <10> pushTemp: 0
    20 <E0> send: canUnderstand:
    21 <7C> returnTop
    

    解释器读取一个字节码,查找其字节码表中的字节码(在解释器类>>initialiseBytecodetable中初始化),并执行适当的方法。因此,<70>(pushReceiverBytecode)将自己推到解释器的内部堆栈上。然后(bytecodeDeprimClass)归结为“找到自我的类”。<10>(pushTemporaryVariableBytecode)将参数推送到堆栈上。有趣的部分发生在(sendliteralselectorbytecode),它调用 self normalSend . #NormalSend依次计算出接收器的类别( self class 在这种情况下),然后调用 self commonSend 找到我们要运行的实际方法,然后运行它。

    我是一个虚拟机新手;上面的内容可能不是看到算法实际运行的最佳场所,等等(甚至不是最好的解释),但我希望这是一个好的开始。

    虚拟机用来实际发送消息的算法和您在问题中概述的一样。该算法的实际实现在 Interpreter>>commonSend . 查找算法在 Interpreter>>lookupMethodInClass: 执行算法在 Interpreter>>internalExecuteNewMethod .

    前者和你描述的差不多:

    1. 列表项
    2. 尝试在此类中查找方法。
    3. 如果找不到,请查看超类。
    4. 如果递归失败,请尝试查找“doesnotunderstand:
    5. 如果不存在:类层次结构中的任何位置都不存在,则抛出一个错误。

    后者的工作原理如下:

    1. 如果是原语,运行原语。
    2. 如果不是,则激活新方法(创建新的激活记录)。
    3. (检查中断。)
        2
  •  1
  •   Oak    14 年前

    再挖一点 ContextPart 类是能够运行字节码的解释器。根据其文件:

    [与此问题相关的方法] 与Smalltalk机器本身的操作完全平行 .

    如果我们检查它是如何解释字节码的,

    1. 它的 interpret 方法调用其 interpretNextInstructionFor: 对于每个指令。
    2. 解释解释说明: 电话 send:super:numArgs: 当遇到发送指令时。
    3. 发送:super:numargs: 电话 send:to:with:super: (假设它不是原始消息)。
    4. 发送:收件人:带有:超级: 使用 Behavior lookupSelector: 找到要使用的正确选择器。
    5. 行为 查找选择器: 是负责超类循环在算法中出现的问题。

    所以这就是 我正在寻找的实际实现(因此这不是一个真正的答案),但我想它可以帮助理解精确算法的细微差别。

        3
  •  1
  •   blabla999    14 年前

    要理解Franks的回答,您需要一些背景信息:

    编译器生成一个“发送字节码”,稍后由VM的字节码解释器执行(或jitted,但语义相同)。因此,您不会期望在任何类中找到实现,而是在VM中。

    大多数其他虚拟机都是用C语言、汇编程序或其他语言编写的…

    但是:scueak vm是用smalltalk编写的,并由“smalltalk-to-c-compiler的子集”(称为“slang”,因为它不包含完整的smalltalk语义)编译到c。

    由于是用smalltalk编写的,所以虚拟机当然可以在squak中进行开发、调试和测试(通过在图像中的图像上运行俚语解释器)。这就是为什么您可以在Frank所描述的解释器中找到实现。