Scratch
ScratchDay 15

Scratch 3.0 を Hackしよう。 ScratchVM の Opcode

Scratch VM を実行した時、その中で何が起きているのでしょうか。
見て行きましょう。

スクリーンショット 2017-12-24 0.08.10.png

https://wiki.scratch.mit.edu/wiki/VM_Preferences
https://wiki.scratch.mit.edu/wiki/Scratch_2.0
https://wiki.scratch.mit.edu/wiki/Scratch_3.0

VMってなんだろう?

VMは、Virtual Machine の 略です。

https://ja.wikipedia.org/wiki/%E4%BB%AE%E6%83%B3%E6%A9%9F%E6%A2%B0

何らかの、機会を模倣して動作するソフトウェアのことです。

例えば、VirtualBox という x86仮想化 VM があります。 このソフトウエアを利用すると、自分のPCに、別の

OSを動作させることとかできます。

Java言語なども、 Java仮想マシン を持ちます。

Javaのバイトコードを、実行するスタック型のソフトで、Javaで書かれたプログラムを

動かすことができます

Scratch VM は、Javaのように、Scratchで書かれたコードを理解して

実行してくれるソフトウエアのことです。

プログラム言語のVMの共通点

OPCODE / ByteCode なるものが存在する。

これは、VMの一個の命令で、非常に単純なことしかしません。

プログラム言語は、「人間の言語に近い記述」を「OPCODE」に変換したあとで、

それを実行します。

 

Scratch のコードを追ってみよう

Scratch は、どんな、OPCODE を持つのだろうか? どんな感じに動作するのだろうか?
探ってみましょう!!

前回のコードをみると、ScratchVM->start() から、始まるのでした。
コードを追って見ましょう!!

ScratchVM->start ()
  ScratchRuntime->start ()
    this._steppingInterval = setInterval(() => {
       this._step();
    }, interval);

https://github.com/LLK/scratch-vm/blob/develop/src/virtual-machine.js
https://github.com/LLK/scratch-vm/blob/develop/src/engine/runtime.js

と、なっていました。
つまり、Scratch VM は、  ScratchRuntime->_step(); を、短い感覚で何度も呼ぶ作りのようです。

 _step () {
    ...
    this.monitorBlocks.runAllMonitored(this);
    ...
    this.sequencer.stepThreads();
    ...
    this.renderer.draw();
  }

this.sequencer.stepThreads(); では、

...
ScratchExecute->execute()
..
ScratchExecute->thread.goToNextBlock();
...

https://github.com/LLK/scratch-vm/blob/develop/src/engine/execute.js
と、なっており、ScratchExecute を、順次実行しながら、
描画していることが、解ります。

ScratchExecute

ScratchExecute->execute()の中では、ブロックを、順次取り出して、

let block = blockContainer.getBlock(currentBlockId);
const opcode = blockContainer.getOpcode(block);
const fields = blockContainer.getFields(block);
const inputs = blockContainer.getInputs(block);
const blockFunction = runtime.getOpcodeFunction(opcode);
const isHat = runtime.getIsHat(opcode);
..
.
primitiveReportedValue = blockFunction(argValues, blockUtility);

順次、実行していきます。
https://github.com/LLK/scratch-vm/tree/develop/src/blocks
のコードが実行されるわけです。

また、この、blocks のことを、Scratchでは、OPCODEとして扱っているようです。

Scratch のOpcodeは、Blockの種類から類推できる

scratch-blocks で、 GUIのBlockを、 json 形式などにに変換
scratch-vm ないで、 json を、木構造に変換
そして、 Spriteを上下左右に移動するとか、 if文を動かすとか、ループ処理をすると行った、
OPCODE として、実行されると...

ScartchVM が 解釈するOPCODE については、ScratchのGUIで操作している内容と、ほとんど同じです。直ぐに理解できると思います。

読んで見ると良いでしょう
https://github.com/LLK/scratch-vm/tree/develop/src/blocks

PS

以下の場所でも、アレコレ書いていきます。

Scratch2.0 入門

火の型 With Scratch 2.0 (プログラム入門)  第00巻

火の型 With Scratch 2.0 (プログラム入門)  第01巻
炎の型 With Scratch 2.0 (ゲームプログラム入門)

Scratch3.0 自分専用機 を作ろう!!

(0)Scratch 3.0 自分専用機 を作ろう!! (0)
(1) Scratch3.0をビルドしてみよう
(2) Scratch3.0 を Androidアプリとして動作させてみよう (1)
(3) Scratch3.0 を Androidアプリとして動作させてみよう (2)
(4) Scratch3.0 を Androidアプリとして動作させてみよう (3)
(5) Webpack とは)
(6) Scratch3.0 の package.jsonを読んでみよう
(7) scratch-gui を インストールしてみよう
(8) scratch-vm に利用されている、scratch-xxx を触ってみよう
(9) Babel を触ってみよう
(10) scratch-render.js で 何か作って触ってみよう
(11) scratch-storage.js を触ってみよう
(12) Blockly を触ってみよう
(13) Scratch Block に触ってみよう
(14) scratch-vm.js を使って、100行でHTML5化しよう
(15) ScratchVM の Opcode