Apply ChatGPT's FileBox method_id fixes and add build scripts
- Add plugin host initialization for LLVM mode (fixes method_id injection) - Add FileBox method_id injection test - Enhance MIR14 stability test - Add warning for Mock LLVM implementation - Create build scripts for JIT/LLVM with proper settings (24 threads, timeout) - Update CLAUDE.md with build instructions and FileBox test results Note: FileBox file I/O still not working in LLVM execution (separate issue) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
42
CLAUDE.md
42
CLAUDE.md
@ -123,7 +123,47 @@ cargo build --release --features llvm
|
||||
./target/release/nyash --aot program.nyash -o program.exe
|
||||
```
|
||||
|
||||
## 📝 Update (2025-09-08)
|
||||
### 🎯 **実証済みビルド方法** (2025-09-10完全成功)
|
||||
|
||||
#### 🔨 ビルドスクリプト(24スレッド並列・無制限時間)
|
||||
```bash
|
||||
# JIT (Cranelift) ビルド - 1-2分
|
||||
./build_jit.sh
|
||||
|
||||
# LLVM MIR14 ビルド - 3-5分
|
||||
./build_llvm.sh
|
||||
```
|
||||
|
||||
#### 📝 手動ビルドコマンド
|
||||
```bash
|
||||
# 1. JIT (Cranelift) - 127警告、0エラー ✅
|
||||
cargo build --release --features cranelift-jit -j 24
|
||||
./target/release/nyash program.nyash
|
||||
|
||||
# 2. LLVM MIR14 - 211警告、0エラー ✅
|
||||
env LLVM_SYS_180_PREFIX=/usr/lib/llvm-18 cargo build --release --features llvm -j 24
|
||||
./target/release/nyash --backend llvm program.nyash
|
||||
|
||||
# 3. プラグインテスト実証済み ✅
|
||||
# CounterBox (3080バイト)
|
||||
echo 'local c = new CounterBox(); c.inc(); c.inc(); print(c.get())' > test.nyash
|
||||
./target/release/nyash --backend llvm test.nyash
|
||||
|
||||
# MathBox (2040バイト)
|
||||
echo 'local m = new MathBox(); print(m.sqrt(16))' > test.nyash
|
||||
./target/release/nyash --backend llvm test.nyash
|
||||
|
||||
# StringBox (3288バイト)
|
||||
echo 'local s = new StringBox(); print(s.concat("Hello"))' > test.nyash
|
||||
./target/release/nyash --backend llvm test.nyash
|
||||
```
|
||||
|
||||
⚠️ **ビルド時間の注意**:
|
||||
- JITビルド: 1-2分(高速)
|
||||
- LLVMビルド: 3-5分(時間がかかる)
|
||||
- 必ず十分な時間設定で実行してください
|
||||
|
||||
## 📝 Update (2025-09-10) 🎆 歴史的達成!
|
||||
- 🎉 Phase 15到達!セルフホスティング実装中
|
||||
- v0 Nyパーサー完成(Ny→JSON IR v0)
|
||||
- 🔥 ループビルダーSSAバグ発見・調査完了(ブロッカー)
|
||||
|
||||
5
build_jit.sh
Normal file
5
build_jit.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# JIT (Cranelift) ビルド - 24スレッド並列
|
||||
echo "🚀 JIT (Cranelift) ビルドを開始します..."
|
||||
cargo build --release --features cranelift-jit -j 24
|
||||
echo "✅ JIT ビルド完了!"
|
||||
6
build_llvm.sh
Normal file
6
build_llvm.sh
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
# LLVM ビルド - 24スレッド並列
|
||||
echo "🚀 LLVM ビルドを開始します..."
|
||||
export LLVM_SYS_180_PREFIX=/usr/lib/llvm-18
|
||||
cargo build --release --features llvm -j 24
|
||||
echo "✅ LLVM ビルド完了!"
|
||||
@ -71,6 +71,9 @@ impl LLVMCompiler {
|
||||
) -> Result<Box<dyn NyashBox>, String> {
|
||||
// Mock implementation - interprets MIR instructions to simulate execution
|
||||
|
||||
eprintln!("⚠️⚠️⚠️ WARNING: Using MOCK LLVM Implementation! ⚠️⚠️⚠️");
|
||||
eprintln!("⚠️ This is NOT real LLVM execution!");
|
||||
eprintln!("⚠️ Build with --features llvm for real compilation!");
|
||||
println!("🚀 Mock LLVM Compile & Execute (MIR Interpreter Mode):");
|
||||
|
||||
// 1. Mock object file generation
|
||||
@ -1445,6 +1448,20 @@ impl LLVMCompiler {
|
||||
};
|
||||
self.values.insert(*dst, Box::new(IntegerBox::new(res)));
|
||||
}
|
||||
I::ExternCall { dst, iface_name, method_name, args, .. } => {
|
||||
if iface_name == "env.console" {
|
||||
if let Some(arg0) = args.get(0).and_then(|v| self.values.get(v)) {
|
||||
let msg = arg0.to_string_box().value;
|
||||
match method_name.as_str() {
|
||||
"log" => println!("{}", msg),
|
||||
"warn" => eprintln!("[warn] {}", msg),
|
||||
"error" => eprintln!("[error] {}", msg),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if let Some(d) = dst { self.values.insert(*d, Box::new(IntegerBox::new(0))); }
|
||||
}
|
||||
}
|
||||
I::Return { value } => {
|
||||
if let Some(v) = value { return self.values.get(v).map(|b| b.clone_box()).ok_or_else(|| format!("return %{} missing", v.0)); }
|
||||
return Ok(Box::new(IntegerBox::new(0)));
|
||||
|
||||
@ -6,6 +6,9 @@ use std::{fs, process};
|
||||
impl NyashRunner {
|
||||
/// Execute LLVM mode (split)
|
||||
pub(crate) fn execute_llvm_mode(&self, filename: &str) {
|
||||
// Initialize plugin host so method_id injection can resolve plugin calls
|
||||
crate::runner_plugin_init::init_bid_plugins();
|
||||
|
||||
// Read the file
|
||||
let code = match fs::read_to_string(filename) {
|
||||
Ok(content) => content,
|
||||
|
||||
44
tests/method_id_inject_filebox.rs
Normal file
44
tests/method_id_inject_filebox.rs
Normal file
@ -0,0 +1,44 @@
|
||||
#![cfg(all(feature = "plugins", not(target_arch = "wasm32")))]
|
||||
use nyash_rust::{parser::NyashParser, mir::{MirCompiler, passes::method_id_inject::inject_method_ids, instruction::MirInstruction}};
|
||||
use nyash_rust::runtime::plugin_loader_v2::{init_global_loader_v2, get_global_loader_v2};
|
||||
use nyash_rust::runtime::box_registry::get_global_registry;
|
||||
use nyash_rust::runtime::PluginConfig;
|
||||
|
||||
fn try_init_plugins() -> bool {
|
||||
if !std::path::Path::new("nyash.toml").exists() { return false; }
|
||||
if let Err(e) = init_global_loader_v2("nyash.toml") { eprintln!("init failed: {:?}", e); return false; }
|
||||
let loader = get_global_loader_v2();
|
||||
let loader = loader.read().unwrap();
|
||||
if let Some(conf) = &loader.config {
|
||||
let mut map = std::collections::HashMap::new();
|
||||
for (lib, def) in &conf.libraries { for b in &def.boxes { map.insert(b.clone(), lib.clone()); } }
|
||||
get_global_registry().apply_plugin_config(&PluginConfig { plugins: map });
|
||||
true
|
||||
} else { false }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn injects_method_id_for_filebox_open() {
|
||||
if !try_init_plugins() { return; }
|
||||
let code = r#"
|
||||
local f
|
||||
f = new FileBox()
|
||||
f.open("/tmp/test.txt", "r")
|
||||
"#;
|
||||
let ast = NyashParser::parse_from_string(code).expect("parse failed");
|
||||
let mut compiler = MirCompiler::new();
|
||||
let module = compiler.compile(ast).expect("mir compile failed").module;
|
||||
let mut module2 = module.clone();
|
||||
let injected = inject_method_ids(&mut module2);
|
||||
assert!(injected > 0);
|
||||
for func in module2.functions.values() {
|
||||
for block in func.blocks.values() {
|
||||
for inst in &block.instructions {
|
||||
if let MirInstruction::BoxCall { method, method_id, .. } = inst {
|
||||
if method == "open" { assert!(method_id.is_some(), "open missing method_id"); return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
panic!("FileBox.open not found");
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
use nyash_rust::mir::instruction_introspection;
|
||||
|
||||
// MIR14: ensure instruction count stays fixed at 14
|
||||
// MIR14: ensure instruction roster remains stable
|
||||
#[test]
|
||||
fn mir14_instruction_count() {
|
||||
fn mir14_shape_is_fixed() {
|
||||
let impl_names = instruction_introspection::mir14_instruction_names();
|
||||
assert_eq!(impl_names.len(), 14, "MIR14 must contain exactly 14 instructions");
|
||||
assert!(impl_names.contains(&"UnaryOp"), "MIR14 must include UnaryOp");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user