📚 Phase 12: Nyashスクリプトプラグインシステム設計と埋め込みVM構想

## 主な成果
- Nyashスクリプトでプラグイン作成可能という革命的発見
- C ABI制約の分析と埋め込みVMによる解決策
- MIR/VM/JIT層での箱引数サポートの詳細分析

## ドキュメント作成
- Phase 12基本構想(README.md)
- Gemini/Codex先生の技術分析
- C ABIとの整合性問題と解決策
- 埋め込みVM実装ロードマップ
- 箱引数サポートの技術詳細

## 重要な洞察
- 制約は「リンク時にC ABI必要」のみ
- 埋め込みVMでMIRバイトコード実行により解決可能
- Nyashスクリプト→C ABIプラグイン変換が実現可能

Everything is Box → Everything is Plugin → Everything is Possible!
This commit is contained in:
Moe Charm
2025-08-30 22:52:16 +09:00
parent 7a0f9bd432
commit c13d9c045e
82 changed files with 5842 additions and 138 deletions

View File

@ -0,0 +1,11 @@
[package]
name = "nyash-python-compiler-plugin"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "staticlib"]
[dependencies]
once_cell = "1.20"
serde_json = "1"

View File

@ -0,0 +1,29 @@
[box]
name = "Nyash Python Compiler Plugin"
version = "0.1.0"
description = "CorePy IR -> Nyash Source (Phase 10.7 C2)"
author = "Nyash Team"
[provides]
boxes = ["PythonCompilerBox"]
[PythonCompilerBox]
type_id = 61
[PythonCompilerBox.lifecycle]
birth = { id = 0 }
fini = { id = 4294967295 }
[PythonCompilerBox.methods.compile]
id = 1
args = [ { name = "ir_json", type = "string" } ]
returns = { type = "string" } # Nyash source (暫定)
[implementation]
ffi_version = 1
thread_safe = false
[artifacts]
windows = "target/x86_64-pc-windows-msvc/release/nyash_python_compiler_plugin.dll"
linux = "target/release/libnyash_python_compiler_plugin.so"
macos = "target/release/libnyash_python_compiler_plugin.dylib"

View File

@ -0,0 +1,103 @@
use once_cell::sync::Lazy;
use std::sync::Mutex;
use serde_json::Value as Json;
const NYB_SUCCESS: i32 = 0;
const NYB_E_INVALID_METHOD: i32 = -3;
const NYB_E_SHORT_BUFFER: i32 = -1;
const TYPE_ID_COMPILER: u32 = 61;
const METHOD_BIRTH: u32 = 0;
const METHOD_COMPILE: u32 = 1;
const METHOD_FINI: u32 = u32::MAX;
static NEXT_ID: Lazy<Mutex<u32>> = Lazy::new(|| Mutex::new(1));
#[no_mangle]
pub extern "C" fn nyash_plugin_abi() -> u32 { 1 }
#[no_mangle]
pub extern "C" fn nyash_plugin_init() -> i32 { NYB_SUCCESS }
#[no_mangle]
pub extern "C" fn nyash_plugin_invoke(
type_id: u32,
method_id: u32,
_instance_id: u32,
args: *const u8,
args_len: usize,
result: *mut u8,
result_len: *mut usize,
) -> i32 {
if type_id != TYPE_ID_COMPILER { return NYB_E_INVALID_METHOD; }
match method_id {
METHOD_BIRTH => {
unsafe {
let mut id_g = NEXT_ID.lock().unwrap();
let id = *id_g; *id_g += 1;
let need = 4usize;
if *result_len < need { *result_len = need; return NYB_E_SHORT_BUFFER; }
let out = std::slice::from_raw_parts_mut(result, *result_len);
out[0..4].copy_from_slice(&(id as u32).to_le_bytes());
*result_len = need;
}
NYB_SUCCESS
}
METHOD_COMPILE => {
// Decode TLV first string arg as JSON IR
let ir = unsafe {
if args.is_null() || args_len < 8 { None } else {
let buf = std::slice::from_raw_parts(args, args_len);
let tag = u16::from_le_bytes([buf[4], buf[5]]);
let len = u16::from_le_bytes([buf[6], buf[7]]) as usize;
if tag == 6 && 8 + len <= buf.len() {
match std::str::from_utf8(&buf[8..8+len]) {
Ok(s) => Some(s.to_string()),
Err(_) => None
}
} else { None }
}
};
let nyash_source = if let Some(s) = ir.or_else(|| std::env::var("NYASH_PY_IR").ok()) {
// Minimal: accept either {"nyash_source": "..."} shortcut, or a tiny IR
match serde_json::from_str::<Json>(&s).ok() {
Some(Json::Object(map)) => {
if let Some(Json::String(src)) = map.get("nyash_source") {
src.clone()
} else if let Some(module) = map.get("module") {
// Try module.functions[0].name and maybe return value
let mut ret_expr = "0".to_string();
if let Some(funcs) = module.get("functions").and_then(|v| v.as_array()) {
if let Some(fun0) = funcs.get(0) {
if let Some(retv) = fun0.get("return_value") {
if retv.is_number() { ret_expr = retv.to_string(); }
else if let Some(s) = retv.as_str() { ret_expr = s.to_string(); }
}
}
}
format!("static box Generated {{\n main() {{\n return {}\n }}\n}}", ret_expr)
} else {
"static box Generated { main() { return 0 } }".to_string()
}
}
_ => "static box Generated { main() { return 0 } }".to_string(),
}
} else {
"static box Generated { main() { return 0 } }".to_string()
};
unsafe {
let bytes = nyash_source.as_bytes();
let need = 4 + bytes.len();
if *result_len < need { *result_len = need; return NYB_E_SHORT_BUFFER; }
let out = std::slice::from_raw_parts_mut(result, *result_len);
out[0..2].copy_from_slice(&6u16.to_le_bytes());
out[2..4].copy_from_slice(&(bytes.len() as u16).to_le_bytes());
out[4..4+bytes.len()].copy_from_slice(bytes);
*result_len = need;
}
NYB_SUCCESS
}
METHOD_FINI => NYB_SUCCESS,
_ => NYB_E_INVALID_METHOD,
}
}