phase-20.45: PRIMARY no-fallback reps + MIR v0 shape fixes

- Fix MIR v0 shape in lowers: functions[] + name="main" + blocks.id
  * lower_return_int_box.hako
  * lower_return_binop_box.hako
- runner_min: adopt LowerReturnBinOpBox before ReturnInt
- Add PRIMARY no-fallback canaries (all PASS):
  * return-binop / array-size / load-store / return-logical (OR)
- Fix phase2043 runner_min canary alias (Runner -> BuilderRunnerMinBox)
- Update docs: phase-20.45 README (PRIMARY reps), CURRENT_TASK progress

Ancillary: keep builder/provider/canary files in sync; no unrelated behavior changes.
This commit is contained in:
nyash-codex
2025-11-05 18:57:03 +09:00
parent 0996090d6d
commit 96ea3892af
119 changed files with 4746 additions and 316 deletions

View File

@ -126,32 +126,75 @@ impl PluginHost {
/// Resolve a method handle for a given plugin box type and method name.
pub fn resolve_method(&self, box_type: &str, method_name: &str) -> BidResult<MethodHandle> {
let cfg = self.config.as_ref().ok_or(BidError::PluginError)?;
let (lib_name, _lib_def) = cfg
.find_library_for_box(box_type)
.ok_or(BidError::InvalidType)?;
let cfg_path = self.config_path.as_deref().unwrap_or("nyash.toml");
let toml_content = std::fs::read_to_string(cfg_path).map_err(|_| BidError::PluginError)?;
let toml_value: toml::Value =
toml::from_str(&toml_content).map_err(|_| BidError::PluginError)?;
let box_conf = cfg
.get_box_config(lib_name, box_type, &toml_value)
.ok_or(BidError::InvalidType)?;
// Prefer config mapping; fallback to loader's TypeBox resolve(name)
let (method_id, returns_result) = if let Some(m) = box_conf.methods.get(method_name) {
(m.method_id, m.returns_result)
} else {
let l = self.loader.read().unwrap();
let mid = l
.resolve_method_id(box_type, method_name)
.map_err(|_| BidError::InvalidMethod)?;
(mid, false)
};
// Path A: library-backed box (dynamic plugin)
if let Some((lib_name, _lib_def)) = cfg.find_library_for_box(box_type) {
if let Some(box_conf) = cfg.get_box_config(lib_name, box_type, &toml_value) {
// Prefer config mapping; fallback to loader's TypeBox resolve(name)
let (method_id, returns_result) = if let Some(m) = box_conf.methods.get(method_name) {
(m.method_id, m.returns_result)
} else {
let l = self.loader.read().unwrap();
let mid = l
.resolve_method_id(box_type, method_name)
.map_err(|_| BidError::InvalidMethod)?;
(mid, false)
};
return Ok(MethodHandle {
lib: lib_name.to_string(),
box_type: box_type.to_string(),
type_id: box_conf.type_id,
method_id,
returns_result,
});
}
}
// Path B: builtin/core boxes via central config (no library/path required)
// Require: [box_types] BoxName = <id> and [box_methods.BoxName.methods] entries
if let Some(type_id) = cfg.box_types.get(box_type).copied() {
if let Some(bm) = toml_value
.get("box_methods")
.and_then(|v| v.get(box_type))
.and_then(|v| v.get("methods"))
.and_then(|v| v.as_table())
{
if let Some(entry) = bm.get(method_name) {
// Support both { method_id = N } and bare integer in the future
let (method_id, returns_result) = if let Some(mid) = entry.get("method_id") {
(mid.as_integer().unwrap_or(0) as u32, entry.get("returns_result").and_then(|b| b.as_bool()).unwrap_or(false))
} else if let Some(mid) = entry.as_integer() {
(mid as u32, false)
} else {
return Err(BidError::InvalidMethod);
};
return Ok(MethodHandle {
lib: "builtin".to_string(),
box_type: box_type.to_string(),
type_id,
method_id,
returns_result,
});
}
}
}
// Fallback: delegate to loader (TypeBox, file-based, etc.)
let l = self.loader.read().unwrap();
let mid = l
.resolve_method_id(box_type, method_name)
.map_err(|_| BidError::InvalidMethod)?;
let type_id = *cfg.box_types.get(box_type).unwrap_or(&0);
Ok(MethodHandle {
lib: lib_name.to_string(),
lib: "builtin".to_string(),
box_type: box_type.to_string(),
type_id: box_conf.type_id,
method_id,
returns_result,
type_id,
method_id: mid,
returns_result: false,
})
}
@ -192,6 +235,36 @@ impl PluginHost {
/// Check if a method returns Result (Ok/Err) per plugin spec or central config.
pub fn method_returns_result(&self, box_type: &str, method_name: &str) -> bool {
// Prefer central config when available (works for builtin boxes)
if let Some(cfg) = self.config.as_ref() {
if let Some(path) = self.config_path.as_deref() {
if let Ok(toml_content) = std::fs::read_to_string(path) {
if let Ok(toml_value) = toml::from_str::<toml::Value>(&toml_content) {
if let Some(bm) = toml_value
.get("box_methods")
.and_then(|v| v.get(box_type))
.and_then(|v| v.get("methods"))
.and_then(|v| v.as_table())
{
if let Some(entry) = bm.get(method_name) {
return entry
.get("returns_result")
.and_then(|b| b.as_bool())
.unwrap_or(false);
}
}
// Library-backed path
if let Some((lib_name, _)) = cfg.find_library_for_box(box_type) {
if let Some(box_conf) = cfg.get_box_config(lib_name, box_type, &toml_value) {
if let Some(m) = box_conf.methods.get(method_name) {
return m.returns_result;
}
}
}
}
}
}
}
let l = self.loader.read().unwrap();
l.method_returns_result(box_type, method_name)
}