json-native: enable float roundtrip in parser (NUMBER => float by '.'/exp); expand roundtrip smoke with more numeric cases
This commit is contained in:
@ -6,7 +6,7 @@ This index points to the currently maintained architectural documents:
|
||||
- Execution Backends: reference/architecture/execution-backends.md
|
||||
- Lowering Contexts: ../../design/LOWERING_CONTEXTS.md
|
||||
- LLVM Layer Overview: ../../design/LLVM_LAYER_OVERVIEW.md
|
||||
- VM Overview: VM_README.md
|
||||
- VM Overview: vm.md
|
||||
- Cranelift AOT design: ../../design/backend-cranelift-aot-design.md
|
||||
|
||||
Note: Some long-form papers reside under `private/papers/reference/architecture/`.
|
||||
|
||||
@ -115,4 +115,4 @@ Nyash Source ──▶ MIR (Builder)
|
||||
|
||||
See also
|
||||
- `docs/guides/examples/http_result_patterns.md` - HTTPのResult挙動(unreachable/404/500)のE2E例
|
||||
- `docs/VM_README.md` - VM統計とプラグイン周りの既知制約
|
||||
- `docs/reference/architecture/vm.md` - VM統計とプラグイン周りの既知制約
|
||||
|
||||
@ -5,4 +5,4 @@ For the full guide, see:
|
||||
|
||||
Additional references:
|
||||
- ../../design/backend-llvm-implementation-guide.md
|
||||
- VM_README.md
|
||||
- vm.md
|
||||
|
||||
70
docs/reference/architecture/llvm-harness.md
Normal file
70
docs/reference/architecture/llvm-harness.md
Normal file
@ -0,0 +1,70 @@
|
||||
# llvmlite Harness(正式導入・Rust LLVM 対置運用)
|
||||
|
||||
Purpose
|
||||
- Python + llvmlite による高速・柔軟な LLVM 生成経路を提供(検証・プロトタイプと将来の主役)。
|
||||
- Rust/inkwell 経路と並走し、代表ケースで機能同値(戻り値・検証)を維持。
|
||||
|
||||
Switch
|
||||
- `NYASH_LLVM_USE_HARNESS=1` でハーネス優先(LLVM バックエンド入口から起動)。
|
||||
|
||||
Tracing
|
||||
- `NYASH_LLVM_TRACE_FINAL=1` を設定すると、代表コール(`Main.node_json/3`, `Main.esc_json/1`, `main` 等)を標準出力へ簡易トレースします。
|
||||
ON/OFF の最終 JSON 突合の補助に使用してください。
|
||||
|
||||
Protocol
|
||||
- Input: MIR14 JSON(Rust 前段で Resolver/LoopForm 規約を満たした形)。
|
||||
- Output: `.o` オブジェクト(既定: `NYASH_AOT_OBJECT_OUT` または `NYASH_LLVM_OBJ_OUT`)。
|
||||
- 入口: `ny_main() -> i64`(戻り値は exit code 相当。必要時 handle 正規化を行う)。
|
||||
|
||||
CLI(crate)
|
||||
- `crates/nyash-llvm-compiler` 提供の `ny-llvmc` は llvmlite ハーネスの薄ラッパーだよ。
|
||||
- ダミー: `./target/release/ny-llvmc --dummy --out /tmp/dummy.o`
|
||||
- JSON→.o: `./target/release/ny-llvmc --in mir.json --out out.o`
|
||||
- JSON→EXE(新規): `./target/release/ny-llvmc --in mir.json --emit exe --nyrt target/release --out app`
|
||||
- `--nyrt <dir>` で `libnyrt.a` の位置を指定(省略時は `target/release`→`crates/nyrt/target/release` の順に探索)
|
||||
- 追加フラグは `--libs "<flags>"` で渡せる(例: `--libs "-static"`)
|
||||
- 既定のハーネススクリプトは `tools/llvmlite_harness.py`(`--harness` で上書き可)。
|
||||
|
||||
Quick Start
|
||||
- 依存: `python3 -m pip install llvmlite`
|
||||
- ダミー生成(配線検証):
|
||||
- `python3 tools/llvmlite_harness.py --out /tmp/dummy.o`
|
||||
- NyRT(libnyrt.a)とリンクして EXE 化(例: `cc /tmp/dummy.o -L target/release -Wl,--whole-archive -lnyrt -Wl,--no-whole-archive -lpthread -ldl -lm -o app_dummy`)。
|
||||
|
||||
Wiring(Rust 側)
|
||||
- `NYASH_LLVM_USE_HARNESS=1` のとき:
|
||||
1) `--emit-mir-json <path>` 等で MIR(JSON) を出力
|
||||
2) `python3 tools/llvmlite_harness.py --in <mir.json> --out <obj.o>` を起動
|
||||
3) 成功後は通常のリンク手順(NyRT とリンク)
|
||||
|
||||
Tools / CLI(統合フロー)
|
||||
- crate 直結の EXE 出力: `NYASH_LLVM_COMPILER=crate NYASH_LLVM_EMIT=exe tools/build_llvm.sh apps/tests/ternary_basic.nyash -o app`
|
||||
- 環境変数 `NYASH_LLVM_NYRT` で NyRT の場所を、`NYASH_LLVM_LIBS` で追加フラグを指定できる。
|
||||
- CLI から直接 EXE 出力(新規):
|
||||
- `./target/release/nyash --emit-exe tmp/app --backend mir apps/tests/ternary_basic.nyash`
|
||||
- 追加オプション: `--emit-exe-nyrt <dir>` / `--emit-exe-libs "<flags>"`
|
||||
|
||||
Scope(Phase 15)
|
||||
- 最小命令: Const/BinOp/Compare/Branch/Jump/Return(PHI は LLVM 側で合成)
|
||||
- 文字列: NyRT Shim(`nyash.string.len_h`, `charCodeAt_h`, `concat_hh`, `eq_hh`)を declare → call
|
||||
- NewBox/ExternCall/BoxCall: まずは固定シンボル/by-id を優先(段階導入)
|
||||
- 目標: `apps/selfhost/tools/dep_tree_min_string.nyash` の `.ll verify green → .o` 安定化
|
||||
|
||||
Acceptance
|
||||
- Harness ON/OFF で機能同値(戻り値/検証)。代表ケースで `.ll verify green` と `.o` 生成成功。
|
||||
|
||||
Notes
|
||||
- 初版は固定 `ny_main` から開始してもよい(配線確認)。以降、MIR 命令を順次対応。
|
||||
- ハーネスは自律(外部状態に依存しない)。エラーは即 stderr に詳細を出す。
|
||||
|
||||
PHI Policy(要点)
|
||||
- Phase‑15 の既定は PHI‑on。MIR 側で SSA `Phi` を生成し、ハーネスは incoming の検証と最終 IR への反映だけを行う。
|
||||
- レガシー互換のために PHI‑off が必要なケースでは `NYASH_MIR_NO_PHI=1` を明示してね(ハーネスは旧 edge-copy 互換ルートで補完する)。
|
||||
- 詳細と背景は `docs/reference/mir/phi_policy.md` を参照。
|
||||
|
||||
Schema Validation(任意)
|
||||
- JSON v0 のスキーマは `docs/reference/mir/json_v0.schema.json` にあるよ。
|
||||
- 検証: `python3 tools/validate_mir_json.py <mir.json>`(要: `python3 -m pip install jsonschema`)。
|
||||
|
||||
Appendix: 静的リンクについて
|
||||
- 生成 EXE は NyRT(libnyrt.a)を静的リンク。完全静的(-static)は musl 推奨(dlopen 不可になるため動的プラグインは使用不可)。
|
||||
107
docs/reference/architecture/vm.md
Normal file
107
docs/reference/architecture/vm.md
Normal file
@ -0,0 +1,107 @@
|
||||
# Nyash VM 実行基盤ガイド(更新)
|
||||
|
||||
- プラグインBox引数の最小対応を追加(TLV: BoxRef)
|
||||
- TLVタグ: 1=Bool, 2=I32, 3=I64, 4=F32, 5=F64, 6=String, 7=Bytes, 8=Handle(BoxRef)
|
||||
- BoxRefはプラグインBox参照(type_id:u32, instance_id:u32)を8バイトでエンコード
|
||||
- ユーザー定義/複雑なBoxは当面一部非対応(toStringフォールバック)。標準Boxはプラグイン経由で統一
|
||||
|
||||
現状のルーティング(Plugin-First):
|
||||
- User-defined: MIR関数({Box}.{method}/{N}) にCall化(関数存在時)。それ以外はBoxCall。
|
||||
- Plugin: BoxCall → PluginInvoke(method_idが解決可能)→ それ以外は名前解決で PluginHost.invoke_instance_method。
|
||||
|
||||
今後のタスク:
|
||||
- VM側のfrom Parent.method対応(Builder/VM両対応)
|
||||
- TLVの型拡張(Float/配列/BoxRef戻り値など)
|
||||
|
||||
## 🧮 VM実行統計(NYASH_VM_STATS / JSON)
|
||||
|
||||
VMは命令カウントと実行時間を出力できます。
|
||||
|
||||
使い方(CLIフラグ):
|
||||
```bash
|
||||
# 人間向け表示
|
||||
nyash --backend vm --vm-stats program.nyash
|
||||
|
||||
# JSON出力
|
||||
nyash --backend vm --vm-stats --vm-stats-json program.nyash
|
||||
```
|
||||
|
||||
環境変数(直接指定):
|
||||
```bash
|
||||
NYASH_VM_STATS=1 ./target/debug/nyash --backend vm program.nyash
|
||||
NYASH_VM_STATS=1 NYASH_VM_STATS_JSON=1 ./target/debug/nyash --backend vm program.nyash
|
||||
# 代替: NYASH_VM_STATS_FORMAT=json
|
||||
```
|
||||
|
||||
出力は `total`(総命令数), `elapsed_ms`(経過時間), `counts`(命令種別→回数), `top20`(上位20種)を含みます。
|
||||
|
||||
## 既知の制約とTips(VM×プラグイン)
|
||||
- Netプラグイン(HTTP)
|
||||
- unreachable(接続不可/タイムアウト)は `Result.Err(ErrorBox)`。
|
||||
- HTTP 404/500 は `Result.Ok(Response)`(アプリ側で `response.status` を確認)。
|
||||
- デバッグ: `NYASH_NET_LOG=1 NYASH_NET_LOG_FILE=net_plugin.log`。
|
||||
- FileBox
|
||||
- `close()` は `Ok(Void)`。`match Ok(_)` で受けるか、戻り値を無視してよい。
|
||||
- Handle(BoxRef)戻り
|
||||
- TLV tag=8(type_id:u32, instance_id:u32)。Loaderが返り値typeに対応する `fini_method_id` を設定し `PluginBoxV2` を構築。
|
||||
- `scope_tracker` がスコープ終了時に `fini()` を呼ぶ(メモリ安全)。
|
||||
- 大きいボディ/多ヘッダー/タイムアウト
|
||||
- 逐次拡張中。異常時の挙動は上記Result規約に従う。実行ログと `--vm-stats` を併用して診断。
|
||||
- 反復タイムアウト: `local_tests/socket_repeated_timeouts.nyash` で `acceptTimeout/recvTimeout` の連続ケース確認
|
||||
- BoxCallデバッグ: `NYASH_VM_DEBUG_BOXCALL=1` でBoxCallの受け手型・引数型・処理経路(enter/fastpath/unified)・結果型をstderr出力
|
||||
- 例: `NYASH_VM_DEBUG_BOXCALL=1 ./target/release/nyash --backend vm local_tests/test_vm_array_getset.nyash`
|
||||
|
||||
## 🔧 BoxCallの統一経路(Phase 9.79b)
|
||||
|
||||
### method_id(スロット)によるBoxCall
|
||||
- Builderが受け手型を推論できる場合、`BoxCall`に数値`method_id`(スロット)を付与。
|
||||
- 低スロットはユニバーサル予約(0=toString, 1=type, 2=equals, 3=clone)。
|
||||
- ユーザー定義Boxは宣言時にインスタンスメソッドへスロットを4番から順に予約(決定論的)。
|
||||
|
||||
### VMの実行経路(thunk + PIC)
|
||||
- ユニバーサルスロット(0..3)はVMのfast-path thunkで即時処理。
|
||||
- toString/type/equals/cloneの4種は受け手`VMValue`から直接評価。
|
||||
- それ以外は以下の順で処理:
|
||||
1. Mono-PIC(モノモーフィックPIC)直呼び: 受け手型×method(またはmethod_id)のキーでホットサイトを判定し、
|
||||
`InstanceBox`は関数名キャッシュを使って `{Class}.{method}/{arity}` を直接呼び出す(閾値=8)。
|
||||
2. 既存経路: `InstanceBox`はMIR関数へCall、それ以外は各Boxのメソッドディスパッチへフォールバック。
|
||||
|
||||
環境変数(デバッグ):
|
||||
```bash
|
||||
NYASH_VM_DEBUG_BOXCALL=1 # BoxCallの入出力と処理経路を出力
|
||||
NYASH_VM_PIC_DEBUG=1 # PICヒットのしきい値通過時にログ
|
||||
```
|
||||
|
||||
今後の拡張:
|
||||
- 一般`method_id`(ユーザー/プラグイン)に対するvtableスロット→thunk直呼び。
|
||||
- PICのキャッシュ無効化(型version)と多相PICへの拡張(Phase 10)。
|
||||
- SocketBox(VM)
|
||||
- 基本API: `bind/listen/accept/connect/read/write/close/isServer/isConnected`
|
||||
- タイムアウト: `acceptTimeout(ms)` は接続なしで `void`、`recvTimeout(ms)` は空文字を返す
|
||||
- 簡易E2E: `local_tests/socket_timeout_server.nyash` と `socket_timeout_client.nyash`
|
||||
- Void 比較の扱い(VM)
|
||||
- `Void` は値を持たないため、`Eq/Ne` のみ有効。`Void == Void` は真、それ以外の型との `==` は偽(`!=` は真)。
|
||||
- 順序比較(`<, <=, >, >=`)は `TypeError`。
|
||||
|
||||
## E2E 実行例(HTTPのResult挙動)
|
||||
|
||||
代表ケースを `tools/run_vm_stats.sh` で実行できます。`--vm-stats-json` により命令プロファイルも取得可能です。
|
||||
|
||||
```bash
|
||||
# 別ターミナルでサーバ起動
|
||||
./target/release/nyash local_tests/http_server_statuses.nyash
|
||||
|
||||
# クライアント(別ターミナル)
|
||||
tools/run_vm_stats.sh local_tests/vm_stats_http_ok.nyash vm_stats_ok.json
|
||||
tools/run_vm_stats.sh local_tests/vm_stats_http_404.nyash vm_stats_404.json
|
||||
tools/run_vm_stats.sh local_tests/vm_stats_http_500.nyash vm_stats_500.json
|
||||
|
||||
# 到達不能(サーバ不要)
|
||||
tools/run_vm_stats.sh local_tests/vm_stats_http_err.nyash vm_stats_err.json
|
||||
```
|
||||
|
||||
期待されるResultモデル
|
||||
- unreachable(接続不可/タイムアウト): `Result.Err(ErrorBox)`
|
||||
- 404/500 等のHTTPエラー: `Result.Ok(Response)`(アプリ側で `response.status` を評価)
|
||||
|
||||
詳細: `docs/reference/architecture/mir-to-vm-mapping.md` と `docs/guides/examples/http_result_patterns.md` を参照。
|
||||
Reference in New Issue
Block a user