docs: WASM Canvas研究とFFI-ABI実装戦略の追加

- CURRENT_TASK.mdにWASM研究メモセクション追加
- MIR→WAT→WASM実行フローの確認
- Canvas実装の3つの選択肢を文書化
  - CanvasBox実装(推奨)
  - グローバルcanvasオブジェクト
  - 標準ライブラリ拡張
- FFI-ABI仕様に基づくFileBox実装戦略を検討
- 純粋FFI-ABI方式でのfile.read/write実装計画策定
This commit is contained in:
Moe Charm
2025-08-17 02:54:05 +09:00
parent aed9d02b0b
commit a8e77f6411
5 changed files with 449 additions and 2 deletions

View File

@ -361,8 +361,72 @@ if let TokenType::IDENTIFIER(id) = &self.current_token().token_type {
- パフォーマンステスト基盤 - パフォーマンステスト基盤
--- ---
**現在状況**: **Phase 9.75i完了 - 全アプリ動作確認!** 🎉 **現在状況**: 🔬 **WASM Canvas機能研究中**
**最終更新**: 2025-08-16 19:15 **最終更新**: 2025-08-16 22:30
## 🌐 **WASM研究メモ**
### **実行フロー: MIR → WAT → WASM**
```
Nyashソースコード
↓ (Parser/AST)
MIR (中間表現)
↓ (WasmCodegen)
WAT (WebAssembly Text形式)
↓ (wabt::wat2wasm)
WASM (バイナリ形式)
```
### **現在の実装状況**
-**console.log()**: ConsoleBox経由で動作
-**canvas操作**: ExternCall定義はあるが、canvasオブジェクトが未実装
-**WAT生成**: UTF-8エラー修正済み、正常に出力
### **Canvas実装の選択肢**
#### **Option 1: CanvasBox実装推奨**
```nyash
// ConsoleBoxと同様のアプローチ
local canvas = new CanvasBox("canvas_id", 800, 600)
canvas.fillRect(10, 10, 100, 50, "#FF0000")
canvas.fillText("Hello", 50, 100, "#000000", "20px Arial")
```
**メリット**:
- Everything is Box哲学に合致
- 既存のBoxパターンと一貫性
- 型安全性の確保
#### **Option 2: グローバルcanvasオブジェクト**
```nyash
// MIRビルダーで特別扱い
canvas.fillRect(10, 10, 100, 50, 255, 0, 0, 255)
```
**メリット**:
- JavaScriptのCanvas APIに近い
- 実装が簡単
**デメリット**:
- Everything is Box哲学から逸脱
- 特殊ケースの増加
#### **Option 3: 標準ライブラリ拡張**
```nyash
using nyashstd
canvas.create("myCanvas", 800, 600)
canvas.fillRect(10, 10, 100, 50)
```
**メリット**:
- 名前空間で整理
- 拡張性が高い
### **次のステップ**
1. CanvasBox実装の設計
2. ExternCall統合
3. WASMブラウザー実行環境の構築
## 🔧 **Parser リファクタリング完了報告** ## 🔧 **Parser リファクタリング完了報告**

View File

@ -0,0 +1,14 @@
// Canvas WASM test - ExternCall経由でCanvas操作
local result = 42
// 赤い矩形を描画
canvas.fillRect(10, 10, 100, 50, 255, 0, 0, 255)
// 青い矩形を描画
canvas.fillRect(120, 10, 100, 50, 0, 0, 255, 255)
// 黒いテキストを描画
canvas.fillText("Hello Nyash!", 10, 100, 0, 0, 0, 255, 24, "Arial")
// コンソールに出力
console.log("Canvas drawing complete!")

View File

@ -0,0 +1,7 @@
// Console WASM test - ExternCall経由でconsole操作
console.log("Hello from Nyash WASM!")
// 複数の値をテスト
local result = 42
console.log("The answer is:")
console.log(result.toString())

View File

@ -0,0 +1,14 @@
// Basic WASM test with ConsoleBox
static box Main {
init { console }
main() {
me.console = new ConsoleBox()
me.console.log("Hello from Nyash WASM!")
local result = 42
me.console.log("The answer is: " + result.toString())
return "WASM test complete"
}
}

View File

@ -0,0 +1,348 @@
(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) "\5f\5f\6d\65\5f\5f")
(data (i32.const 4102) "\43\6f\6e\73\6f\6c\65\42\6f\78")
(data (i32.const 4121) "\49\6e\74\65\67\65\72\42\6f\78")
(data (i32.const 4112) "\53\74\72\69\6e\67\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) (local $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) (local $6 i32) (local $7 i32) (local $8 i32) (local $9 i32) (local $10 i32) (local $11 i32) (local $12 i32) (local $13 i32) (local $14 i32) (local $15 i32) (local $16 i32) (local $17 i32) (local $18 i32)
nop
call $alloc_stringbox
local.set $0
local.get $0
i32.const 12
i32.add
i32.const 4096
i32.store
local.get $0
i32.const 16
i32.add
i32.const 6
i32.store
call $alloc_stringbox
local.set $2
local.get $2
i32.const 12
i32.add
i32.const 4102
i32.store
local.get $2
i32.const 16
i32.add
i32.const 10
i32.store
local.get $2
local.set $1
local.get $0
i32.const 12
i32.add
local.get $1
i32.store
call $alloc_stringbox
local.set $3
local.get $3
i32.const 12
i32.add
i32.const 4096
i32.store
local.get $3
i32.const 16
i32.add
i32.const 6
i32.store
local.get $3
i32.const 12
i32.add
i32.load
local.set $4
call $alloc_stringbox
local.set $6
local.get $6
i32.const 12
i32.add
i32.const 4112
i32.store
local.get $6
i32.const 16
i32.add
i32.const 9
i32.store
local.get $6
local.set $5
;; log() implementation for ValueId(4)
local.get $4
local.get $5
call $console_log
i32.const 0
local.set $7
call $alloc_stringbox
local.set $9
local.get $9
i32.const 12
i32.add
i32.const 4121
i32.store
local.get $9
i32.const 16
i32.add
i32.const 10
i32.store
local.get $9
local.set $8
call $alloc_stringbox
local.set $10
local.get $10
i32.const 12
i32.add
i32.const 4096
i32.store
local.get $10
i32.const 16
i32.add
i32.const 6
i32.store
local.get $10
i32.const 12
i32.add
i32.load
local.set $11
call $alloc_stringbox
local.set $13
local.get $13
i32.const 12
i32.add
i32.const 4112
i32.store
local.get $13
i32.const 16
i32.add
i32.const 9
i32.store
local.get $13
local.set $12
;; toString() implementation for ValueId(8)
local.get $8
call $box_to_string
local.set $14
local.get $12
local.get $14
i32.add
local.set $15
;; log() implementation for ValueId(11)
local.get $11
local.get $15
call $console_log
i32.const 0
local.set $16
call $alloc_stringbox
local.set $18
local.get $18
i32.const 12
i32.add
i32.const 4112
i32.store
local.get $18
i32.const 16
i32.add
i32.const 9
i32.store
local.get $18
local.set $17
local.get $17
return
)
(export "main" (func $main))
)