- Smalltalk総合 Squeak Pharo
276 :デフォルトの名無しさん[sage]:2015/02/18(水) 09:22:33.83 ID:wdCl3CCW - >>264
興味があって調べてみたのですが、GNU Smalltalk で定数同士演算(たとえば + 演算)で メッセージ送信が省略されているのかが ideone.com の処理系では確認できませんでした。 「翻訳時」を「コンパイル時」、つまり「バイトコード変換時」と読み取ったのですが バイトコードレベルで省略されているという話ではないのでしょうか? メッセージ送信が省略されていることの確認の方法を教えていただければさいわいです。 UndefinedObject extend [ plusLit [^3+4] plusNonLit [^3 + OrderedCollection new] ] (UndefinedObject >> #plusLit) inspect printNl "=> [1] source code line number 2 [3] push 3 [5] push 4 send 1 args message #+ [7] return stack top " (UndefinedObject >> #plusNonLit) inspect printNl "=> [1] source code line number 3 [3] push 3 [5] push Global Variable {Smalltalk.OrderedCollection} [7] send 0 args message #new [9] send 1 args message #+ [11] return stack top " http://ideone.com/zWMggc
|
- Smalltalk総合 Squeak Pharo
278 :デフォルトの名無しさん[sage]:2015/02/18(水) 12:57:09.98 ID:wdCl3CCW - >>277
ありがとうございます。 >>264 の「翻訳時にすませてる」を、3+4 を 7 にする!? と勘違いしていました。 #+ などは特殊なバイトコードを使用し、そうした特殊なバイトコードでは引数の組み合わせ次第で レシーバー(この場合 3)へのメッセージ送信は行なわない、ということですね。 別件ですが、メソッドにコードされたプリミティブが #perfom: 等でコールされたときのためとは 知りませんでした。 そうすると、3 + 4 時は VM 内の + 関数で処理され、 3 + OrderedCollection new 時は + 〜 (バイトコード的には + )が 3 に送られて そこでプリミティブ記述により改めて VM 内の + 関数がコールされ それが失敗してフォールバックコード(たとえば ^super + aNumber)が実行される、 という理解で合っていますか?
|
- Smalltalk総合 Squeak Pharo
279 :デフォルトの名無しさん[sage]:2015/02/18(水) 18:55:49.75 ID:wdCl3CCW - >>278
> 3 + 4 時は… 自己レスです。(Squeak で、かつ旧 VM でですが)どうなっているか調べてみたら、 VM 内でプリミティブとしてコールされる + 関数(Squeak の場合 primitiveAdd )と バイトコード実行時にコールされる + 関数(同、bytecodePrimAdd )は別物なんですね。 通常は bytecodePrimAdd がコールされ、整数/整数とかでなければメッセージを送信、 #perform: などで呼んだ場合は primitiveAdd がコールされ、それが失敗すると プリミティブに続いて記述してあるフォールバックコードが実行されるというカラクリでした。
|