Skip to content

context

Context は YanmaJS エンジンの実行単位です。VM・グローバル環境・GC 状態を1つに束ね、スクリプトの評価からホスト関数の登録、GC 制御まで、埋め込み API のほぼすべてがこの型のメソッドとして提供されます。型定義は typeValue の生成・変換・判定は value、エラー処理は error を参照してください。


Lifecycle

Context.init

pub fn init(allocator: std.mem.Allocator) !*Context

Context を初期化して返します。内部で VM・グローバルレルムを初期化します。

戻り値 説明
!*Context 新規 Context。失敗時は error.OutOfMemory

使用後は deinit で解放してください。

Context.initWithMemoryLimit

pub fn initWithMemoryLimit(backing_allocator: std.mem.Allocator, max_bytes: usize) !*Context

割り当て量に上限を課した Context を作ります。信頼できない JavaScript コードをサンドボックス実行する際に使います。

引数 説明
backing_allocator 実際にメモリを確保する下位アロケータ
max_bytes 累計割り当てバイト数の上限

Context 自身を含むすべての内部割り当てがこのアロケータ経由になり、上限を超えると通常の割り当てエラーと同じ error.OutOfMemory が(スクリプト評価であれば EvalError.OutOfMemory として)返ります。現在の使用量・上限は getMemoryUsage/getMemoryLimit で取得できます。

Context.deinit

pub fn deinit(ctx: *Context) void

Context とその内部状態(VM・ホスト関数ラッパー・initWithMemoryLimit で使った上限付きアロケータなど)をすべて解放します。以後 ctx は使用できません。


Evaluation

Context.eval

pub fn eval(ctx: *Context, source: []const u8) EvalError!Value

JavaScript ソースコードをその場でパース・コンパイル・実行し、最後の式文の評価結果を返します。

戻り値 説明
EvalError!Value 成功時は最後の式の値。構文エラーや実行時エラーは対応する EvalError バリアントとして返る

例外が捕捉されずに伝播した場合は error.UncaughtException になり、例外値は getPendingException で取得します。

Context.compileScript

pub fn compileScript(ctx: *Context, source: []const u8) EvalError!CompiledScript

ソースコードをパース・コンパイルするが実行はしません。同じスクリプトを複数回実行したい場合や、シリアライズして永続化したい場合に使います。

戻り値 説明
EvalError!CompiledScript コンパイル済みのトップレベル関数。コンパイルエラーは EvalError として返る

戻り値は Context の永続値テーブルに登録されるため、ctx が生きている限り GC で回収されません(明示的な解放 API はなく、ctx.deinit() まで保持され続けます)。

Context.serializeScript

pub fn serializeScript(ctx: *Context, script: CompiledScript) ![]u8

compileScript/deserializeScript で得たコンパイル済みスクリプトを、独自形式のバイトコードバイナリへシリアライズします。

戻り値 説明
![]u8 シリアライズされたバイト列。呼び出し側が ctx.allocator.free() で解放すること

シリアライズ形式はエンジン内部のバイトコード表現に依存しており、YanmaJS のバージョン間で互換性は保証されません。

Context.deserializeScript

pub fn deserializeScript(ctx: *Context, data: []const u8) !CompiledScript

serializeScript が出力したバイト列から CompiledScript を復元します。compileScript と同様に結果は永続値テーブルへ登録されます。パース(ソースの字句・構文解析)を経ないため、同じスクリプトを繰り返しロードする場合は compileScript より高速です。

Context.runScript

pub fn runScript(ctx: *Context, script: CompiledScript) EvalError!Value

compileScript/deserializeScript で得たスクリプトを実行し、結果を返します。同じ CompiledScript を複数回 runScript することもできますが、トップレベルの var/let/const 宣言は実行のたびに再評価される点に注意してください。

Context.evalModule

pub fn evalModule(ctx: *Context, specifier: []const u8, source: []const u8) EvalError!Value

ES Modules(import/export)として source を評価します。specifier はこのモジュール自身の識別子(相対 import の解決基準)として使われます。依存モジュールの解決には setModuleLoader で登録したローダーが使われます。

Context.setModuleLoader

pub fn setModuleLoader(ctx: *Context, loader: ModuleLoader) void

evalModule 内の import 文が参照する他モジュールをホスト側から供給するためのローダーを登録します。loader の型は ModuleLoader を参照してください。未登録のまま存在しない specifierimport するとモジュール解決エラーになります。

Context.callFunction

pub fn callFunction(ctx: *Context, func: Value, args: []const Value) EvalError!Value

JavaScript の関数値 func を Zig 側から呼び出します。func が呼び出し可能でない場合は TypeError("value is not a function")を pending exception にセットした error.RuntimeError になります。thisundefined(sloppy mode 関数では globalThis に強制)として呼ばれます。this を明示したい場合は callFunctionWithReceiver を使います。

Context.callFunctionWithReceiver

pub fn callFunctionWithReceiver(ctx: *Context, func: Value, receiver: Value, args: []const Value) EvalError!Value

callFunction と同じですが、this(レシーバ)に receiver を明示指定して func を呼び出します(QuickJS の JS_Call / V8 の Function::Call 相当)。sloppy mode 関数では undefined/null の receiver は globalThis に強制されます。メソッド呼び出しやイベントリスナーの this をホストから指定したいケースで使います。

Context.drainMicrotasks

pub fn drainMicrotasks(ctx: *Context) !void

保留中のマイクロタスクキュー(Promise の .then/.catch/.finally コールバックなど)をキューが空になるまで実行します。eval/callFunction はマイクロタスクを自動的にはドレインしないため、Promise の解決結果を JavaScript 側の状態に反映させたい場合は明示的に呼ぶ必要があります。ドレイン完了後、未処理のまま残っている reject を検出し、setUnhandledRejectionHandler で登録したハンドラへ通知します。


Globals

Context.getGlobal

pub fn getGlobal(ctx: *Context, name: []const u8) Value

現在のレルムのグローバル変数 name の値を返します。未定義なら undefined

Context.setGlobal

pub fn setGlobal(ctx: *Context, name: []const u8, val: Value) !void

現在のレルムのグローバル変数 nameval を設定します(存在しなければ作成)。val がオブジェクト系の値の場合、呼び出し前に GC ルートされていなくても、この呼び出しによってグローバルテーブル経由で到達可能になります(以後は GC 対象から保護されます)。


Functions

Context.setFunction

pub fn setFunction(ctx: *Context, name: []const u8, zig_fn: HostFn) !void

Zig で実装した HostFn をグローバル関数 name として登録します。this を受け取らないシンプルな関数向けです。

Context.makeFunction

pub fn makeFunction(ctx: *Context, name: []const u8, func: HostMethod) !Value

this を受け取れる HostMethod をネイティブ関数 Value として作ります。setProperty/setGlobal でメソッド・グローバル関数として設定するほか、definePropertygetter/setter に渡すとネイティブアクセサとして機能します。

戻り値は他の make* 系関数と同様に GC 未ルートです。呼び出し側は setProperty/setGlobal/defineProperty で即座にオブジェクトへ attach するか、protect/HandleScope.pin でルートしてください。attach 前に GC を誘発しうる別の割り当てを行わないよう注意してください。

Context.makeFunctionWithData

pub fn makeFunctionWithData(ctx: *Context, name: []const u8, func: HostMethod, data: ?*anyopaque) !Value

makeFunction と同じですが、個別のユーザーデータポインタ data を関数に紐付けます。コールバック内から value.getFunctionData で取り出せます。エンジンは data を一切解釈しません(GC 対象外・解放はホスト責任)。

Context.callFunction

callFunctionEvaluation を参照してください。

Context.getCurrentCallee

pub fn getCurrentCallee(ctx: *Context) Value

ネイティブ関数の実行中に、現在実行中の関数自身の Value を返します。HostMethod コールバック内から value.getFunctionData と組み合わせて、自身に紐付いたユーザーデータへアクセスするために使います。ネイティブ関数の実行中以外に呼んだ場合の戻り値は未規定です。

Context.setUserData / Context.getUserData

pub fn setUserData(ctx: *Context, data: ?*anyopaque) void
pub fn getUserData(ctx: *Context) ?*anyopaque

Context 全体に紐付くホスト専用の自由スロットです。エンジンはこの値を一切解釈せず、GC 対象にもなりません(寿命・解放はホスト側の責任)。HostMethod からレシーバ以外のホスト状態(バインディング全体など)へ到達するために使います。setUserData(ctx, null) でクリアできます。


Promises

Context.makePromise

pub fn makePromise(ctx: *Context) !struct { promise: Value, handle: PromiseHandle }

pending 状態の Promise を新規作成します。

戻り値フィールド 説明
promise Value 作成された Promise オブジェクト(JavaScript 側に渡す用)
handle PromiseHandle resolvePromise/rejectPromise に渡す操作用ハンドル

promise は内部で handle 経由の PersistentHandle によってルートされているため、resolvePromise/rejectPromise を呼ぶまで GC で回収されません。

Context.resolvePromise

pub fn resolvePromise(ctx: *Context, handle: PromiseHandle, val: Value) void

handle に対応する Promise を val で fulfill します。呼び出し後、内部で保持していたルートは解除されます(Promise 自体は他から参照されていれば生存し続けます)。実際にコールバックへ反映するには drainMicrotasks を呼ぶ必要があります。

Context.rejectPromise

pub fn rejectPromise(ctx: *Context, handle: PromiseHandle, val: Value) void

handle に対応する Promise を理由 val で reject します。resolvePromise と同様、反映には drainMicrotasks が必要です。


Objects/Arrays

Context.makeObject

pub fn makeObject(ctx: *Context) !Value

空のプレーンオブジェクト({})を作ります。戻り値は GC 未ルートです(makeFunction と同様、即座に attach するかルートしてください)。

Context.makeArray

pub fn makeArray(ctx: *Context) !Value

空の配列([])を作ります。戻り値は GC 未ルートです。

Context.makeHostObject

pub fn makeHostObject(
    ctx: *Context,
    data: ?*anyopaque,
    finalizer: ?*const fn (?*anyopaque) void,
) !Value

ホスト側データ data とファイナライザ finalizer を紐付けたプレーンオブジェクトを作ります。DOM ライクなホストオブジェクトを実装する際の基本ブロックです。

引数 説明
data オブジェクトに紐付けるホスト側ポインタ。value.getHostData で取り出す
finalizer オブジェクトが GC で回収される際に一度だけ呼ばれる。null なら何もしない

setPrototype と組み合わせて複数の makeHostObject 結果をプロトタイプチェーンで繋げば、多段の interface(例: NodeElementHTMLElement)を構築できます。戻り値は GC 未ルートです。


Properties

Context.defineProperty

pub fn defineProperty(ctx: *Context, obj: Value, name: []const u8, desc: PropertyDescriptor) !void

Object.defineProperty 相当の低レベル API です。desc の型・既定値は PropertyDescriptor を参照してください。obj がプレーンオブジェクトでない場合は何もしません。

Context.setProperty

pub fn setProperty(ctx: *Context, obj: Value, name: []const u8, val: Value) !void

プレーンオブジェクト obj のプロパティ nameval を設定します(writable: true, enumerable: true, configurable: true の通常のデータプロパティとして、既存プロパティがあれば値のみ更新)。obj がプレーンオブジェクトでなければ何もしません。

Context.setIndex

pub fn setIndex(ctx: *Context, arr: Value, index: usize, val: Value) !void

配列 arrindex 番目の要素に val を設定します。index が現在の長さ以上の場合は配列を伸張します。arr が配列でなければ何もしません。

Context.setPrototype

pub fn setPrototype(ctx: *Context, obj: Value, proto: Value) void

obj のプロトタイプを proto に設定します(Object.setPrototypeOf 相当)。proto が JavaScript の null ならプロトタイプチェーンを切り離します。obj がプレーンオブジェクトでない場合、または proto がプレーンオブジェクトでも null でもない場合は何もしません。


Errors

Context.getPendingException

pub fn getPendingException(ctx: *Context) ?Value

保留中の JavaScript 例外値を返し、同時にスロットをクリアします。詳細なパターンは error を参照してください。

Context.throwValue / throwError / throwTypeError / throwRangeError / throwReferenceError / throwSyntaxError

pub fn throwValue(ctx: *Context, val: Value) void
pub fn throwError(ctx: *Context, name: []const u8, message: []const u8) void
pub fn throwTypeError(ctx: *Context, message: []const u8) void
pub fn throwRangeError(ctx: *Context, message: []const u8) void
pub fn throwReferenceError(ctx: *Context, message: []const u8) void
pub fn throwSyntaxError(ctx: *Context, message: []const u8) void

ホスト側から JavaScript 例外を発生させます。いずれも pending exception スロットへ値を設定するのみで、Zig の制御フローは中断しません。詳細・使い分けは error を参照してください。


Event Loop/Timers

Context.setEventLoopHook / Context.clearEventLoopHook

pub fn setEventLoopHook(ctx: *Context, hook: EventLoopHook) void
pub fn clearEventLoopHook(ctx: *Context) void

setTimeout/setInterval/clearTimeout/clearInterval の実体をホストのイベントループへ委譲するフックを設定・解除します。フックの型は EventLoopHook を参照してください。フック未設定時、これらの組み込み関数は遅延を無視して即座にコールバックを実行します。

Context.fireTimer

pub fn fireTimer(ctx: *Context, id: u32) void

EventLoopHook.set_timer で受け取った id のタイマーコールバックを実行します(ホストの実際のタイマー機構が発火したタイミングで呼び出す)。setInterval 由来のタイマー(is_repeat = true)は実行後も登録が残り、それ以外(setTimeout)は実行後に自動的に登録解除されます。実行後、内部でマイクロタスクのドレインと未処理 reject のチェックも行います。

Context.hasPendingTimers

pub fn hasPendingTimers(ctx: *Context) bool

clearTimeout/clearInterval されていない、発火待ちのタイマーが1つ以上あるかを返します。ホストのイベントループを「もう処理すべきものがないので終了してよいか」判定する際に使います。


Console/Handlers

Context.setConsoleHandler

pub fn setConsoleHandler(ctx: *Context, handler: ?ConsoleHandler) void

console.log/info/warn/error/debug の出力先をホストコールバックに切り替えます。handler が設定されている間、各メソッドは引数を(String(arg) 相当で)結合したテキストと呼び出しレベルをコールバックへ渡し、標準出力へは出力しません。null を渡すと従来の標準出力への出力に戻ります。型は ConsoleHandler を参照してください。

Context.setUnhandledRejectionHandler

pub fn setUnhandledRejectionHandler(ctx: *Context, handler: ?UnhandledRejectionHandler) void

Promise が reject され、drainMicrotasks 完了時点でも reject ハンドラが一度も付いていない場合にホストへ通知するハンドラを設定します(HostPromiseRejectionTracker 相当)。null を渡すと通知を止めます。型は UnhandledRejectionHandler を参照してください。


決定的実行(Deterministic Execution)

Context.setDateNowMs

pub fn setDateNowMs(ctx: *Context, now_ms: ?f64) void

スクリプトから見える現在時刻(Date.now()new Date() 等)を固定します。フレームクロックに同期した描画など、スクリプト可視の時刻を決定的にしたい場合に使います。null を渡すとシステムクロックに戻ります。

Context.setRandomSeed

pub fn setRandomSeed(ctx: *Context, seed: u64) void

Math.random() の背後にある決定的 PRNG を再シードします。エンジンは常に固定のデフォルトシードを使うため、再現性を保ったままセッション間で系列を変えたい場合にのみ必要です。

GC/Memory

Context.collectGarbage

pub fn collectGarbage(ctx: *Context) void

GC サイクルを即座に1回実行します。GCMode.manual 時に明示的な回収を行うため、あるいは auto モードでもタイミングを制御したい場合に使います。

Context.requestInterrupt / Context.clearInterrupt

pub fn requestInterrupt(ctx: *Context) void
pub fn clearInterrupt(ctx: *Context) void

実行中のスクリプトを安全に中断させるための割り込みフラグを操作します。requestInterrupt を呼ぶと、実行中(または次に開始する)の eval/runScript/callFunction などが EvalError.RuntimeError を返して停止します(例外メッセージには "interrupted" を含む)。無限ループに陥ったスクリプトを別スレッド・シグナルハンドラなどから停止させる用途を想定しています。clearInterrupt はまだ消費されていない割り込み要求を取り消します。割り込み後も Context 自体は再利用可能です。

Context.setExecutionTimeLimitMs

pub fn setExecutionTimeLimitMs(ctx: *Context, ms: ?u64) void

以後の eval/evalModule/runScript/callFunction/fireTimer の各呼び出しに、壁時計ベースの実行時間バジェット(ミリ秒)を課します。バジェットは各エントリポイントの呼び出し時点からそれぞれ独立に計測され(ホスト関数から再入的に eval した場合、内側の呼び出しにも新しいバジェットが与えられ、外側の残り時間は内側の完了後に再開します)、超過すると実行中のスクリプトは Error("Execution time limit exceeded") の送出(EvalError.RuntimeError)で中断されます。中断後も Context は再利用可能です。null を渡すと制限を解除します。

  • チェックは一定命令数(WATCHDOG_INTERVAL = 4096 命令)ごとに行われるため、実際の超過検出は ms ちょうどではなく若干の遅れを伴います。
  • requestInterrupt/clearInterrupt とは独立で、互いに影響しません。
  • 時刻源は Linux の clock_gettime(CLOCK_MONOTONIC) です。非 Linux ターゲットではクロックが常に 0 を返すため、設定した制限は事実上無効(恒久 no-op)になります。

Context.handleScope

pub fn handleScope(ctx: *Context) HandleScope

短命な GC ルートスコープを開始します。戻り値の HandleScope.pin でオブジェクト値を一時的にルートし、HandleScope.close で巻き戻します。型の詳細は HandleScope を参照してください。

var scope = ctx.handleScope();
defer scope.close();
const obj = try ctx.eval("({value: 42})");
scope.pin(obj);
ctx.collectGarbage(); // obj は回収されない

Context.protect / Context.unprotect

pub fn protect(ctx: *Context, val: Value) PersistentHandle
pub fn unprotect(ctx: *Context, handle: PersistentHandle) void

HandleScope よりも長寿命な GC ルートを張ります。unprotect を呼ぶまで(あるいは ctx.deinit() まで)val は GC で回収されません。val が非オブジェクト値の場合、protect はダミーハンドルを返し、それに対する unprotect は安全に無視されます。型は PersistentHandle を参照してください。

Context.persistentGet

pub fn persistentGet(ctx: *Context, handle: PersistentHandle) Value

protect で作ったハンドルが現在指している値を返します。無効なハンドル(非オブジェクト値の protect が返すダミー、または unprotect 済みのスロット)では undefined を返します。主に C API(yjs_persistent_get)の下請けですが、Zig ホストからも利用できます。

Context.setGCMode

pub fn setGCMode(ctx: *Context, mode: GCMode) void

GC の起動方式を切り替えます(auto/manual)。型は GCMode を参照してください。

Context.suppressGC / Context.resumeGC

pub fn suppressGC(ctx: *Context) void
pub fn resumeGC(ctx: *Context) void

自動 GC を一時的に止め(suppressGC)、後で元のしきい値に戻します(resumeGC)。setGCMode(.manual) と異なり、resumeGC を呼ぶと suppressGC 呼び出し時点のしきい値設定に自動的に復帰する点が特徴で、一時的にアロケーションが多いクリティカルセクションを GC なしで走らせたい場合に向きます。ネストはサポートされません(2回目の suppressGC は1回目のしきい値を上書きします)。

Context.getGCStats

pub fn getGCStats(ctx: *Context) GCStats

GC の統計情報のスナップショットを返します。型は GCStats を参照してください。

Context.setGCConfig

pub fn setGCConfig(ctx: *Context, config: GCConfig) void

GC のしきい値・成長係数を設定します。config.initial_threshold は呼び出し直後の getGCStats().threshold に即座に反映されます。型は GCConfig を参照してください。

Context.getMemoryUsage

pub fn getMemoryUsage(ctx: *const Context) usize

initWithMemoryLimit で作成した Context の現在の累計割り当てバイト数を返します。init(上限なし)で作成した Context では常に 0 を返します。

Context.getMemoryLimit

pub fn getMemoryLimit(ctx: *const Context) ?usize

initWithMemoryLimit で設定した上限バイト数を返します。init で作成した Context では null


Realms

Realm は、グローバル変数・組み込みプロトタイプの集合をひとまとめにした環境です。1つの Context 内で複数の Realm を切り替えることで、グローバル状態を分離した複数の実行環境を扱えます(詳細は Realm を参照)。

Context.createRealm

pub fn createRealm(ctx: *Context) !*Realm

新しい Realm(組み込みオブジェクト一式を再構築した、独立したグローバル環境)を作成して返します。作成時点では現在の実行対象レルムには影響しません(setRealm で明示的に切り替えるまで有効化されません)。

Context.setRealm

pub fn setRealm(ctx: *Context, realm: *Realm) *Realm

以後の eval/getGlobal/setGlobal などが対象とするレルムを realm に切り替え、切り替え前のレルムを返します。元に戻したい場合は戻り値を保持しておき、再度 setRealm に渡してください。

なお、関数(クロージャ・組み込みとも)は作成されたレルムを記憶しており、レルムをまたいで呼び出された場合は実行中だけ自動的にその関数のレルムへ切り替わります(仕様の execution context の realm に相当)。別レルム由来の関数が投げるエラーはその関数のレルムの TypeError 等になり、prototype フォールバックもその関数のレルムの intrinsic が使われます。

Context.getRealm

pub fn getRealm(ctx: *Context) *Realm

現在アクティブなレルムを返します。

Context.destroyRealm

pub fn destroyRealm(ctx: *Context, realm: *Realm) void

createRealm で作成したレルムを破棄します。現在アクティブなレルムを破棄してはいけません(setRealm で他のレルムに切り替えてから呼ぶこと)。また、Context.init 直後から存在するデフォルトレルム(ctx.deinit() が解放する)を destroyRealm に渡さないでください — 二重解放になります。

さらに、そのレルムで作成された関数オブジェクトは所属レルムへのポインタを保持しています。そのレルム由来の関数がまだ他のレルムから到達可能な状態で destroyRealm を呼ばないでください — 以後その関数を呼び出すと解放済みレルムを参照します。レルムを破棄するのは、そのレルム由来の値への参照をすべて手放した後にしてください。