「foo」という名前の別のプログラミング言語を実装するためにpythonを使用しています。foo のコードはすべて python に変換され、同じ python インタープリターで実行されるため、python に JIT 変換されます。
以下は foo のコードの一部です。
function bar(arg1, arg2) {
while (arg1 > arg2) {
arg2 += 5;
}
return arg2 - arg1;
}
これは次のように変換されます:
def _bar(arg1, arg2):
while arg1 > arg2:
arg2 += 5
watchdog.switch()
watchdog.switch()
return arg2 - arg1
「ウォッチドッグ」は、言語が信頼できないコードを実行するため、リソースの使用を監視/制限する greenlet (生成されたコードも greenlet コンテキストで実行されます) です。
例でわかるように、python コードが生成される前に、ウォッチドッグ スイッチを追加し、関数識別子に小さな変更を加えるために、解析ツリーに小さな変更が加えられます。
すべての要件を満たすには、言語にトレースバック/デバッグ機能も追加する必要があります。これにより、python ランタイムが例外をスローしたときに、ユーザーが表示するのは foo のコード トレースバック (生成された python コード トレースバックを表示するのではなく) になります。
ユーザーが次の内容で「program.foo」という名前のファイルを作成するとします。
1 function bar() {
2 throw Exception('Some exception message');
3 }
4
5 function foo() {
6 output('invoking function bar');
7 bar();
8 }
9
10 foo();
これは次のように変換されます:
def _bar():
watchdog.switch()
raise Exception('Some exception message')
def _foo():
print 'invoking function bar'
watchdog.switch()
_bar()
watchdog.switch()
_foo()
次に、「program.foo」の出力は次のようになります。
invoking function bar
Traceback (most recent call last):
File "program.foo", line 10
foo();
File "program.foo", line 7, inside function 'foo'
bar();
File "program.foo", line 2, inside function 'bar'
throw Exception('Some exception message');
Exception: Some exception message
それを行う簡単な方法はありますか?Pythonバイトコードはインタープリター実装の内部にあるため、インストルメント化を伴わないソリューションを好みますが、他に何もない場合は、バイトコードをインストルメント化することもできます。