Skip to content

Vec and Memory

james-yusuke edited this page Jul 16, 2026 · 1 revision

Vecとメモリ所有

Vec<T>はコンパイラ組み込みのmanaged dynamic arrayです。[]Tは 非拡張viewであり、Vecとは別の静的型です。

構築と操作

values := Vec<i32>{}
nodes := Vec<ExprNode>{capacity: 512}

index := values.push(10)
values.push(20)

length := values.len()
reserved := values.capacity()
values.reserve(1024)

values[index] = 11
value := values[index]
view := values.as_slice()

values.clear()
操作 仕様
push(value) 末尾へ追加し、挿入indexをi32で返す
len() 要素数
capacity() 予約容量
reserve(n) capacityを最低nまで増やす
clear() managed要素をreleaseし、lengthを0にする
vec[index] bounds check付きread
vec[index] = value ownership置換を伴うwrite
as_slice() 同じ要素への[]T view

参照セマンティクス

a := Vec<i32>{}
a.push(1)

b := a
b[0] = 2

println(a[0]) // 2

Vecを代入、引数渡し、returnしても、同じmanaged container handleを共有します。 deep copyではありません。nested Vec、string、managed fieldを持つstructも managed要素としてownership graphへ接続されます。

安全性

  • 負のcapacityは拒否します。
  • capacity計算overflowは診断後abortします。
  • index範囲外は診断後abortします。
  • as_slice()で得た[]Tにはpushreserveはありません。
  • 公開APIにfreeやraw backing pointerはありません。
  • 暗黙のVec<T> -> *T変換は拒否します。

managed runtime

Vec headerとbacking storageはstatic linkされるYCPL runtimeが管理します。 function/scope frameを抜ける際に決定的にcleanupし、returnされるrootと到達可能な childはcaller frameへ移します。

Vec root
└─ backing storage
   ├─ managed element
   ├─ managed element
   └─ nested Vec root
      └─ nested backing storage

通常のYCPLコードはmalloc/calloc/realloc/freeを使う必要がありません。 raw allocatorはruntime内部またはstl/cstd/unsafe/memの明示的な境界に 限定します。セルフホストコンパイラ本体は直接std/memをimportしません。

Dynamic AST Arena

セルフホストコンパイラはAST node、field、parameter、child ID、project file、 symbol、import、localをVec<T>で保持します。

struct AstArena {
    file_id i32
    exprs Vec<ExprNode>
    stmts Vec<StmtNode>
    decls Vec<DeclNode>
}

これにより、以前のlocals/functions/arguments/struct fieldsの固定上限と manual realloc依存を撤廃しています。

Clone this wiki locally