llvm: gate empty PHI sanitize behind NYASH_LLVM_SANITIZE_EMPTY_PHI=1; docs: AGENTS.md note. perf: begin clone() reduction plan — TypeBox.name/type_parameters to Arc<str>, adjusted builders/registry; no behavior change
This commit is contained in:
@ -212,6 +212,7 @@ Flags
|
|||||||
- Do not commit secrets. Plug‑in paths and native libs are configured via `nyash.toml`.
|
- Do not commit secrets. Plug‑in paths and native libs are configured via `nyash.toml`.
|
||||||
- LLVM builds require system LLVM 18; install via apt.llvm.org in CI.
|
- LLVM builds require system LLVM 18; install via apt.llvm.org in CI.
|
||||||
- Optional logs: enable `NYASH_CLI_VERBOSE=1` for detailed emit diagnostics.
|
- Optional logs: enable `NYASH_CLI_VERBOSE=1` for detailed emit diagnostics.
|
||||||
|
- LLVM harness safety valve (dev only): set `NYASH_LLVM_SANITIZE_EMPTY_PHI=1` to drop malformed empty PHI lines from IR before llvmlite parses it. Keep OFF for normal runs; use only to unblock bring-up when `finalize_phis` is being debugged.
|
||||||
|
|
||||||
## Codex Async Workflow (Background Jobs)
|
## Codex Async Workflow (Background Jobs)
|
||||||
- Purpose: run Codex tasks in the background and notify a tmux session on completion.
|
- Purpose: run Codex tasks in the background and notify a tmux session on completion.
|
||||||
|
|||||||
@ -24,6 +24,14 @@ Refactor Progress (2025-09-19, noon)
|
|||||||
- Behavior preserved: once/birth_once/computed generation identical to prior inline branch, including cache/poison and self-cycle guard.
|
- Behavior preserved: once/birth_once/computed generation identical to prior inline branch, including cache/poison and self-cycle guard.
|
||||||
- Postfix handlers (catch/cleanup) remain supported under Stage‑3 gate and are wrapped into TryCatch on the member body.
|
- Postfix handlers (catch/cleanup) remain supported under Stage‑3 gate and are wrapped into TryCatch on the member body.
|
||||||
|
|
||||||
|
P0/P1 Safety Fixes (2025-09-19)
|
||||||
|
- UserDefinedBoxFactory
|
||||||
|
- Added safe init stub: call InstanceBox::init(args) after creation (no panic; ignore error). Birth/init AST execution remains interpreter-owned.
|
||||||
|
- HTTPResponseBox interior mutability (thread-safe)
|
||||||
|
- Replaced fields with Mutex-based interior mutability and implemented setters: set_status/set_header/set_body/append_body.
|
||||||
|
- Updated to_http_string and Display/to_string to read via locks; manual Clone implemented.
|
||||||
|
- Removes RefCell TODOs at http_message_box.rs:292–330 without violating BoxCore Send+Sync.
|
||||||
|
|
||||||
Refactor Plan (next 1–2 weeks)
|
Refactor Plan (next 1–2 weeks)
|
||||||
1) Split parse_box_declaration (667 lines) in src/parser/declarations/box_definition.rs
|
1) Split parse_box_declaration (667 lines) in src/parser/declarations/box_definition.rs
|
||||||
- Targets (line ranges are indicative):
|
- Targets (line ranges are indicative):
|
||||||
|
|||||||
@ -1207,17 +1207,19 @@ class NyashLLVMBuilder:
|
|||||||
|
|
||||||
# Compile
|
# Compile
|
||||||
ir_text = str(self.module)
|
ir_text = str(self.module)
|
||||||
# Sanitize: drop any empty PHI rows (no incoming list) to satisfy IR parser
|
# Optional sanitize: drop any empty PHI rows (no incoming list) to satisfy IR parser.
|
||||||
try:
|
# Gate with NYASH_LLVM_SANITIZE_EMPTY_PHI=1. Default OFF.
|
||||||
fixed_lines = []
|
if os.environ.get('NYASH_LLVM_SANITIZE_EMPTY_PHI') == '1':
|
||||||
for line in ir_text.splitlines():
|
try:
|
||||||
if (" = phi i64" in line or " = phi i64" in line) and ("[" not in line):
|
fixed_lines = []
|
||||||
# Skip malformed PHI without incoming pairs
|
for line in ir_text.splitlines():
|
||||||
continue
|
if (" = phi i64" in line or " = phi i64" in line) and ("[" not in line):
|
||||||
fixed_lines.append(line)
|
# Skip malformed PHI without incoming pairs
|
||||||
ir_text = "\n".join(fixed_lines)
|
continue
|
||||||
except Exception:
|
fixed_lines.append(line)
|
||||||
pass
|
ir_text = "\n".join(fixed_lines)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
mod = llvm.parse_assembly(ir_text)
|
mod = llvm.parse_assembly(ir_text)
|
||||||
# Allow skipping verifier for iterative bring-up
|
# Allow skipping verifier for iterative bring-up
|
||||||
if os.environ.get('NYASH_LLVM_SKIP_VERIFY') != '1':
|
if os.environ.get('NYASH_LLVM_SKIP_VERIFY') != '1':
|
||||||
|
|||||||
@ -52,7 +52,7 @@ impl MethodSignature {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TypeBox {
|
pub struct TypeBox {
|
||||||
/// 型名
|
/// 型名
|
||||||
pub name: String,
|
pub name: Arc<str>,
|
||||||
|
|
||||||
/// フィールド情報 (field_name -> field_type)
|
/// フィールド情報 (field_name -> field_type)
|
||||||
pub fields: HashMap<String, Arc<TypeBox>>,
|
pub fields: HashMap<String, Arc<TypeBox>>,
|
||||||
@ -64,7 +64,7 @@ pub struct TypeBox {
|
|||||||
pub parent_type: Option<Arc<TypeBox>>,
|
pub parent_type: Option<Arc<TypeBox>>,
|
||||||
|
|
||||||
/// ジェネリクス型パラメータ
|
/// ジェネリクス型パラメータ
|
||||||
pub type_parameters: Vec<String>,
|
pub type_parameters: Vec<Arc<str>>,
|
||||||
|
|
||||||
/// インスタンス化された具体型(ジェネリクス用)
|
/// インスタンス化された具体型(ジェネリクス用)
|
||||||
pub concrete_types: HashMap<String, Arc<TypeBox>>,
|
pub concrete_types: HashMap<String, Arc<TypeBox>>,
|
||||||
@ -80,7 +80,7 @@ impl TypeBox {
|
|||||||
/// 新しいTypeBoxを作成
|
/// 新しいTypeBoxを作成
|
||||||
pub fn new(name: &str) -> Self {
|
pub fn new(name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: name.to_string(),
|
name: Arc::<str>::from(name),
|
||||||
fields: HashMap::new(),
|
fields: HashMap::new(),
|
||||||
methods: HashMap::new(),
|
methods: HashMap::new(),
|
||||||
parent_type: None,
|
parent_type: None,
|
||||||
@ -114,8 +114,8 @@ impl TypeBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 型パラメータを追加
|
/// 型パラメータを追加
|
||||||
pub fn add_type_parameter(&mut self, param: String) {
|
pub fn add_type_parameter<S: Into<Arc<str>>>(&mut self, param: S) {
|
||||||
self.type_parameters.push(param);
|
self.type_parameters.push(param.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 具体型を設定(ジェネリクス用)
|
/// 具体型を設定(ジェネリクス用)
|
||||||
@ -183,9 +183,9 @@ impl TypeBox {
|
|||||||
/// 型名を完全表示(ジェネリクス対応)
|
/// 型名を完全表示(ジェネリクス対応)
|
||||||
pub fn full_name(&self) -> String {
|
pub fn full_name(&self) -> String {
|
||||||
if self.concrete_types.is_empty() {
|
if self.concrete_types.is_empty() {
|
||||||
self.name.clone()
|
self.name.as_ref().to_string()
|
||||||
} else {
|
} else {
|
||||||
let mut result = self.name.clone();
|
let mut result = self.name.as_ref().to_string();
|
||||||
result.push('<');
|
result.push('<');
|
||||||
|
|
||||||
let concrete_names: Vec<String> = self
|
let concrete_names: Vec<String> = self
|
||||||
@ -193,9 +193,9 @@ impl TypeBox {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|param| {
|
.map(|param| {
|
||||||
self.concrete_types
|
self.concrete_types
|
||||||
.get(param)
|
.get(param.as_ref())
|
||||||
.map(|t| t.name.clone())
|
.map(|t| t.name.as_ref().to_string())
|
||||||
.unwrap_or_else(|| param.clone())
|
.unwrap_or_else(|| param.as_ref().to_string())
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -331,18 +331,18 @@ impl TypeRegistry {
|
|||||||
|
|
||||||
/// 型を登録
|
/// 型を登録
|
||||||
pub fn register_type(&mut self, type_box: Arc<TypeBox>) {
|
pub fn register_type(&mut self, type_box: Arc<TypeBox>) {
|
||||||
let name = type_box.name.clone();
|
let name_s: String = type_box.name.as_ref().to_string();
|
||||||
|
|
||||||
// 継承チェーンを構築
|
// 継承チェーンを構築
|
||||||
let mut chain = vec![name.clone()];
|
let mut chain = vec![name_s.clone()];
|
||||||
let mut current = &type_box.parent_type;
|
let mut current = &type_box.parent_type;
|
||||||
while let Some(parent) = current {
|
while let Some(parent) = current {
|
||||||
chain.push(parent.name.clone());
|
chain.push(parent.name.as_ref().to_string());
|
||||||
current = &parent.parent_type;
|
current = &parent.parent_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.inheritance_chains.insert(name.clone(), chain);
|
self.inheritance_chains.insert(name_s.clone(), chain);
|
||||||
self.types.insert(name, type_box);
|
self.types.insert(name_s, type_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 型を取得
|
/// 型を取得
|
||||||
@ -393,7 +393,7 @@ impl TypeRegistry {
|
|||||||
|
|
||||||
// 新しい具体化型を作成
|
// 新しい具体化型を作成
|
||||||
let mut concrete_type = (*base).clone();
|
let mut concrete_type = (*base).clone();
|
||||||
concrete_type.name = format!("{}_{}", base_type, concrete_types.join("_"));
|
concrete_type.name = format!("{}_{}", base_type, concrete_types.join("_")).into();
|
||||||
concrete_type.concrete_types.clear();
|
concrete_type.concrete_types.clear();
|
||||||
|
|
||||||
// 具体型を設定
|
// 具体型を設定
|
||||||
@ -446,7 +446,7 @@ impl TypeBoxBuilder {
|
|||||||
|
|
||||||
/// 型パラメータを追加
|
/// 型パラメータを追加
|
||||||
pub fn type_param(mut self, param: &str) -> Self {
|
pub fn type_param(mut self, param: &str) -> Self {
|
||||||
self.type_box.add_type_parameter(param.to_string());
|
self.type_box.add_type_parameter(param);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user