pub struct FnBody {
state: RefCell<FnBodyState>,
pub strict: bool,
uses_args: Cell<u8>,
}Expand description
関数本体。大きな本体は解析せずにソースだけ持ち、初めて実行するときに解析する(遅延解析)。
【2026-10-17】YouTube のアプリ JS(10.9MB)・player(3MB)は関数の大半が呼ばれないのに、 全関数の構文木を作るとヒープ 512MB に収まらなかった。未解析の本体同士は入れ子に ならない(外側を解析した時点で内側が作られる)ので、保持する文字列の合計はソース以下。 パーサは文脈(generator / async)に依存しないので、後から本体だけ解析しても結果は同じ。
Fields§
§state: RefCell<FnBodyState>§strict: boolstrict モードの本体か("use strict" の指令・strict な外側・クラス)。
非 strict の関数は this が undefined/null のときグローバル(window)になる。
uses_args: Cell<u8>本体(または内側のアロー関数)が arguments / eval を参照するか(0=未計算, 1=いいえ, 2=はい)。
Implementations§
Source§impl FnBody
impl FnBody
pub fn parsed(stmts: Vec<Statement>) -> Rc<Self>
pub fn parsed_with(stmts: Vec<Statement>, strict: bool) -> Rc<Self>
pub fn from_rc(stmts: Rc<Vec<Statement>>) -> Rc<Self>
pub fn lazy(source: String, strict: bool) -> Rc<Self>
Sourcepub fn stmts(&self) -> Rc<Vec<Statement>>
pub fn stmts(&self) -> Rc<Vec<Statement>>
本体の文(初回は構文木を保持せず返し、2 回目以降だけ構文木に置き換える)。
【2026-10-19】従来は 1 回呼ばれただけの関数でも構文木(ソース文字列の約 5〜8 倍の
大きさ)を self.state に永続保持していた。特に YouTube の kevlar_base(10.88MB)や
base.js(2.97MB)の最外の即時関数は 1 回しか実行されないのに、約 40MB の構文木が
クロージャ経由で最後まで残り続けていた。
- 64KB 以上の巨大な本体(バンドル全体の即時関数など)は初回でソースも構文木も手放す。
- それ以外は 1 回目の呼び出しではソースのまま残して構文木は呼び出し終了時に解放し、 2 回目に呼ばれた関数だけ構文木をキャッシュする。
Sourcepub fn uses_arguments(&self, stmts: &[Statement]) -> bool
pub fn uses_arguments(&self, stmts: &[Statement]) -> bool
この関数本体(および内側のアロー関数)が arguments または eval を参照するか。
fn raw_might_use_arguments(&self) -> bool
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for FnBody
impl !RefUnwindSafe for FnBody
impl !Send for FnBody
impl !Sync for FnBody
impl !UnwindSafe for FnBody
impl Unpin for FnBody
impl UnsafeUnpin for FnBody
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more