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
|
./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到達!セルフホスティング実装中
|
- 🎉 Phase 15到達!セルフホスティング実装中
|
||||||
- v0 Nyパーサー完成(Ny→JSON IR v0)
|
- v0 Nyパーサー完成(Ny→JSON IR v0)
|
||||||
- 🔥 ループビルダーSSAバグ発見・調査完了(ブロッカー)
|
- 🔥 ループビルダー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> {
|
) -> Result<Box<dyn NyashBox>, String> {
|
||||||
// Mock implementation - interprets MIR instructions to simulate execution
|
// 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):");
|
println!("🚀 Mock LLVM Compile & Execute (MIR Interpreter Mode):");
|
||||||
|
|
||||||
// 1. Mock object file generation
|
// 1. Mock object file generation
|
||||||
@ -1445,6 +1448,20 @@ impl LLVMCompiler {
|
|||||||
};
|
};
|
||||||
self.values.insert(*dst, Box::new(IntegerBox::new(res)));
|
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 } => {
|
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)); }
|
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)));
|
return Ok(Box::new(IntegerBox::new(0)));
|
||||||
|
|||||||
@ -6,6 +6,9 @@ use std::{fs, process};
|
|||||||
impl NyashRunner {
|
impl NyashRunner {
|
||||||
/// Execute LLVM mode (split)
|
/// Execute LLVM mode (split)
|
||||||
pub(crate) fn execute_llvm_mode(&self, filename: &str) {
|
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
|
// Read the file
|
||||||
let code = match fs::read_to_string(filename) {
|
let code = match fs::read_to_string(filename) {
|
||||||
Ok(content) => content,
|
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;
|
use nyash_rust::mir::instruction_introspection;
|
||||||
|
|
||||||
// MIR14: ensure instruction count stays fixed at 14
|
// MIR14: ensure instruction roster remains stable
|
||||||
#[test]
|
#[test]
|
||||||
fn mir14_instruction_count() {
|
fn mir14_shape_is_fixed() {
|
||||||
let impl_names = instruction_introspection::mir14_instruction_names();
|
let impl_names = instruction_introspection::mir14_instruction_names();
|
||||||
assert_eq!(impl_names.len(), 14, "MIR14 must contain exactly 14 instructions");
|
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