简体   繁体   English

Smalltalk:如何实现原语?

[英]Smalltalk: How primitives are implemented?

I know that everything is an object and you send messages to objects in Smalltalk to do almost everything. 我知道一切都是对象,您将消息发送到Smalltalk中的对象以执行几乎所有操作。 Now how can we implement an object (memory representation and basic operations) to represent a primitive data type? 现在我们如何实现一个对象(内存表示和基本操作)来表示原始数据类型? For example how + for integers is implemented? 例如,如何实现+表示整数?

I looked at the source code for Smalltalk and found this in Smallint.st . 我查看了Smalltalk的源代码,并在Smallint.st找到了它。 Can someone explain this piece of code? 有人可以解释这段代码吗?

 + arg [
    "Sum the receiver and arg and answer another Number"

    <category: 'built ins'>
    <primitive: VMpr_SmallInteger_plus>
    ^self generality == arg generality 
        ifFalse: [self retrySumCoercing: arg]
        ifTrue: [(LargeInteger fromInteger: self) + (LargeInteger fromInteger: arg)]
    ]

Here is the link of above code: https://github.com/gnu-smalltalk/smalltalk/blob/62dab58e5231909c7286f1e61e26c9f503b2b3df/kernel/SmallInt.st 这是上面的代码的链接: https : //github.com/gnu-smalltalk/smalltalk/blob/62dab58e5231909c7286f1e61e26c9f503b2b3df/kernel/SmallInt.st

Conceptually speaking primitive methods are pieces of behavior (routines) implemented by the Virtual Machine (VM), not by regular Smalltalk code. 从概念上讲, 原始方法是由虚拟机(VM)而非常规Smalltalk代码实现的行为(例程)。

When the Smalltalk compiler finds the statement <primitive: ...> it interprets this as an special type of method whose argument (in your case VMpr_SmallInteger_plus ) indicates the integer index of the target routine within the VM. 当Smalltalk编译器找到语句<primitive: ...>会将其解释为一种特殊类型的方法,其参数(在您的情况下为VMpr_SmallInteger_plus )指示VM中目标例程的整数索引。

In this sense a primitive is a global routine not bound to the MethodDictionary of any particular class. 从这个意义上说,原语是一个全局例程,不与任何特定类的MethodDictionary绑定。 The primitive logic is intended for a receiver and arguments of certain classes and that's why it must check that the receiver and the arguments (if any) conform its requirements. 原始逻辑旨在用于某些类的接收器和参数,这就是为什么它必须检查接收器和参数(如果有)是否符合其要求的原因。 If not, the primitive fails and in that case the control flows to the Smalltalk code that follows the <primitive: ...> statement. 如果不是,则原语失败,并且在这种情况下,控制流向<primitive: ...>语句之后的Smalltalk代码。 Otherwise the primitive succeeds and the Smalltalk code below is not executed. 否则,原语成功,并且不会执行下面的Smalltalk代码。 Note also that the compiler will not allow for any Smalltalk code other than temporary declaration occurring above the <primitive:...> sentence. 还要注意,除了<primitive:...>语句上方的临时声明以外,编译器将不允许任何Smalltalk代码。

In your example, if the argument arg is not of the expected class (presumably a SmallInteger ) the routine gives up trying to sum it to the receiver and delegates the resolution of the operation to the Smalltalk code. 在您的示例中,如果参数arg不是期望的类(大概是SmallInteger ),则例程放弃尝试将其求和到接收器,并将操作的分辨率委托给Smalltalk代码。

If the argument happens to be a SmallInteger , the primitive will compute the result (using the routine held in the VM) and answer with it. 如果参数碰巧是SmallInteger ,则原语将计算结果(使用VM中包含的例程)并进行回答。

I haven't seen the code of this primitive but it could also happen that the primitive fails if the result of the sum does not fit in a SmallInteger , in which case both the receiver and the argument would be cast to LargeInteger s and the addition would take place in the #+ method of the appropriate class ( LargePositiveInteger or LargeNegativeInteger ). 我还没有看到该原语的代码,但是如果总和的结果不适合SmallInteger ,则原语也会失败,在这种情况下,接收者和参数都将被LargeIntegerLargeInteger s和加法会在相应类的#+方法中发生( LargePositiveIntegerLargeNegativeInteger )。

The other branch of the Smalltalk code allows for the implementation of a polymorphic sum between a SmallInteger and any other type of object. Smalltalk代码的另一个分支允许在SmallInteger与任何其他类型的对象之间实现多态和。 For instance this part of the Smalltalk code would take place if you evaluate 3 + 4.0 because in this case the argument is a Float . 例如,如果您评估3 + 4.0则会发生Smalltalk代码的这一部分,因为在这种情况下,参数为Float Something similar happens if you evaluate 3 + (4 / 3) , etc. 如果您评估3 + (4 / 3)等,也会发生类似的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM