fix(llvm): Phase 131-10 - Smart console.log routing(Segfault修正)

## 問題
- Integer値をi8*ポインタに変換 → Segfault(Exit 139)

## 解決策
- String literal → nyash.console.log(i8*)
- Integer/Handle → nyash.console.log_handle(i64)

## 結果
- Case B (loop_min_while): LLVM outputs `0,1,2` 
- VM/LLVM完全パリティ達成

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-14 09:19:00 +09:00
parent bfe047840b
commit 18bf35e6d4
8 changed files with 97 additions and 104 deletions

View File

@ -80,10 +80,30 @@ def lower_externcall(
# Many call sites pass handles or pointers; we coerce below.
}
# Phase 131-10: Smart console.log routing
# If console.log is called with a non-string-literal argument, use console.log_handle instead
actual_c_symbol = c_symbol_name
use_handle_variant = False
if llvm_name in ("nyash.console.log", "nyash.console.warn", "nyash.console.error"):
# Check if first argument is a string literal
if len(args) > 0:
first_arg = args[0]
is_string_literal = False
if resolver is not None and hasattr(resolver, 'string_ptrs'):
is_string_literal = first_arg in resolver.string_ptrs
# If NOT a string literal, use the _handle variant
if not is_string_literal:
use_handle_variant = True
# Extract method name (log, warn, error)
method = llvm_name.split('.')[-1]
actual_c_symbol = f"nyash.console.{method}_handle"
# Find or declare function with appropriate prototype
func = None
for f in module.functions:
if f.name == c_symbol_name:
if f.name == actual_c_symbol:
func = f
break
if not func:
@ -91,6 +111,10 @@ def lower_externcall(
ret_ty, arg_tys = sig_map[llvm_name]
fnty = ir.FunctionType(ret_ty, arg_tys)
func = ir.Function(module, fnty, name=c_symbol_name)
elif use_handle_variant:
# console.*_handle: (i64) -> i64
fnty = ir.FunctionType(i64, [i64])
func = ir.Function(module, fnty, name=actual_c_symbol)
elif llvm_name.startswith("nyash.console."):
# console.*: (i8*) -> i64
fnty = ir.FunctionType(i64, [i8p])