docs: Add LLVM Python harness plan to CURRENT_TASK
- Added llvmlite verification harness strategy - Python as parallel verification path for PHI/SSA issues - Nyash ABI wrapper for LLVM emit abstraction - NYASH_LLVM_USE_HARNESS=1 flag for mode switching - Goal: Rust implementation in 1-2 days, Python for rapid verification Acknowledging reality: When stuck at minimal viable implementation, changing implementation language is a practical solution. 'Simple is Best' - the core Nyash philosophy.
This commit is contained in:
@ -4,10 +4,13 @@ use inkwell::values::BasicValueEnum as BVE;
|
||||
use inkwell::AddressSpace;
|
||||
|
||||
use crate::backend::llvm::context::CodegenContext;
|
||||
use crate::mir::{function::MirFunction, ValueId};
|
||||
use crate::mir::{function::MirFunction, BasicBlockId, ValueId};
|
||||
use crate::backend::llvm::compiler::codegen::instructions::builder_cursor::BuilderCursor;
|
||||
|
||||
pub(super) fn lower_future_spawn_instance<'ctx>(
|
||||
pub(super) fn lower_future_spawn_instance<'ctx, 'b>(
|
||||
codegen: &CodegenContext<'ctx>,
|
||||
cursor: &mut BuilderCursor<'ctx, 'b>,
|
||||
cur_bid: BasicBlockId,
|
||||
vmap: &mut HashMap<ValueId, BVE<'ctx>>,
|
||||
dst: &Option<ValueId>,
|
||||
args: &[ValueId],
|
||||
@ -20,9 +23,8 @@ pub(super) fn lower_future_spawn_instance<'ctx>(
|
||||
let recv_v = *vmap.get(&args[0]).ok_or("recv missing")?;
|
||||
let recv_h = match recv_v {
|
||||
BVE::IntValue(iv) => iv,
|
||||
BVE::PointerValue(pv) => codegen
|
||||
.builder
|
||||
.build_ptr_to_int(pv, i64t, "recv_p2i")
|
||||
BVE::PointerValue(pv) => cursor
|
||||
.emit_instr(cur_bid, |b| b.build_ptr_to_int(pv, i64t, "recv_p2i"))
|
||||
.map_err(|e| e.to_string())?,
|
||||
_ => return Err("spawn_instance recv must be int or ptr".to_string()),
|
||||
};
|
||||
@ -36,9 +38,8 @@ pub(super) fn lower_future_spawn_instance<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.future.spawn_instance")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.future.spawn_instance", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[recv_h.into(), name_p.into()], "spawn_instance")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[recv_h.into(), name_p.into()], "spawn_instance"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
if let Some(d) = dst {
|
||||
let rv = call
|
||||
@ -50,8 +51,10 @@ pub(super) fn lower_future_spawn_instance<'ctx>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn lower_local_get<'ctx>(
|
||||
pub(super) fn lower_local_get<'ctx, 'b>(
|
||||
codegen: &CodegenContext<'ctx>,
|
||||
cursor: &mut BuilderCursor<'ctx, 'b>,
|
||||
cur_bid: BasicBlockId,
|
||||
func: &MirFunction,
|
||||
vmap: &mut HashMap<ValueId, BVE<'ctx>>,
|
||||
dst: &Option<ValueId>,
|
||||
@ -73,9 +76,8 @@ pub(super) fn lower_local_get<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.env.local.get_h")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.env.local.get_h", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[name_p.into()], "local_get_h")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[name_p.into()], "local_get_h"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call
|
||||
.try_as_basic_value()
|
||||
@ -98,9 +100,8 @@ pub(super) fn lower_local_get<'ctx>(
|
||||
| crate::mir::MirType::Unknown => {
|
||||
let h = rv.into_int_value();
|
||||
let pty = codegen.context.ptr_type(AddressSpace::from(0));
|
||||
let ptr = codegen
|
||||
.builder
|
||||
.build_int_to_ptr(h, pty, "local_get_handle_to_ptr")
|
||||
let ptr = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_int_to_ptr(h, pty, "local_get_handle_to_ptr"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
vmap.insert(*d, ptr.into());
|
||||
}
|
||||
@ -115,8 +116,10 @@ pub(super) fn lower_local_get<'ctx>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn lower_box_new<'ctx>(
|
||||
pub(super) fn lower_box_new<'ctx, 'b>(
|
||||
codegen: &CodegenContext<'ctx>,
|
||||
cursor: &mut BuilderCursor<'ctx, 'b>,
|
||||
cur_bid: BasicBlockId,
|
||||
vmap: &mut HashMap<ValueId, BVE<'ctx>>,
|
||||
dst: &Option<ValueId>,
|
||||
args: &[ValueId],
|
||||
@ -137,18 +140,16 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.env.box.new")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.env.box.new", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[name_p.into()], "env_box_new")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[name_p.into()], "env_box_new"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let h = call
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.ok_or("env.box.new returned void".to_string())?
|
||||
.into_int_value();
|
||||
let out_ptr = codegen
|
||||
.builder
|
||||
.build_int_to_ptr(h, i8p, "box_handle_to_ptr")
|
||||
let out_ptr = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_int_to_ptr(h, i8p, "box_handle_to_ptr"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
if let Some(d) = dst {
|
||||
vmap.insert(*d, out_ptr.into());
|
||||
@ -192,9 +193,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_f64")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_f64", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[fv.into()], "arg1_f64_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[fv.into()], "arg1_f64_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call
|
||||
.try_as_basic_value()
|
||||
@ -208,9 +208,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_i8_string")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_i8_string", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[pv.into()], "arg1_i8_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[pv.into()], "arg1_i8_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call.try_as_basic_value().left().ok_or("from_i8_string returned void".to_string())?;
|
||||
if let BVE::IntValue(h) = rv { h } else { return Err("from_i8_string ret expected i64".to_string()); }
|
||||
@ -229,9 +228,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_f64")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_f64", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[fv.into()], "arg2_f64_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[fv.into()], "arg2_f64_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call
|
||||
.try_as_basic_value()
|
||||
@ -245,9 +243,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_i8_string")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_i8_string", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[pv.into()], "arg2_i8_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[pv.into()], "arg2_i8_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call.try_as_basic_value().left().ok_or("from_i8_string returned void".to_string())?;
|
||||
if let BVE::IntValue(h) = rv { h } else { return Err("from_i8_string ret expected i64".to_string()); }
|
||||
@ -266,9 +263,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_f64")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_f64", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[fv.into()], "arg3_f64_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[fv.into()], "arg3_f64_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call
|
||||
.try_as_basic_value()
|
||||
@ -282,9 +278,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_i8_string")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_i8_string", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[pv.into()], "arg3_i8_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[pv.into()], "arg3_i8_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call.try_as_basic_value().left().ok_or("from_i8_string returned void".to_string())?;
|
||||
if let BVE::IntValue(h) = rv { h } else { return Err("from_i8_string ret expected i64".to_string()); }
|
||||
@ -303,9 +298,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_f64")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_f64", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[fv.into()], "arg4_f64_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[fv.into()], "arg4_f64_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call
|
||||
.try_as_basic_value()
|
||||
@ -319,9 +313,8 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
.module
|
||||
.get_function("nyash.box.from_i8_string")
|
||||
.unwrap_or_else(|| codegen.module.add_function("nyash.box.from_i8_string", fnty, None));
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(callee, &[pv.into()], "arg4_i8_to_box")
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(callee, &[pv.into()], "arg4_i8_to_box"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call.try_as_basic_value().left().ok_or("from_i8_string returned void".to_string())?;
|
||||
if let BVE::IntValue(h) = rv { h } else { return Err("from_i8_string ret expected i64".to_string()); }
|
||||
@ -329,22 +322,20 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
_ => return Err("unsupported arg value for env.box.new".to_string()),
|
||||
};
|
||||
}
|
||||
let call = codegen
|
||||
.builder
|
||||
.build_call(
|
||||
let call = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_call(
|
||||
callee,
|
||||
&[ty_ptr.into(), argc_val.into(), a1.into(), a2.into(), a3.into(), a4.into()],
|
||||
"env_box_new_i64x",
|
||||
)
|
||||
))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let rv = call
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.ok_or("env.box.new_i64 returned void".to_string())?;
|
||||
let i64v = if let BVE::IntValue(iv) = rv { iv } else { return Err("env.box.new_i64 ret expected i64".to_string()); };
|
||||
let out_ptr = codegen
|
||||
.builder
|
||||
.build_int_to_ptr(i64v, i8p, "box_handle_to_ptr")
|
||||
let out_ptr = cursor
|
||||
.emit_instr(cur_bid, |b| b.build_int_to_ptr(i64v, i8p, "box_handle_to_ptr"))
|
||||
.map_err(|e| e.to_string())?;
|
||||
if let Some(d) = dst {
|
||||
vmap.insert(*d, out_ptr.into());
|
||||
@ -353,4 +344,3 @@ pub(super) fn lower_box_new<'ctx>(
|
||||
}
|
||||
Err("env.box.new requires at least 1 arg".to_string())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user