# 機能設計書 67-ポインタ操作

## 概要

本ドキュメントは、Juliaにおけるポインタ操作（`Ptr` / `Ref` / `unsafe_load` / `unsafe_store!` / `unsafe_wrap` / `pointer_from_objref`）の設計と実装を記述するものである。

### 本機能の処理概要

本機能は、C言語との相互運用に必要な低レベルのポインタ操作を提供する。メモリアドレスへの直接アクセス、Julia オブジェクトとCポインタ間の変換、アトミックなメモリ操作を含む。

**業務上の目的・背景**：Juliaは高レベル言語でありながら、C/C++ライブラリとの直接的な連携を可能にする必要がある。ポインタ操作はccall（No.66）の基盤であり、外部ライブラリのメモリバッファを直接操作したり、C構造体を直接読み書きしたりする場面で不可欠である。

**機能の利用シーン**：ccall での引数/戻り値のポインタ渡し、C ライブラリが返すバッファのJulia配列へのラップ、C構造体のフィールドアクセス、メモリマップドI/O操作、アトミックなメモリ操作（ロックフリーデータ構造）に利用される。

**主要な処理内容**：
1. `Ptr{T}` 型によるメモリアドレスの表現
2. `Ref{T}` 型によるGC保護されたポインタ
3. `unsafe_load` / `unsafe_store!` による直接メモリアクセス
4. `unsafe_wrap` によるCポインタからJulia配列への変換
5. `unsafe_modify!` / `unsafe_replace!` / `unsafe_swap!` によるアトミック操作
6. `cconvert` / `unsafe_convert` による型変換

**関連システム・外部連携**：GC（ガベージコレクタ）との連携、ccall機構との連携。

**権限による制御**：なし（unsafe操作はセグフォルトのリスクがある）。

## 関連画面

該当なし。本機能はプログラマティックに使用されるAPI。

## 機能種別

低レベルメモリ操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p | `Ptr{T}` | Yes | メモリアドレス | 有効なアドレスであること（検証なし） |
| i | `Integer` | No | インデックス（1始まり） | デフォルト 1 |
| x | `T` | Yes（store の場合） | 格納する値 | T に変換可能であること |
| dims | `NTuple{N,Int}` or `Integer` | Yes（wrap の場合） | 配列の次元 | 正の整数 |
| own | `Bool` | No | メモリの所有権を Julia が持つか | デフォルト `false` |
| order | `Symbol` | No | アトミック操作の順序 | `:not_atomic`, `:monotonic`, `:acquire`, `:release` 等 |

### 入力データソース

ccall の戻り値ポインタ、Julia オブジェクトのアドレス

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| loaded_value | `T` | unsafe_load で読み出した値 |
| array | `Array{T,N}` | unsafe_wrap で生成した配列 |
| old_new_pair | `Pair` | unsafe_modify! の返り値（old => new） |
| replace_result | `NamedTuple` | unsafe_replace! の返り値（old, success） |

### 出力先

呼び出し元に値として返却

## 処理フロー

### 処理シーケンス

```
1. ポインタの取得
   └─ ccall 戻り値、cglobal、pointer_from_objref 等でポインタ取得
2. 型変換（必要に応じて）
   └─ cconvert → unsafe_convert で Julia 値を C ポインタに変換
3. メモリ操作
   └─ unsafe_load / unsafe_store! / unsafe_wrap でメモリにアクセス
4. アトミック操作（必要に応じて）
   └─ order パラメータに従いアトミックアクセス
```

### フローチャート

```mermaid
flowchart TD
    A[ポインタ取得] --> B{操作種別}
    B -->|読み込み| C[unsafe_load p i]
    B -->|書き込み| D[unsafe_store! p x i]
    B -->|配列ラップ| E[unsafe_wrap Array p dims]
    B -->|アトミック| F[unsafe_modify!/replace!/swap!]
    C --> G[pointerref intrinsic]
    D --> H[pointerset intrinsic]
    E --> I[jl_ptr_to_array ccall]
    F --> J[atomic_pointer* intrinsic]
    G --> K[値返却]
    H --> K
    I --> K
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-67-01 | unsafe 原則 | ポインタ操作はすべて unsafe であり、無効なポインタへのアクセスはセグフォルトする | 全ポインタ操作 |
| BR-67-02 | GC 保護 | unsafe_wrap でラップした配列の元ポインタが GC されないよう注意が必要 | unsafe_wrap 使用時 |
| BR-67-03 | 所有権 | `own=true` の場合、Julia が free を呼び出す | unsafe_wrap で own=true の場合 |
| BR-67-04 | アトミック順序 | order は有効なメモリ順序シンボルでなければならない | アトミック操作使用時 |

### 計算ロジック

ポインタ算術: `p + (elsize(typeof(p)) * (i - 1))` でインデックスアクセス

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | セグメンテーション違反 | 無効なポインタへのアクセス | ポインタの有効性を確認 |
| - | TypeError | 型の不一致でのアクセス | 正しい型を指定 |

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- ポインタ操作はインライン化され、ゼロオーバーヘッドであること
- unsafe_wrap は O(1) 操作（コピーなし）

## セキュリティ考慮事項

- すべての unsafe 操作はメモリ安全性の保証がない
- 不正なポインタ操作によりプログラムの任意のメモリを読み書きできる可能性がある

## 備考

- Julia 1.10 以降でアトミックメモリ操作（order パラメータ）が利用可能
- `C_NULL` は `Ptr{Cvoid}(0)` として定義される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pointer.jl | `base/pointer.jl` | `Ptr{T}` 型（3-9行目）: メモリアドレスを表現するパラメトリック型 |
| 1-2 | pointer.jl | `base/pointer.jl` | `C_NULL` 定数（18行目）: ヌルポインタ `bitcast(Ptr{Cvoid}, 0)` |
| 1-3 | refpointer.jl | `base/refpointer.jl` | `Ref{T}` 型（5-81行目）: GC保護されたポインタ。Cstring/Cwstring の定義（86-92行目）も含む |

**読解のコツ**: `Ptr{T}` と `Ref{T}` の違いが重要。`Ptr{T}` はGC管理外の生ポインタ、`Ref{T}` はJuliaのGCが管理する安全な参照。ccall に渡す際、`Ref{T}` は自動的に `Ptr{T}` に変換される。

#### Step 2: 型変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pointer.jl | `base/pointer.jl` | `unsafe_convert` 関数（34-55行目）: Julia オブジェクトを C ポインタに変換 |
| 2-2 | pointer.jl | `base/pointer.jl` | `cconvert` の各種オーバーロード（58-73行目）: ccall 用の変換準備 |

**主要処理フロー**:
1. **58-59行目**: 文字列を String に変換して Ptr{UInt8} として渡す準備
2. **63行目**: Array は内部の ref フィールドを取得
3. **71-73行目**: GenericMemory は内部のポインタフィールドを取得

#### Step 3: メモリアクセスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pointer.jl | `base/pointer.jl` | `unsafe_load` 関数（131-155行目）: メモリからの値の読み出し |
| 3-2 | pointer.jl | `base/pointer.jl` | `unsafe_store!` 関数（157-182行目）: メモリへの値の書き込み |
| 3-3 | pointer.jl | `base/pointer.jl` | `unsafe_wrap` 関数（91-129行目）: C ポインタの Julia 配列へのラップ |

#### Step 4: アトミック操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | pointer.jl | `base/pointer.jl` | `unsafe_modify!` 関数（184-209行目）: アトミックな読み-修正-書き込み |
| 4-2 | pointer.jl | `base/pointer.jl` | `unsafe_replace!` 関数（211-243行目）: アトミックなCAS操作 |
| 4-3 | pointer.jl | `base/pointer.jl` | `unsafe_swap!` 関数（245行目以降）: アトミックなスワップ操作 |

### プログラム呼び出し階層図

```
ccall((:func, lib), RetType, (Ptr{T},), arg)
    │
    ├─ cconvert(Ptr{T}, arg)          # 変換準備
    │      └─ String / Array.ref 等
    │
    └─ unsafe_convert(Ptr{T}, ...)    # ポインタ取得
           └─ getfield(a, :ptr) 等

unsafe_load(p, i)
    └─ pointerref(p, Int(i), 1)       # コンパイラ intrinsic

unsafe_store!(p, x, i)
    └─ pointerset(p, convert(T,x), Int(i), 1)  # コンパイラ intrinsic

unsafe_wrap(Array, p, dims)
    └─ jl_ptr_to_array(...)           # C ランタイム

unsafe_modify!(p, op, x, order)
    └─ atomic_pointermodify(p, op, x, order)   # コンパイラ intrinsic
```

### データフロー図

```
[入力]                    [処理]                        [出力]

Ptr{T} ──────────▶ unsafe_load() ──────▶ T 値
                         │
T 値 ─────────────▶ unsafe_store!() ──▶ メモリへ書き込み
                         │
Ptr{T} + dims ───▶ unsafe_wrap() ────▶ Array{T,N}
                         │
Julia オブジェクト ──▶ cconvert() ──▶ unsafe_convert() ──▶ Ptr{T}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pointer.jl | `base/pointer.jl` | ソース | Ptr 型とポインタ操作の主実装 |
| refpointer.jl | `base/refpointer.jl` | ソース | Ref 型と Cstring/Cwstring の定義 |
| c.jl | `base/c.jl` | ソース | ccall 関連定義（No.66） |
| ctypes.jl | `base/ctypes.jl` | ソース | C 互換型定義（No.69） |
| boot.jl | `base/boot.jl` | ソース | Ptr/Ref の基本型定義 |
