Skip to main content

FnBody

Struct FnBody 

Source
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: bool

strict モードの本体か("use strict" の指令・strict な外側・クラス)。 非 strict の関数は this が undefined/null のときグローバル(window)になる。

§uses_args: Cell<u8>

本体(または内側のアロー関数)が arguments / eval を参照するか(0=未計算, 1=いいえ, 2=はい)。

Implementations§

Source§

impl FnBody

Source

pub fn parsed(stmts: Vec<Statement>) -> Rc<Self>

Source

pub fn parsed_with(stmts: Vec<Statement>, strict: bool) -> Rc<Self>

Source

pub fn from_rc(stmts: Rc<Vec<Statement>>) -> Rc<Self>

Source

pub fn lazy(source: String, strict: bool) -> Rc<Self>

Source

pub fn is_lazy(&self) -> bool

まだ解析していないか。

Source

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 回目に呼ばれた関数だけ構文木をキャッシュする。
Source

pub fn uses_arguments(&self, stmts: &[Statement]) -> bool

この関数本体(および内側のアロー関数)が arguments または eval を参照するか。

Source

fn raw_might_use_arguments(&self) -> bool

Trait Implementations§

Source§

impl Debug for FnBody

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for FnBody

同じ本体(同じ定義)かどうかで比べる。

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.