gpt4 book ai didi

smalltalk - 优化 ifTrue :ifFalse: in Smalltalk

转载 作者:行者123 更新时间:2023-12-04 19:54:00 25 4
gpt4 key购买 nike

Smalltalk 蓝皮书说编译器优化了 ifTrue:ifFalse:和 friend 使用特殊的操作码,以避免创建闭包并对实际的 bool 对象进行动态调度。

如果我正确理解了这一点,那么:

o ifTrue: [ ^ 'yes' ] ifElse: [ ^ 'no' ]

...变成类似:
    push o
jump_if_false 1
return 'yes'
jump 2
1:
return 'no'
2:

(我查了一下,GNU Smalltalk 正是这样做的。)

如果 o,这将正常工作是 Boolean ,但我不明白如果不是会发生什么。毕竟编译器不知道是什么类型 o是。它不能保证它是一个 bool 值。它甚至不知道 ifTrue:ifFalse:方法具有传统的语义。

例如:
Fnord ifTrue: tb ifFalse: fb
"muhahaha"
tb value: self.
fb value: self and: 9.
^ 7

为了使这个实现工作,true 和 false block 必须是闭包,分别采用一个和两个参数。那么编译器是如何知道生成闭包的呢?还是允许编译器在这种情况下中断?

最佳答案

这是字节码(在我使用的方言中)

1  frameless prolog
2 load R with instance o ; o is an ivar in my code
4 test jump false 13
7 load R with literal 'yes'
9 return
10 jump 16
13 load R with literal 'no'
15 return
16 return self

这是本地化代码(简化):
    cmp eax, false       ; test jump false
jz @2
cmp eax, true
jz @1
call mustBeBoolean ; <--- here!
@1: mov eax, 'true'
ret
jmp @3 ; jump
@2: mov eax, 'no'
ret
@3: move eax, esi
ret

如您所见,检查 #ifTrue:ifFalse: 的接收者是否是 JIT 编译器(a.k.a. nativizer)是否为 bool 值。更准确地说, test jump false 的本土化字节码发出的代码将发送 mustBeBoolean如果接收者不是 bool 值,则通知。

编辑

关于你的第二个问题, #ifTrue:ifFalse: 的实现如果发件人内联(显式) block 参数,则在另一个类中将不起作用,如下所示:
receiver ifTrue: ['yes'] ifFalse: ['no']

此代码将失败并显示 #mustBeBoolean如果 receiverFnord 的一个实例(即使 receiver 理解 #ifTrue:ifFalse: 。)原因是,在这种情况下,编译器将优化 #ifTrue:ifFalse:正如我们在上面看到的,而不是将其作为常规消息发送。

然而,表达式
receiver ifTrue: [:a | <whatever>] ifFalse: [:a :b | <your code>]


fa := [:a | <whatever>].
fb := [:a :b | <yourcode>].
receiver ifTrue: fa ifFalse: fb

不会被优化,这意味着 #ifTrue:ifFalse:将被发送。

关于smalltalk - 优化 ifTrue :ifFalse: in Smalltalk,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32662354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com