深さのV8エンジン-AST(3)

パートIは、プロセスおよび関連するクラスのスキャナ入力方法の一部を紹介し、この1つは、初期化スキャナについて、主である、つまり

scanner_.Initialize();

これは、静的メソッドの呼び出しではないことに注意してください。例パーサーは、実際にスキャナは、属性を初期化する際に発生するので、直接使用することができます。

:: Parserのパーサ(parseInfo *情報):ParserBase <パーサ>(/ * 親クラスの属性を初期化する* / 
scanner_(情報 - > character_stream()、info-> is_module())、/ * 他の属性を初期化します* /

実際には、プロパティSOURCE_フラグが初期化メソッドを呼び出すために、スキャナ上のモジュールで初期化されます。

このメソッドは、非同期操作をlibuvがやや似ていますが、確かではない事、ソースコードを以下のように。

/ * * 
 *全体的な変換がASTないことに注意
 * / 
ボイドスキャナ::初期化(){ 
  初期化(); 
  次に()after_line_terminator = trueに
  スキャン(); 
}

第二のステップは、私はまだその変数の重要性を理解していない、知らないやっているので、彼らは、initで始まる、第一及び第三のステップについて話しています。

無効初期化(){ 
  ;アドバンスでは、()
  / * * 
   * TokenDescのtoken_storage_の[3。]; 
   *ここでエイリアスに対応する地図を作るため
   * / 
  CURRENT_ =&token_storage_ [ 0 ]; 
  NEXT_ =&token_storage_ [ 1 ]; 
  next_next_ =&token_storage_ [ 2 ]。

  found_html_comment_ = falseに; 
  scanner_error_ = messageTemplate :: kNone; 
} 

/ * * 
 * SOURCE_NAME、パーサのコンストラクタで初期化
 *型Utf16CharacterStream実装を参照してくださいすることが必要
 * / 
無効をアドバンス(){上
  c0_ = _-ソース>前進(); 
}

ビュースキャナレベルの点から、その役割は、単にプライベートプロパティc0_(現在のUnicode文字エンコーディング)割当の事前方法であり、実際の動作はSOURCE_アドバンスメソッド属性に行われ、型の属性は、以前にストリームクラスを変換しました(フルネームは長すぎるので、すべてがStreamクラスを差し戻さ、xxxCharacterStreamである)ので、次のようにソースコードがあり、特定の実装にジャンプするが必要があります。

/ * * 
 *メソッドフィールドUtf16CharacterStreamジャンプここから、BufferedCharacterStreams 
 * ::即ちアドバンスUtf16CharacterStream、Utf16CharacterStream :: PEEK、Utf16CharacterStream ReadBlockCheckedに:: 
 * / 
インラインUC32アドバンス(){に
  UC32結果 = PEEK(); 
  buffer_cursor_ ++ ;
   リターン結果; 
} 

/ * * 
 *カーソル位置の値を返し
 、初期化* 1、
 * 2、初期化されていない
 * 3は、終了しなければならない
 * / 
インラインUC32覗くは(){ 
  IF(V8_LIKELY(buffer_cursor_ < buffer_end_)){
     戻りはstatic_cast < UC32>(* buffer_cursor_); 
  } 他の IF(ReadBlockChecked()){
     戻りはstatic_cast <uc32>(* buffer_cursor_)。
  } {
     戻りkEndOfInputと、
  } 
}

ここで説明するいくつかのものは、(名前は私自身のテイクで、ASTの解析は、常に私は、ノギス高校で考えさせる参照)Streamクラス3カーソル財産に関するすべての最初の、ある文字を表す、buffer_start_、buffer_cursor_、buffer_end_ありますこれらの3つの属性のないStreamクラスの初期化処理は、デフォルトではゼロに設定されている間、現在の終了位置を解析し始めます。字句と、ここで文字に属性ポイントは、異なる概念であることに注意してください、3つのプロパティスキャナは字句レベルです。たとえば、ビューの字句の点からあれば話すが、ビューの文字のポイントから2です。

以下のコメントが意味での3人の裁判官が与えられ、より興味深いのは無意味なマクロとして見なさ開発者のためのV8_LIKELYマクロですが、マクロが、この分岐が発生する可能性が高いことを示す、コンパイラに見ている、それが推奨されます最適化。もちろん、初期化はほとんどの場合の終了前にもう一度行きますので、現在のカーソルポイントの戻り値の最初の分岐に直接移動しない解決されます。しかし、今、このメソッドが呼び出された最初の時間のために、私たちは第二分岐を取ります。

/ * * 
 *这里是做一个合法性检测
 *实际上只有ReadBlock做事
 * / 
BOOL ReadBlockChecked(){ 
  size_tの位置 = POS(); 
  (位置)を使用します。
  ブール!成功= has_parser_error()&& ReadBlock(); 

  // 事後条件:1、我々は常に正しい位置にあるべきです。
  //                   2、カーソルはバッファ内にある必要があります。
  //                   3、我々は成功IFF可能な複数の文字を持っている必要があります。
  DCHECK_EQ(POS()、位置)。
  DCHECK_LE(buffer_cursor_、buffer_end_)。
  DCHECK_LE(buffer_start_、buffer_cursor_)。
  DCHECK_EQ(成功、buffer_cursor_ <buffer_end_);
   戻り成功; 
} 

/ * * 
 型成形の進展の現在位置の* buffer_pos_代表
 *カーソル、配列buffer_に現在のポインタとして開始し、初期アドレス
 メモリアレイ内*アドレスと符号なしの短い連続会計1 
 *現在位置算出することにより直接得ることができる
 * / 
POS()SIZE_TインラインCONST {
   戻り buffer_pos_の+(buffer_cursor_ - buffer_start_); 
} 

/ * * 
 。* 1は、単一の文字がbuffer_ある符号化処理格納する符号なしの短い配列であり、
 * 2、ポインタの開始、終了の頭部と尾部の配列が初期化されている
 カーソルは、カーソルの初期スタートポイントしている、* 3 
 *、例えば、 "(機能)" buffer_の[40、102、...]のように表現
 * / 
BOOL readBlock(){最終
  サイズ_t位置 = = POS()。
  buffer_pos_ポジション; 
  buffer_start_ =&buffer_ [ 0 ]。
  buffer_cursor_ = buffer_start_。

  DisallowHeapAllocationのno_gc。
  範囲 <uint8_t>範囲= byte_stream_.GetDataAt(位置、runtime_call_stats()、&no_gc)。
  もし(range.length()== 0 ){ 
    buffer_end_ = buffer_start_。
    返す ; 
  } 

  size_tの長さ = MIN(kBufferSize、range.length())。
  私:: CopyCharsUnsigned(buffer_、range.start、長さ); 
  buffer_end_ =&buffer_ [長さ]。
  返す ; 
}

コンテンツのこの作品は、ほとんどがあまりないことを、実際には、より多くのです。第1の方法は、カーソルの正当性を確保するだけの純粋なチェックで、POSはコメントで書かれた基本的に解決されたアドレス計算によって現在位置を取得する直接的な方法です。

ReadBlockメソッドは、ストリームの属性を初期化する責任があり、このクラスは、上記の文を与えられていない、それは私有財産は、アレイ512の長さが短いため、buffer_です。DisallowHeapAllocationは心配しないで、V8奇妙なものがたくさんあり、現在は理解していない、もちろん、AST自体とは何の関係もありません。多くの問題をGetDataAt、Unicodeは、各文字列、上記CopyCharsUnsigned buffer_でコピーする方法、およびエンドポイントbuffer_end_最後の部分をコードして、最終的なリターンの観点からの結果から、話したくありません。

たとえば、文字列「『ハロー』 + '世界」にコンパイルする、治療後GetDataAtは、39、72になります....

ここで、デバッグ結果を与える、buffer_次のように初期化した後、(傍受のみ前部512の長さ)、ダーティデータの山が存在するであろう。

方法の一連の処理の後、に

スペースでは、文字列全体の18ビットの合計は、0から17までの値がすべてリセットされた、または古いデータの後ろに汚いです。これらの数字は、手動で取得することができ、それを変換します

コンパイルされた文字列(文字列の長さが512未満であると仮定し、その後の合併症の背後に係合している)であることを起こります。

この時点で、全体のinitメソッドが再び動作するように、スキャン話の下で、このような長いを期待していなかった、終了しませんでした。

おすすめ

転載: www.cnblogs.com/QH-Jimmy/p/11125607.html