Iroh.jsを使用した動的コード分析

Developer SoftのソフトウェアエンジニアでNetologyの教師であるVladislav Vlasovは、ブログのEcmaScript6に関する一連の記事を執筆しました。最初の部分では、Iroh.jsを使用してEcmaScriptのコードの動的分析を調べました。



静的および動的コード分析



コード分​​析ツールは、コード内のエラーと機能を検出および特定できる便利なツールです。 コード分​​析は静的および動的にすることができます。 最初のケースでは、ソースコードは実行されずに解析および分析されます。2番目のケースでは、実行中にアプリケーションの要素に関するメタ情報を提供するマネージドサンドボックス環境で実行されます。



画像



ダックタイピングを備えたEcmaScriptは、静的解析ツールを使用して、コードを実行せずに潜在的に危険な状況を検出することがよくあります:送受信される引数のタイプの不一致、不一致のタイプの変数による不正な操作、コードの非実行セクションなど。 最も一般的なのは、特殊な構文を使用した言語の拡張に基づいたTypescriptおよびFlowソリューションです。



厳密な型システムがそれらの不可欠な部分であるプログラミング言語とは異なり、したがって、変数とオブジェクトの型の記述はすでにソースコードに埋め込まれていますが、逆に、EcmaScriptは手動の記述を必要とします。これは個々の静的型付けツールに依存し、異なります。 これには、 次の欠点が伴います





Iroh.js-EcmaScriptアプリケーションの動的分析のためのソリューション



上記の欠点の解決策は、EcmaScriptコードの動的アナライザーであるIroh.jsです 。 Iroh.jsを使用すると、実行中にコードを分析および操作できますが、静的型付けツールの場合のようにソースコードを変更したり、注釈を付けたりする必要はありません。



Iroh.jsを使用すると、コードの実行スキームをリアルタイムで記録したり、オブジェクトの状態や呼び出しスタックに関する情報を受信したり、プログラムの動作をオンザフライで制御したりできます。

Iroh.jsを使用して、ランタイムの次の側面に関する情報を取得できます:関数呼び出しツリー、オブジェクトと変数の実際のデータ型、オブジェクトへの暗黙的な変換、および文字列への変換を含むプリミティブ型(ボックス化/非ボックス化)。
Iroh.jsは、元のプログラムのロジックと実行スキームを変更せずに発生するイベントを記録するようにコードを事前に修正することにより機能します。 これにより、後で追跡し、アクションに反応するためのリスナー関数を追加できます。 Iroh.jsを使用すると、実行時のコードの動作を監視できるだけでなく、コードの変更、特定の関数の呼び出しのインターセプト、変数の重複値の設定などを行うことができます。



Iroh.jsは、変更されたコードの呼び出しスタックのみを追跡し、ランタイムのネイティブ関数またはインポートされたライブラリ要素のメタ情報やオンザフライの変更を提供できません。 原則として、ライブラリコードの動作を分析および変更する必要はありませんが、必要な場合は可能です。Iroh.jsの範囲は、事前のパッチによってIroh.jsのサンドボックスに追加されたコードによって決定されます。



Iroh.jsは、 npmパッケージとしてnode.jsアプリケーションに追加でき、 ブラウザーで直接実行できます。これは、小さな独立したコードフラグメントを動的に分析したり、デモを作成したりするのに役立ちます。



例1.フィボナッチ数を計算する関数の呼び出しグラフの分析



最も単純な例として、フィボナッチ数を計算するための関数の2つの実装、完全な再帰ツリーを備えた単純なバージョン、および以前の結果をメモ化した最適化ソリューションを検討できます。 提案された関数のソースコードを以下に示します。



function fibonacciNaive(n) {  if(n <= 0) return 0;  return fibonacciNaive(n - 1) + fibonacciNaive(n - 2); };
      
      





 function fibonacciMemoized(n, x1 = 0, x2 = 1) { if(n <= 0) return x1; return fibonacciMemoized(n - 1, x2, x1 + x2); };
      
      





これで、これらの機能の動的分析を実行できます。 もちろん、どちらの実装も正しい結果を提供しますが、 fibonacciMemoized



fibonacciNaive



よりもはるかに高速に動作し、メモリの消費も少なくなります。



明らかに、ポイントは中間計算を保存し、末尾再帰を最適化することです。 Iroh.jsに基づく実行フローアナライザーを使用すると、これを明確に確認できます。





ダイナミックアナライザーを使用すると、最初の最適でないケースで6番目のフィボナッチ数を計算すると、再帰呼び出しの数は41に達し、2番目の呼び出しでは7になります。指数関数的であり、二番目に-線形になります。



フィボナッチ数を計算するタスクは非常に単純であり、上記の最適化は簡単で広く知られていますが、Iroh.jsを使用すると、関数呼び出しのグラフを追跡して、冗長または誤った呼び出しを見つけることができます。



引数と変数の実際の値を表示することにより、合成console.log



指示を追加することなく、実行時にコードをデバッグできます。



例2.実行中のオブジェクトと変数の変更



潜在的に複雑で非線形のロジックを持つアプリケーションの動作を分析するプロセスでは、特定の変数またはオブジェクトの値が変更された瞬間を追跡するか、逆に、特定の瞬間に現在の値を特別な値に変更する必要があります。 これはすべてIroh.jsを使用して実行できます。



簡単な例として、いくつかのWebリソースへのAJAXリクエストを実行するWebページのコードを検討できますが、デバッグの目的で、それらの一部へのアクセスをインターセプトして、URLをデバッグスタブに置き換える必要があります。 ソースコードの簡略化された部分は次のようになります。



 const urlAddresses = ['ADDR1', 'ADDR2', 'ADDR3']; const resultPromise = Promise.all(urlAddresses.map(addr => fetch(addr).then(res => res.text()).catch(err => new Error(err)))); resultPromise.then(result => console.log(result))
      
      





ADDR3



ADDR3-test



に置き換えたいとします。 Iroh.jsを使用すると、対応する操作を次のように実行できます。



 const stage = new Iroh.Stage(code); // code -      const listener = stage.addListener(Iroh.CALL); const originalFetch = fetch; listener.on("before", function (e) { if (e.object === fetch) {   e.call = function (url) {     const targetUrl = url === 'ADDR3' ? 'ADDR3-test' : url;     return originalFetch.call(null, [targetUrl].concat(arguments.slice(1)))   }); } }); eval(stage.script);
      
      





Iroh.jsを使用すると、関数呼び出しと変数の割り当てを分析およびインターセプトでき、その値と動作を即座に変更できます。 その他の例については、 こちらをご覧ください



結論



Iroh.jsは、EcmaScriptの動的コード分析のための強力で機能的なツールです。 このツールは、呼び出しのグラフの構築、変数とオブジェクトの実際のタイプと値の表示、イベントベースのコード修正を含むコードのオンザフライでの変更など、コード分析の両方に使用できます。



動的分析はかなり複雑な方法ですが、EcmaScriptの場合、ダックタイピング、ホストオブジェクト、およびコードの動作をその場で変更できるネイティブ関数が存在する場合、これが実行中にコードを分析およびデバッグする唯一の方法です。



Iroh.jsは、コードを使用して機能テストを作成することもできます。最初にコードを変更して値をエクスポートする必要はありません。 Iroh.jsに基づいて、コード問題のあるセクションのパフォーマンスを測定し、 ステップバイステップのデバッグと時間移動デバッグの可能性があるオンラインIDE開発環境を実装することもできます。



編集者から



トピックに関するNetologyコース:






All Articles