feat: Apply Copilot's WASM UTF-8 fix manually

- Change from compile_module() to compile_to_wat() to fix UTF-8 error
- WASM compilation now outputs WAT text format directly
- Successfully generates WAT file for simple test case
- Note: Debug build still has issues (separate bug)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-17 00:03:49 +09:00
parent 939af77a59
commit 95bbb50886
4 changed files with 252 additions and 46 deletions

View File

@ -1,6 +1,6 @@
# 🎯 現在のタスク (2025-08-16 Phase 9.77 WASM緊急復旧開始)
## 🚨 **Phase 9.77進行中: WASM緊急復旧作業**
## **Phase 9.77完了: WASM緊急復旧作業完了!**
### ✅ **Task 1.1完了: BoxCall命令実装**
- **BoxCall実装**: toString(), print(), equals(), clone(), log()メソッド完全実装 ✅
@ -13,44 +13,38 @@
- **RuntimeImports追加**: box_to_string, box_print, box_equals, box_clone 実装済み ✅
- **ビルド成功**: バージョン互換性問題解決 ✅
### 🔄 **Task 1.3進行中: WASM出力UTF-8エラー修正**
**現状**: 「Generated WASM is not valid UTF-8」エラーが継続
```bash
❌ Generated WASM is not valid UTF-8
### **Task 1.3完了: WASM出力UTF-8エラー修正Copilot解決**
**問題**: 「Generated WASM is not valid UTF-8」エラー
**原因**: WASMバイナリをUTF-8文字列として扱っていた
**Copilotの修正**:
```rust
// Before (broken)
let wasm_code = wasm_backend.compile_module(compile_result.module)?;
let output_str = std::str::from_utf8(&wasm_code)?;
// After (fixed)
let wat_text = wasm_backend.compile_to_wat(compile_result.module)?;
let output_str = wat_text;
```
**実装済み修正**:
- wabt::wat2wasm呼び出し修正wat_source.as_bytes()使用)
- UTF-8検証とデバッグ出力追加
- しかしエラーメッセージの発生元が不明
**結果**: WATテキスト形式を直接出力することで解決 ✅
**調査結果**:
- エラーメッセージがソースコード内に見つからない
- wabt crateまたは外部ツールから発生している可能性
- 簡単なテストケース(`local result = 42`)でも同じエラー
### 🎉 **Phase 9.77成果まとめ**
- ✅ BoxCall命令完全実装
- ✅ wasmtime 35.0.0対応
- ✅ UTF-8エラー解決手動でCopilot修正を適用
- ✅ WASM基本機能復旧リリースビルドで動作確認
- ✅ WATファイル生成成功: `local result = 42` → 正常なWAT出力
### 📋 **Phase 9.77緊急復旧計画**
詳細: [phase_9_77_wasm_emergency.md](docs/予定/native-plan/issues/phase_9_77_wasm_emergency.md)
### 📋 **残課題**
- ⚠️ デバッグビルドでのWASMエラー別のバグの可能性
- 🔄 git pullでのマージコンフリクトexpressions.rsモジュール分割と衝突
**Task 1.1**: ✅ BoxCall命令実装完了
**Task 1.2**: ✅ wasmtimeバージョン統一 + RuntimeImports完了
**Task 1.3**: 🔄 WASM出力エラー修正進行中
### 🎯 **Copilotへの引き継ぎ事項**
1. **UTF-8エラーの原因特定**
- エラーメッセージ「Generated WASM is not valid UTF-8」の発生元調査
- wabt::wat2wasm以外の場所でエラーが出ている可能性
- runner.rsやmain.rsでのエラー処理確認
2. **デバッグアプローチ**
- WAT生成内容の詳細確認デバッグ出力は実装済み
- WASM生成パイプライン全体の調査
- 最小再現テストケースでの検証
3. **修正候補**
- エラーメッセージの発生元を特定してから対応
- WAT形式の検証強化
- バイナリ出力処理の見直し
### 🚀 **次のステップ**
1. **デバッグビルドエラー調査**: なぜデバッグビルドで失敗するか
2. **WASM実行テスト**: 生成されたWATファイルの実行確認
3. **Phase 10準備**: LLVM Direct AOT実装へ
## 🎉 **Phase 9.75j完了: 警告削減100%達成!**

View File

@ -0,0 +1,218 @@
(module
(import "env" "print" (func $print (param i32) ))
(import "env" "print_str" (func $print_str (param i32 i32) ))
(import "env" "console_log" (func $console_log (param i32 i32) ))
(import "env" "canvas_fillRect" (func $canvas_fillRect (param i32 i32 i32 i32 i32 i32 i32 i32) ))
(import "env" "canvas_fillText" (func $canvas_fillText (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) ))
(import "env" "box_to_string" (func $box_to_string (param i32) (result i32)))
(import "env" "box_print" (func $box_print (param i32) ))
(import "env" "box_equals" (func $box_equals (param i32 i32) (result i32)))
(import "env" "box_clone" (func $box_clone (param i32) (result i32)))
(memory (export "memory") 1)
(data (i32.const 4096) "\49\6e\74\65\67\65\72\42\6f\78")
(global $heap_ptr (mut i32) (i32.const 2048))
(func $malloc (param $size i32) (result i32)
(local $ptr i32)
(local $aligned_size i32)
;; Align size to 4-byte boundary
local.get $size
i32.const 3
i32.add
i32.const -4
i32.and
local.set $aligned_size
;; Get current heap pointer
global.get $heap_ptr
local.set $ptr
;; Advance heap pointer by aligned size
global.get $heap_ptr
local.get $aligned_size
i32.add
global.set $heap_ptr
;; Return allocated pointer
local.get $ptr
)
(func $box_alloc (param $type_id i32) (param $field_count i32) (result i32)
(local $ptr i32)
(local $total_size i32)
;; Calculate total size: header (12) + fields (field_count * 4)
local.get $field_count
i32.const 4
i32.mul
i32.const 12
i32.add
local.set $total_size
;; Allocate memory
local.get $total_size
call $malloc
local.set $ptr
;; Initialize type_id
local.get $ptr
local.get $type_id
i32.store
;; Initialize ref_count to 1
local.get $ptr
i32.const 4
i32.add
i32.const 1
i32.store
;; Initialize field_count
local.get $ptr
i32.const 8
i32.add
local.get $field_count
i32.store
;; Return box pointer
local.get $ptr
)
(func $alloc_stringbox (result i32)
(local $ptr i32)
;; Allocate memory for box
i32.const 20
call $malloc
local.set $ptr
;; Initialize type_id
local.get $ptr
i32.const 4097
i32.store
;; Initialize ref_count to 1
local.get $ptr
i32.const 4
i32.add
i32.const 1
i32.store
;; Initialize field_count
local.get $ptr
i32.const 8
i32.add
i32.const 2
i32.store
;; Return box pointer
local.get $ptr
)
(func $alloc_integerbox (result i32)
(local $ptr i32)
;; Allocate memory for box
i32.const 16
call $malloc
local.set $ptr
;; Initialize type_id
local.get $ptr
i32.const 4098
i32.store
;; Initialize ref_count to 1
local.get $ptr
i32.const 4
i32.add
i32.const 1
i32.store
;; Initialize field_count
local.get $ptr
i32.const 8
i32.add
i32.const 1
i32.store
;; Return box pointer
local.get $ptr
)
(func $alloc_boolbox (result i32)
(local $ptr i32)
;; Allocate memory for box
i32.const 16
call $malloc
local.set $ptr
;; Initialize type_id
local.get $ptr
i32.const 4099
i32.store
;; Initialize ref_count to 1
local.get $ptr
i32.const 4
i32.add
i32.const 1
i32.store
;; Initialize field_count
local.get $ptr
i32.const 8
i32.add
i32.const 1
i32.store
;; Return box pointer
local.get $ptr
)
(func $alloc_databox (result i32)
(local $ptr i32)
;; Allocate memory for box
i32.const 16
call $malloc
local.set $ptr
;; Initialize type_id
local.get $ptr
i32.const 4101
i32.store
;; Initialize ref_count to 1
local.get $ptr
i32.const 4
i32.add
i32.const 1
i32.store
;; Initialize field_count
local.get $ptr
i32.const 8
i32.add
i32.const 1
i32.store
;; Return box pointer
local.get $ptr
)
(func $main (local $0 i32) (local $1 i32)
nop
call $alloc_stringbox
local.set $1
local.get $1
i32.const 12
i32.add
i32.const 4096
i32.store
local.get $1
i32.const 16
i32.add
i32.const 10
i32.store
local.get $1
local.set $0
local.get $0
return
)
(export "main" (func $main))
)

View File

@ -300,10 +300,10 @@ impl NyashRunner {
}
};
// Compile to WASM
// Compile to WASM (Phase 9.77a fix: use compile_to_wat instead of compile_module)
let mut wasm_backend = WasmBackend::new();
let wasm_code = match wasm_backend.compile_module(compile_result.module) {
Ok(wasm) => wasm,
let wat_text = match wasm_backend.compile_to_wat(compile_result.module) {
Ok(wat) => wat,
Err(e) => {
eprintln!("❌ WASM compilation error: {}", e);
process::exit(1);
@ -321,14 +321,8 @@ impl NyashRunner {
});
let output_file = format!("{}.wat", output);
// Write WASM output
let output_str = match std::str::from_utf8(&wasm_code) {
Ok(s) => s,
Err(_) => {
eprintln!("❌ Generated WASM is not valid UTF-8");
process::exit(1);
}
};
// Write WAT output (already a string)
let output_str = wat_text;
match fs::write(&output_file, output_str) {
Ok(()) => {