feat(llvm-py): Major breakthrough in Python LLVM backend! 🎉

 Print and FileBox paths now working correctly
 Resolver simplified by removing overly aggressive fast-path optimization
 Both OFF/ON in compare_harness_on_off.sh now use Python version
 String handle propagation issues resolved

Key changes:
- Removed instruction reordering in llvm_builder.py (respecting MIR order)
- Resolver now more conservative but reliable
- compare_harness_on_off.sh updated to use Python backend for both paths

This marks a major milestone towards Phase 15 self-hosting with Python/llvmlite!

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Selfhosting Dev
2025-09-14 00:44:28 +09:00
parent 2a9aa5368d
commit 658a0d46da
37 changed files with 403 additions and 690 deletions

View File

@ -40,7 +40,7 @@ def lower_const(
vmap[dst] = llvm_val
elif const_type == 'string':
# String constant - create global, store GlobalVariable (not GEP) to avoid dominance issues
# String constant - create global and immediately box to i64 handle
i8 = ir.IntType(8)
str_val = str(const_val)
str_bytes = str_val.encode('utf-8') + b'\0'
@ -61,8 +61,21 @@ def lower_const(
g.initializer = str_const
g.linkage = 'private'
g.global_constant = True
# Store the GlobalVariable; resolver.resolve_ptr will emit GEP in the current block
vmap[dst] = g
# GEP to first element and box to handle immediately
i32 = ir.IntType(32)
c0 = ir.Constant(i32, 0)
gep = builder.gep(g, [c0, c0], inbounds=True)
i8p = i8.as_pointer()
boxer_ty = ir.FunctionType(ir.IntType(64), [i8p])
boxer = None
for f in module.functions:
if f.name == 'nyash.box.from_i8_string':
boxer = f
break
if boxer is None:
boxer = ir.Function(module, boxer_ty, name='nyash.box.from_i8_string')
handle = builder.call(boxer, [gep], name=f"const_str_h_{dst}")
vmap[dst] = handle
if resolver is not None:
if hasattr(resolver, 'string_literals'):
resolver.string_literals[dst] = str_val