[英]Smalltalk: How primitives are implemented?
我知道一切都是對象,您將消息發送到Smalltalk中的對象以執行幾乎所有操作。 現在我們如何實現一個對象(內存表示和基本操作)來表示原始數據類型? 例如,如何實現+
表示整數?
我查看了Smalltalk的源代碼,並在Smallint.st
找到了它。 有人可以解釋這段代碼嗎?
+ 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)]
]
這是上面的代碼的鏈接: https : //github.com/gnu-smalltalk/smalltalk/blob/62dab58e5231909c7286f1e61e26c9f503b2b3df/kernel/SmallInt.st
從概念上講, 原始方法是由虛擬機(VM)而非常規Smalltalk代碼實現的行為(例程)。
當Smalltalk編譯器找到語句<primitive: ...>
會將其解釋為一種特殊類型的方法,其參數(在您的情況下為VMpr_SmallInteger_plus
)指示VM中目標例程的整數索引。
從這個意義上說,原語是一個全局例程,不與任何特定類的MethodDictionary
綁定。 原始邏輯旨在用於某些類的接收器和參數,這就是為什么它必須檢查接收器和參數(如果有)是否符合其要求的原因。 如果不是,則原語失敗,並且在這種情況下,控制流向<primitive: ...>
語句之后的Smalltalk代碼。 否則,原語成功,並且不會執行下面的Smalltalk代碼。 還要注意,除了<primitive:...>
語句上方的臨時聲明以外,編譯器將不允許任何Smalltalk代碼。
在您的示例中,如果參數arg
不是期望的類(大概是SmallInteger
),則例程放棄嘗試將其求和到接收器,並將操作的分辨率委托給Smalltalk代碼。
如果參數碰巧是SmallInteger
,則原語將計算結果(使用VM中包含的例程)並進行回答。
我還沒有看到該原語的代碼,但是如果總和的結果不適合SmallInteger
,則原語也會失敗,在這種情況下,接收者和參數都將被LargeInteger
為LargeInteger
s和加法會在相應類的#+
方法中發生( LargePositiveInteger
或LargeNegativeInteger
)。
Smalltalk代碼的另一個分支允許在SmallInteger
與任何其他類型的對象之間實現多態和。 例如,如果您評估3 + 4.0
則會發生Smalltalk代碼的這一部分,因為在這種情況下,參數為Float
。 如果您評估3 + (4 / 3)
等,也會發生類似的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.