Scratch 3.0 を Hackしよう。 ScratchVM の Opcode

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


![スクリーンショット 2017-12-24 0.08.10.png](https://qiita-image-store.s3.amazonaws.com/0/54192/14ca5828-4779-166c-fcc7-54e7dc98dcc6.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巻](https://www.gitbook.com/book/kyorohiro/firestyle/details)

<img src="https://qiita-image-store.s3.amazonaws.com/0/54192/ce995d78-4d14-fe94-0ac5-216d24ddf391.png" width=50%>

[火の型 With Scratch 2.0 (プログラム入門) 　第01巻](https://www.gitbook.com/book/kyorohiro/firestyle01/details)
[炎の型 With Scratch 2.0 (ゲームプログラム入門)](https://www.gitbook.com/book/kyorohiro/doc_scratch/details)



#### Scratch3.0 自分専用機 を作ろう!!
[(0)Scratch 3.0 自分専用機 を作ろう!! (0)](http://blogger.firefirestyle.net/2017/09/scratch30-0.html)
[(1) Scratch3.0をビルドしてみよう](
http://blogger.firefirestyle.net/2017/12/scratch30-1-scratch30.html)
[(2) Scratch3.0 を Androidアプリとして動作させてみよう (1)](http://blogger.firefirestyle.net/2017/12/scratch30-2-scratch30-android-1.html)
[(3) Scratch3.0 を Androidアプリとして動作させてみよう (2)](http://blogger.firefirestyle.net/2017/12/scratch-30-3-scratch30-android-2.html)
[(4) Scratch3.0 を Androidアプリとして動作させてみよう (3)](http://blogger.firefirestyle.net/2017/12/scratch-30-3-scratch30-android-3.html)
[(5) Webpack とは)](http://blogger.firefirestyle.net/2017/12/scratch-30-5-webpack.html)
[(6) Scratch3.0 の package.jsonを読んでみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-6-scratch30-packagejson.html)
[(7) scratch-gui を インストールしてみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-7-scratch-gui.html)
[(8) scratch-vm に利用されている、scratch-xxx を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-8-scratch-vm-scratch-xxx.html)
[(9) Babel を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-9-babel.html)
[ (10) scratch-render.js で 何か作って触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-9-scratch-renderjs.html)
[ (11) scratch-storage.js を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-11-scratch-storagejs.html)
[ (12) Blockly を触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-12-blockly.html)
[ (13) Scratch Block に触ってみよう](http://blogger.firefirestyle.net/2017/12/scratch-30-13-scratch-block.html)
[ (14) scratch-vm.js を使って、100行でHTML5化しよう](http://blogger.firefirestyle.net/2017/12/scratch-30-14-scratch-vmjs-100html5.html)
[ (15) ScratchVM の Opcode](http://blogger.firefirestyle.net/2017/12/scratch-30-15-scratchvm-opcode.html)