イミフなスタックオーバーフローに悩まされた。
static dataDumpNest = [];
static DATADUMPNEXT_MAX = 100;
static dataDump(objectName, obj, pOptions) {
try {
・・・
Helper.dataDumpNest.push(obj);
rc = true;
・・・
return true;
・・・
// 再帰呼び出し時はtrueを返す
if (Helper.dataDumpNest.length > 1) {
return true;
}
// それ以外は result を結合し返す
return Helper.result.join("\n");
} catch (e) {
throw e;
} finally {
Helper.dataDumpNest.pop();
}
}
finallyで無条件でpopしているので、
重複チェックで弾かれてpushしてない時に
無駄にjoinしてしまうのが気になり
執拗にF10でトレースしていると・・・
finallyブロックの終わりで呼び出し元のメソッドに戻るべきところが、
- ソース画面が何行か戻ってしまう。
- スタックトレースが妙に長くなっていた。
という摩訶不可解な現象にぶち当たった。
どうやら、return文無しで、finallyブロックの末尾にぶち当たると、ヤバイ事が起きている。
1万個の配列を何度もjoinさせ、しかも結果は捨てているのでブチ切れさせてしまったかもね。(大笑
普通、ドコかのreturn文の後に処理するハズのfinally句なのに。
延々と待たされた挙句にスタックオーバーフローになるソースを
finally句でtryの外の変数rcをreturnする様にしてみた。
static dataDumpNest = [];
static DATADUMPNEXT_MAX = 100;
static dataDump(objectName, obj, pOptions) {
let rc = false;
try {
・・・
Helper.dataDumpNest.push(obj);
rc = true;
・・・
rc = true;
return rc;
・・・
// 再帰呼び出し時はtrueを返す
if (Helper.dataDumpNest.length > 1) {
rc = true;
return rc;
}
// それ以外は result を結合し返す
rc = Helper.result.join("\n");
return rc;
} catch (e) {
throw e;
} finally {
if (rc != false) {
Helper.dataDumpNest.pop();
}
return rc;
}
}
と変えたら、即終わったった。
setTimeoutでワーカースレッドっぽい状態なんで、
finallyが、Promiseと勘違いしてスタックを遡ってみると配列がいっぱい積んであるので
Array[ Array[1], Array[2] ] あたりが、
new Promise((resolve, reject) {
・・・
}
に、そっくりだったのかもしれない。
しかし、違うと気が付いて、throw new Error(“Don’t mind.”);
して、普通のfinally になるつもりが、ソコのfinallyでまた躓いて、無限ループしてそう。
でも、そのうち治るでしょ?
やっと、本題の文法解析に戻れそう。
ん?三国英雄たちの夜明けがフリーズしやすいのは
もしやコレなのか?