[メモ] JavaScriptエンジンを作る話

[Rapidus](https://github.com/maekawatoshiki/rapidus)の進捗を記していく。逐次更新

# どんなJSエンジンを目指してるのか

- 自作ブラウザ([Naglfar](https://github.com/maekawatoshiki/naglfar/))に組み込めるようなもの
- ↑でも当分はNodeJSみたいなのを目指すと思う (それ単体で使えるような物、という意味)
- JITに対応し、速い (LLVM使う?) *8/11追記: Tracing JITが部分的に動いた*

# 課題

- グローバル変数の呼び出し、遅い
- <strike>ネストした関数、実装してない</strike> **実装しました**
- VMとVMのコード生成に関するコードのテストを書いてない (*最近書き始めた*)
- <strike>よく考えたら、字句解析器がコメントに対応してない</strike> **対応**
- 参照渡しできない

# 進捗

日数は、Gitでコミットした日を数えてます。(7/1 7/2 7/5 とコミットしていたら、7/5は3日目としてカウント)

## 1日目

- 字句解析器がほぼ完成

```js
function f() { return 1 + 2; }
```

みたいなのをトークンごとに分解できる感じ。

## 2日目

- (Circle)CIを使いはじめる
- パーサを作り始める
- 簡単な数式のパースに対応

```js
1 + 2 * 30
```

みたいな

## 3日目

- パーサ、``== !=``に対応
- 字句解析器、``=== !==``が正しくトークンに分解できなかったので修正

## 4日目

- パーサ、``=== !== > < >= <=``に対応
- テストを追加し始めた　

## 5日目

- パーサ、``?: && || & ^ | << >> >>> ** =``, 単項演算子, 関数呼び出し構文, メンバ呼び出し?(``something.x``みたいな)に対応
- VMを作り始める

## 6日目

- VMの仕様で苦戦する (現時点(7/10/2018)でも苦戦してるけど)

## 7日目

- VMのバグ修正

## 8日目

- パーサ、``,``(コンマ演算子), ``var``での変数定義, に対応

## 9日目

- VMで、高速化のために生ポインタを使う
- パーサ、ブロック構文(``{ }``)に対応

## 10日目

- VM向けコードをASTから生成するコードを書き始める
- いくつかのJSコードがVM上で動き始める

```js
console.log(1)
```
みたいなのとか。

## 11日目

- VM(& CodeGen)、四則演算+Mod, ジャンプ命令に対応
- パーサ, ``if, while``に対応
- ↑上記により、``while``とか``if``とか使ったJSコードが動き始める

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/rapidus?src=hash&amp;ref_src=twsrc%5Etfw">#rapidus</a><br>自作JSエンジン in Rust<br><br>FizzBuzzが動きました<br>一つのマイルストーン達成、ってところですかね。 <a href="https://t.co/gF3Qc2FFTB">pic.twitter.com/gF3Qc2FFTB</a></p>&mdash; uint256_t (@uint256_t) <a href="https://twitter.com/uint256_t/status/1015606676500566018?ref_src=twsrc%5Etfw">2018年7月7日</a></blockquote>
　
## 12日目

- ローカル変数, 関数定義に対応

```js
function f(x) {
  var i = x+1;
  return i;
}

console.log( f(1) )
```

が動く。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/rapidus?src=hash&amp;ref_src=twsrc%5Etfw">#rapidus</a> <br>再帰もちゃんと可能（ネストした関数はまだ無理です..)な関数をサポート<br>フィボナッチできる <a href="https://t.co/X9HYx5592G">pic.twitter.com/X9HYx5592G</a></p>&mdash; uint256_t (@uint256_t) <a href="https://twitter.com/uint256_t/status/1015894695115780096?ref_src=twsrc%5Etfw">2018年7月8日</a></blockquote>


## 13日目

- VMが少し速くなった

## 14日目

- 多分、クロージャに対応した

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/rapidus?src=hash&amp;ref_src=twsrc%5Etfw">#rapidus</a><br>祝クロージャ動いた <a href="https://t.co/wQnecr7Txm">pic.twitter.com/wQnecr7Txm</a></p>&mdash; uint256_t (@uint256_t) <a href="https://twitter.com/uint256_t/status/1017013287488065536?ref_src=twsrc%5Etfw">July 11, 2018</a></blockquote>

## 15日目 

- クロージャのバグ修正

## 16日目 

- ``return``のない関数が正しくコード生成されなくてVMが落ちるバグを修正

```js
// これが落ちてた
function a() { }
a()
```

## 17日目

- ``this`` に対応

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/rapidus?src=hash&amp;ref_src=twsrc%5Etfw">#rapidus</a><br>thisのバグを直しました<br>これで this が普通に使えるように。 <a href="https://t.co/dQEii5l0H2">pic.twitter.com/dQEii5l0H2</a></p>&mdash; uint256_t (@uint256_t) <a href="https://twitter.com/uint256_t/status/1018137028813250560?ref_src=twsrc%5Etfw">July 14, 2018</a></blockquote>


## 18日目

- thisのバグ修正

## 19日目

- VMがちょっと速くなった
- VMの速度はあまり追求しないつもりだけどね (どのみちJITするし)

## 20日目 

- クロージャの名前をマングリングするようにした (今まではマングリングしてなかったから、グローバルな同じ名前の関数があったら、名前が衝突してた。要するにbug fix)

## 21日目 (7/21)

- バグ修正 
- VM Codegenのテストを書いたり

## 22日目

- テストをいろいろ追加した

## 23日目

- ``new``の実装を正しい物にした

```js
function f() { this.x = 123; return 456; }
var a = f();
var b = new b();
// 今までは、aは456, bも456となっていた
// これを修正し、aは456, bはf{x:123}になった
```

## 24日目

- 今日もまた、テストを書くのであった。

## 25日目

- パーサ、配列リテラルとオブジェクトリテラルをパースできるようになった

## 26日目

- ちょっとテスト追加

## 27日目

- クロージャのバグを直すなど

## 28日目

- オブジェクトリテラルがだいたい使えるようになった

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/rapidus?src=hash&amp;ref_src=twsrc%5Etfw">#rapidus</a><br>オブジェクトリテラル, 大体動くよ <a href="https://t.co/496qaKt7Mu">pic.twitter.com/496qaKt7Mu</a></p>&mdash; uint256_t (@uint256_t) <a href="https://twitter.com/uint256_t/status/1024303134053548042?ref_src=twsrc%5Etfw">July 31, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>