Phase A リファクタリング: String.length デバッグ基盤の強化
## 実装内容(振る舞い変更なし)
A-1: Hostcall シンボルの定数化
- 直書き文字列を SYM_* 定数に統一
- nyash.handle.of / nyash.string.len_h / nyash.console.birth_h
A-2: string_len ヘルパー抽出(共通化)
- src/jit/lower/core/string_len.rs 新設
- emit_len_with_fallback_{param,local_handle,literal} を移設
- 二段フォールバック(string.len_h → any.length_h)の集約
A-3: 観測の統一
- import 呼び出しトレース機能を追加(NYASH_JIT_TRACE_IMPORT=1)
- CraneliftBuilder/ObjectBuilder の emit_host_call に構造化イベント
- observe::lower_hostcall で len_h/any.length_h の追跡
## 今後の道筋(CURRENT_TASK.md に記載)
- P0: フェイルセーフ(NYASH_LEN_FORCE_BRIDGE=1)
- P1: シンボル解決の可視化
- P2: リテラル最優先の安定化
- P3: Return 材化の後方走査
バグは手強いけど、デバッグ基盤が整ったにゃ!
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -285,6 +285,22 @@ impl IRBuilder for ObjectBuilder {
|
||||
fn emit_host_call(&mut self, symbol: &str, argc: usize, has_ret: bool) {
|
||||
use cranelift_codegen::ir::{AbiParam, Signature, types};
|
||||
use cranelift_frontend::FunctionBuilder;
|
||||
// Structured lower event for import call (AOT builder)
|
||||
{
|
||||
let mut arg_types: Vec<&'static str> = Vec::new();
|
||||
for _ in 0..argc { arg_types.push("I64"); }
|
||||
crate::jit::events::emit_lower(
|
||||
serde_json::json!({
|
||||
"id": symbol,
|
||||
"decision": "allow",
|
||||
"reason": "import_call",
|
||||
"argc": argc,
|
||||
"arg_types": arg_types,
|
||||
"ret": if has_ret { "I64" } else { "Void" }
|
||||
}),
|
||||
"hostcall","<aot>"
|
||||
);
|
||||
}
|
||||
let mut fb = FunctionBuilder::new(&mut self.ctx.func, &mut self.fbc);
|
||||
if let Some(idx) = self.current_block_index { fb.switch_to_block(self.blocks[idx]); }
|
||||
else if let Some(b) = self.entry_block { fb.switch_to_block(b); }
|
||||
@ -304,6 +320,22 @@ impl IRBuilder for ObjectBuilder {
|
||||
fn emit_host_call_typed(&mut self, symbol: &str, params: &[super::ParamKind], has_ret: bool, ret_is_f64: bool) {
|
||||
use cranelift_codegen::ir::{AbiParam, Signature, types};
|
||||
use cranelift_frontend::FunctionBuilder;
|
||||
// Structured lower event for typed import call (AOT builder)
|
||||
{
|
||||
let mut arg_types: Vec<&'static str> = Vec::new();
|
||||
for k in params { arg_types.push(match k { super::ParamKind::I64 | super::ParamKind::B1 => "I64", super::ParamKind::F64 => "F64" }); }
|
||||
crate::jit::events::emit_lower(
|
||||
serde_json::json!({
|
||||
"id": symbol,
|
||||
"decision": "allow",
|
||||
"reason": "import_call_typed",
|
||||
"argc": params.len(),
|
||||
"arg_types": arg_types,
|
||||
"ret": if has_ret { if ret_is_f64 { "F64" } else { "I64" } } else { "Void" }
|
||||
}),
|
||||
"hostcall","<aot>"
|
||||
);
|
||||
}
|
||||
let mut fb = FunctionBuilder::new(&mut self.ctx.func, &mut self.fbc);
|
||||
if let Some(idx) = self.current_block_index { fb.switch_to_block(self.blocks[idx]); }
|
||||
else if let Some(b) = self.entry_block { fb.switch_to_block(b); }
|
||||
|
||||
Reference in New Issue
Block a user