runner: split modes (mir/vm/llvm/bench) and extract plugin init; interpreter: split objects into ops/methods/fields; VM logs gated; Phi selection minimal fix; CURRENT_TASK updated; remove legacy backups
This commit is contained in:
29
.gitignore
vendored
29
.gitignore
vendored
@ -48,6 +48,35 @@ nyash-rust/
|
|||||||
|
|
||||||
# Test files
|
# Test files
|
||||||
*.tmp
|
*.tmp
|
||||||
|
|
||||||
|
# 🚨 ルートディレクトリ汚染防止(毎回散らかる問題対策)
|
||||||
|
# デバッグ・テスト関連ファイル
|
||||||
|
/test_*.txt
|
||||||
|
/test_*.log
|
||||||
|
/build_*.txt
|
||||||
|
/mir_*.txt
|
||||||
|
/mir_*.log
|
||||||
|
/vm_*.log
|
||||||
|
/vm_*.json
|
||||||
|
/cmp_*.log
|
||||||
|
/out.txt
|
||||||
|
/err.txt
|
||||||
|
/test.txt
|
||||||
|
/*_output.txt
|
||||||
|
/*_errors.txt
|
||||||
|
/*_error.txt
|
||||||
|
|
||||||
|
# 一時的なテストファイル(ルートに置かない!)
|
||||||
|
/test_*.nyash
|
||||||
|
|
||||||
|
# HTTP/ネットワークテストログ
|
||||||
|
/http_test*.log
|
||||||
|
/http_test*.txt
|
||||||
|
|
||||||
|
# 分析・コンサルテーション結果
|
||||||
|
/*_consultation.txt
|
||||||
|
/*_analysis.txt
|
||||||
|
/nekocode_*.txt
|
||||||
*.bak
|
*.bak
|
||||||
*.orig
|
*.orig
|
||||||
test_*.ny
|
test_*.ny
|
||||||
|
|||||||
31
CLAUDE.md
31
CLAUDE.md
@ -500,10 +500,29 @@ Related-Code: src/backend/vm_instructions.rs::execute_binop()
|
|||||||
|
|
||||||
### 🧪 テスト実行
|
### 🧪 テスト実行
|
||||||
|
|
||||||
#### 📁 **テストファイル配置ルール(重要!)**
|
#### 📁 **テストファイル配置ルール(超重要!毎回ルートが散らかる問題)**
|
||||||
- **local_testsフォルダを使用**: 一時的なテストファイルは`local_tests/`に配置
|
|
||||||
- **ルートディレクトリには置かない**: プロジェクトルートが散らからないように
|
⚠️ **ルートディレクトリの汚染防止ルール** ⚠️
|
||||||
- **実行例**: `./target/debug/nyash local_tests/test_example.nyash`
|
```bash
|
||||||
|
# ❌ 絶対ダメ:ルートで実行
|
||||||
|
./target/release/nyash test.nyash # ログがルートに散乱!
|
||||||
|
cargo test > test_output.txt # 出力ファイルがルートに!
|
||||||
|
|
||||||
|
# ✅ 正しい方法:必ずディレクトリを使う
|
||||||
|
cd local_tests && ../target/release/nyash test.nyash
|
||||||
|
./target/release/nyash local_tests/test.nyash
|
||||||
|
```
|
||||||
|
|
||||||
|
**必須ルール:**
|
||||||
|
- **テストファイル**: 必ず `local_tests/` に配置
|
||||||
|
- **ログファイル**: 環境変数で `logs/` に出力するか、実行後即削除
|
||||||
|
- **デバッグ出力**: `local_tests/` または `logs/` に保存
|
||||||
|
- **一時ファイル**: `/tmp/` を使用
|
||||||
|
|
||||||
|
**なぜ毎回ルートが散らかるのか:**
|
||||||
|
1. テスト実行時にカレントディレクトリにログ出力
|
||||||
|
2. エラー時のデバッグファイルが自動削除されない
|
||||||
|
3. VM統計やMIRダンプがデフォルトでカレントに出力
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 基本機能テスト
|
# 基本機能テスト
|
||||||
@ -514,8 +533,8 @@ mkdir -p local_tests
|
|||||||
echo 'print("Hello Nyash!")' > local_tests/test_hello.nyash
|
echo 'print("Hello Nyash!")' > local_tests/test_hello.nyash
|
||||||
./target/debug/nyash local_tests/test_hello.nyash
|
./target/debug/nyash local_tests/test_hello.nyash
|
||||||
|
|
||||||
# 演算子統合テスト
|
# 演算子統合テスト(local_testsから実行)
|
||||||
./target/debug/nyash test_comprehensive_operators.nyash
|
./target/debug/nyash local_tests/test_comprehensive_operators.nyash
|
||||||
|
|
||||||
# 実用アプリテスト
|
# 実用アプリテスト
|
||||||
./target/debug/nyash app_dice_rpg.nyash
|
./target/debug/nyash app_dice_rpg.nyash
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@
|
|||||||
ChatGPT5<EFBFBD><EFBFBD>k<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɨ<EFBFBD><EFBFBD>:
|
|
||||||
|
|
||||||
1. [E0599] no method named `call_fini` found for reference `&enabled::PluginBoxV2`
|
|
||||||
4@: src/scope_tracker.rs:45:28
|
|
||||||
<20><><EFBFBD>: plugin.call_fini() - <20><><EFBFBD><EFBFBD>LX(WjD
|
|
||||||
|
|
||||||
2. [E0308] mismatched types (2<>@)
|
|
||||||
4@: src/interpreter/core.rs:579:45, 618:45
|
|
||||||
<20><><EFBFBD>: &**v - expected `&Box<dyn NyashBox>`, found `&dyn NyashBox`
|
|
||||||
|
|
||||||
3. [E0615] attempted to take value of method `instance_id` (3<>@)
|
|
||||||
4@:
|
|
||||||
- src/interpreter/expressions/calls.rs:695:98
|
|
||||||
- src/interpreter/expressions/calls.rs:785:98
|
|
||||||
- src/backend/vm.rs:567:90
|
|
||||||
<20><><EFBFBD>: plugin.instance_id - <20><><EFBFBD>ɒգ<C992><D5A3><EFBFBD>hWf(
|
|
||||||
<20>cH: plugin.instance_id() k <09>
|
|
||||||
|
|
||||||
4. [E0609] no field `invoke_fn` on type `&enabled::PluginBoxV2`
|
|
||||||
4@: src/runtime/plugin_loader_v2.rs:139:19
|
|
||||||
<20><><EFBFBD>: self.invoke_fn - X(WjDգ<44><D5A3><EFBFBD>
|
|
||||||
<20>cH: self.inner.invoke_fn
|
|
||||||
|
|
||||||
: 7n<><6E>Ѥ<EFBFBD><D1A4><EFBFBD><EFBFBD>
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
ChatGPT5実装による更新後のビルドエラー:
|
|
||||||
|
|
||||||
改善された点(修正済み):
|
|
||||||
- ✅ call_fini() メソッドエラー解決
|
|
||||||
- ✅ instance_id フィールド/メソッドエラー解決
|
|
||||||
- ✅ invoke_fn フィールドエラー解決
|
|
||||||
|
|
||||||
残存エラー(2個):
|
|
||||||
|
|
||||||
1. [E0308] mismatched types - src/interpreter/core.rs:579:45
|
|
||||||
エラー: &**v - expected `&Box<dyn NyashBox>`, found `&dyn NyashBox`
|
|
||||||
|
|
||||||
2. [E0308] mismatched types - src/interpreter/core.rs:618:45
|
|
||||||
エラー: &**v - expected `&Box<dyn NyashBox>`, found `&dyn NyashBox`
|
|
||||||
|
|
||||||
推奨修正:
|
|
||||||
- &**v を v に変更(Arc<dyn NyashBox>への参照として扱う)
|
|
||||||
- または型注釈を &dyn NyashBox に変更
|
|
||||||
|
|
||||||
影響範囲:
|
|
||||||
- interpreter/core.rsのみ(他のモジュールのエラーは解決済み)
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
src/interpreter/core.rs:33:14: warning: unused macro definition: `debug_trace`
|
|
||||||
src/mir/loop_builder.rs:9:21: warning: unused imports: `BasicBlockIdGenerator`, `BasicBlock`, `CompareOp`, `EffectMask`, `MirFunction`, and `ValueIdGenerator`
|
|
||||||
src/mir/loop_builder.rs:13:33: warning: unused import: `HashSet`
|
|
||||||
src/backend/mod.rs:13:7: warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
src/backend/mod.rs:23:7: warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
src/backend/vm_phi.rs:9:41: warning: unused import: `MirInstruction`
|
|
||||||
src/bid/types.rs:1:5: warning: unused import: `super::Usize`
|
|
||||||
src/bid/plugin_api.rs:2:5: warning: unused import: `std::os::raw::c_char`
|
|
||||||
src/bid/plugins/filebox/mod.rs:7:18: warning: unused imports: `NyashHostVtable`, `NyashMethodInfo`, and `NyashPluginInfo`
|
|
||||||
src/bid/plugins/filebox/mod.rs:10:28: warning: unused imports: `SeekFrom` and `Seek`
|
|
||||||
src/bid/plugins/filebox/mod.rs:11:20: warning: unused imports: `c_char` and `c_void`
|
|
||||||
src/bid/plugins/filebox/mod.rs:13:16: warning: unused imports: `CStr` and `CString`
|
|
||||||
src/bid/loader.rs:4:5: warning: unused import: `std::ffi::c_void`
|
|
||||||
src/bid/generic_plugin_box.rs:5:23: warning: unused imports: `TlvDecoder` and `TlvEncoder`
|
|
||||||
src/bid/generic_plugin_box.rs:6:5: warning: unused import: `crate::bid::types::BidTag`
|
|
||||||
src/runtime/plugin_loader_v2.rs:10:47: warning: unused import: `BoxBase`
|
|
||||||
src/runtime/plugin_loader_v2.rs:14:9: warning: unused import: `std::ffi::c_void`
|
|
||||||
src/box_factory/plugin.rs:53:13: warning: unused variable: `registry`: help: if this is intentional, prefix it with an underscore: `_registry`
|
|
||||||
src/interpreter/expressions/calls.rs:739:13: warning: variable does not need to be mutable
|
|
||||||
src/interpreter/objects.rs:1106:17: warning: variable does not need to be mutable
|
|
||||||
src/instance_v2.rs:147:28: warning: unused variable: `args`: help: if this is intentional, prefix it with an underscore: `_args`
|
|
||||||
src/instance_v2.rs:289:21: warning: unused variable: `nyash_value`: help: if this is intentional, prefix it with an underscore: `_nyash_value`
|
|
||||||
src/mir/loop_builder.rs:246:39: warning: unused variable: `block_id`: help: if this is intentional, prefix it with an underscore: `_block_id`
|
|
||||||
src/mir/loop_builder.rs:273:49: warning: unused variable: `block_id`: help: if this is intentional, prefix it with an underscore: `_block_id`
|
|
||||||
src/backend/vm_phi.rs:48:9: warning: unused variable: `dst`: help: if this is intentional, prefix it with an underscore: `_dst`
|
|
||||||
src/bid/plugin_api.rs:167:36: warning: unused variable: `f`: help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
src/bid/plugin_api.rs:167:26: warning: variable does not need to be mutable
|
|
||||||
src/bid/plugin_api.rs:176:35: warning: unused variable: `f`: help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
src/bid/plugin_api.rs:176:25: warning: variable does not need to be mutable
|
|
||||||
src/bid/plugin_api.rs:183:34: warning: unused variable: `f`: help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
src/bid/plugin_api.rs:183:24: warning: variable does not need to be mutable
|
|
||||||
src/runtime/plugin_loader_v2.rs:270:46: warning: unused variable: `args`: help: if this is intentional, prefix it with an underscore: `_args`
|
|
||||||
src/bid/plugins/filebox/mod.rs:44:5: warning: type `FileMode` is more private than the item `FileBoxRegistry::open`: method `FileBoxRegistry::open` is reachable at visibility `pub`
|
|
||||||
src/mir/loop_builder.rs:35:5: warning: field `block_var_maps` is never read
|
|
||||||
src/bid/metadata.rs:148:5: warning: fields `type_name_holder` and `method_holders` are never read
|
|
||||||
src/bid/plugins/filebox/mod.rs:24:5: warning: fields `path` and `mode` are never read
|
|
||||||
src/runtime/plugin_loader_v2.rs:24:5: warning: fields `box_types` and `init_fn` are never read
|
|
||||||
src/mir/loop_builder.rs:62:9: warning: unused `Result` that must be used
|
|
||||||
src/mir/loop_builder.rs:66:9: warning: unused `Result` that must be used
|
|
||||||
src/mir/loop_builder.rs:78:9: warning: unused `Result` that must be used
|
|
||||||
src/mir/loop_builder.rs:79:9: warning: unused `Result` that must be used
|
|
||||||
src/mir/loop_builder.rs:93:9: warning: unused `Result` that must be used
|
|
||||||
src/bid/plugins/filebox/mod.rs:102:12: warning: creating a shared reference to mutable static: shared reference to mutable static
|
|
||||||
src/bid/plugins/filebox/mod.rs:105:9: warning: creating a shared reference to mutable static: shared reference to mutable static
|
|
||||||
warning: `nyash-rust` (lib) generated 44 warnings (run `cargo fix --lib -p nyash-rust` to apply 19 suggestions)
|
|
||||||
Checking nyash-rust v0.1.0 (/mnt/c/git/nyash-project/nyash)
|
|
||||||
src/backend/vm.rs:18:12: error[E0432]: unresolved import `crate::scope_tracker`: unresolved import, help: a similar path exists: `nyash_rust::scope_tracker`
|
|
||||||
src/runner.rs:22:7: warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
src/runner.rs:503:15: warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
src/runner.rs:526:19: warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
src/runner.rs:286:17: warning: variable does not need to be mutable
|
|
||||||
warning: `nyash-rust` (bin "nyash") generated 36 warnings (32 duplicates)
|
|
||||||
error: could not compile `nyash-rust` (bin "nyash") due to 1 previous error; 36 warnings emitted
|
|
||||||
@ -7,9 +7,14 @@
|
|||||||
|
|
||||||
### 直近の実行タスク(9.78h)
|
### 直近の実行タスク(9.78h)
|
||||||
1) 一時デバッグログの抑制(`NYASH_VM_DEBUG_*`のみ)
|
1) 一時デバッグログの抑制(`NYASH_VM_DEBUG_*`のみ)
|
||||||
|
- 進捗: Runnerのバナー/プラグイン初期化ログは `NYASH_CLI_VERBOSE`/`NYASH_DEBUG_PLUGIN` のみで出力。
|
||||||
|
VMの逐次ログは `NYASH_VM_DEBUG[_EXEC|_CMP|_ANDOR|_PHI]` に限定。
|
||||||
2) Phi正規化(LoopExecutorの借用衝突解消 → 正しい選択へ復帰)
|
2) Phi正規化(LoopExecutorの借用衝突解消 → 正しい選択へ復帰)
|
||||||
|
- 進捗: VM側の選択を `previous_block` 基準に復帰(fallback: 先頭)。`NYASH_VM_DEBUG_PHI=1` でログ。
|
||||||
|
- 設計: docs/development/current/PHI_NORMALIZATION_PLAN.md を参照(段階プラン/次アクション)。
|
||||||
3) 基本ボックス統一(StringBox/BoolBoxもre-export化)
|
3) 基本ボックス統一(StringBox/BoolBoxもre-export化)
|
||||||
4) VM分割の導線(control_flow/dispatch/frameへ分離設計)
|
4) VM分割の導線(control_flow/dispatch/frameへ分離設計)
|
||||||
|
- 進捗: `src/backend/{control_flow.rs,dispatch.rs,frame.rs}` を追加(骨組み)。ビルド通過。
|
||||||
5) 代表スナップショット追加(compare/loop/typeop_mixed)
|
5) 代表スナップショット追加(compare/loop/typeop_mixed)
|
||||||
|
|
||||||
### すぐ試せるコマンド
|
### すぐ試せるコマンド
|
||||||
@ -74,7 +79,15 @@ nyash --backend vm local_tests/and_or_truthy_vm.nyash # 期待: false,true,fals
|
|||||||
- 対応中: 比較前に i64 へ正規化するフォールバックをVMに実装(downcast→toString→parse)。
|
- 対応中: 比較前に i64 へ正規化するフォールバックをVMに実装(downcast→toString→parse)。
|
||||||
- 80/20ポリシー: 数値にパース可能なら比較継続、失敗時のみTypeError。
|
- 80/20ポリシー: 数値にパース可能なら比較継続、失敗時のみTypeError。
|
||||||
|
|
||||||
### 🎯 次の優先タスク
|
### 🆕 進捗(2025-08-26 午前)
|
||||||
|
- TypeError(`And/Or` 経路)再発なしを確認(3スモーク緑: compare/and_or/and_or_truthy)。
|
||||||
|
- ログ抑制の徹底: Runner/VMのデバッグ出力を既定で静音、環境変数でのみ有効化。
|
||||||
|
- Phi正規化 Step1: `previous_block` によるPhi入力選択をVMに実装(`NYASH_VM_DEBUG_PHI=1`)。
|
||||||
|
- VM分割の骨組み: `control_flow.rs`/`dispatch.rs`/`frame.rs` 追加(今後段階移動)。
|
||||||
|
- レガシー削除: `src/mir/builder_old.rs`, `src/mir/builder.rs.backup`, `src/parser.rs.backup`, `src/instance.rs.backup`, `src/box_trait.rs.backup` を削除。
|
||||||
|
- objects.rs 分解 Step1: `execute_new` をヘルパ(三分割)へ抽出しスリム化(等価挙動)。
|
||||||
|
|
||||||
|
### 🎯 次の優先タスク(更新)
|
||||||
|
|
||||||
1. **copilot_issues.txtの確認**
|
1. **copilot_issues.txtの確認**
|
||||||
- Phase 8.4: AST→MIR Lowering完全実装(最優先)
|
- Phase 8.4: AST→MIR Lowering完全実装(最優先)
|
||||||
@ -87,6 +100,16 @@ nyash --backend vm local_tests/and_or_truthy_vm.nyash # 期待: false,true,fals
|
|||||||
- 代替経路の洗い出し: `src/` 全体で `execute_binop`/`And`/`Unsupported binary operation` を再走査し、影響箇所を一掃。
|
- 代替経路の洗い出し: `src/` 全体で `execute_binop`/`And`/`Unsupported binary operation` を再走査し、影響箇所を一掃。
|
||||||
- 修正後、`local_tests/and_or_vm.nyash` で `false/true` の出力を確認。
|
- 修正後、`local_tests/and_or_vm.nyash` で `false/true` の出力を確認。
|
||||||
- ルート確定: Compare経路はBuilder側のCast導線で安定。VM側は保険フォールバックを維持しつつ一時ログを抑制へ。
|
- ルート確定: Compare経路はBuilder側のCast導線で安定。VM側は保険フォールバックを維持しつつ一時ログを抑制へ。
|
||||||
|
1.6 **objects.rs 分解 Step2(安全にファイル分割)**
|
||||||
|
- `objects_impl.rs` を導入し、抽出済みヘルパを移動。本体は薄いラッパに。
|
||||||
|
- 以降: `objects/{fields.rs,methods.rs,ops.rs}` への段階分解。
|
||||||
|
|
||||||
|
1.7 **runner.rs 分離**
|
||||||
|
- `init_bid_plugins` を `runner/plugin_init.rs` へ抽出。各モードを `runner/modes/*.rs` に。
|
||||||
|
|
||||||
|
1.8 **VM分割の段階移動**
|
||||||
|
- ブロック遷移を `control_flow.rs`、フレーム状態を `frame.rs` に移し、`dispatch.rs` の導線を準備。
|
||||||
|
|
||||||
2. **MIR26命令対応**
|
2. **MIR26命令対応**
|
||||||
- TypeOp/WeakRef/Barrierのプリンタ拡張
|
- TypeOp/WeakRef/Barrierのプリンタ拡張
|
||||||
- スナップショット整備(extern_call/loop/boxcall/typeop_mixed 追加済)
|
- スナップショット整備(extern_call/loop/boxcall/typeop_mixed 追加済)
|
||||||
|
|||||||
26
docs/development/current/PHI_NORMALIZATION_PLAN.md
Normal file
26
docs/development/current/PHI_NORMALIZATION_PLAN.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Phi 正規化プラン(9.78h スキャフォールド)
|
||||||
|
|
||||||
|
目的: ループ/分岐における Phi 選択を正道に戻し、借用衝突を避けつつ段階導入する。
|
||||||
|
|
||||||
|
段階プラン(80/20)
|
||||||
|
- Step 1: 実行系での選択復帰(完了)
|
||||||
|
- `previous_block` に基づき `inputs[(bb==prev)]` を選択。見つからない場合は先頭をフォールバック。
|
||||||
|
- デバッグ: `NYASH_VM_DEBUG_PHI=1` で選択ログ。
|
||||||
|
- Step 2: LoopExecutor 連携
|
||||||
|
- `VM::loop_execute_phi` を `LoopExecutor::execute_phi` に委譲(安全な借用構成に整理)。
|
||||||
|
- `record_transition(from,to)` をもとにヘッダ検出・イテレーション情報を活用。
|
||||||
|
- Step 3: 正規 SSA への復帰
|
||||||
|
- Builder 側で phi 挿入・seal・predecessor 更新を正道で実装。
|
||||||
|
- Verifier に phi 一貫性(定義支配/マージ使用)チェックを追加・厳格化。
|
||||||
|
- Step 4: ログ削減とテスト
|
||||||
|
- 代表ケース(loop/if-merge/while)をスナップショット化。
|
||||||
|
- 既定で静音、`NYASH_VM_DEBUG_PHI` のみで詳細。
|
||||||
|
|
||||||
|
実装状況(2025-08-26)
|
||||||
|
- Step 1 完了: `VM::loop_execute_phi` が `previous_block` による選択に対応。
|
||||||
|
- 既知の課題: LoopExecutor 経由の借用安全な委譲(Step 2)。
|
||||||
|
|
||||||
|
次アクション
|
||||||
|
- VM 内部の phi 実行を LoopExecutor へ委譲できるよう API を見直し(`get_value` クロージャの借用境界を調整)。
|
||||||
|
- Builder 側の phi 正規化 TODO を CURRENT_TASK に追記。
|
||||||
|
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
# VM比較処理のリファクタリング
|
||||||
|
Status: Pending (80%実装済み)
|
||||||
|
Created: 2025-08-25
|
||||||
|
Priority: Medium
|
||||||
|
Related-Code: src/backend/vm_instructions.rs::execute_compare(), src/backend/vm_values.rs::execute_compare_op()
|
||||||
|
|
||||||
|
## 現状(80%実装)
|
||||||
|
- BoxRef比較のTypeErrorは解決済み
|
||||||
|
- 正規化処理が2箇所に分散(execute_compare, execute_compare_op)
|
||||||
|
- デバッグログが複数の環境変数に依存
|
||||||
|
- 基本動作は完全に正常
|
||||||
|
|
||||||
|
## 問題点
|
||||||
|
1. **重複した正規化ロジック**
|
||||||
|
- vm_instructions.rs: BoxRef → Integer変換
|
||||||
|
- vm_values.rs: 同様の変換処理
|
||||||
|
|
||||||
|
2. **デバッグの複雑さ**
|
||||||
|
- NYASH_VM_DEBUG
|
||||||
|
- NYASH_VM_DEBUG_CMP
|
||||||
|
- 複数箇所でのログ出力
|
||||||
|
|
||||||
|
3. **エラーパスの複雑さ**
|
||||||
|
- "[BoxRef-BoxRef]", "[BoxRef-Integer]", "[Integer-BoxRef]", "[Default]"
|
||||||
|
- どこでエラーが出るか予測困難
|
||||||
|
|
||||||
|
## 改善案(残り20%)
|
||||||
|
|
||||||
|
### 1. 正規化を単一関数に統一
|
||||||
|
```rust
|
||||||
|
fn canonicalize_for_comparison(value: VMValue) -> VMValue {
|
||||||
|
match value {
|
||||||
|
VMValue::BoxRef(b) => {
|
||||||
|
// IntegerBox → Integer
|
||||||
|
if let Some(ib) = b.as_any().downcast_ref::<IntegerBox>() {
|
||||||
|
return VMValue::Integer(ib.value);
|
||||||
|
}
|
||||||
|
// String parse fallback
|
||||||
|
if let Ok(n) = b.to_string_box().value.trim().parse::<i64>() {
|
||||||
|
return VMValue::Integer(n);
|
||||||
|
}
|
||||||
|
VMValue::BoxRef(b)
|
||||||
|
}
|
||||||
|
other => other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 比較処理の階層化
|
||||||
|
```rust
|
||||||
|
impl VM {
|
||||||
|
// エントリーポイント
|
||||||
|
pub fn execute_compare(...) {
|
||||||
|
let left = self.canonicalize_value(lhs)?;
|
||||||
|
let right = self.canonicalize_value(rhs)?;
|
||||||
|
let result = self.compare_canonical(op, &left, &right)?;
|
||||||
|
self.set_value(dst, VMValue::Bool(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正規化
|
||||||
|
fn canonicalize_value(&self, id: ValueId) -> Result<VMValue, VMError> {
|
||||||
|
let raw = self.get_value(id)?;
|
||||||
|
Ok(canonicalize_for_comparison(raw))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 比較実行
|
||||||
|
fn compare_canonical(&self, op: &CompareOp, left: &VMValue, right: &VMValue) -> Result<bool, VMError> {
|
||||||
|
// シンプルな比較ロジックのみ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. デバッグトレースの統一
|
||||||
|
```rust
|
||||||
|
struct ComparisonTrace {
|
||||||
|
original_left: VMValue,
|
||||||
|
original_right: VMValue,
|
||||||
|
canonical_left: VMValue,
|
||||||
|
canonical_right: VMValue,
|
||||||
|
result: Result<bool, VMError>,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 実装タイミング
|
||||||
|
- [ ] 次の大きなバグが出たとき
|
||||||
|
- [ ] Phase 10の最適化フェーズ
|
||||||
|
- [ ] 新しい比較演算子追加時
|
||||||
|
|
||||||
|
## メリット
|
||||||
|
- デバッグが容易になる
|
||||||
|
- 新しい型の比較追加が簡単
|
||||||
|
- テストが書きやすくなる
|
||||||
@ -1,19 +0,0 @@
|
|||||||
FileBox Plugin E2E Test Results:
|
|
||||||
|
|
||||||
Build Status:
|
|
||||||
- Main build: ✅ Success
|
|
||||||
- Plugin build: ✅ Success (with 3 warnings)
|
|
||||||
|
|
||||||
Test Results:
|
|
||||||
- e2e_interpreter_plugin_filebox_close_void: ✅ PASSED
|
|
||||||
- e2e_vm_plugin_filebox_close_void: ✅ PASSED
|
|
||||||
- e2e_interpreter_plugin_filebox_delegation: ❌ FAILED
|
|
||||||
|
|
||||||
Failure Details:
|
|
||||||
❌ Interpreter error: Invalid operation: birth() method not yet implemented for builtin box 'FileBox'
|
|
||||||
|
|
||||||
The error occurs when trying to create a LoggingFileBox that delegates from FileBox.
|
|
||||||
The test expects to use birth() constructor but FileBox (as a plugin) doesn't implement it yet.
|
|
||||||
|
|
||||||
This suggests the plugin system is working correctly (FileBox is recognized), but the
|
|
||||||
birth() constructor delegation for plugin boxes needs implementation.
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
NEW ERROR AFTER FIX:
|
|
||||||
|
|
||||||
running 2 tests
|
|
||||||
test e2e_create_echo_box_and_return_string ... FAILED
|
|
||||||
test e2e_create_adder_box_and_return_sum ... FAILED
|
|
||||||
|
|
||||||
failures:
|
|
||||||
|
|
||||||
---- e2e_create_echo_box_and_return_string stdout ----
|
|
||||||
❌ Interpreter error: Return outside of function
|
|
||||||
|
|
||||||
thread 'e2e_create_echo_box_and_return_string' panicked at tests/e2e_plugin_echo.rs:102:33:
|
|
||||||
exec ok: ReturnOutsideFunction
|
|
||||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
|
||||||
|
|
||||||
---- e2e_create_adder_box_and_return_sum stdout ----
|
|
||||||
❌ Interpreter error: Return outside of function
|
|
||||||
|
|
||||||
thread 'e2e_create_adder_box_and_return_sum' panicked at tests/e2e_plugin_echo.rs:114:33:
|
|
||||||
exec ok: ReturnOutsideFunction
|
|
||||||
|
|
||||||
|
|
||||||
failures:
|
|
||||||
e2e_create_adder_box_and_return_sum
|
|
||||||
e2e_create_echo_box_and_return_string
|
|
||||||
|
|
||||||
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
|
|
||||||
|
|
||||||
PROGRESS: The Box types (EchoBox, AdderBox) are now recognized!
|
|
||||||
The error changed from "Unknown Box type" to "Return outside of function".
|
|
||||||
This suggests the unified registry is working correctly after ChatGPT5's fix.
|
|
||||||
16
err.txt
16
err.txt
@ -1,16 +0,0 @@
|
|||||||
🔍 DEBUG: Initializing v2 plugin system
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_counter_plugin.so
|
|
||||||
Net plugin: LOG_ON=false, LOG_PATH=net_plugin.log
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_net_plugin.so
|
|
||||||
[FileBox] Plugin initialized
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_filebox_plugin.so
|
|
||||||
📦 Registering plugin provider for CounterBox
|
|
||||||
📦 Registering plugin provider for HttpServerBox
|
|
||||||
📦 Registering plugin provider for HttpClientBox
|
|
||||||
📦 Registering plugin provider for HttpResponseBox
|
|
||||||
📦 Registering plugin provider for HttpRequestBox
|
|
||||||
📦 Registering plugin provider for SocketServerBox
|
|
||||||
📦 Registering plugin provider for SocketClientBox
|
|
||||||
📦 Registering plugin provider for SocketConnBox
|
|
||||||
📦 Registering plugin provider for FileBox
|
|
||||||
❌ VM execution error: Type error: Unsupported comparison: Lt on BoxRef(IntegerBox { value: 0, base: BoxBase { id: 3, parent_type_id: None } }) and BoxRef(IntegerBox { value: 3, base: BoxBase { id: 7, parent_type_id: None } })
|
|
||||||
@ -1 +0,0 @@
|
|||||||
hello nyash
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,118 +0,0 @@
|
|||||||
Gemini先生の部分的な回答(レート制限で途中まで)
|
|
||||||
|
|
||||||
Nyashの統一Box設計について、専門的な観点から分析と提案をさせていただきます。
|
|
||||||
|
|
||||||
## 設計の評価
|
|
||||||
|
|
||||||
### 美しい点
|
|
||||||
|
|
||||||
1. **「Everything is Box」の一貫性**: この哲学は Smalltalk の「Everything is an Object」に通じる美しさがあります。概念的な統一感は言語の学習曲線を緩やかにし、予測可能性を高めます。
|
|
||||||
|
|
||||||
2. **透過的な置き換え機構**: プラグインによるビルトインBoxの置き換えは、Rubyの `refinements` や Python の `__import__` フックを彷彿とさせます。テスタビリティと拡張性の観点から優れています。
|
|
||||||
|
|
||||||
3. **優先順位システム**: 明確な優先順位(ビルトイン > ユーザー定義 > プラグイン)は、名前解決の曖昧さを排除し、デバッグを容易にします。
|
|
||||||
|
|
||||||
### 改善の余地がある点
|
|
||||||
|
|
||||||
1. **パフォーマンスのオーバーヘッド**: すべてを `Box<dyn NyashBox>` でラップすることは、小さな値(整数、真偽値など)にとって大きなオーバーヘッドです。Rust の `enum` を活用した値の内部表現最適化を検討すべきです。
|
|
||||||
|
|
||||||
2. **型の曖昧さ**: `Option<Box<dyn NyashBox>>` のような入れ子構造は、実行時の型チェックを複雑にします。静的型付けの利点を活かしきれていません。
|
|
||||||
|
|
||||||
## 改善提案
|
|
||||||
|
|
||||||
### 1. Enum ベースの値表現
|
|
||||||
|
|
||||||
現在の `Box<dyn NyashBox>` 一辺倒から、以下のような enum ベースの表現への移行を提案します:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub enum NyashValue {
|
|
||||||
// 即値(スタック上)
|
|
||||||
Void,
|
|
||||||
Bool(bool),
|
|
||||||
Integer(i64),
|
|
||||||
Float(f64),
|
|
||||||
|
|
||||||
// ヒープ上の不変値
|
|
||||||
String(Arc<String>),
|
|
||||||
|
|
||||||
// 複雑なオブジェクト
|
|
||||||
Object(Arc<NyashObject>),
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**メリット**:
|
|
||||||
- 小さな値のヒープアロケーションを回避
|
|
||||||
- パターンマッチによる高速なディスパッチ
|
|
||||||
- 型安全性の向上
|
|
||||||
|
|
||||||
### 2. トレイトの階層化
|
|
||||||
|
|
||||||
基本メソッドの統一案は良いですが、さらに階層化することで柔軟性を高められます:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// 基本トレイト(すべてのBoxが実装)
|
|
||||||
pub trait NyashBox: Send + Sync + Debug {
|
|
||||||
fn to_string(&self) -> String;
|
|
||||||
fn type_name(&self) -> &'static str;
|
|
||||||
fn equals(&self, other: &dyn NyashBox) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拡張トレイト(必要に応じて実装)
|
|
||||||
pub trait Comparable: NyashBox {
|
|
||||||
fn compare(&self, other: &dyn NyashBox) -> Option<Ordering>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Arithmetic: NyashBox {
|
|
||||||
fn add(&self, other: &dyn NyashBox) -> Result<Box<dyn NyashBox>, String>;
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. メタプログラミング機能
|
|
||||||
|
|
||||||
ユーザー定義Boxの完全統一のために、メタプログラミング機能を提供:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Box定義時のフック
|
|
||||||
pub trait BoxMetadata {
|
|
||||||
fn on_method_missing(&self, name: &str, args: &[NyashValue]) -> Option<NyashValue>;
|
|
||||||
fn on_field_access(&self, name: &str) -> Option<NyashValue>;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. パイプライン演算子の実装
|
|
||||||
|
|
||||||
パイプライン演算子は、メソッドチェーンの代替として優れています:
|
|
||||||
|
|
||||||
```nyash
|
|
||||||
// 現在
|
|
||||||
result = str.substring(0, 5).toUpperCase().trim()
|
|
||||||
|
|
||||||
// パイプライン版
|
|
||||||
result = str
|
|
||||||
|> substring(0, 5)
|
|
||||||
|> toUpperCase()
|
|
||||||
|> trim()
|
|
||||||
```
|
|
||||||
|
|
||||||
実装は、単純な構文糖として扱えます。
|
|
||||||
|
|
||||||
## 他言語との比較
|
|
||||||
|
|
||||||
**Smalltalk**: 最も近い哲学を持ちますが、Nyashの方が実用的(ファイルI/O、ネットワーク等を最初から考慮)
|
|
||||||
|
|
||||||
**Ruby**: オープンクラスの柔軟性はありませんが、その分予測可能性が高い
|
|
||||||
|
|
||||||
**Python**: `__getattr__` のような動的フックより、明示的なメソッド定義の方が保守しやすい
|
|
||||||
|
|
||||||
## 総合的な推奨事項
|
|
||||||
|
|
||||||
1. **段階的な移行**: 現在の設計を一度に変更するのではなく、まず `NyashValue` enum を導入し、徐々に最適化
|
|
||||||
|
|
||||||
2. **プロファイリング駆動**: パフォーマンスの問題が実際に発生している箇所から最適化
|
|
||||||
|
|
||||||
3. **ドキュメント駆動開発**: 各Boxの振る舞いを明確に文書化し、それに基づいて実装
|
|
||||||
|
|
||||||
4. **テストの充実**: 特に異なる種類のBox間の相互作用をテスト
|
|
||||||
|
|
||||||
この設計は十分に美しく、実用的です。過度に複雑というより、むしろ適切な抽象化レベルだと評価します。
|
|
||||||
@ -1,2 +1,5 @@
|
|||||||
// Simple return test
|
static box Main {
|
||||||
|
main() {
|
||||||
return 42
|
return 42
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,19 @@
|
|||||||
# Simple test without external calls
|
// 簡単なNyashテストプログラム
|
||||||
static box Main {
|
print("🎉 Nyash is working!")
|
||||||
init { result }
|
print("Everything is Box!")
|
||||||
|
|
||||||
main() {
|
// 基本的な演算
|
||||||
me.result = "Simple test"
|
local a = 10
|
||||||
return me.result
|
local b = 20
|
||||||
}
|
local result = a + b
|
||||||
}
|
print("10 + 20 = " + result.toString())
|
||||||
|
|
||||||
|
// StringBox
|
||||||
|
local greeting = "Hello, Nyash!"
|
||||||
|
print(greeting)
|
||||||
|
|
||||||
|
// ArrayBox
|
||||||
|
local arr = new ArrayBox()
|
||||||
|
arr.push("First")
|
||||||
|
arr.push("Second")
|
||||||
|
print("Array length: " + arr.length().toString())
|
||||||
@ -1,42 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash MIR Compiler - Processing file: local_tests/test_http_error_simple.nyash 🚀
|
|
||||||
🚀 MIR Output for local_tests/test_http_error_simple.nyash:
|
|
||||||
; MIR Module: main
|
|
||||||
|
|
||||||
define void @main() {
|
|
||||||
bb0:
|
|
||||||
0: safepoint
|
|
||||||
1: %0 = const void
|
|
||||||
2: %1 = const void
|
|
||||||
3: %2 = const void
|
|
||||||
4: %3 = const void
|
|
||||||
5: %4 = new HttpClientBox()
|
|
||||||
6: call %4.birth()
|
|
||||||
7: %5 = const "http://127.0.0.1:8099/nope"
|
|
||||||
8: %6 = new StringBox(%5)
|
|
||||||
9: call %6.birth(%5)
|
|
||||||
10: %7 = const "http://127.0.0.1:8099/nope"
|
|
||||||
11: %8 = new StringBox(%7)
|
|
||||||
12: call %8.birth(%7)
|
|
||||||
13: %9 = call %4.get(%8)
|
|
||||||
14: %10 = call %9.isOk()
|
|
||||||
15: br %10, label bb1, label bb2
|
|
||||||
|
|
||||||
bb1:
|
|
||||||
0: %11 = const "unexpected_ok"
|
|
||||||
1: %12 = new StringBox(%11)
|
|
||||||
2: call %12.birth(%11)
|
|
||||||
3: br label bb3
|
|
||||||
|
|
||||||
bb2:
|
|
||||||
0: %13 = call %9.getError()
|
|
||||||
1: %14 = call %13.toString()
|
|
||||||
2: br label bb3
|
|
||||||
|
|
||||||
bb3:
|
|
||||||
0: %15 = phi [%12, bb1], [%14, bb2]
|
|
||||||
1: ret %15
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash MIR Compiler - Processing file: local_tests/test_http_error_simple.nyash 🚀
|
|
||||||
🚀 MIR Output for local_tests/test_http_error_simple.nyash:
|
|
||||||
; MIR Module: main
|
|
||||||
|
|
||||||
define void @main() {
|
|
||||||
bb0:
|
|
||||||
0: safepoint
|
|
||||||
1: %0 = const void
|
|
||||||
2: %1 = const void
|
|
||||||
3: %2 = const void
|
|
||||||
4: %3 = const void
|
|
||||||
5: %4 = new HttpClientBox()
|
|
||||||
6: call %4.birth()
|
|
||||||
7: %5 = const "http://127.0.0.1:8099/nope"
|
|
||||||
8: %6 = new StringBox(%5)
|
|
||||||
9: call %6.birth(%5)
|
|
||||||
10: %7 = const "http://127.0.0.1:8099/nope"
|
|
||||||
11: %8 = new StringBox(%7)
|
|
||||||
12: call %8.birth(%7)
|
|
||||||
13: %9 = call %4.get(%8)
|
|
||||||
14: %10 = call %9.isOk()
|
|
||||||
15: br %10, label bb1, label bb2
|
|
||||||
|
|
||||||
bb1:
|
|
||||||
0: %11 = const "unexpected_ok"
|
|
||||||
1: %12 = new StringBox(%11)
|
|
||||||
2: call %12.birth(%11)
|
|
||||||
3: br label bb3
|
|
||||||
|
|
||||||
bb2:
|
|
||||||
0: %13 = call %9.getError()
|
|
||||||
1: %14 = call %13.toString()
|
|
||||||
2: br label bb3
|
|
||||||
|
|
||||||
bb3:
|
|
||||||
0: %15 = phi [%12, bb1], [%14, bb2]
|
|
||||||
1: ret %14
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash MIR Compiler - Processing file: local_tests/test_http_error_simple.nyash 🚀
|
|
||||||
🚀 MIR Output for local_tests/test_http_error_simple.nyash:
|
|
||||||
; MIR Module: main
|
|
||||||
|
|
||||||
define void @main() {
|
|
||||||
bb0:
|
|
||||||
0: safepoint
|
|
||||||
1: %0 = const void
|
|
||||||
2: %1 = const void
|
|
||||||
3: %2 = const void
|
|
||||||
4: %3 = const void
|
|
||||||
5: %4 = new HttpClientBox()
|
|
||||||
6: call %4.birth()
|
|
||||||
7: %5 = const "http://127.0.0.1:8099/nope"
|
|
||||||
8: %6 = new StringBox(%5)
|
|
||||||
9: call %6.birth(%5)
|
|
||||||
10: %7 = const "http://127.0.0.1:8099/nope"
|
|
||||||
11: %8 = new StringBox(%7)
|
|
||||||
12: call %8.birth(%7)
|
|
||||||
13: %9 = call %4.get(%8)
|
|
||||||
14: %10 = call %9.isOk()
|
|
||||||
15: br %10, label bb1, label bb2
|
|
||||||
|
|
||||||
bb1:
|
|
||||||
0: %11 = const "unexpected_ok"
|
|
||||||
1: %12 = new StringBox(%11)
|
|
||||||
2: call %12.birth(%11)
|
|
||||||
3: br label bb3
|
|
||||||
|
|
||||||
bb2:
|
|
||||||
0: %13 = call %9.getError()
|
|
||||||
1: %14 = call %13.toString()
|
|
||||||
2: br label bb3
|
|
||||||
|
|
||||||
bb3:
|
|
||||||
0: %15 = phi [%12, bb1], [%14, bb2]
|
|
||||||
1: ret %14
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,96 +0,0 @@
|
|||||||
Nyashプログラミング言語の統一Box設計について相談
|
|
||||||
|
|
||||||
【背景】
|
|
||||||
Nyashは「Everything is Box」哲学を持つプログラミング言語です。現在、以下の3種類のBoxが存在します:
|
|
||||||
|
|
||||||
1. ビルトインBox(StringBox, IntegerBox等)- Rustで実装
|
|
||||||
2. プラグインBox(FileBox等)- 動的ライブラリで提供
|
|
||||||
3. ユーザー定義Box(box Person等)- Nyashコードで定義
|
|
||||||
|
|
||||||
【現在の統一アーキテクチャ】
|
|
||||||
```
|
|
||||||
UnifiedBoxRegistry(統一レジストリ)
|
|
||||||
├── BuiltinBoxFactory(優先度1)
|
|
||||||
├── UserDefinedBoxFactory(優先度2)
|
|
||||||
└── PluginBoxFactory(優先度3)
|
|
||||||
```
|
|
||||||
|
|
||||||
BoxFactoryトレイト:
|
|
||||||
```rust
|
|
||||||
pub trait BoxFactory: Send + Sync {
|
|
||||||
fn create_box(&self, name: &str, args: &[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, RuntimeError>;
|
|
||||||
fn box_types(&self) -> Vec<&str>;
|
|
||||||
fn supports_birth(&self) -> bool;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
【統一の美しさ】
|
|
||||||
1. 透過的な置き換え - 同じ名前のBoxをプラグインで上書き可能
|
|
||||||
2. 統一インターフェース - すべてのBoxが同じAPIを持つ
|
|
||||||
3. 優先順位システム - ビルトイン > ユーザー定義 > プラグイン
|
|
||||||
|
|
||||||
【InstanceBoxによる統一実装】
|
|
||||||
```rust
|
|
||||||
pub struct InstanceBox {
|
|
||||||
pub class_name: String, // "StringBox", "Person"等
|
|
||||||
pub inner_content: Option<Box<dyn NyashBox>>, // 内包Box(統一!)
|
|
||||||
pub fields_ng: Arc<Mutex<HashMap<String, NyashValue>>>,
|
|
||||||
pub methods: Arc<HashMap<String, ASTNode>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3つの形態を統一
|
|
||||||
InstanceBox::from_any_box("StringBox", Box::new(StringBox::new("hello"))) // ビルトイン
|
|
||||||
InstanceBox::from_any_box("FileBox", plugin_box) // プラグイン
|
|
||||||
InstanceBox::from_declaration("Person", fields, methods) // ユーザー定義
|
|
||||||
```
|
|
||||||
|
|
||||||
【検討事項】
|
|
||||||
|
|
||||||
1. **基本メソッドの統一**
|
|
||||||
現在、各Boxで個別実装されている基本メソッド(toString, type, equals等)をNyashBoxトレイトのデフォルト実装として統一したい。
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub trait NyashBox: BoxCore + Debug {
|
|
||||||
// Nyash標準メソッド(デフォルト実装)
|
|
||||||
fn toString(&self) -> Box<dyn NyashBox> {
|
|
||||||
Box::new(StringBox::new(&self.to_string_box().value))
|
|
||||||
}
|
|
||||||
fn type(&self) -> Box<dyn NyashBox> {
|
|
||||||
Box::new(StringBox::new(self.type_name()))
|
|
||||||
}
|
|
||||||
fn equals(&self, other: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
|
||||||
Box::new(BoolBox::new(self.equals_internal(other.as_ref())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **ユーザー定義Boxの完全統一**
|
|
||||||
ユーザー定義Boxも、ビルトイン/プラグインBoxと同じように扱えるようにしたい。継承も統一的に:
|
|
||||||
|
|
||||||
```nyash
|
|
||||||
box MyString from StringBox { } // ビルトイン継承
|
|
||||||
box MyFile from FileBox { } // プラグイン継承
|
|
||||||
box Employee from Person { } // ユーザー定義継承
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **動的な切り替え**
|
|
||||||
実行時にビルトインBoxをプラグインBoxで置き換える機能は既に実装済み。これをさらに洗練させたい。
|
|
||||||
|
|
||||||
【質問】
|
|
||||||
|
|
||||||
1. この統一設計は美しいと思いますか?それとも過度に複雑でしょうか?
|
|
||||||
|
|
||||||
2. 基本メソッド(toString, type, equals, clone)をトレイトのデフォルト実装にすることで、すべてのBoxで統一的に使えるようにする案についてどう思いますか?
|
|
||||||
|
|
||||||
3. ユーザー定義Boxを、ビルトイン/プラグインBoxと完全に同じレベルで扱うことは、設計として自然でしょうか?それとも強引でしょうか?
|
|
||||||
|
|
||||||
4. さらに設計を美しくするためのアイデアはありますか?例えば:
|
|
||||||
- パイプライン演算子(|>)の導入
|
|
||||||
- エフェクトシステムの整理
|
|
||||||
- Box階層の整理(ValueBox, ContainerBox, IOBox等)
|
|
||||||
|
|
||||||
5. 他のプログラミング言語(Ruby, Python, Smalltalk等)の統一オブジェクトシステムと比較して、この設計の良い点・改善点は何でしょうか?
|
|
||||||
|
|
||||||
6. パフォーマンスと美しさのトレードオフについて、どのようなバランスが良いと思いますか?
|
|
||||||
|
|
||||||
プログラミング言語設計の専門的観点から、実装の現実性も考慮しつつ、より美しい設計への道筋をアドバイスしてください。
|
|
||||||
3
out.txt
3
out.txt
@ -1,3 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/simple_loop_test.nyash 🚀
|
|
||||||
33
src/backend/control_flow.rs
Normal file
33
src/backend/control_flow.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*!
|
||||||
|
* VM Control-Flow helpers (scaffolding)
|
||||||
|
*
|
||||||
|
* Purpose: Encapsulate block transitions, branching decisions, and phi entry bookkeeping.
|
||||||
|
* Status: Initial skeleton for future extraction from vm.rs
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::mir::BasicBlockId;
|
||||||
|
use super::vm::{VMError};
|
||||||
|
|
||||||
|
/// Result of a block step when evaluating a terminator
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Step {
|
||||||
|
/// Continue in the same block (advance pc)
|
||||||
|
Continue,
|
||||||
|
/// Jump to target block
|
||||||
|
Jump(BasicBlockId),
|
||||||
|
/// Function returned (handled by VM)
|
||||||
|
Return,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Record a block transition inside VM bookkeeping
|
||||||
|
pub fn record_transition(
|
||||||
|
previous_block: &mut Option<BasicBlockId>,
|
||||||
|
loop_recorder: &mut crate::backend::vm_phi::LoopExecutor,
|
||||||
|
from: BasicBlockId,
|
||||||
|
to: BasicBlockId,
|
||||||
|
) -> Result<(), VMError> {
|
||||||
|
*previous_block = Some(from);
|
||||||
|
loop_recorder.record_transition(from, to);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
26
src/backend/dispatch.rs
Normal file
26
src/backend/dispatch.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*!
|
||||||
|
* VM Dispatch table (scaffolding)
|
||||||
|
*
|
||||||
|
* Purpose: Centralize mapping from MIR instruction kinds to handler fns.
|
||||||
|
* Status: Initial skeleton; currently unused. Future: build static table for hot-path dispatch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::mir::MirInstruction;
|
||||||
|
use super::vm::{VMError};
|
||||||
|
|
||||||
|
/// Placeholder for an instruction dispatch entry
|
||||||
|
pub struct DispatchEntry;
|
||||||
|
|
||||||
|
/// Placeholder dispatch table
|
||||||
|
pub struct DispatchTable;
|
||||||
|
|
||||||
|
impl DispatchTable {
|
||||||
|
pub fn new() -> Self { Self }
|
||||||
|
|
||||||
|
/// Example API for future use: resolve a handler for an instruction
|
||||||
|
pub fn resolve(&self, _instr: &MirInstruction) -> Option<DispatchEntry> { None }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example execution of a dispatch entry
|
||||||
|
pub fn execute_entry(_entry: &DispatchEntry) -> Result<(), VMError> { Ok(()) }
|
||||||
|
|
||||||
21
src/backend/frame.rs
Normal file
21
src/backend/frame.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*!
|
||||||
|
* VM Frame management (scaffolding)
|
||||||
|
*
|
||||||
|
* Purpose: Provide a dedicated struct for per-function execution state (pc, block, locals).
|
||||||
|
* Status: Initial skeleton; VM still stores fields directly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::mir::{BasicBlockId, ValueId};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct ExecutionFrame {
|
||||||
|
pub current_block: Option<BasicBlockId>,
|
||||||
|
pub pc: usize,
|
||||||
|
pub last_result: Option<ValueId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExecutionFrame {
|
||||||
|
pub fn new() -> Self { Self { current_block: None, pc: 0, last_result: None } }
|
||||||
|
pub fn reset(&mut self) { self.current_block = None; self.pc = 0; self.last_result = None; }
|
||||||
|
}
|
||||||
|
|
||||||
@ -8,6 +8,10 @@ pub mod vm_instructions;
|
|||||||
pub mod vm_values;
|
pub mod vm_values;
|
||||||
pub mod vm_boxcall;
|
pub mod vm_boxcall;
|
||||||
pub mod vm_stats;
|
pub mod vm_stats;
|
||||||
|
// Phase 9.78h: VM split scaffolding (control_flow/dispatch/frame)
|
||||||
|
pub mod control_flow;
|
||||||
|
pub mod dispatch;
|
||||||
|
pub mod frame;
|
||||||
|
|
||||||
#[cfg(feature = "wasm-backend")]
|
#[cfg(feature = "wasm-backend")]
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
|||||||
@ -225,14 +225,25 @@ pub struct VM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VM {
|
impl VM {
|
||||||
/// Helper: execute phi via loop executor (exposes private field safely)
|
/// Helper: execute phi selection based on previous_block (borrow-safe minimal)
|
||||||
pub(super) fn loop_execute_phi(&mut self, _dst: ValueId, inputs: &[(BasicBlockId, ValueId)]) -> Result<VMValue, VMError> {
|
pub(super) fn loop_execute_phi(&mut self, _dst: ValueId, inputs: &[(BasicBlockId, ValueId)]) -> Result<VMValue, VMError> {
|
||||||
// 80/20 minimal: select first input when we can't safely borrow executor + self simultaneously
|
if inputs.is_empty() {
|
||||||
if let Some((_, val_id)) = inputs.first() {
|
return Err(VMError::InvalidInstruction("Phi node has no inputs".to_string()));
|
||||||
self.get_value(*val_id)
|
|
||||||
} else {
|
|
||||||
Err(VMError::InvalidInstruction("Phi node has no inputs".to_string()))
|
|
||||||
}
|
}
|
||||||
|
let debug_phi = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1")
|
||||||
|
|| std::env::var("NYASH_VM_DEBUG_PHI").ok().as_deref() == Some("1");
|
||||||
|
let prev = self.previous_block;
|
||||||
|
if debug_phi { eprintln!("[VM] phi-select prev={:?} inputs={:?}", prev, inputs); }
|
||||||
|
if let Some(prev_bb) = prev {
|
||||||
|
if let Some((_, val_id)) = inputs.iter().find(|(bb, _)| *bb == prev_bb) {
|
||||||
|
if debug_phi { eprintln!("[VM] phi-select hit prev={:?} -> {:?}", prev_bb, val_id); }
|
||||||
|
return self.get_value(*val_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback: first input
|
||||||
|
let (_, val_id) = inputs[0];
|
||||||
|
if debug_phi { eprintln!("[VM] phi-select fallback first -> {:?}", val_id); }
|
||||||
|
self.get_value(val_id)
|
||||||
}
|
}
|
||||||
/// Create a new VM instance
|
/// Create a new VM instance
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -438,7 +449,9 @@ impl VM {
|
|||||||
/// Execute a single instruction
|
/// Execute a single instruction
|
||||||
fn execute_instruction(&mut self, instruction: &MirInstruction) -> Result<ControlFlow, VMError> {
|
fn execute_instruction(&mut self, instruction: &MirInstruction) -> Result<ControlFlow, VMError> {
|
||||||
// Record instruction for stats
|
// Record instruction for stats
|
||||||
eprintln!("[VM] execute_instruction: {:?}", instruction);
|
let debug_global = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1");
|
||||||
|
let debug_exec = debug_global || std::env::var("NYASH_VM_DEBUG_EXEC").ok().as_deref() == Some("1");
|
||||||
|
if debug_exec { eprintln!("[VM] execute_instruction: {:?}", instruction); }
|
||||||
self.record_instruction(instruction);
|
self.record_instruction(instruction);
|
||||||
|
|
||||||
match instruction {
|
match instruction {
|
||||||
@ -447,7 +460,7 @@ impl VM {
|
|||||||
self.execute_const(*dst, value),
|
self.execute_const(*dst, value),
|
||||||
|
|
||||||
MirInstruction::BinOp { dst, op, lhs, rhs } => {
|
MirInstruction::BinOp { dst, op, lhs, rhs } => {
|
||||||
if std::env::var("NYASH_VM_DEBUG_ANDOR").ok().as_deref() == Some("1") {
|
if debug_global || std::env::var("NYASH_VM_DEBUG_ANDOR").ok().as_deref() == Some("1") {
|
||||||
eprintln!("[VM] execute_instruction -> BinOp({:?})", op);
|
eprintln!("[VM] execute_instruction -> BinOp({:?})", op);
|
||||||
}
|
}
|
||||||
self.execute_binop(*dst, op, *lhs, *rhs)
|
self.execute_binop(*dst, op, *lhs, *rhs)
|
||||||
@ -457,12 +470,13 @@ impl VM {
|
|||||||
self.execute_unaryop(*dst, op, *operand),
|
self.execute_unaryop(*dst, op, *operand),
|
||||||
|
|
||||||
MirInstruction::Compare { dst, op, lhs, rhs } => {
|
MirInstruction::Compare { dst, op, lhs, rhs } => {
|
||||||
eprintln!("[VM] dispatch Compare op={:?} lhs={:?} rhs={:?}", op, lhs, rhs);
|
let debug_cmp = debug_global || std::env::var("NYASH_VM_DEBUG_CMP").ok().as_deref() == Some("1");
|
||||||
|
if debug_cmp { eprintln!("[VM] dispatch Compare op={:?} lhs={:?} rhs={:?}", op, lhs, rhs); }
|
||||||
// Fast path: if both BoxRef, try numeric parse and compare
|
// Fast path: if both BoxRef, try numeric parse and compare
|
||||||
if let (Ok(lv), Ok(rv)) = (self.get_value(*lhs), self.get_value(*rhs)) {
|
if let (Ok(lv), Ok(rv)) = (self.get_value(*lhs), self.get_value(*rhs)) {
|
||||||
eprintln!("[VM] values before fastpath: left={:?} right={:?}", lv, rv);
|
if debug_cmp { eprintln!("[VM] values before fastpath: left={:?} right={:?}", lv, rv); }
|
||||||
if let (VMValue::BoxRef(lb), VMValue::BoxRef(rb)) = (&lv, &rv) {
|
if let (VMValue::BoxRef(lb), VMValue::BoxRef(rb)) = (&lv, &rv) {
|
||||||
eprintln!("[VM] BoxRef types: lty={} rty={} lstr={} rstr={}", lb.type_name(), rb.type_name(), lb.to_string_box().value, rb.to_string_box().value);
|
if debug_cmp { eprintln!("[VM] BoxRef types: lty={} rty={} lstr={} rstr={}", lb.type_name(), rb.type_name(), lb.to_string_box().value, rb.to_string_box().value); }
|
||||||
let li = lb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)
|
let li = lb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)
|
||||||
.or_else(|| lb.to_string_box().value.trim().parse::<i64>().ok());
|
.or_else(|| lb.to_string_box().value.trim().parse::<i64>().ok());
|
||||||
let ri = rb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)
|
let ri = rb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)
|
||||||
|
|||||||
@ -58,10 +58,12 @@ impl VM {
|
|||||||
|
|
||||||
/// Execute a comparison instruction
|
/// Execute a comparison instruction
|
||||||
pub(super) fn execute_compare(&mut self, dst: ValueId, op: &CompareOp, lhs: ValueId, rhs: ValueId) -> Result<ControlFlow, VMError> {
|
pub(super) fn execute_compare(&mut self, dst: ValueId, op: &CompareOp, lhs: ValueId, rhs: ValueId) -> Result<ControlFlow, VMError> {
|
||||||
eprintln!("[VM] execute_compare enter op={:?} lhs={:?} rhs={:?}", op, lhs, rhs);
|
let debug_cmp = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1") ||
|
||||||
|
std::env::var("NYASH_VM_DEBUG_CMP").ok().as_deref() == Some("1");
|
||||||
|
if debug_cmp { eprintln!("[VM] execute_compare enter op={:?} lhs={:?} rhs={:?}", op, lhs, rhs); }
|
||||||
let mut left = self.get_value(lhs)?;
|
let mut left = self.get_value(lhs)?;
|
||||||
let mut right = self.get_value(rhs)?;
|
let mut right = self.get_value(rhs)?;
|
||||||
eprintln!("[VM] execute_compare values: left={:?} right={:?}", left, right);
|
if debug_cmp { eprintln!("[VM] execute_compare values: left={:?} right={:?}", left, right); }
|
||||||
|
|
||||||
// Canonicalize BoxRef(any) → try Integer via downcast/parse (no type_name reliance)
|
// Canonicalize BoxRef(any) → try Integer via downcast/parse (no type_name reliance)
|
||||||
left = match left {
|
left = match left {
|
||||||
|
|||||||
@ -136,7 +136,9 @@ impl VM {
|
|||||||
|
|
||||||
/// Execute comparison operation
|
/// Execute comparison operation
|
||||||
pub(super) fn execute_compare_op(&self, op: &CompareOp, left: &VMValue, right: &VMValue) -> Result<bool, VMError> {
|
pub(super) fn execute_compare_op(&self, op: &CompareOp, left: &VMValue, right: &VMValue) -> Result<bool, VMError> {
|
||||||
eprintln!("[VM] execute_compare_op enter: op={:?}, left={:?}, right={:?}", op, left, right);
|
let debug_cmp = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1") ||
|
||||||
|
std::env::var("NYASH_VM_DEBUG_CMP").ok().as_deref() == Some("1");
|
||||||
|
if debug_cmp { eprintln!("[VM] execute_compare_op enter: op={:?}, left={:?}, right={:?}", op, left, right); }
|
||||||
match (left, right) {
|
match (left, right) {
|
||||||
// Mixed numeric
|
// Mixed numeric
|
||||||
(VMValue::Integer(l), VMValue::Float(r)) => {
|
(VMValue::Integer(l), VMValue::Float(r)) => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,538 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Nyash Instance System - Box Instance Implementation
|
|
||||||
*
|
|
||||||
* BoxインスタンスとClassBoxの実装
|
|
||||||
* Everything is Box哲学に基づくオブジェクト指向システム
|
|
||||||
*/
|
|
||||||
|
|
||||||
use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox, BoxCore, BoxBase, SharedNyashBox};
|
|
||||||
use crate::ast::ASTNode;
|
|
||||||
use crate::value::NyashValue;
|
|
||||||
use crate::interpreter::NyashInterpreter;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fmt::{Debug, Display};
|
|
||||||
use std::any::Any;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
/// Boxインスタンス - フィールドとメソッドを持つオブジェクト
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct InstanceBox {
|
|
||||||
/// クラス名
|
|
||||||
pub class_name: String,
|
|
||||||
|
|
||||||
/// フィールド値 (Updated to use Arc for reference sharing)
|
|
||||||
pub fields: Arc<Mutex<HashMap<String, SharedNyashBox>>>,
|
|
||||||
|
|
||||||
/// 🔗 Next-generation fields (weak reference capable)
|
|
||||||
pub fields_ng: Arc<Mutex<HashMap<String, NyashValue>>>,
|
|
||||||
|
|
||||||
/// メソッド定義(ClassBoxから共有)
|
|
||||||
pub methods: Arc<HashMap<String, ASTNode>>,
|
|
||||||
|
|
||||||
/// Box基底
|
|
||||||
base: BoxBase,
|
|
||||||
|
|
||||||
/// 解放済みフラグ
|
|
||||||
finalized: Arc<Mutex<bool>>,
|
|
||||||
|
|
||||||
/// 🔥 Phase 2: finiシステム完全実装 - ChatGPT5設計
|
|
||||||
/// init宣言順序(決定的カスケード用)
|
|
||||||
init_field_order: Vec<String>,
|
|
||||||
|
|
||||||
/// weak フィールド高速判定用
|
|
||||||
weak_fields_union: std::collections::HashSet<String>,
|
|
||||||
|
|
||||||
/// 解放中フラグ(再入防止)
|
|
||||||
in_finalization: Arc<Mutex<bool>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InstanceBox {
|
|
||||||
pub fn new(class_name: String, fields: Vec<String>, methods: HashMap<String, ASTNode>) -> Self {
|
|
||||||
// フィールドをVoidBoxで初期化
|
|
||||||
let mut field_map: HashMap<String, SharedNyashBox> = HashMap::new();
|
|
||||||
for field in &fields {
|
|
||||||
field_map.insert(field.clone(), Arc::new(VoidBox::new()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
class_name,
|
|
||||||
fields: Arc::new(Mutex::new(field_map)),
|
|
||||||
fields_ng: Arc::new(Mutex::new(HashMap::new())), // 🔗 Initialize next-gen fields
|
|
||||||
methods: Arc::new(methods),
|
|
||||||
base: BoxBase::new(),
|
|
||||||
finalized: Arc::new(Mutex::new(false)),
|
|
||||||
init_field_order: fields.clone(), // 🔥 Basic field order for backwards compatibility
|
|
||||||
weak_fields_union: std::collections::HashSet::new(), // 🔥 Empty for backwards compatibility
|
|
||||||
in_finalization: Arc::new(Mutex::new(false)), // 🔥 Initialize finalization guard
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔥 Enhanced constructor with complete fini system support
|
|
||||||
pub fn new_with_box_info(
|
|
||||||
class_name: String,
|
|
||||||
fields: Vec<String>,
|
|
||||||
methods: HashMap<String, ASTNode>,
|
|
||||||
init_field_order: Vec<String>,
|
|
||||||
weak_fields: Vec<String>
|
|
||||||
) -> Self {
|
|
||||||
// フィールドをVoidBoxで初期化
|
|
||||||
let mut field_map = HashMap::new();
|
|
||||||
for field in &fields {
|
|
||||||
field_map.insert(field.clone(), Arc::new(VoidBox::new()) as Arc<dyn NyashBox>);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weak fields をHashSetに変換(高速判定用)
|
|
||||||
let weak_fields_union: std::collections::HashSet<String> = weak_fields.into_iter().collect();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
class_name,
|
|
||||||
fields: Arc::new(Mutex::new(field_map)),
|
|
||||||
fields_ng: Arc::new(Mutex::new(HashMap::new())),
|
|
||||||
methods: Arc::new(methods),
|
|
||||||
base: BoxBase::new(),
|
|
||||||
finalized: Arc::new(Mutex::new(false)),
|
|
||||||
init_field_order, // 🔥 決定的カスケード順序
|
|
||||||
weak_fields_union, // 🔥 高速weak判定
|
|
||||||
in_finalization: Arc::new(Mutex::new(false)), // 🔥 再入防止
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔗 Unified field access - prioritizes fields_ng, fallback to legacy fields with conversion
|
|
||||||
pub fn get_field_unified(&self, field_name: &str) -> Option<NyashValue> {
|
|
||||||
// Check fields_ng first
|
|
||||||
if let Some(value) = self.fields_ng.lock().unwrap().get(field_name) {
|
|
||||||
return Some(value.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to legacy fields with conversion
|
|
||||||
if let Some(legacy_box) = self.fields.lock().unwrap().get(field_name) {
|
|
||||||
// For backward compatibility, we need to work around the type mismatch
|
|
||||||
// Since we can't easily convert Box<dyn NyashBox> to Arc<Mutex<dyn NyashBox>>
|
|
||||||
// We'll use the from_box method which handles this conversion
|
|
||||||
// We need to create a temporary Arc to satisfy the method signature
|
|
||||||
let _temp_arc = Arc::new(Mutex::new(VoidBox::new()));
|
|
||||||
// Unfortunately, there's a type system limitation here
|
|
||||||
// For now, let's return a simple converted value
|
|
||||||
let string_rep = legacy_box.to_string_box().value;
|
|
||||||
return Some(NyashValue::String(string_rep));
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔗 Unified field setting - always stores in fields_ng
|
|
||||||
pub fn set_field_unified(&self, field_name: String, value: NyashValue) -> Result<(), String> {
|
|
||||||
// Always store in fields_ng for future compatibility
|
|
||||||
self.fields_ng.lock().unwrap().insert(field_name.clone(), value.clone());
|
|
||||||
|
|
||||||
// For backward compatibility, also update legacy fields if they exist
|
|
||||||
// Convert NyashValue back to Box<dyn NyashBox> for legacy storage
|
|
||||||
if self.fields.lock().unwrap().contains_key(&field_name) {
|
|
||||||
if let Ok(legacy_box) = value.to_box() {
|
|
||||||
// Convert Arc<Mutex<dyn NyashBox>> to Box<dyn NyashBox>
|
|
||||||
if let Ok(_inner_box) = legacy_box.try_lock() {
|
|
||||||
self.fields.lock().unwrap().insert(field_name, Arc::from(_inner_box.clone_box()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔗 Set weak field - converts strong reference to weak and stores in fields_ng
|
|
||||||
pub fn set_weak_field(&self, field_name: String, value: NyashValue) -> Result<(), String> {
|
|
||||||
match value {
|
|
||||||
NyashValue::Box(arc_box) => {
|
|
||||||
let weak_ref = Arc::downgrade(&arc_box);
|
|
||||||
let field_name_clone = field_name.clone(); // Clone for eprintln
|
|
||||||
self.fields_ng.lock().unwrap().insert(field_name, NyashValue::WeakBox(weak_ref));
|
|
||||||
eprintln!("🔗 DEBUG: Successfully converted strong reference to weak for field '{}'", field_name_clone);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// For non-Box values, store as-is (they don't need weak conversion)
|
|
||||||
self.fields_ng.lock().unwrap().insert(field_name, value);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔗 Set weak field from legacy Box<dyn NyashBox> - helper method for interpreter
|
|
||||||
pub fn set_weak_field_from_legacy(&self, field_name: String, legacy_box: Box<dyn NyashBox>) -> Result<(), String> {
|
|
||||||
// Convert Box<dyn NyashBox> to Arc<Mutex<dyn NyashBox>> via temporary wrapper
|
|
||||||
// We create a temporary holder struct that implements NyashBox
|
|
||||||
|
|
||||||
|
|
||||||
// Store the object info in a way we can track
|
|
||||||
let object_info = legacy_box.to_string_box().value;
|
|
||||||
let field_name_clone = field_name.clone();
|
|
||||||
|
|
||||||
// Create a special weak reference marker with object details
|
|
||||||
let weak_marker = format!("WEAK_REF_TO:{}", object_info);
|
|
||||||
self.fields_ng.lock().unwrap().insert(field_name, NyashValue::String(weak_marker));
|
|
||||||
|
|
||||||
eprintln!("🔗 DEBUG: Stored weak field '{}' with reference tracking", field_name_clone);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔗 Get weak field with auto-upgrade and nil fallback
|
|
||||||
pub fn get_weak_field(&self, field_name: &str, interpreter: &NyashInterpreter) -> Option<NyashValue> {
|
|
||||||
if let Some(value) = self.fields_ng.lock().unwrap().get(field_name) {
|
|
||||||
match value {
|
|
||||||
NyashValue::WeakBox(weak_ref) => {
|
|
||||||
if let Some(strong_ref) = weak_ref.upgrade() {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' upgraded successfully", field_name);
|
|
||||||
Some(NyashValue::Box(strong_ref))
|
|
||||||
} else {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' target was dropped - returning null", field_name);
|
|
||||||
Some(NyashValue::Null) // 🎯 Auto-nil behavior!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NyashValue::String(s) => {
|
|
||||||
// For string-based weak fields, check if they're marked as "dropped"
|
|
||||||
if s.starts_with("WEAK_REF_TO:") {
|
|
||||||
// Extract the object ID from the weak reference string
|
|
||||||
// Format: "WEAK_REF_TO:<ClassName instance #ID>"
|
|
||||||
let mut is_dropped = false;
|
|
||||||
|
|
||||||
if let Some(hash_pos) = s.find('#') {
|
|
||||||
let id_str = &s[hash_pos + 1..];
|
|
||||||
let id_end = id_str.find('>').unwrap_or(id_str.len());
|
|
||||||
let clean_id_str = &id_str[..id_end];
|
|
||||||
|
|
||||||
if let Ok(id) = clean_id_str.parse::<u64>() {
|
|
||||||
is_dropped = interpreter.invalidated_ids.lock().unwrap().contains(&id);
|
|
||||||
eprintln!("🔗 DEBUG: Checking weak field '{}' with ID {} - dropped: {}", field_name, id, is_dropped);
|
|
||||||
} else {
|
|
||||||
eprintln!("🔗 DEBUG: Failed to parse ID from weak reference: {}", clean_id_str);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Fallback to old behavior for backwards compatibility
|
|
||||||
is_dropped = s.contains("Parent") && interpreter.invalidated_ids.lock().unwrap().contains(&999);
|
|
||||||
eprintln!("🔗 DEBUG: Using fallback check for weak field '{}' - dropped: {}", field_name, is_dropped);
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_dropped {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' target was dropped - returning null", field_name);
|
|
||||||
return Some(NyashValue::Null); // 🎉 Auto-nil!
|
|
||||||
}
|
|
||||||
|
|
||||||
// Still valid
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field_name);
|
|
||||||
Some(value.clone())
|
|
||||||
} else if s == "WEAK_REFERENCE_DROPPED" {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' target was dropped - returning null", field_name);
|
|
||||||
Some(NyashValue::Null)
|
|
||||||
} else {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field_name);
|
|
||||||
Some(value.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// Non-weak value, return as-is
|
|
||||||
Some(value.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔗 Mark weak references to this instance as dropped
|
|
||||||
pub fn invalidate_weak_references_to(&self, target_info: &str) {
|
|
||||||
let mut fields = self.fields_ng.lock().unwrap();
|
|
||||||
for (field_name, value) in fields.iter_mut() {
|
|
||||||
match value {
|
|
||||||
NyashValue::String(s) => {
|
|
||||||
// Check if this is a weak reference to the target
|
|
||||||
if s.starts_with("WEAK_REF_TO:") && s.contains(target_info) {
|
|
||||||
*s = "WEAK_REFERENCE_DROPPED".to_string();
|
|
||||||
eprintln!("🔗 DEBUG: Marked weak field '{}' as dropped", field_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NyashValue::WeakBox(weak_ref) => {
|
|
||||||
// Check if the weak reference is dead
|
|
||||||
if weak_ref.upgrade().is_none() {
|
|
||||||
eprintln!("🔗 DEBUG: Weak field '{}' reference is already dead", field_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔗 Global invalidation - call this when any object is dropped
|
|
||||||
pub fn global_invalidate_weak_references(target_info: &str) {
|
|
||||||
// In a real implementation, we'd maintain a global registry of all instances
|
|
||||||
// and iterate through them to invalidate weak references.
|
|
||||||
// For this demo, we'll add the capability to the instance itself.
|
|
||||||
eprintln!("🔗 DEBUG: Global weak reference invalidation for: {}", target_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// フィールドの値を取得
|
|
||||||
pub fn get_field(&self, field_name: &str) -> Option<SharedNyashBox> {
|
|
||||||
eprintln!("✅ FIX: get_field('{}') returning shared Arc reference", field_name);
|
|
||||||
|
|
||||||
// 🔧 修正:v.clone_box() → Arc::clone(v) で参照共有
|
|
||||||
self.fields.lock().unwrap().get(field_name).map(Arc::clone)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// フィールドに値を設定
|
|
||||||
pub fn set_field(&self, field_name: &str, value: SharedNyashBox) -> Result<(), String> {
|
|
||||||
eprintln!("🔧 INSTANCE: set_field('{}') with shared Arc reference id={}",
|
|
||||||
field_name, value.box_id());
|
|
||||||
|
|
||||||
let mut fields = self.fields.lock().unwrap();
|
|
||||||
if fields.contains_key(field_name) {
|
|
||||||
if let Some(old_value) = fields.get(field_name) {
|
|
||||||
eprintln!("🔧 INSTANCE: Replacing field '{}': old_id={} -> new_id={}",
|
|
||||||
field_name, old_value.box_id(), value.box_id());
|
|
||||||
}
|
|
||||||
fields.insert(field_name.to_string(), value);
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(format!("Field '{}' does not exist in {}", field_name, self.class_name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🌍 GlobalBox用:フィールドを動的に追加・設定
|
|
||||||
pub fn set_field_dynamic(&mut self, field_name: String, value: SharedNyashBox) {
|
|
||||||
let mut fields = self.fields.lock().unwrap();
|
|
||||||
fields.insert(field_name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// メソッド定義を取得
|
|
||||||
pub fn get_method(&self, method_name: &str) -> Option<&ASTNode> {
|
|
||||||
self.methods.get(method_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// メソッドが存在するかチェック
|
|
||||||
pub fn has_method(&self, method_name: &str) -> bool {
|
|
||||||
self.methods.contains_key(method_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🌍 GlobalBox用:メソッドを動的に追加 - 🔥 暗黙オーバーライド禁止による安全実装
|
|
||||||
pub fn add_method(&mut self, method_name: String, method_ast: ASTNode) -> Result<(), String> {
|
|
||||||
// Arc<T>は不変なので、新しいHashMapを作成してArcで包む
|
|
||||||
let mut new_methods = (*self.methods).clone();
|
|
||||||
|
|
||||||
// 🚨 暗黙オーバーライド禁止:既存メソッドの検査
|
|
||||||
if let Some(_existing_method) = new_methods.get(&method_name) {
|
|
||||||
// 新しいメソッドのoverride状態を確認
|
|
||||||
let is_override = match &method_ast {
|
|
||||||
crate::ast::ASTNode::FunctionDeclaration { is_override, .. } => *is_override,
|
|
||||||
_ => false, // FunctionDeclaration以外はオーバーライドなし
|
|
||||||
};
|
|
||||||
|
|
||||||
if !is_override {
|
|
||||||
// 🔥 明示的オーバーライド革命:overrideキーワードなしの重複を禁止
|
|
||||||
return Err(format!(
|
|
||||||
"🚨 EXPLICIT OVERRIDE REQUIRED: Method '{}' already exists.\n\
|
|
||||||
💡 To replace the existing method, use 'override {}(...) {{ ... }}'.\n\
|
|
||||||
🌟 This is Nyash's explicit delegation philosophy - no hidden overrides!",
|
|
||||||
method_name, method_name
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// override宣言があれば、明示的な置換として許可
|
|
||||||
eprintln!("🔥 EXPLICIT OVERRIDE: Method '{}' replaced with override declaration", method_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
new_methods.insert(method_name, method_ast);
|
|
||||||
self.methods = Arc::new(new_methods);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔥 Enhanced fini()メソッド - ChatGPT5設計による完全実装
|
|
||||||
pub fn fini(&self) -> Result<(), String> {
|
|
||||||
// 1) finalized チェック(idempotent)
|
|
||||||
let mut finalized = self.finalized.lock().unwrap();
|
|
||||||
if *finalized {
|
|
||||||
// 既に解放済みなら何もしない
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) in_finalization = true(再入防止)
|
|
||||||
let mut in_finalization = self.in_finalization.lock().unwrap();
|
|
||||||
if *in_finalization {
|
|
||||||
return Err("Circular finalization detected - fini() called recursively".to_string());
|
|
||||||
}
|
|
||||||
*in_finalization = true;
|
|
||||||
|
|
||||||
// 3) TODO: ユーザー定義fini()実行(インタープリター側で実装予定)
|
|
||||||
// このメソッドは低レベルなfini処理なので、高レベルなユーザー定義fini()は
|
|
||||||
// インタープリター側で先に呼び出される想定
|
|
||||||
|
|
||||||
// 4) 自動カスケード: init_field_order の強参照フィールドに child.fini()
|
|
||||||
self.cascade_finalize_fields()?;
|
|
||||||
|
|
||||||
// 5) 全フィールドクリア + finalized = true
|
|
||||||
let mut fields = self.fields.lock().unwrap();
|
|
||||||
fields.clear();
|
|
||||||
let mut fields_ng = self.fields_ng.lock().unwrap();
|
|
||||||
fields_ng.clear();
|
|
||||||
|
|
||||||
*finalized = true;
|
|
||||||
*in_finalization = false; // 再入フラグをクリア
|
|
||||||
|
|
||||||
eprintln!("🔥 fini(): Instance {} (ID: {}) finalized", self.class_name, self.base.id);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔥 自動カスケード解放 - init宣言順でフィールドをfini
|
|
||||||
fn cascade_finalize_fields(&self) -> Result<(), String> {
|
|
||||||
let fields_ng = self.fields_ng.lock().unwrap();
|
|
||||||
|
|
||||||
// init_field_order の逆順でfiniを実行(LIFO - Last In First Out)
|
|
||||||
for field_name in self.init_field_order.iter().rev() {
|
|
||||||
// weak フィールドはスキップ
|
|
||||||
if self.weak_fields_union.contains(field_name) {
|
|
||||||
eprintln!("🔥 fini(): Skipping weak field '{}' (non-owning reference)", field_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// フィールドの値を取得してfini呼び出し
|
|
||||||
if let Some(field_value) = fields_ng.get(field_name) {
|
|
||||||
match field_value {
|
|
||||||
crate::value::NyashValue::Box(arc_box) => {
|
|
||||||
if let Ok(inner_box) = arc_box.try_lock() {
|
|
||||||
// InstanceBoxならfini()を呼び出し
|
|
||||||
if let Some(instance) = inner_box.as_any().downcast_ref::<InstanceBox>() {
|
|
||||||
eprintln!("🔥 fini(): Cascading finalization to field '{}'", field_name);
|
|
||||||
if let Err(e) = instance.fini() {
|
|
||||||
eprintln!("🔥 fini(): Warning - failed to finalize field '{}': {}", field_name, e);
|
|
||||||
// エラーは警告として記録するが、続行する
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// non-Box値はfini不要
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 解放済みかチェック
|
|
||||||
pub fn is_finalized(&self) -> bool {
|
|
||||||
*self.finalized.lock().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔥 解放中かチェック
|
|
||||||
pub fn is_in_finalization(&self) -> bool {
|
|
||||||
*self.in_finalization.lock().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 🔥 指定フィールドがweakかチェック
|
|
||||||
pub fn is_weak_field(&self, field_name: &str) -> bool {
|
|
||||||
self.weak_fields_union.contains(field_name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NyashBox for InstanceBox {
|
|
||||||
fn to_string_box(&self) -> StringBox {
|
|
||||||
StringBox::new(format!("<{} instance #{}>", self.class_name, self.base.id))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
|
||||||
if let Some(other_instance) = other.as_any().downcast_ref::<InstanceBox>() {
|
|
||||||
// 同じインスタンスIDなら等しい
|
|
||||||
BoolBox::new(self.base.id == other_instance.base.id)
|
|
||||||
} else {
|
|
||||||
BoolBox::new(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn type_name(&self) -> &'static str {
|
|
||||||
"InstanceBox"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn NyashBox> {
|
|
||||||
// インスタンスは同じフィールドを共有
|
|
||||||
Box::new(self.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 仮実装: clone_boxと同じ(後で修正)
|
|
||||||
fn share_box(&self) -> Box<dyn NyashBox> {
|
|
||||||
self.clone_box()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BoxCore for InstanceBox {
|
|
||||||
fn box_id(&self) -> u64 {
|
|
||||||
self.base.id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parent_type_id(&self) -> Option<std::any::TypeId> {
|
|
||||||
self.base.parent_type_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "<{} instance #{}>", self.class_name, self.base.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for InstanceBox {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.fmt_box(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== Tests =====
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::box_trait::IntegerBox;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_instance_creation() {
|
|
||||||
let fields = vec!["x".to_string(), "y".to_string()];
|
|
||||||
let methods = HashMap::new();
|
|
||||||
let instance = InstanceBox::new("Point".to_string(), fields, methods);
|
|
||||||
|
|
||||||
assert_eq!(instance.class_name, "Point");
|
|
||||||
assert!(instance.get_field("x").is_some());
|
|
||||||
assert!(instance.get_field("y").is_some());
|
|
||||||
assert!(instance.get_field("z").is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_field_access() {
|
|
||||||
let fields = vec!["value".to_string()];
|
|
||||||
let methods = HashMap::new();
|
|
||||||
let instance = InstanceBox::new("TestBox".to_string(), fields, methods);
|
|
||||||
|
|
||||||
// フィールドに値を設定
|
|
||||||
let int_value = Box::new(IntegerBox::new(42)) as Box<dyn NyashBox>;
|
|
||||||
instance.set_field("value", int_value).unwrap();
|
|
||||||
|
|
||||||
// フィールドの値を取得
|
|
||||||
let retrieved = instance.get_field("value").unwrap();
|
|
||||||
let int_box = retrieved.as_any().downcast_ref::<IntegerBox>().unwrap();
|
|
||||||
assert_eq!(int_box.value, 42);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_instance_equality() {
|
|
||||||
let instance1 = InstanceBox::new("Test".to_string(), vec![], HashMap::new());
|
|
||||||
let instance2 = InstanceBox::new("Test".to_string(), vec![], HashMap::new());
|
|
||||||
|
|
||||||
// 異なるインスタンスは等しくない
|
|
||||||
assert!(!instance1.equals(&instance2).value);
|
|
||||||
|
|
||||||
// 同じインスタンスは等しい
|
|
||||||
assert!(instance1.equals(&instance1).value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -33,7 +33,7 @@ mod core;
|
|||||||
mod expressions;
|
mod expressions;
|
||||||
mod statements;
|
mod statements;
|
||||||
mod functions;
|
mod functions;
|
||||||
mod objects;
|
pub mod objects;
|
||||||
mod objects_basic_constructors;
|
mod objects_basic_constructors;
|
||||||
mod io;
|
mod io;
|
||||||
mod methods;
|
mod methods;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
193
src/interpreter/objects/fields.rs
Normal file
193
src/interpreter/objects/fields.rs
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl NyashInterpreter {
|
||||||
|
/// Box宣言を登録 - 🔥 コンストラクタオーバーロード禁止対応
|
||||||
|
pub(crate) fn register_box_declaration(
|
||||||
|
&mut self,
|
||||||
|
name: String,
|
||||||
|
fields: Vec<String>,
|
||||||
|
public_fields: Vec<String>,
|
||||||
|
private_fields: Vec<String>,
|
||||||
|
methods: HashMap<String, ASTNode>,
|
||||||
|
constructors: HashMap<String, ASTNode>,
|
||||||
|
init_fields: Vec<String>,
|
||||||
|
weak_fields: Vec<String>,
|
||||||
|
is_interface: bool,
|
||||||
|
extends: Vec<String>,
|
||||||
|
implements: Vec<String>,
|
||||||
|
type_parameters: Vec<String>
|
||||||
|
) -> Result<(), RuntimeError> {
|
||||||
|
if !constructors.is_empty() {
|
||||||
|
eprintln!("🐛 DEBUG: Registering Box '{}' with constructors: {:?}", name, constructors.keys().collect::<Vec<_>>());
|
||||||
|
}
|
||||||
|
if constructors.len() > 1 {
|
||||||
|
let constructor_names: Vec<String> = constructors.keys().cloned().collect();
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!(
|
||||||
|
"🚨 CONSTRUCTOR OVERLOAD FORBIDDEN: Box '{}' has {} constructors: [{}].\n\
|
||||||
|
🌟 Nyash's explicit philosophy: One Box, One Constructor!\n\
|
||||||
|
💡 Use different Box classes for different initialization patterns.\n\
|
||||||
|
📖 Example: UserBox, AdminUserBox, GuestUserBox instead of User(type)",
|
||||||
|
name,
|
||||||
|
constructors.len(),
|
||||||
|
constructor_names.join(", ")
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let box_decl = super::BoxDeclaration {
|
||||||
|
name: name.clone(),
|
||||||
|
fields,
|
||||||
|
public_fields,
|
||||||
|
private_fields,
|
||||||
|
methods,
|
||||||
|
constructors,
|
||||||
|
init_fields,
|
||||||
|
weak_fields,
|
||||||
|
is_interface,
|
||||||
|
extends,
|
||||||
|
implements,
|
||||||
|
type_parameters,
|
||||||
|
};
|
||||||
|
{
|
||||||
|
let mut box_decls = self.shared.box_declarations.write().unwrap();
|
||||||
|
box_decls.insert(name, box_decl);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🔥 ジェネリクス型引数の検証
|
||||||
|
pub(super) fn validate_generic_arguments(&self, box_decl: &BoxDeclaration, type_arguments: &[String])
|
||||||
|
-> Result<(), RuntimeError> {
|
||||||
|
if box_decl.type_parameters.len() != type_arguments.len() {
|
||||||
|
return Err(RuntimeError::TypeError {
|
||||||
|
message: format!(
|
||||||
|
"Generic class '{}' expects {} type parameters, got {}. Expected: <{}>, Got: <{}>",
|
||||||
|
box_decl.name,
|
||||||
|
box_decl.type_parameters.len(),
|
||||||
|
type_arguments.len(),
|
||||||
|
box_decl.type_parameters.join(", "),
|
||||||
|
type_arguments.join(", ")
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if box_decl.type_parameters.is_empty() && !type_arguments.is_empty() {
|
||||||
|
return Err(RuntimeError::TypeError {
|
||||||
|
message: format!(
|
||||||
|
"Class '{}' is not generic, but got type arguments <{}>",
|
||||||
|
box_decl.name,
|
||||||
|
type_arguments.join(", ")
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for type_arg in type_arguments {
|
||||||
|
if !self.is_valid_type(type_arg) {
|
||||||
|
return Err(RuntimeError::TypeError { message: format!("Unknown type '{}'", type_arg) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 型が有効かどうかをチェック
|
||||||
|
fn is_valid_type(&self, type_name: &str) -> bool {
|
||||||
|
if let Ok(reg) = self.runtime.box_registry.lock() {
|
||||||
|
if reg.has_type(type_name) { return true; }
|
||||||
|
}
|
||||||
|
self.shared.box_declarations.read().unwrap().contains_key(type_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 継承チェーンを解決してフィールドとメソッドを収集 - Inheritance resolution
|
||||||
|
pub(crate) fn resolve_inheritance(&self, box_decl: &BoxDeclaration)
|
||||||
|
-> Result<(Vec<String>, HashMap<String, ASTNode>), RuntimeError> {
|
||||||
|
let mut all_fields = Vec::new();
|
||||||
|
let mut all_methods = HashMap::new();
|
||||||
|
for parent_name in &box_decl.extends {
|
||||||
|
use crate::box_trait::is_builtin_box;
|
||||||
|
let mut is_builtin = is_builtin_box(parent_name);
|
||||||
|
#[cfg(all(feature = "gui", not(target_arch = "wasm32")))]
|
||||||
|
{
|
||||||
|
if parent_name == "EguiBox" { is_builtin = true; }
|
||||||
|
}
|
||||||
|
if is_builtin {
|
||||||
|
// skip builtin inheritance
|
||||||
|
} else {
|
||||||
|
let parent_decl = {
|
||||||
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
|
box_decls.get(parent_name)
|
||||||
|
.ok_or(RuntimeError::UndefinedClass { name: parent_name.to_string() })?
|
||||||
|
.clone()
|
||||||
|
};
|
||||||
|
if parent_decl.is_interface {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("Cannot extend interface '{}'. Use 'implements' instead.", parent_name),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let (parent_fields, parent_methods) = self.resolve_inheritance(&parent_decl)?;
|
||||||
|
all_fields.extend(parent_fields);
|
||||||
|
all_methods.extend(parent_methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
all_fields.extend(box_decl.fields.clone());
|
||||||
|
for init_field in &box_decl.init_fields {
|
||||||
|
if !all_fields.contains(init_field) { all_fields.push(init_field.clone()); }
|
||||||
|
}
|
||||||
|
for (method_name, method_ast) in &box_decl.methods {
|
||||||
|
all_methods.insert(method_name.clone(), method_ast.clone());
|
||||||
|
}
|
||||||
|
for interface_name in &box_decl.implements {
|
||||||
|
let interface_decl = {
|
||||||
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
|
box_decls.get(interface_name)
|
||||||
|
.ok_or(RuntimeError::UndefinedClass { name: interface_name.clone() })?
|
||||||
|
.clone()
|
||||||
|
};
|
||||||
|
if !interface_decl.is_interface {
|
||||||
|
return Err(RuntimeError::InvalidOperation { message: format!("'{}' is not an interface", interface_name) });
|
||||||
|
}
|
||||||
|
for (required_method, _) in &interface_decl.methods {
|
||||||
|
if !all_methods.contains_key(required_method) {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("Class '{}' must implement method '{}' from interface '{}'",
|
||||||
|
box_decl.name, required_method, interface_name),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok((all_fields, all_methods))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🚀 ジェネリクス型を特殊化してBoxDeclarationを生成
|
||||||
|
pub(super) fn specialize_generic_class(
|
||||||
|
&self,
|
||||||
|
generic_decl: &BoxDeclaration,
|
||||||
|
type_arguments: &[String]
|
||||||
|
) -> Result<BoxDeclaration, RuntimeError> {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
let specialized_name = format!("{}_{}", generic_decl.name, type_arguments.join("_"));
|
||||||
|
let mut type_mapping = HashMap::new();
|
||||||
|
for (i, param) in generic_decl.type_parameters.iter().enumerate() {
|
||||||
|
type_mapping.insert(param.clone(), type_arguments[i].clone());
|
||||||
|
}
|
||||||
|
let mut specialized = generic_decl.clone();
|
||||||
|
specialized.name = specialized_name.clone();
|
||||||
|
specialized.type_parameters.clear();
|
||||||
|
specialized.init_fields = self.substitute_types_in_fields(&specialized.init_fields, &type_mapping);
|
||||||
|
let mut updated_constructors = HashMap::new();
|
||||||
|
for (old_key, constructor_node) in &generic_decl.constructors {
|
||||||
|
if let Some(args_count) = old_key.split('/').nth(1) {
|
||||||
|
let new_key = format!("{}/{}", specialized_name, args_count);
|
||||||
|
updated_constructors.insert(new_key, constructor_node.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
specialized.constructors = updated_constructors;
|
||||||
|
Ok(specialized)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// フィールドの型置換(現状はそのまま)
|
||||||
|
pub(super) fn substitute_types_in_fields(
|
||||||
|
&self,
|
||||||
|
fields: &[String],
|
||||||
|
_type_mapping: &HashMap<String, String>
|
||||||
|
) -> Vec<String> {
|
||||||
|
fields.to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
66
src/interpreter/objects/methods.rs
Normal file
66
src/interpreter/objects/methods.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::box_trait::SharedNyashBox;
|
||||||
|
|
||||||
|
impl NyashInterpreter {
|
||||||
|
/// コンストラクタを実行 - Constructor execution
|
||||||
|
pub(super) fn execute_constructor(
|
||||||
|
&mut self,
|
||||||
|
instance: &SharedNyashBox,
|
||||||
|
constructor: &ASTNode,
|
||||||
|
arguments: &[ASTNode],
|
||||||
|
box_decl: &BoxDeclaration
|
||||||
|
) -> Result<(), RuntimeError> {
|
||||||
|
if let ASTNode::FunctionDeclaration { name: _, params, body, .. } = constructor {
|
||||||
|
let mut arg_values = Vec::new();
|
||||||
|
for arg in arguments { arg_values.push(self.execute_expression(arg)?); }
|
||||||
|
if params.len() != arg_values.len() {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("Constructor expects {} arguments, got {}", params.len(), arg_values.len()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let saved_locals = self.save_local_vars();
|
||||||
|
self.local_vars.clear();
|
||||||
|
for (param, value) in params.iter().zip(arg_values.iter()) {
|
||||||
|
self.declare_local_variable(param, value.clone_or_share());
|
||||||
|
}
|
||||||
|
self.declare_local_variable("me", instance.clone_or_share());
|
||||||
|
let old_context = self.current_constructor_context.clone();
|
||||||
|
self.current_constructor_context = Some(ConstructorContext {
|
||||||
|
class_name: box_decl.name.clone(),
|
||||||
|
parent_class: box_decl.extends.first().cloned(),
|
||||||
|
});
|
||||||
|
let mut result = Ok(());
|
||||||
|
for statement in body.iter() {
|
||||||
|
if let Err(e) = self.execute_statement(statement) { result = Err(e); break; }
|
||||||
|
}
|
||||||
|
self.restore_local_vars(saved_locals);
|
||||||
|
self.current_constructor_context = old_context;
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
Err(RuntimeError::InvalidOperation { message: "Invalid constructor node".to_string() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 親コンストラクタを実行 - Parent constructor execution
|
||||||
|
pub(crate) fn execute_parent_constructor(&mut self, parent_class: &str, arguments: &[ASTNode])
|
||||||
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
let parent_decl = {
|
||||||
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
|
box_decls.get(parent_class)
|
||||||
|
.ok_or(RuntimeError::UndefinedClass { name: parent_class.to_string() })?
|
||||||
|
.clone()
|
||||||
|
};
|
||||||
|
let birth_key = format!("birth/{}", arguments.len());
|
||||||
|
if let Some(parent_constructor) = parent_decl.constructors.get(&birth_key) {
|
||||||
|
let this_instance = self.resolve_variable("me").map_err(|_| RuntimeError::InvalidOperation {
|
||||||
|
message: "'this' not available in parent constructor call".to_string(),
|
||||||
|
})?;
|
||||||
|
self.execute_constructor(&this_instance, parent_constructor, arguments, &parent_decl)?;
|
||||||
|
Ok(Box::new(VoidBox::new()))
|
||||||
|
} else {
|
||||||
|
Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("No constructor found for parent class {} with {} arguments", parent_class, arguments.len()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/interpreter/objects/mod.rs
Normal file
15
src/interpreter/objects/mod.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*!
|
||||||
|
* Interpreter Objects Module (mod)
|
||||||
|
*
|
||||||
|
* Split into submodules:
|
||||||
|
* - ops.rs: instantiation (execute_new) and helpers
|
||||||
|
* - methods.rs: constructor-related methods
|
||||||
|
* - fields.rs: declarations, inheritance, generics utilities
|
||||||
|
*/
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod ops;
|
||||||
|
mod methods;
|
||||||
|
mod fields;
|
||||||
|
|
||||||
91
src/interpreter/objects/ops.rs
Normal file
91
src/interpreter/objects/ops.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::box_trait::SharedNyashBox;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
impl NyashInterpreter {
|
||||||
|
/// Evaluate `new` expression arguments to NyashBox values
|
||||||
|
pub(super) fn new_eval_args(&mut self, arguments: &[ASTNode]) -> Result<Vec<Box<dyn NyashBox>>, RuntimeError> {
|
||||||
|
arguments.iter().map(|arg| self.execute_expression(arg)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If user-defined and type args provided, validate/specialize and register declaration
|
||||||
|
pub(super) fn new_specialize_if_needed(&self, class: &str, type_arguments: &[String]) -> Result<String, RuntimeError> {
|
||||||
|
let mut target_class = class.to_string();
|
||||||
|
let user_defined_exists = {
|
||||||
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
|
box_decls.contains_key(class)
|
||||||
|
};
|
||||||
|
if user_defined_exists && !type_arguments.is_empty() {
|
||||||
|
let generic_decl = {
|
||||||
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
|
box_decls.get(class).cloned()
|
||||||
|
};
|
||||||
|
if let Some(generic_decl) = generic_decl {
|
||||||
|
self.validate_generic_arguments(&generic_decl, type_arguments)?;
|
||||||
|
let specialized = self.specialize_generic_class(&generic_decl, type_arguments)?;
|
||||||
|
target_class = specialized.name.clone();
|
||||||
|
// Insert specialized declaration so registry can create it
|
||||||
|
let mut box_decls = self.shared.box_declarations.write().unwrap();
|
||||||
|
box_decls.insert(target_class.clone(), specialized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(target_class)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create box via registry and optionally run user-defined constructor (birth/arity)
|
||||||
|
pub(super) fn new_create_via_registry_and_maybe_ctor(
|
||||||
|
&mut self,
|
||||||
|
target_class: &str,
|
||||||
|
args: Vec<Box<dyn NyashBox>>,
|
||||||
|
arguments: &[ASTNode],
|
||||||
|
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
// Try unified registry (use interpreter's runtime registry to include user-defined boxes)
|
||||||
|
let registry = self.runtime.box_registry.clone();
|
||||||
|
let registry_lock = registry.lock().unwrap();
|
||||||
|
match registry_lock.create_box(target_class, &args) {
|
||||||
|
Ok(box_instance) => {
|
||||||
|
// Check if this is a user-defined box that needs constructor execution
|
||||||
|
if let Some(_instance_box) = box_instance.as_any().downcast_ref::<crate::instance_v2::InstanceBox>() {
|
||||||
|
// Check if we have a box declaration for this class
|
||||||
|
let (box_decl_opt, constructor_opt) = {
|
||||||
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
|
if let Some(box_decl) = box_decls.get(target_class) {
|
||||||
|
// Find the birth constructor (unified constructor system)
|
||||||
|
let birth_key = format!("birth/{}", arguments.len());
|
||||||
|
let constructor = box_decl.constructors.get(&birth_key).cloned();
|
||||||
|
(Some(box_decl.clone()), constructor)
|
||||||
|
} else { (None, None) }
|
||||||
|
};
|
||||||
|
if let Some(box_decl) = box_decl_opt {
|
||||||
|
if let Some(constructor) = constructor_opt {
|
||||||
|
// Execute the constructor
|
||||||
|
let instance_arc: SharedNyashBox = Arc::from(box_instance);
|
||||||
|
drop(registry_lock); // Release lock before executing constructor
|
||||||
|
self.execute_constructor(&instance_arc, &constructor, arguments, &box_decl)?;
|
||||||
|
return Ok((*instance_arc).clone_box());
|
||||||
|
} else if arguments.is_empty() {
|
||||||
|
// No constructor needed for zero arguments
|
||||||
|
return Ok(box_instance);
|
||||||
|
} else {
|
||||||
|
return Err(RuntimeError::InvalidOperation {
|
||||||
|
message: format!("No constructor found for {} with {} arguments", target_class, arguments.len()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Not a user-defined box or no constructor needed
|
||||||
|
Ok(box_instance)
|
||||||
|
},
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// new式を実行 - Object creation engine
|
||||||
|
pub(crate) fn execute_new(&mut self, class: &str, arguments: &[ASTNode], type_arguments: &[String])
|
||||||
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
// 80/20 path: unified registry + constructor
|
||||||
|
let args = self.new_eval_args(arguments)?;
|
||||||
|
let target_class = self.new_specialize_if_needed(class, type_arguments)?;
|
||||||
|
self.new_create_via_registry_and_maybe_ctor(&target_class, args, arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -58,6 +58,7 @@ pub mod cli;
|
|||||||
|
|
||||||
// Runtime system (plugins, registry, etc.)
|
// Runtime system (plugins, registry, etc.)
|
||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
|
pub mod runner_plugin_init;
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
pub mod wasm_test;
|
pub mod wasm_test;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2279
src/parser.rs.backup
2279
src/parser.rs.backup
File diff suppressed because it is too large
Load Diff
@ -28,10 +28,11 @@ use nyash_rust::backend::{wasm::WasmBackend, aot::AotBackend};
|
|||||||
#[cfg(feature = "llvm")]
|
#[cfg(feature = "llvm")]
|
||||||
use nyash_rust::backend::{llvm_compile_and_execute};
|
use nyash_rust::backend::{llvm_compile_and_execute};
|
||||||
use std::{fs, process};
|
use std::{fs, process};
|
||||||
|
mod modes;
|
||||||
|
|
||||||
// v2 plugin system imports
|
// v2 plugin system imports
|
||||||
use nyash_rust::runtime::{init_global_loader_v2, get_global_registry, get_global_loader_v2, PluginConfig};
|
use nyash_rust::runtime;
|
||||||
use crate::runtime;
|
use nyash_rust::runner_plugin_init;
|
||||||
|
|
||||||
/// Main execution coordinator
|
/// Main execution coordinator
|
||||||
pub struct NyashRunner {
|
pub struct NyashRunner {
|
||||||
@ -50,7 +51,7 @@ impl NyashRunner {
|
|||||||
runtime::init_global_unified_registry();
|
runtime::init_global_unified_registry();
|
||||||
|
|
||||||
// Try to initialize BID plugins from nyash.toml (best-effort)
|
// Try to initialize BID plugins from nyash.toml (best-effort)
|
||||||
self.init_bid_plugins();
|
runner_plugin_init::init_bid_plugins();
|
||||||
|
|
||||||
// Optional: enable VM stats via CLI flags
|
// Optional: enable VM stats via CLI flags
|
||||||
if self.config.vm_stats {
|
if self.config.vm_stats {
|
||||||
@ -78,38 +79,7 @@ impl NyashRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_bid_plugins(&self) {
|
// init_bid_plugins moved to runner_plugin_init.rs
|
||||||
// v2プラグインシステムを初期化
|
|
||||||
eprintln!("🔍 DEBUG: Initializing v2 plugin system");
|
|
||||||
|
|
||||||
// Try to load nyash.toml configuration
|
|
||||||
if let Ok(()) = init_global_loader_v2("nyash.toml") {
|
|
||||||
println!("🔌 v2 plugin system initialized from nyash.toml");
|
|
||||||
|
|
||||||
// Apply plugin configuration to the box registry
|
|
||||||
let loader = get_global_loader_v2();
|
|
||||||
let loader = loader.read().unwrap();
|
|
||||||
|
|
||||||
if let Some(config) = &loader.config {
|
|
||||||
// Register plugin providers in the box registry
|
|
||||||
let registry = get_global_registry();
|
|
||||||
|
|
||||||
for (lib_name, lib_def) in &config.libraries {
|
|
||||||
for box_name in &lib_def.boxes {
|
|
||||||
eprintln!(" 📦 Registering plugin provider for {}", box_name);
|
|
||||||
// Note: plugin_name is lib_name in v2 system
|
|
||||||
registry.apply_plugin_config(&PluginConfig {
|
|
||||||
plugins: [(box_name.clone(), lib_name.clone())].into(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("✅ v2 plugin system fully configured");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
eprintln!("⚠️ Failed to load nyash.toml - plugins disabled");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute file-based mode with backend selection
|
/// Execute file-based mode with backend selection
|
||||||
fn execute_file_mode(&self, filename: &str) {
|
fn execute_file_mode(&self, filename: &str) {
|
||||||
@ -158,19 +128,31 @@ impl NyashRunner {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
} else if self.config.backend == "vm" {
|
} else if self.config.backend == "vm" {
|
||||||
|
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||||
println!("🚀 Nyash VM Backend - Executing file: {} 🚀", filename);
|
println!("🚀 Nyash VM Backend - Executing file: {} 🚀", filename);
|
||||||
|
}
|
||||||
self.execute_vm_mode(filename);
|
self.execute_vm_mode(filename);
|
||||||
} else if self.config.backend == "llvm" {
|
} else if self.config.backend == "llvm" {
|
||||||
|
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||||
println!("⚡ Nyash LLVM Backend - Executing file: {} ⚡", filename);
|
println!("⚡ Nyash LLVM Backend - Executing file: {} ⚡", filename);
|
||||||
|
}
|
||||||
self.execute_llvm_mode(filename);
|
self.execute_llvm_mode(filename);
|
||||||
} else {
|
} else {
|
||||||
|
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||||
println!("🦀 Nyash Rust Implementation - Executing file: {} 🦀", filename);
|
println!("🦀 Nyash Rust Implementation - Executing file: {} 🦀", filename);
|
||||||
|
}
|
||||||
if let Some(fuel) = self.config.debug_fuel {
|
if let Some(fuel) = self.config.debug_fuel {
|
||||||
|
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||||
println!("🔥 Debug fuel limit: {} iterations", fuel);
|
println!("🔥 Debug fuel limit: {} iterations", fuel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||||
println!("🔥 Debug fuel limit: unlimited");
|
println!("🔥 Debug fuel limit: unlimited");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||||
println!("====================================================");
|
println!("====================================================");
|
||||||
|
}
|
||||||
|
|
||||||
self.execute_nyash_file(filename);
|
self.execute_nyash_file(filename);
|
||||||
}
|
}
|
||||||
|
|||||||
50
src/runner/modes/bench.rs
Normal file
50
src/runner/modes/bench.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use super::super::NyashRunner;
|
||||||
|
use nyash_rust::{parser::NyashParser, interpreter::NyashInterpreter, box_factory::builtin::BuiltinGroups, mir::MirCompiler, backend::VM};
|
||||||
|
|
||||||
|
impl NyashRunner {
|
||||||
|
/// Execute benchmark mode (split)
|
||||||
|
pub(crate) fn execute_benchmark_mode(&self) {
|
||||||
|
println!("🏁 Running benchmark mode with {} iterations", self.config.iterations);
|
||||||
|
let test_code = r#"
|
||||||
|
local x
|
||||||
|
x = 42
|
||||||
|
local y
|
||||||
|
y = x + 58
|
||||||
|
return y
|
||||||
|
"#;
|
||||||
|
|
||||||
|
println!("\n🧪 Test code:\n{}", test_code);
|
||||||
|
|
||||||
|
// Interpreter
|
||||||
|
println!("\n⚡ Interpreter Backend:");
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
for _ in 0..self.config.iterations {
|
||||||
|
if let Ok(ast) = NyashParser::parse_from_string(test_code) {
|
||||||
|
let mut interp = NyashInterpreter::new_with_groups(BuiltinGroups::native_full());
|
||||||
|
let _ = interp.execute(ast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let interpreter_time = start.elapsed();
|
||||||
|
println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, interpreter_time, self.config.iterations as f64 / interpreter_time.as_secs_f64());
|
||||||
|
|
||||||
|
// VM
|
||||||
|
println!("\n🚀 VM Backend:");
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
for _ in 0..self.config.iterations {
|
||||||
|
if let Ok(ast) = NyashParser::parse_from_string(test_code) {
|
||||||
|
let mut mc = MirCompiler::new();
|
||||||
|
if let Ok(cr) = mc.compile(ast) {
|
||||||
|
let mut vm = VM::new();
|
||||||
|
let _ = vm.execute_module(&cr.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let vm_time = start.elapsed();
|
||||||
|
println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, vm_time, self.config.iterations as f64 / vm_time.as_secs_f64());
|
||||||
|
|
||||||
|
// Summary
|
||||||
|
let speedup = interpreter_time.as_secs_f64() / vm_time.as_secs_f64();
|
||||||
|
println!("\n📊 Performance Summary:\n VM is {:.2}x {} than Interpreter", if speedup > 1.0 { speedup } else { 1.0 / speedup }, if speedup > 1.0 { "faster" } else { "slower" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
70
src/runner/modes/llvm.rs
Normal file
70
src/runner/modes/llvm.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
use super::super::NyashRunner;
|
||||||
|
use nyash_rust::{parser::NyashParser, mir::{MirCompiler, MirInstruction}, box_trait::IntegerBox};
|
||||||
|
use std::{fs, process};
|
||||||
|
|
||||||
|
impl NyashRunner {
|
||||||
|
/// Execute LLVM mode (split)
|
||||||
|
pub(crate) fn execute_llvm_mode(&self, filename: &str) {
|
||||||
|
// Read the file
|
||||||
|
let code = match fs::read_to_string(filename) {
|
||||||
|
Ok(content) => content,
|
||||||
|
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse to AST
|
||||||
|
let ast = match NyashParser::parse_from_string(&code) {
|
||||||
|
Ok(ast) => ast,
|
||||||
|
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compile to MIR
|
||||||
|
let mut mir_compiler = MirCompiler::new();
|
||||||
|
let compile_result = match mir_compiler.compile(ast) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("📊 MIR Module compiled successfully!");
|
||||||
|
println!("📊 Functions: {}", compile_result.module.functions.len());
|
||||||
|
|
||||||
|
// Execute via LLVM backend (mock or real)
|
||||||
|
#[cfg(feature = "llvm")]
|
||||||
|
{
|
||||||
|
use nyash_rust::backend::llvm_compile_and_execute;
|
||||||
|
let temp_path = "nyash_llvm_temp";
|
||||||
|
match llvm_compile_and_execute(&compile_result.module, temp_path) {
|
||||||
|
Ok(result) => {
|
||||||
|
if let Some(int_result) = result.as_any().downcast_ref::<IntegerBox>() {
|
||||||
|
let exit_code = int_result.value;
|
||||||
|
println!("✅ LLVM execution completed!");
|
||||||
|
println!("📊 Exit code: {}", exit_code);
|
||||||
|
process::exit(exit_code as i32);
|
||||||
|
} else {
|
||||||
|
println!("✅ LLVM execution completed (non-integer result)!");
|
||||||
|
println!("📊 Result: {}", result.to_string_box().value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => { eprintln!("❌ LLVM execution error: {}", e); process::exit(1); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "llvm"))]
|
||||||
|
{
|
||||||
|
println!("🔧 Mock LLVM Backend Execution:");
|
||||||
|
println!(" Build with --features llvm for real compilation.");
|
||||||
|
if let Some(main_func) = compile_result.module.functions.get("Main.main") {
|
||||||
|
for (_bid, block) in &main_func.blocks {
|
||||||
|
for inst in &block.instructions {
|
||||||
|
match inst {
|
||||||
|
MirInstruction::Return { value: Some(_) } => { println!("✅ Mock exit code: 42"); process::exit(42); }
|
||||||
|
MirInstruction::Return { value: None } => { println!("✅ Mock exit code: 0"); process::exit(0); }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("✅ Mock exit code: 0");
|
||||||
|
process::exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
49
src/runner/modes/mir.rs
Normal file
49
src/runner/modes/mir.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use super::super::NyashRunner;
|
||||||
|
use nyash_rust::{parser::NyashParser, mir::{MirCompiler, MirPrinter}};
|
||||||
|
use std::{fs, process};
|
||||||
|
|
||||||
|
impl NyashRunner {
|
||||||
|
/// Execute MIR compilation and processing mode (split)
|
||||||
|
pub(crate) fn execute_mir_mode(&self, filename: &str) {
|
||||||
|
// Read the file
|
||||||
|
let code = match fs::read_to_string(filename) {
|
||||||
|
Ok(content) => content,
|
||||||
|
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse to AST
|
||||||
|
let ast = match NyashParser::parse_from_string(&code) {
|
||||||
|
Ok(ast) => ast,
|
||||||
|
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compile to MIR (opt passes configurable)
|
||||||
|
let mut mir_compiler = MirCompiler::with_options(!self.config.no_optimize);
|
||||||
|
let compile_result = match mir_compiler.compile(ast) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Verify MIR if requested
|
||||||
|
if self.config.verify_mir {
|
||||||
|
println!("🔍 Verifying MIR...");
|
||||||
|
match &compile_result.verification_result {
|
||||||
|
Ok(()) => println!("✅ MIR verification passed!"),
|
||||||
|
Err(errors) => {
|
||||||
|
eprintln!("❌ MIR verification failed:");
|
||||||
|
for error in errors { eprintln!(" • {}", error); }
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump MIR if requested
|
||||||
|
if self.config.dump_mir {
|
||||||
|
let mut printer = if self.config.mir_verbose { MirPrinter::verbose() } else { MirPrinter::new() };
|
||||||
|
if self.config.mir_verbose_effects { printer.set_show_effects_inline(true); }
|
||||||
|
println!("🚀 MIR Output for {}:", filename);
|
||||||
|
println!("{}", printer.print_module(&compile_result.module));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
6
src/runner/modes/mod.rs
Normal file
6
src/runner/modes/mod.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
pub mod mir;
|
||||||
|
pub mod vm;
|
||||||
|
pub mod llvm;
|
||||||
|
pub mod bench;
|
||||||
|
// WASM/AOT modes remain in runner.rs for now (feature-gated)
|
||||||
|
|
||||||
84
src/runner/modes/vm.rs
Normal file
84
src/runner/modes/vm.rs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
use super::super::NyashRunner;
|
||||||
|
use nyash_rust::{parser::NyashParser, mir::MirCompiler, backend::VM, runtime::{NyashRuntime, NyashRuntimeBuilder}, ast::ASTNode, core::model::BoxDeclaration as CoreBoxDecl, interpreter::SharedState, box_factory::{builtin::BuiltinGroups, user_defined::UserDefinedBoxFactory}};
|
||||||
|
use std::{fs, process};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
impl NyashRunner {
|
||||||
|
/// Execute VM mode (split)
|
||||||
|
pub(crate) fn execute_vm_mode(&self, filename: &str) {
|
||||||
|
// Read the file
|
||||||
|
let code = match fs::read_to_string(filename) {
|
||||||
|
Ok(content) => content,
|
||||||
|
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse to AST
|
||||||
|
let ast = match NyashParser::parse_from_string(&code) {
|
||||||
|
Ok(ast) => ast,
|
||||||
|
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prepare runtime and collect Box declarations for VM user-defined types
|
||||||
|
let runtime = {
|
||||||
|
let rt = NyashRuntimeBuilder::new()
|
||||||
|
.with_builtin_groups(BuiltinGroups::native_full())
|
||||||
|
.build();
|
||||||
|
self.collect_box_declarations(&ast, &rt);
|
||||||
|
// Register UserDefinedBoxFactory backed by the same declarations
|
||||||
|
let mut shared = SharedState::new();
|
||||||
|
shared.box_declarations = rt.box_declarations.clone();
|
||||||
|
let udf = Arc::new(UserDefinedBoxFactory::new(shared));
|
||||||
|
if let Ok(mut reg) = rt.box_registry.lock() { reg.register(udf); }
|
||||||
|
rt
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compile to MIR (opt passes configurable)
|
||||||
|
let mut mir_compiler = MirCompiler::with_options(!self.config.no_optimize);
|
||||||
|
let compile_result = match mir_compiler.compile(ast) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Execute with VM using prepared runtime
|
||||||
|
let mut vm = VM::with_runtime(runtime);
|
||||||
|
match vm.execute_module(&compile_result.module) {
|
||||||
|
Ok(result) => {
|
||||||
|
println!("✅ VM execution completed successfully!");
|
||||||
|
println!("Result: {:?}", result);
|
||||||
|
},
|
||||||
|
Err(e) => { eprintln!("❌ VM execution error: {}", e); process::exit(1); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Collect Box declarations from AST and register into runtime
|
||||||
|
pub(crate) fn collect_box_declarations(&self, ast: &ASTNode, runtime: &NyashRuntime) {
|
||||||
|
fn walk(node: &ASTNode, runtime: &NyashRuntime) {
|
||||||
|
match node {
|
||||||
|
ASTNode::Program { statements, .. } => { for st in statements { walk(st, runtime); } }
|
||||||
|
ASTNode::FunctionDeclaration { body, .. } => { for st in body { walk(st, runtime); } }
|
||||||
|
ASTNode::BoxDeclaration { name, fields, public_fields, private_fields, methods, constructors, init_fields, weak_fields, is_interface, extends, implements, type_parameters, .. } => {
|
||||||
|
for (_mname, mnode) in methods { walk(mnode, runtime); }
|
||||||
|
for (_ckey, cnode) in constructors { walk(cnode, runtime); }
|
||||||
|
let decl = CoreBoxDecl {
|
||||||
|
name: name.clone(),
|
||||||
|
fields: fields.clone(),
|
||||||
|
public_fields: public_fields.clone(),
|
||||||
|
private_fields: private_fields.clone(),
|
||||||
|
methods: methods.clone(),
|
||||||
|
constructors: constructors.clone(),
|
||||||
|
init_fields: init_fields.clone(),
|
||||||
|
weak_fields: weak_fields.clone(),
|
||||||
|
is_interface: *is_interface,
|
||||||
|
extends: extends.clone(),
|
||||||
|
implements: implements.clone(),
|
||||||
|
type_parameters: type_parameters.clone(),
|
||||||
|
};
|
||||||
|
if let Ok(mut map) = runtime.box_declarations.write() { map.insert(name.clone(), decl); }
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
walk(ast, runtime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
36
src/runner_plugin_init.rs
Normal file
36
src/runner_plugin_init.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*!
|
||||||
|
* Runner plugin initialization (extracted from runner.rs)
|
||||||
|
*
|
||||||
|
* Purpose: Initialize v2 plugin system from nyash.toml and apply config
|
||||||
|
* Behavior: Quiet by default; use NYASH_CLI_VERBOSE=1 or NYASH_DEBUG_PLUGIN=1 for logs
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::runtime::{init_global_loader_v2, get_global_registry, get_global_loader_v2, PluginConfig};
|
||||||
|
|
||||||
|
pub fn init_bid_plugins() {
|
||||||
|
let cli_verbose = std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1");
|
||||||
|
let plugin_debug = std::env::var("NYASH_DEBUG_PLUGIN").ok().as_deref() == Some("1");
|
||||||
|
if plugin_debug { eprintln!("🔍 DEBUG: Initializing v2 plugin system"); }
|
||||||
|
|
||||||
|
if let Ok(()) = init_global_loader_v2("nyash.toml") {
|
||||||
|
if plugin_debug || cli_verbose {
|
||||||
|
println!("🔌 v2 plugin system initialized from nyash.toml");
|
||||||
|
}
|
||||||
|
let loader = get_global_loader_v2();
|
||||||
|
let loader = loader.read().unwrap();
|
||||||
|
if let Some(config) = &loader.config {
|
||||||
|
let registry = get_global_registry();
|
||||||
|
for (lib_name, lib_def) in &config.libraries {
|
||||||
|
for box_name in &lib_def.boxes {
|
||||||
|
if plugin_debug { eprintln!(" 📦 Registering plugin provider for {}", box_name); }
|
||||||
|
registry.apply_plugin_config(&PluginConfig { plugins: [(box_name.clone(), lib_name.clone())].into(), });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if plugin_debug || cli_verbose {
|
||||||
|
println!("✅ v2 plugin system fully configured");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if plugin_debug || cli_verbose {
|
||||||
|
eprintln!("⚠️ Failed to load nyash.toml - plugins disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
434
ta.txt
434
ta.txt
@ -1,434 +0,0 @@
|
|||||||
warning: unused imports: `BoolBox`, `IntegerBox`, and `StringBox`
|
|
||||||
--> src/ast.rs:885:28
|
|
||||||
|
|
|
||||||
885 | use crate::box_trait::{StringBox, IntegerBox, BoolBox};
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_imports)]` on by default
|
|
||||||
|
|
||||||
warning: unused import: `Mutex`
|
|
||||||
--> src/instance_v2.rs:387:26
|
|
||||||
|
|
|
||||||
387 | use std::sync::{Arc, Mutex};
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `BasicBlockIdGenerator`, `BasicBlock`, `CompareOp`, `EffectMask`, `MirFunction`, and `ValueIdGenerator`
|
|
||||||
--> src/mir/loop_builder.rs:9:21
|
|
||||||
|
|
|
||||||
9 | MirInstruction, BasicBlock, BasicBlockId, MirFunction, ValueId,
|
|
||||||
| ^^^^^^^^^^ ^^^^^^^^^^^
|
|
||||||
10 | ConstValue, CompareOp, BasicBlockIdGenerator, ValueIdGenerator, EffectMask
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `HashSet`
|
|
||||||
--> src/mir/loop_builder.rs:13:33
|
|
||||||
|
|
|
||||||
13 | use std::collections::{HashMap, HashSet};
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `BasicBlock`
|
|
||||||
--> src/mir/verification.rs:311:75
|
|
||||||
|
|
|
||||||
311 | use crate::mir::{MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
--> src/backend/mod.rs:13:7
|
|
||||||
|
|
|
||||||
13 | #[cfg(feature = "llvm")]
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
|
|
||||||
= help: consider adding `llvm` as a feature in `Cargo.toml`
|
|
||||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
|
|
||||||
= note: `#[warn(unexpected_cfgs)]` on by default
|
|
||||||
|
|
||||||
warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
--> src/backend/mod.rs:23:7
|
|
||||||
|
|
|
||||||
23 | #[cfg(feature = "llvm")]
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
|
|
||||||
= help: consider adding `llvm` as a feature in `Cargo.toml`
|
|
||||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
|
|
||||||
|
|
||||||
warning: unused imports: `BasicBlock`, `EffectMask`, `FunctionSignature`, `MirFunction`, `MirModule`, and `MirType`
|
|
||||||
--> src/backend/vm.rs:860:22
|
|
||||||
|
|
|
||||||
860 | use crate::mir::{MirModule, MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `MirInstruction`
|
|
||||||
--> src/backend/vm_phi.rs:9:41
|
|
||||||
|
|
|
||||||
9 | use crate::mir::{BasicBlockId, ValueId, MirInstruction};
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `super::Usize`
|
|
||||||
--> src/bid/types.rs:1:5
|
|
||||||
|
|
|
||||||
1 | use super::Usize;
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `std::os::raw::c_char`
|
|
||||||
--> src/bid/plugin_api.rs:2:5
|
|
||||||
|
|
|
||||||
2 | use std::os::raw::c_char;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `NyashHostVtable`, `NyashMethodInfo`, and `NyashPluginInfo`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:7:18
|
|
||||||
|
|
|
||||||
7 | use crate::bid::{NyashPluginInfo, NyashMethodInfo, NyashHostVtable};
|
|
||||||
| ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `SeekFrom` and `Seek`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:10:28
|
|
||||||
|
|
|
||||||
10 | use std::io::{Read, Write, Seek, SeekFrom};
|
|
||||||
| ^^^^ ^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `c_char` and `c_void`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:11:20
|
|
||||||
|
|
|
||||||
11 | use std::os::raw::{c_char, c_void};
|
|
||||||
| ^^^^^^ ^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `CStr` and `CString`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:13:16
|
|
||||||
|
|
|
||||||
13 | use std::ffi::{CStr, CString};
|
|
||||||
| ^^^^ ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `std::ffi::c_void`
|
|
||||||
--> src/bid/loader.rs:3:5
|
|
||||||
|
|
|
||||||
3 | use std::ffi::c_void;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `TlvDecoder` and `TlvEncoder`
|
|
||||||
--> src/bid/generic_plugin_box.rs:2:23
|
|
||||||
|
|
|
||||||
2 | use crate::bid::tlv::{TlvEncoder, TlvDecoder};
|
|
||||||
| ^^^^^^^^^^ ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `crate::bid::types::BidTag`
|
|
||||||
--> src/bid/generic_plugin_box.rs:3:5
|
|
||||||
|
|
|
||||||
3 | use crate::bid::types::BidTag;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `BoxBase`
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:7:43
|
|
||||||
|
|
|
||||||
7 | use crate::box_trait::{NyashBox, BoxCore, BoxBase, StringBox};
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `std::ffi::c_void`
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:11:5
|
|
||||||
|
|
|
||||||
11 | use std::ffi::c_void;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `BidHandle` and `BoxTypeId`
|
|
||||||
--> src/runtime/tests.rs:10:22
|
|
||||||
|
|
|
||||||
10 | use crate::bid::{BidHandle, BoxTypeId};
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused variable: `registry`
|
|
||||||
--> src/box_factory/plugin.rs:53:13
|
|
||||||
|
|
|
||||||
53 | let registry = get_global_registry();
|
|
||||||
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_registry`
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_variables)]` on by default
|
|
||||||
|
|
||||||
warning: unused variable: `args`
|
|
||||||
--> src/instance_v2.rs:147:28
|
|
||||||
|
|
|
||||||
147 | pub fn init(&mut self, args: &[Box<dyn NyashBox>]) -> Result<(), String> {
|
|
||||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
|
|
||||||
|
|
||||||
warning: unused variable: `nyash_value`
|
|
||||||
--> src/instance_v2.rs:289:21
|
|
||||||
|
|
|
||||||
289 | if let Some(nyash_value) = self.fields_ng.lock().unwrap().get(field_name) {
|
|
||||||
| ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_nyash_value`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/mir/basic_block.rs:314:13
|
|
||||||
|
|
|
||||||
314 | let mut bb = BasicBlock::new(bb_id);
|
|
||||||
| ----^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_mut)]` on by default
|
|
||||||
|
|
||||||
warning: unused variable: `block_id`
|
|
||||||
--> src/mir/loop_builder.rs:246:39
|
|
||||||
|
|
|
||||||
246 | fn mark_block_unsealed(&mut self, block_id: BasicBlockId) -> Result<(), String> {
|
|
||||||
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
|
|
||||||
|
|
||||||
warning: unused variable: `block_id`
|
|
||||||
--> src/mir/loop_builder.rs:273:49
|
|
||||||
|
|
|
||||||
273 | fn get_variable_at_block(&self, name: &str, block_id: BasicBlockId) -> Option<ValueId> {
|
|
||||||
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
|
|
||||||
|
|
||||||
warning: unused variable: `child`
|
|
||||||
--> src/mir/ownership_verifier_simple.rs:313:13
|
|
||||||
|
|
|
||||||
313 | let child = value_gen.next();
|
|
||||||
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_child`
|
|
||||||
|
|
||||||
warning: unused variable: `dst`
|
|
||||||
--> src/backend/vm_phi.rs:48:9
|
|
||||||
|
|
|
||||||
48 | dst: ValueId,
|
|
||||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_dst`
|
|
||||||
|
|
||||||
warning: unused variable: `f`
|
|
||||||
--> src/bid/plugin_api.rs:167:36
|
|
||||||
|
|
|
||||||
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/bid/plugin_api.rs:167:26
|
|
||||||
|
|
|
||||||
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
|
|
||||||
| ----^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: unused variable: `f`
|
|
||||||
--> src/bid/plugin_api.rs:176:35
|
|
||||||
|
|
|
||||||
176 | pub fn with_free<F>(mut self, f: F) -> Self
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/bid/plugin_api.rs:176:25
|
|
||||||
|
|
|
||||||
176 | pub fn with_free<F>(mut self, f: F) -> Self
|
|
||||||
| ----^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: unused variable: `f`
|
|
||||||
--> src/bid/plugin_api.rs:183:34
|
|
||||||
|
|
|
||||||
183 | pub fn with_log<F>(mut self, f: F) -> Self
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/bid/plugin_api.rs:183:24
|
|
||||||
|
|
|
||||||
183 | pub fn with_log<F>(mut self, f: F) -> Self
|
|
||||||
| ----^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: unused variable: `args`
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:236:46
|
|
||||||
|
|
|
||||||
236 | pub fn create_box(&self, box_type: &str, args: &[Box<dyn NyashBox>]) -> BidResult<Box<dyn NyashBox>> {
|
|
||||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/tests/box_tests.rs:11:13
|
|
||||||
|
|
|
||||||
11 | let mut array = ArrayBox::new();
|
|
||||||
| ----^^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/tests/box_tests.rs:90:13
|
|
||||||
|
|
|
||||||
90 | let mut stream = NyashStreamBox::from_data(vec![72, 101, 108, 108, 111]); // "Hello"
|
|
||||||
| ----^^^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: type `FileMode` is more private than the item `FileBoxRegistry::open`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:44:5
|
|
||||||
|
|
|
||||||
44 | pub fn open(&mut self, path: &str, mode: FileMode) -> Result<BidHandle, std::io::Error> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method `FileBoxRegistry::open` is reachable at visibility `pub`
|
|
||||||
|
|
|
||||||
note: but type `FileMode` is only usable at visibility `pub(self)`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:29:1
|
|
||||||
|
|
|
||||||
29 | enum FileMode {
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
= note: `#[warn(private_interfaces)]` on by default
|
|
||||||
|
|
||||||
warning: field `block_var_maps` is never read
|
|
||||||
--> src/mir/loop_builder.rs:35:5
|
|
||||||
|
|
|
||||||
27 | pub struct LoopBuilder<'a> {
|
|
||||||
| ----------- field in this struct
|
|
||||||
...
|
|
||||||
35 | block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>>,
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(dead_code)]` on by default
|
|
||||||
|
|
||||||
warning: fields `type_name_holder` and `method_holders` are never read
|
|
||||||
--> src/bid/metadata.rs:148:5
|
|
||||||
|
|
|
||||||
143 | pub struct PluginMetadata {
|
|
||||||
| -------------- fields in this struct
|
|
||||||
...
|
|
||||||
148 | type_name_holder: Option<CString>,
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
149 | method_holders: Vec<(NyashMethodInfo, CString)>,
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: fields `path` and `mode` are never read
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:24:5
|
|
||||||
|
|
|
||||||
22 | struct FileBoxState {
|
|
||||||
| ------------ fields in this struct
|
|
||||||
23 | file: File,
|
|
||||||
24 | path: String,
|
|
||||||
| ^^^^
|
|
||||||
25 | mode: FileMode,
|
|
||||||
| ^^^^
|
|
||||||
|
|
||||||
warning: fields `box_types` and `init_fn` are never read
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:20:5
|
|
||||||
|
|
|
||||||
15 | pub struct LoadedPluginV2 {
|
|
||||||
| -------------- fields in this struct
|
|
||||||
...
|
|
||||||
20 | box_types: Vec<String>,
|
|
||||||
| ^^^^^^^^^
|
|
||||||
...
|
|
||||||
23 | init_fn: Option<unsafe extern "C" fn() -> i32>,
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:62:9
|
|
||||||
|
|
|
||||||
62 | self.add_predecessor(header_id, preheader_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
= note: `#[warn(unused_must_use)]` on by default
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
62 | let _ = self.add_predecessor(header_id, preheader_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:66:9
|
|
||||||
|
|
|
||||||
66 | self.mark_block_unsealed(header_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
66 | let _ = self.mark_block_unsealed(header_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:78:9
|
|
||||||
|
|
|
||||||
78 | self.add_predecessor(body_id, header_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
78 | let _ = self.add_predecessor(body_id, header_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:79:9
|
|
||||||
|
|
|
||||||
79 | self.add_predecessor(after_loop_id, header_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
79 | let _ = self.add_predecessor(after_loop_id, header_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:93:9
|
|
||||||
|
|
|
||||||
93 | self.add_predecessor(header_id, latch_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
93 | let _ = self.add_predecessor(header_id, latch_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: creating a shared reference to mutable static
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:102:12
|
|
||||||
|
|
|
||||||
102 | if FILEBOX_REGISTRY.is_none() {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
|
||||||
|
|
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
|
|
||||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
|
||||||
= note: `#[warn(static_mut_refs)]` on by default
|
|
||||||
|
|
||||||
warning: creating a shared reference to mutable static
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:105:9
|
|
||||||
|
|
|
||||||
105 | FILEBOX_REGISTRY.as_ref().unwrap().clone()
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
|
||||||
|
|
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
|
|
||||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
|
||||||
|
|
||||||
warning: `nyash-rust` (lib test) generated 50 warnings (run `cargo fix --lib -p nyash-rust --tests` to apply 25 suggestions)
|
|
||||||
Finished `test` profile [unoptimized + debuginfo] target(s) in 1.81s
|
|
||||||
Running unittests src/lib.rs (target/debug/deps/nyash_rust-027bd4c76143e77b)
|
|
||||||
|
|
||||||
running 1 test
|
|
||||||
🔍 DEBUG: Starting interpreter execution...
|
|
||||||
🔍 DEBUG: execute_node called with node type: Program
|
|
||||||
🔍 DEBUG: Executing program with 1 statements
|
|
||||||
🔍 DEBUG: Executing statement 1 of 1: Assignment
|
|
||||||
🔍 execute_statement called with node type: "Assignment"
|
|
||||||
🔍 About to call execute_assignment...
|
|
||||||
🔍 execute_assignment called, evaluating value expression...
|
|
||||||
🔍 execute_new called for class: IntegerBox, with 1 arguments
|
|
||||||
🔍 Trying unified registry for class: IntegerBox
|
|
||||||
🏭 Unified registry created: IntegerBox
|
|
||||||
🔍 execute_new called for class: IntegerBox, with 1 arguments
|
|
||||||
🔍 Trying unified registry for class: IntegerBox
|
|
||||||
🏭 Unified registry created: IntegerBox
|
|
||||||
🔧 execute_binary_op: op=Add, left=IntegerBox, right=IntegerBox
|
|
||||||
🔍 try_add_operation: left=IntegerBox, right=IntegerBox
|
|
||||||
🔍 After unwrap: left=IntegerBox, right=IntegerBox
|
|
||||||
🔍 Checking StringBox downcast...
|
|
||||||
🔍 StringBox downcast FAILED!
|
|
||||||
❌ Interpreter error: Invalid operation: Addition not supported between IntegerBox and IntegerBox
|
|
||||||
🔍 DEBUG: Interpreter execution completed
|
|
||||||
|
|
||||||
thread 'interpreter::core::tests::test_arithmetic' panicked at src/interpreter/core.rs:590:34:
|
|
||||||
called `Result::unwrap()` on an `Err` value: InvalidOperation { message: "Addition not supported between IntegerBox and IntegerBox" }
|
|
||||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
|
||||||
test interpreter::core::tests::test_arithmetic ... FAILED
|
|
||||||
|
|
||||||
failures:
|
|
||||||
|
|
||||||
failures:
|
|
||||||
interpreter::core::tests::test_arithmetic
|
|
||||||
|
|
||||||
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 155 filtered out; finished in 0.19s
|
|
||||||
|
|
||||||
error: test failed, to rerun pass `--lib`
|
|
||||||
1108
test_out2.txt
1108
test_out2.txt
File diff suppressed because it is too large
Load Diff
1104
test_out3.txt
1104
test_out3.txt
File diff suppressed because it is too large
Load Diff
405
test_out4.txt
405
test_out4.txt
@ -1,405 +0,0 @@
|
|||||||
Compiling nyash-rust v0.1.0 (/mnt/c/git/nyash-project/nyash)
|
|
||||||
warning: unused imports: `BoolBox`, `IntegerBox`, and `StringBox`
|
|
||||||
--> src/ast.rs:885:28
|
|
||||||
|
|
|
||||||
885 | use crate::box_trait::{StringBox, IntegerBox, BoolBox};
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_imports)]` on by default
|
|
||||||
|
|
||||||
warning: unused import: `Mutex`
|
|
||||||
--> src/instance_v2.rs:387:26
|
|
||||||
|
|
|
||||||
387 | use std::sync::{Arc, Mutex};
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `BasicBlockIdGenerator`, `BasicBlock`, `CompareOp`, `EffectMask`, `MirFunction`, and `ValueIdGenerator`
|
|
||||||
--> src/mir/loop_builder.rs:9:21
|
|
||||||
|
|
|
||||||
9 | MirInstruction, BasicBlock, BasicBlockId, MirFunction, ValueId,
|
|
||||||
| ^^^^^^^^^^ ^^^^^^^^^^^
|
|
||||||
10 | ConstValue, CompareOp, BasicBlockIdGenerator, ValueIdGenerator, EffectMask
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `HashSet`
|
|
||||||
--> src/mir/loop_builder.rs:13:33
|
|
||||||
|
|
|
||||||
13 | use std::collections::{HashMap, HashSet};
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `BasicBlock`
|
|
||||||
--> src/mir/verification.rs:311:75
|
|
||||||
|
|
|
||||||
311 | use crate::mir::{MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
--> src/backend/mod.rs:13:7
|
|
||||||
|
|
|
||||||
13 | #[cfg(feature = "llvm")]
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
|
|
||||||
= help: consider adding `llvm` as a feature in `Cargo.toml`
|
|
||||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
|
|
||||||
= note: `#[warn(unexpected_cfgs)]` on by default
|
|
||||||
|
|
||||||
warning: unexpected `cfg` condition value: `llvm`
|
|
||||||
--> src/backend/mod.rs:23:7
|
|
||||||
|
|
|
||||||
23 | #[cfg(feature = "llvm")]
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
|
|
||||||
= help: consider adding `llvm` as a feature in `Cargo.toml`
|
|
||||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
|
|
||||||
|
|
||||||
warning: unused imports: `BasicBlock`, `EffectMask`, `FunctionSignature`, `MirFunction`, `MirModule`, and `MirType`
|
|
||||||
--> src/backend/vm.rs:860:22
|
|
||||||
|
|
|
||||||
860 | use crate::mir::{MirModule, MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `MirInstruction`
|
|
||||||
--> src/backend/vm_phi.rs:9:41
|
|
||||||
|
|
|
||||||
9 | use crate::mir::{BasicBlockId, ValueId, MirInstruction};
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `super::Usize`
|
|
||||||
--> src/bid/types.rs:1:5
|
|
||||||
|
|
|
||||||
1 | use super::Usize;
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `std::os::raw::c_char`
|
|
||||||
--> src/bid/plugin_api.rs:2:5
|
|
||||||
|
|
|
||||||
2 | use std::os::raw::c_char;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `NyashHostVtable`, `NyashMethodInfo`, and `NyashPluginInfo`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:7:18
|
|
||||||
|
|
|
||||||
7 | use crate::bid::{NyashPluginInfo, NyashMethodInfo, NyashHostVtable};
|
|
||||||
| ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `SeekFrom` and `Seek`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:10:28
|
|
||||||
|
|
|
||||||
10 | use std::io::{Read, Write, Seek, SeekFrom};
|
|
||||||
| ^^^^ ^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `c_char` and `c_void`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:11:20
|
|
||||||
|
|
|
||||||
11 | use std::os::raw::{c_char, c_void};
|
|
||||||
| ^^^^^^ ^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `CStr` and `CString`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:13:16
|
|
||||||
|
|
|
||||||
13 | use std::ffi::{CStr, CString};
|
|
||||||
| ^^^^ ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `std::ffi::c_void`
|
|
||||||
--> src/bid/loader.rs:3:5
|
|
||||||
|
|
|
||||||
3 | use std::ffi::c_void;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `TlvDecoder` and `TlvEncoder`
|
|
||||||
--> src/bid/generic_plugin_box.rs:2:23
|
|
||||||
|
|
|
||||||
2 | use crate::bid::tlv::{TlvEncoder, TlvDecoder};
|
|
||||||
| ^^^^^^^^^^ ^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `crate::bid::types::BidTag`
|
|
||||||
--> src/bid/generic_plugin_box.rs:3:5
|
|
||||||
|
|
|
||||||
3 | use crate::bid::types::BidTag;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `BoxBase`
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:7:43
|
|
||||||
|
|
|
||||||
7 | use crate::box_trait::{NyashBox, BoxCore, BoxBase, StringBox};
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused import: `std::ffi::c_void`
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:11:5
|
|
||||||
|
|
|
||||||
11 | use std::ffi::c_void;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused imports: `BidHandle` and `BoxTypeId`
|
|
||||||
--> src/runtime/tests.rs:10:22
|
|
||||||
|
|
|
||||||
10 | use crate::bid::{BidHandle, BoxTypeId};
|
|
||||||
| ^^^^^^^^^ ^^^^^^^^^
|
|
||||||
|
|
||||||
warning: unused variable: `registry`
|
|
||||||
--> src/box_factory/plugin.rs:53:13
|
|
||||||
|
|
|
||||||
53 | let registry = get_global_registry();
|
|
||||||
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_registry`
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_variables)]` on by default
|
|
||||||
|
|
||||||
warning: unused variable: `args`
|
|
||||||
--> src/instance_v2.rs:147:28
|
|
||||||
|
|
|
||||||
147 | pub fn init(&mut self, args: &[Box<dyn NyashBox>]) -> Result<(), String> {
|
|
||||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
|
|
||||||
|
|
||||||
warning: unused variable: `nyash_value`
|
|
||||||
--> src/instance_v2.rs:289:21
|
|
||||||
|
|
|
||||||
289 | if let Some(nyash_value) = self.fields_ng.lock().unwrap().get(field_name) {
|
|
||||||
| ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_nyash_value`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/mir/basic_block.rs:314:13
|
|
||||||
|
|
|
||||||
314 | let mut bb = BasicBlock::new(bb_id);
|
|
||||||
| ----^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_mut)]` on by default
|
|
||||||
|
|
||||||
warning: unused variable: `block_id`
|
|
||||||
--> src/mir/loop_builder.rs:246:39
|
|
||||||
|
|
|
||||||
246 | fn mark_block_unsealed(&mut self, block_id: BasicBlockId) -> Result<(), String> {
|
|
||||||
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
|
|
||||||
|
|
||||||
warning: unused variable: `block_id`
|
|
||||||
--> src/mir/loop_builder.rs:273:49
|
|
||||||
|
|
|
||||||
273 | fn get_variable_at_block(&self, name: &str, block_id: BasicBlockId) -> Option<ValueId> {
|
|
||||||
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
|
|
||||||
|
|
||||||
warning: unused variable: `child`
|
|
||||||
--> src/mir/ownership_verifier_simple.rs:313:13
|
|
||||||
|
|
|
||||||
313 | let child = value_gen.next();
|
|
||||||
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_child`
|
|
||||||
|
|
||||||
warning: unused variable: `dst`
|
|
||||||
--> src/backend/vm_phi.rs:48:9
|
|
||||||
|
|
|
||||||
48 | dst: ValueId,
|
|
||||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_dst`
|
|
||||||
|
|
||||||
warning: unused variable: `f`
|
|
||||||
--> src/bid/plugin_api.rs:167:36
|
|
||||||
|
|
|
||||||
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/bid/plugin_api.rs:167:26
|
|
||||||
|
|
|
||||||
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
|
|
||||||
| ----^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: unused variable: `f`
|
|
||||||
--> src/bid/plugin_api.rs:176:35
|
|
||||||
|
|
|
||||||
176 | pub fn with_free<F>(mut self, f: F) -> Self
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/bid/plugin_api.rs:176:25
|
|
||||||
|
|
|
||||||
176 | pub fn with_free<F>(mut self, f: F) -> Self
|
|
||||||
| ----^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: unused variable: `f`
|
|
||||||
--> src/bid/plugin_api.rs:183:34
|
|
||||||
|
|
|
||||||
183 | pub fn with_log<F>(mut self, f: F) -> Self
|
|
||||||
| ^ help: if this is intentional, prefix it with an underscore: `_f`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/bid/plugin_api.rs:183:24
|
|
||||||
|
|
|
||||||
183 | pub fn with_log<F>(mut self, f: F) -> Self
|
|
||||||
| ----^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: unused variable: `args`
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:236:46
|
|
||||||
|
|
|
||||||
236 | pub fn create_box(&self, box_type: &str, args: &[Box<dyn NyashBox>]) -> BidResult<Box<dyn NyashBox>> {
|
|
||||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/tests/box_tests.rs:11:13
|
|
||||||
|
|
|
||||||
11 | let mut array = ArrayBox::new();
|
|
||||||
| ----^^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: variable does not need to be mutable
|
|
||||||
--> src/tests/box_tests.rs:90:13
|
|
||||||
|
|
|
||||||
90 | let mut stream = NyashStreamBox::from_data(vec![72, 101, 108, 108, 111]); // "Hello"
|
|
||||||
| ----^^^^^^
|
|
||||||
| |
|
|
||||||
| help: remove this `mut`
|
|
||||||
|
|
||||||
warning: type `FileMode` is more private than the item `FileBoxRegistry::open`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:44:5
|
|
||||||
|
|
|
||||||
44 | pub fn open(&mut self, path: &str, mode: FileMode) -> Result<BidHandle, std::io::Error> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method `FileBoxRegistry::open` is reachable at visibility `pub`
|
|
||||||
|
|
|
||||||
note: but type `FileMode` is only usable at visibility `pub(self)`
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:29:1
|
|
||||||
|
|
|
||||||
29 | enum FileMode {
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
= note: `#[warn(private_interfaces)]` on by default
|
|
||||||
|
|
||||||
warning: field `block_var_maps` is never read
|
|
||||||
--> src/mir/loop_builder.rs:35:5
|
|
||||||
|
|
|
||||||
27 | pub struct LoopBuilder<'a> {
|
|
||||||
| ----------- field in this struct
|
|
||||||
...
|
|
||||||
35 | block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>>,
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(dead_code)]` on by default
|
|
||||||
|
|
||||||
warning: fields `type_name_holder` and `method_holders` are never read
|
|
||||||
--> src/bid/metadata.rs:148:5
|
|
||||||
|
|
|
||||||
143 | pub struct PluginMetadata {
|
|
||||||
| -------------- fields in this struct
|
|
||||||
...
|
|
||||||
148 | type_name_holder: Option<CString>,
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
149 | method_holders: Vec<(NyashMethodInfo, CString)>,
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: fields `path` and `mode` are never read
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:24:5
|
|
||||||
|
|
|
||||||
22 | struct FileBoxState {
|
|
||||||
| ------------ fields in this struct
|
|
||||||
23 | file: File,
|
|
||||||
24 | path: String,
|
|
||||||
| ^^^^
|
|
||||||
25 | mode: FileMode,
|
|
||||||
| ^^^^
|
|
||||||
|
|
||||||
warning: fields `box_types` and `init_fn` are never read
|
|
||||||
--> src/runtime/plugin_loader_v2.rs:20:5
|
|
||||||
|
|
|
||||||
15 | pub struct LoadedPluginV2 {
|
|
||||||
| -------------- fields in this struct
|
|
||||||
...
|
|
||||||
20 | box_types: Vec<String>,
|
|
||||||
| ^^^^^^^^^
|
|
||||||
...
|
|
||||||
23 | init_fn: Option<unsafe extern "C" fn() -> i32>,
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:62:9
|
|
||||||
|
|
|
||||||
62 | self.add_predecessor(header_id, preheader_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
= note: `#[warn(unused_must_use)]` on by default
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
62 | let _ = self.add_predecessor(header_id, preheader_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:66:9
|
|
||||||
|
|
|
||||||
66 | self.mark_block_unsealed(header_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
66 | let _ = self.mark_block_unsealed(header_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:78:9
|
|
||||||
|
|
|
||||||
78 | self.add_predecessor(body_id, header_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
78 | let _ = self.add_predecessor(body_id, header_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:79:9
|
|
||||||
|
|
|
||||||
79 | self.add_predecessor(after_loop_id, header_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
79 | let _ = self.add_predecessor(after_loop_id, header_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: unused `Result` that must be used
|
|
||||||
--> src/mir/loop_builder.rs:93:9
|
|
||||||
|
|
|
||||||
93 | self.add_predecessor(header_id, latch_id);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this `Result` may be an `Err` variant, which should be handled
|
|
||||||
help: use `let _ = ...` to ignore the resulting value
|
|
||||||
|
|
|
||||||
93 | let _ = self.add_predecessor(header_id, latch_id);
|
|
||||||
| +++++++
|
|
||||||
|
|
||||||
warning: creating a shared reference to mutable static
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:102:12
|
|
||||||
|
|
|
||||||
102 | if FILEBOX_REGISTRY.is_none() {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
|
||||||
|
|
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
|
|
||||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
|
||||||
= note: `#[warn(static_mut_refs)]` on by default
|
|
||||||
|
|
||||||
warning: creating a shared reference to mutable static
|
|
||||||
--> src/bid/plugins/filebox/mod.rs:105:9
|
|
||||||
|
|
|
||||||
105 | FILEBOX_REGISTRY.as_ref().unwrap().clone()
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
|
||||||
|
|
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
|
|
||||||
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
|
|
||||||
|
|
||||||
error: could not compile `nyash-rust` (lib)
|
|
||||||
|
|
||||||
Caused by:
|
|
||||||
could not execute process `/home/tomoaki/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name nyash_rust --edition=2021 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type cdylib --crate-type rlib --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --cfg 'feature="cli"' --cfg 'feature="default"' --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("all-examples", "cli", "default", "dynamic-file", "gui", "gui-examples", "wasm-backend"))' -C metadata=024e0bfefa24aea7 --out-dir /mnt/c/git/nyash-project/nyash/target/debug/deps -C incremental=/mnt/c/git/nyash-project/nyash/target/debug/incremental -L dependency=/mnt/c/git/nyash-project/nyash/target/debug/deps --extern anyhow=/mnt/c/git/nyash-project/nyash/target/debug/deps/libanyhow-cb0106135621df54.rlib --extern chrono=/mnt/c/git/nyash-project/nyash/target/debug/deps/libchrono-0d332b6d25ba4f26.rlib --extern clap=/mnt/c/git/nyash-project/nyash/target/debug/deps/libclap-402745ede5642e57.rlib --extern console_error_panic_hook=/mnt/c/git/nyash-project/nyash/target/debug/deps/libconsole_error_panic_hook-8d542a370ca115ea.rlib --extern env_logger=/mnt/c/git/nyash-project/nyash/target/debug/deps/libenv_logger-b5822987cce07060.rlib --extern js_sys=/mnt/c/git/nyash-project/nyash/target/debug/deps/libjs_sys-9f8e174f128030e3.rlib --extern lazy_static=/mnt/c/git/nyash-project/nyash/target/debug/deps/liblazy_static-a60c6f0d6f5b0a48.rlib --extern libloading=/mnt/c/git/nyash-project/nyash/target/debug/deps/liblibloading-212293e6e9433adc.rlib --extern log=/mnt/c/git/nyash-project/nyash/target/debug/deps/liblog-97254b5c9fae48ec.rlib --extern once_cell=/mnt/c/git/nyash-project/nyash/target/debug/deps/libonce_cell-140027e2059e248c.rlib --extern regex=/mnt/c/git/nyash-project/nyash/target/debug/deps/libregex-593e58218ee7d01e.rlib --extern serde=/mnt/c/git/nyash-project/nyash/target/debug/deps/libserde-fe05dc3dd0f4c02d.rlib --extern serde_json=/mnt/c/git/nyash-project/nyash/target/debug/deps/libserde_json-4c960d663cd516d2.rlib --extern thiserror=/mnt/c/git/nyash-project/nyash/target/debug/deps/libthiserror-4e3b67f662716893.rlib --extern toml=/mnt/c/git/nyash-project/nyash/target/debug/deps/libtoml-5883ff1c2c8abaf1.rlib --extern wasm_bindgen=/mnt/c/git/nyash-project/nyash/target/debug/deps/libwasm_bindgen-79650e8bccd47590.rlib --extern web_sys=/mnt/c/git/nyash-project/nyash/target/debug/deps/libweb_sys-a459292f085ab080.rlib` (never executed)
|
|
||||||
|
|
||||||
Caused by:
|
|
||||||
Operation not permitted (os error 1)
|
|
||||||
warning: build failed, waiting for other jobs to finish...
|
|
||||||
warning: `nyash-rust` (lib test) generated 50 warnings (run `cargo fix --lib -p nyash-rust --tests` to apply 25 suggestions)
|
|
||||||
1155
test_out5.txt
1155
test_out5.txt
File diff suppressed because it is too large
Load Diff
1155
test_out_full.txt
1155
test_out_full.txt
File diff suppressed because it is too large
Load Diff
197
test_output.txt
197
test_output.txt
@ -1,197 +0,0 @@
|
|||||||
🔍 DEBUG: Initializing v2 plugin system
|
|
||||||
[net] Net plugin initialized, LOG_ON=true, LOG_PATH=net_plugin.log
|
|
||||||
Net plugin: LOG_ON=true, LOG_PATH=net_plugin.log
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_net_plugin.so
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_counter_plugin.so
|
|
||||||
[FileBox] Plugin initialized
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_filebox_plugin.so
|
|
||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
📦 Registering plugin provider for HttpServerBox
|
|
||||||
📦 Registering plugin provider for HttpClientBox
|
|
||||||
📦 Registering plugin provider for HttpResponseBox
|
|
||||||
📦 Registering plugin provider for HttpRequestBox
|
|
||||||
📦 Registering plugin provider for SocketServerBox
|
|
||||||
📦 Registering plugin provider for SocketClientBox
|
|
||||||
📦 Registering plugin provider for SocketConnBox
|
|
||||||
📦 Registering plugin provider for CounterBox
|
|
||||||
📦 Registering plugin provider for FileBox
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🦀 Nyash Rust Implementation - Executing file: local_tests/test_http_simple_e2e.nyash 🦀
|
|
||||||
🔥 Debug fuel limit: 100000 iterations
|
|
||||||
====================================================
|
|
||||||
📝 File contents:
|
|
||||||
// Very simple HTTP test
|
|
||||||
local srv, cli, r, resp
|
|
||||||
srv = new HttpServerBox()
|
|
||||||
print("HttpServerBox created")
|
|
||||||
|
|
||||||
// Start server
|
|
||||||
local startResult = srv.start(8090)
|
|
||||||
print("Server start result:")
|
|
||||||
print(startResult)
|
|
||||||
|
|
||||||
// Create client
|
|
||||||
cli = new HttpClientBox()
|
|
||||||
print("HttpClientBox created")
|
|
||||||
|
|
||||||
// Make request
|
|
||||||
r = cli.get("http://localhost:8090/test")
|
|
||||||
print("Request made")
|
|
||||||
|
|
||||||
// Accept connection
|
|
||||||
local acceptResult = srv.accept()
|
|
||||||
print("Accept result:")
|
|
||||||
print(acceptResult)
|
|
||||||
|
|
||||||
// Get value from accept result
|
|
||||||
local req = acceptResult.get_value()
|
|
||||||
print("Got request value")
|
|
||||||
|
|
||||||
// Create response
|
|
||||||
resp = new HttpResponseBox()
|
|
||||||
resp.write("Hello!")
|
|
||||||
print("Response created and written")
|
|
||||||
|
|
||||||
// Send response
|
|
||||||
req.respond(resp)
|
|
||||||
print("Response sent")
|
|
||||||
|
|
||||||
// Get response on client side
|
|
||||||
local clientResp = r.get_value()
|
|
||||||
print("Got client response")
|
|
||||||
|
|
||||||
// Read body
|
|
||||||
local body = clientResp.readBody()
|
|
||||||
print("Body: " + body)
|
|
||||||
|
|
||||||
🚀 Parsing and executing...
|
|
||||||
|
|
||||||
🔍 DEBUG: Starting parse with fuel: Some(100000)...
|
|
||||||
🔍 DEBUG: Parse completed, AST created
|
|
||||||
🔍 DEBUG: About to print parse success message...
|
|
||||||
✅ Parse successful!
|
|
||||||
🔍 DEBUG: Parse success message printed
|
|
||||||
🔍 DEBUG: Creating interpreter...
|
|
||||||
🔍 DEBUG: Starting execution...
|
|
||||||
🔍 create_box called for: HttpServerBox
|
|
||||||
🔍 Config loaded successfully
|
|
||||||
🔍 Found library: libnyash_net_plugin.so for box type: HttpServerBox
|
|
||||||
🔍 Plugin loaded successfully
|
|
||||||
🔍 Reading nyash.toml for type configuration...
|
|
||||||
🔍 nyash.toml read successfully
|
|
||||||
🔍 nyash.toml parsed successfully
|
|
||||||
🔍 Found box config for HttpServerBox with type_id: 20
|
|
||||||
🔍 Preparing to call birth() with type_id: 20
|
|
||||||
🔍 Output buffer allocated, about to call plugin invoke_fn...
|
|
||||||
🔍 Calling invoke_fn(type_id=20, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
|
|
||||||
🔍 invoke_fn returned with result: 0
|
|
||||||
🎉 birth() success: HttpServerBox instance_id=1
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpServerBox (id=1)
|
|
||||||
HttpServerBox created
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpServerBox (id=1)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: start
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 execute_plugin_box_v2_method called: HttpServerBox.start
|
|
||||||
[PluginLoaderV2] Invoke HttpServerBox.start: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: Integer(8090) -> I32(tag=2)
|
|
||||||
[net] http:listener bound 127.0.0.1:8090
|
|
||||||
Server start result:
|
|
||||||
Ok(void)
|
|
||||||
🔍 create_box called for: HttpClientBox
|
|
||||||
🔍 Config loaded successfully
|
|
||||||
🔍 Found library: libnyash_net_plugin.so for box type: HttpClientBox
|
|
||||||
🔍 Plugin loaded successfully
|
|
||||||
🔍 Reading nyash.toml for type configuration...
|
|
||||||
🔍 nyash.toml read successfully
|
|
||||||
🔍 nyash.toml parsed successfully
|
|
||||||
🔍 Found box config for HttpClientBox with type_id: 23
|
|
||||||
🔍 Preparing to call birth() with type_id: 23
|
|
||||||
🔍 Output buffer allocated, about to call plugin invoke_fn...
|
|
||||||
🔍 Calling invoke_fn(type_id=23, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
|
|
||||||
🔍 invoke_fn returned with result: 0
|
|
||||||
🎉 birth() success: HttpClientBox instance_id=1
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpClientBox (id=1)
|
|
||||||
HttpClientBox created
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpClientBox (id=1)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: get
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 execute_plugin_box_v2_method called: HttpClientBox.get
|
|
||||||
[PluginLoaderV2] Invoke HttpClientBox.get: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: String(len=26) -> String(tag=6)
|
|
||||||
[net] client.get: url=http://localhost:8090/test resp_id=1 tcp_ok=true conn_id=1
|
|
||||||
[net] http:accept linked resp_id hint=1 for req_id=1 conn_id=2
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
|
|
||||||
Request made
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpServerBox (id=1)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: accept
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 execute_plugin_box_v2_method called: HttpServerBox.accept
|
|
||||||
[PluginLoaderV2] Invoke HttpServerBox.accept: resolving and encoding args (argc=0)
|
|
||||||
[net] server.accept: return req_id=1 srv_id=1
|
|
||||||
Accept result:
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
|
|
||||||
Ok(HttpRequestBox(1))
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: NyashResultBox, method: get_value
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: NyashResultBox
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
|
|
||||||
Got request value
|
|
||||||
🔍 create_box called for: HttpResponseBox
|
|
||||||
🔍 Config loaded successfully
|
|
||||||
🔍 Found library: libnyash_net_plugin.so for box type: HttpResponseBox
|
|
||||||
🔍 Plugin loaded successfully
|
|
||||||
🔍 Reading nyash.toml for type configuration...
|
|
||||||
🔍 nyash.toml read successfully
|
|
||||||
🔍 nyash.toml parsed successfully
|
|
||||||
🔍 Found box config for HttpResponseBox with type_id: 22
|
|
||||||
🔍 Preparing to call birth() with type_id: 22
|
|
||||||
🔍 Output buffer allocated, about to call plugin invoke_fn...
|
|
||||||
🔍 Calling invoke_fn(type_id=22, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
|
|
||||||
🔍 invoke_fn returned with result: 0
|
|
||||||
🎉 birth() success: HttpResponseBox instance_id=2
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=2)
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=2)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: write
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 execute_plugin_box_v2_method called: HttpResponseBox.write
|
|
||||||
[PluginLoaderV2] Invoke HttpResponseBox.write: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: String(len=6) -> String(tag=6)
|
|
||||||
[net] HttpResponse.write: id=2 bytes_len=6
|
|
||||||
[net] HttpResponse.write: body now has 6 bytes
|
|
||||||
Response created and written
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: respond
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 execute_plugin_box_v2_method called: HttpRequestBox.respond
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=2)
|
|
||||||
[PluginLoaderV2] Invoke HttpRequestBox.respond: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: PluginBoxV2(HttpResponseBox, id=2) -> Handle(tag=8)
|
|
||||||
Response sent
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: NyashResultBox, method: get_value
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: NyashResultBox
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
|
|
||||||
Got client response
|
|
||||||
🔍 stdlib not initialized for method call
|
|
||||||
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
|
|
||||||
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: readBody
|
|
||||||
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
|
|
||||||
🔍 DEBUG: StringBox downcast failed
|
|
||||||
🔍 execute_plugin_box_v2_method called: HttpResponseBox.readBody
|
|
||||||
[PluginLoaderV2] Invoke HttpResponseBox.readBody: resolving and encoding args (argc=0)
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
|
|
||||||
running 8 tests
|
|
||||||
test mir::instruction_v2::tests::test_instruction_count ... ok
|
|
||||||
test mir::instruction_v2::tests::test_ownership_operations ... ok
|
|
||||||
test mir::instruction_v2::tests::test_effect_categories ... ok
|
|
||||||
test instance_v2::tests::test_from_declaration_creation ... ok
|
|
||||||
test instance_v2::tests::test_from_any_box_creation ... ok
|
|
||||||
test instance_v2::tests::test_unified_approach ... ok
|
|
||||||
test instance_v2::tests::test_field_operations ... ok
|
|
||||||
test config::nyash_toml_v2::tests::test_parse_v2_config ... ok
|
|
||||||
|
|
||||||
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 148 filtered out; finished in 0.04s
|
|
||||||
|
|
||||||
|
|
||||||
running 8 tests
|
|
||||||
test mir::instruction_v2::tests::test_ownership_operations ... ok
|
|
||||||
test mir::instruction_v2::tests::test_instruction_count ... ok
|
|
||||||
test mir::instruction_v2::tests::test_effect_categories ... ok
|
|
||||||
test instance_v2::tests::test_field_operations ... ok
|
|
||||||
test instance_v2::tests::test_from_declaration_creation ... ok
|
|
||||||
test instance_v2::tests::test_from_any_box_creation ... ok
|
|
||||||
test instance_v2::tests::test_unified_approach ... ok
|
|
||||||
test config::nyash_toml_v2::tests::test_parse_v2_config ... ok
|
|
||||||
|
|
||||||
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 137 filtered out; finished in 0.04s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 16 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
|
|
||||||
running 0 tests
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
|
||||||
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
static box Main {
|
|
||||||
main() {
|
|
||||||
return 42
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1140
test_run_output.txt
1140
test_run_output.txt
File diff suppressed because it is too large
Load Diff
@ -1,19 +0,0 @@
|
|||||||
// 簡単なNyashテストプログラム
|
|
||||||
print("🎉 Nyash is working!")
|
|
||||||
print("Everything is Box!")
|
|
||||||
|
|
||||||
// 基本的な演算
|
|
||||||
local a = 10
|
|
||||||
local b = 20
|
|
||||||
local result = a + b
|
|
||||||
print("10 + 20 = " + result.toString())
|
|
||||||
|
|
||||||
// StringBox
|
|
||||||
local greeting = "Hello, Nyash!"
|
|
||||||
print(greeting)
|
|
||||||
|
|
||||||
// ArrayBox
|
|
||||||
local arr = new ArrayBox()
|
|
||||||
arr.push("First")
|
|
||||||
arr.push("Second")
|
|
||||||
print("Array length: " + arr.length().toString())
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
🔍 DEBUG: Initializing v2 plugin system
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_counter_plugin.so
|
|
||||||
[FileBox] Plugin initialized
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_filebox_plugin.so
|
|
||||||
Net plugin: LOG_ON=false, LOG_PATH=net_plugin.log
|
|
||||||
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_net_plugin.so
|
|
||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
📦 Registering plugin provider for CounterBox
|
|
||||||
📦 Registering plugin provider for FileBox
|
|
||||||
📦 Registering plugin provider for HttpServerBox
|
|
||||||
📦 Registering plugin provider for HttpClientBox
|
|
||||||
📦 Registering plugin provider for HttpResponseBox
|
|
||||||
📦 Registering plugin provider for HttpRequestBox
|
|
||||||
📦 Registering plugin provider for SocketServerBox
|
|
||||||
📦 Registering plugin provider for SocketClientBox
|
|
||||||
📦 Registering plugin provider for SocketConnBox
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_http_404.nyash 🚀
|
|
||||||
🔍 create_box called for: HttpServerBox
|
|
||||||
🔍 Config loaded successfully
|
|
||||||
🔍 Found library: libnyash_net_plugin.so for box type: HttpServerBox
|
|
||||||
🔍 Plugin loaded successfully
|
|
||||||
🔍 Reading nyash.toml for type configuration...
|
|
||||||
🔍 nyash.toml read successfully
|
|
||||||
🔍 nyash.toml parsed successfully
|
|
||||||
🔍 Found box config for HttpServerBox with type_id: 20
|
|
||||||
🔍 Preparing to call birth() with type_id: 20
|
|
||||||
🔍 Output buffer allocated, about to call plugin invoke_fn...
|
|
||||||
🔍 Calling invoke_fn(type_id=20, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
|
|
||||||
🔍 invoke_fn returned with result: 0
|
|
||||||
🎉 birth() success: HttpServerBox instance_id=1
|
|
||||||
[PluginLoaderV2] Invoke HttpServerBox.birth: resolving and encoding args (argc=0)
|
|
||||||
[VM→Plugin] call HttpServerBox.birth recv_id=1 returns_result=false
|
|
||||||
[PluginLoaderV2] Invoke HttpServerBox.start: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: Integer(8404) -> I32(tag=2)
|
|
||||||
[VM→Plugin] call HttpServerBox.start recv_id=1 returns_result=true
|
|
||||||
🔍 create_box called for: HttpClientBox
|
|
||||||
🔍 Config loaded successfully
|
|
||||||
🔍 Found library: libnyash_net_plugin.so for box type: HttpClientBox
|
|
||||||
🔍 Plugin loaded successfully
|
|
||||||
🔍 Reading nyash.toml for type configuration...
|
|
||||||
🔍 nyash.toml read successfully
|
|
||||||
🔍 nyash.toml parsed successfully
|
|
||||||
🔍 Found box config for HttpClientBox with type_id: 23
|
|
||||||
🔍 Preparing to call birth() with type_id: 23
|
|
||||||
🔍 Output buffer allocated, about to call plugin invoke_fn...
|
|
||||||
🔍 Calling invoke_fn(type_id=23, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
|
|
||||||
🔍 invoke_fn returned with result: 0
|
|
||||||
🎉 birth() success: HttpClientBox instance_id=1
|
|
||||||
[PluginLoaderV2] Invoke HttpClientBox.birth: resolving and encoding args (argc=0)
|
|
||||||
[VM→Plugin] call HttpClientBox.birth recv_id=1 returns_result=false
|
|
||||||
[PluginLoaderV2] Invoke HttpClientBox.get: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: String(len=31) -> String(tag=6)
|
|
||||||
[VM→Plugin] call HttpClientBox.get recv_id=1 returns_result=true
|
|
||||||
[PluginLoaderV2] Invoke HttpServerBox.accept: resolving and encoding args (argc=0)
|
|
||||||
[VM→Plugin] call HttpServerBox.accept recv_id=1 returns_result=true
|
|
||||||
🔍 create_box called for: HttpResponseBox
|
|
||||||
🔍 Config loaded successfully
|
|
||||||
🔍 Found library: libnyash_net_plugin.so for box type: HttpResponseBox
|
|
||||||
🔍 Plugin loaded successfully
|
|
||||||
🔍 Reading nyash.toml for type configuration...
|
|
||||||
🔍 nyash.toml read successfully
|
|
||||||
🔍 nyash.toml parsed successfully
|
|
||||||
🔍 Found box config for HttpResponseBox with type_id: 22
|
|
||||||
🔍 Preparing to call birth() with type_id: 22
|
|
||||||
🔍 Output buffer allocated, about to call plugin invoke_fn...
|
|
||||||
🔍 Calling invoke_fn(type_id=22, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
|
|
||||||
🔍 invoke_fn returned with result: 0
|
|
||||||
🎉 birth() success: HttpResponseBox instance_id=2
|
|
||||||
[PluginLoaderV2] Invoke HttpResponseBox.birth: resolving and encoding args (argc=0)
|
|
||||||
[VM→Plugin] call HttpResponseBox.birth recv_id=2 returns_result=false
|
|
||||||
[PluginLoaderV2] Invoke HttpResponseBox.setStatus: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: Integer(404) -> I32(tag=2)
|
|
||||||
[VM→Plugin] call HttpResponseBox.setStatus recv_id=2 returns_result=false
|
|
||||||
[PluginLoaderV2] Invoke HttpResponseBox.write: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: String(len=9) -> String(tag=6)
|
|
||||||
[VM→Plugin] call HttpResponseBox.write recv_id=2 returns_result=false
|
|
||||||
[PluginLoaderV2] Invoke HttpRequestBox.respond: resolving and encoding args (argc=1)
|
|
||||||
[PluginLoaderV2] arg[0]: PluginBoxV2(HttpResponseBox, id=2) -> Handle(tag=8)
|
|
||||||
[VM→Plugin] call HttpRequestBox.respond recv_id=1 returns_result=false
|
|
||||||
[PluginLoaderV2] Invoke HttpResponseBox.getStatus: resolving and encoding args (argc=0)
|
|
||||||
[VM→Plugin] call HttpResponseBox.getStatus recv_id=1 returns_result=false
|
|
||||||
[PluginLoaderV2] Invoke HttpResponseBox.readBody: resolving and encoding args (argc=0)
|
|
||||||
[VM→Plugin] call HttpResponseBox.readBody recv_id=1 returns_result=false
|
|
||||||
✅ VM execution completed successfully!
|
|
||||||
Result: StringBox { value: "404:Not Found", base: BoxBase { id: 57, parent_type_id: None } }
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_http_err.nyash 🚀
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_filebox.nyash 🚀
|
|
||||||
{
|
|
||||||
"counts": {
|
|
||||||
"BoxCall": 17,
|
|
||||||
"Const": 13,
|
|
||||||
"NewBox": 12,
|
|
||||||
"Return": 1,
|
|
||||||
"Safepoint": 1
|
|
||||||
},
|
|
||||||
"elapsed_ms": 26.658774,
|
|
||||||
"timestamp_ms": 1755900319445,
|
|
||||||
"top20": [
|
|
||||||
{
|
|
||||||
"count": 17,
|
|
||||||
"op": "BoxCall"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 13,
|
|
||||||
"op": "Const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 12,
|
|
||||||
"op": "NewBox"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Return"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Safepoint"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"total": 44
|
|
||||||
}
|
|
||||||
✅ VM execution completed successfully!
|
|
||||||
Result: StringBox { value: "HELLO", base: BoxBase { id: 59, parent_type_id: None } }
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_http_ok.nyash 🚀
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/test_vm_simple.nyash 🚀
|
|
||||||
15
|
|
||||||
{
|
|
||||||
"counts": {
|
|
||||||
"BinOp": 1,
|
|
||||||
"BoxCall": 2,
|
|
||||||
"Const": 5,
|
|
||||||
"NewBox": 2,
|
|
||||||
"Print": 1,
|
|
||||||
"Return": 1,
|
|
||||||
"Safepoint": 1
|
|
||||||
},
|
|
||||||
"elapsed_ms": 0.154706,
|
|
||||||
"timestamp_ms": 1755939354732,
|
|
||||||
"top20": [
|
|
||||||
{
|
|
||||||
"count": 5,
|
|
||||||
"op": "Const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "BoxCall"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "NewBox"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "BinOp"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Print"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Return"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Safepoint"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"total": 13
|
|
||||||
}
|
|
||||||
✅ VM execution completed successfully!
|
|
||||||
Result: IntegerBox { value: 15, base: BoxBase { id: 12, parent_type_id: None } }
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/weak_field_poc.nyash 🚀
|
|
||||||
0
|
|
||||||
{
|
|
||||||
"counts": {
|
|
||||||
"BarrierRead": 1,
|
|
||||||
"BarrierWrite": 1,
|
|
||||||
"BoxCall": 2,
|
|
||||||
"Const": 9,
|
|
||||||
"NewBox": 2,
|
|
||||||
"Print": 1,
|
|
||||||
"RefGet": 4,
|
|
||||||
"RefSet": 3,
|
|
||||||
"Return": 3,
|
|
||||||
"Safepoint": 1,
|
|
||||||
"WeakLoad": 1,
|
|
||||||
"WeakNew": 1
|
|
||||||
},
|
|
||||||
"elapsed_ms": 0.194731,
|
|
||||||
"timestamp_ms": 1755956955634,
|
|
||||||
"top20": [
|
|
||||||
{
|
|
||||||
"count": 9,
|
|
||||||
"op": "Const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 4,
|
|
||||||
"op": "RefGet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 3,
|
|
||||||
"op": "RefSet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 3,
|
|
||||||
"op": "Return"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "BoxCall"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "NewBox"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "BarrierRead"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "BarrierWrite"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Print"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Safepoint"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "WeakLoad"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "WeakNew"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"total": 29
|
|
||||||
}
|
|
||||||
✅ VM execution completed successfully!
|
|
||||||
Result: IntegerBox { value: 0, base: BoxBase { id: 4, parent_type_id: None } }
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
🔌 v2 plugin system initialized from nyash.toml
|
|
||||||
✅ v2 plugin system fully configured
|
|
||||||
🚀 Nyash VM Backend - Executing file: local_tests/weak_field_poc.nyash 🚀
|
|
||||||
0
|
|
||||||
{
|
|
||||||
"counts": {
|
|
||||||
"Barrier": 2,
|
|
||||||
"BoxCall": 2,
|
|
||||||
"Const": 9,
|
|
||||||
"NewBox": 2,
|
|
||||||
"Print": 1,
|
|
||||||
"RefGet": 4,
|
|
||||||
"RefSet": 3,
|
|
||||||
"Return": 3,
|
|
||||||
"Safepoint": 1,
|
|
||||||
"WeakRef": 2
|
|
||||||
},
|
|
||||||
"elapsed_ms": 0.16804799999999998,
|
|
||||||
"timestamp_ms": 1755957108401,
|
|
||||||
"top20": [
|
|
||||||
{
|
|
||||||
"count": 9,
|
|
||||||
"op": "Const"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 4,
|
|
||||||
"op": "RefGet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 3,
|
|
||||||
"op": "RefSet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 3,
|
|
||||||
"op": "Return"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "Barrier"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "BoxCall"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "NewBox"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 2,
|
|
||||||
"op": "WeakRef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Print"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"op": "Safepoint"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"total": 29
|
|
||||||
}
|
|
||||||
✅ VM execution completed successfully!
|
|
||||||
Result: IntegerBox { value: 0, base: BoxBase { id: 4, parent_type_id: None } }
|
|
||||||
Reference in New Issue
Block a user