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:
@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user