Stage-A selfhost emitter fixes and LLVM opt toggle

This commit is contained in:
nyash-codex
2025-10-31 23:16:27 +09:00
parent abe174830f
commit 8b71f25dd4
10 changed files with 353 additions and 38 deletions

View File

@ -2,6 +2,7 @@
use super::{ConstValue, MirInstruction, ValueId};
use crate::ast::ASTNode;
use crate::mir::slot_registry::{get_or_assign_type_id, reserve_method_slot};
use serde_json;
use std::collections::HashSet;
impl super::MirBuilder {
@ -27,17 +28,18 @@ impl super::MirBuilder {
self.current_static_box = Some(box_name.clone());
// Look for the main() method
let out = if let Some(main_method) = methods.get("main") {
if let ASTNode::FunctionDeclaration { params, body, .. } = main_method {
// Also materialize a callable function entry "BoxName.main/N" for harness/PyVM
let func_name = format!("{}.{}", box_name, "main");
let _ = self.lower_static_method_as_function(func_name, params.clone(), body.clone());
// Convert the method body to a Program AST node and lower it
let program_ast = ASTNode::Program {
if let ASTNode::FunctionDeclaration { params, body, .. } = main_method {
// Also materialize a callable function entry "BoxName.main/N" for harness/PyVM
let func_name = format!("{}.{}", box_name, "main");
let _ = self.lower_static_method_as_function(func_name, params.clone(), body.clone());
// Convert the method body to a Program AST node and lower it
let program_ast = ASTNode::Program {
statements: body.clone(),
span: crate::ast::Span::unknown(),
};
// Bind default parameters if present (e.g., args=[])
let saved_var_map = std::mem::take(&mut self.variable_map);
let script_args = collect_script_args_from_env();
for p in params.iter() {
let pid = self.value_gen.next();
if p == "args" {
@ -47,6 +49,24 @@ impl super::MirBuilder {
box_type: "ArrayBox".to_string(),
args: vec![],
})?;
self.value_origin_newbox
.insert(pid, "ArrayBox".to_string());
self
.value_types
.insert(pid, super::MirType::Box("ArrayBox".to_string()));
if let Some(args) = script_args.as_ref() {
for arg in args {
let val = crate::mir::builder::emission::constant::emit_string(self, arg.clone());
self.emit_instruction(MirInstruction::BoxCall {
dst: None,
box_val: pid,
method: "push".to_string(),
method_id: None,
args: vec![val],
effects: super::EffectMask::MUT,
})?;
}
}
} else {
let v = crate::mir::builder::emission::constant::emit_void(self);
// ensure pid holds the emitted const id
@ -137,3 +157,13 @@ impl super::MirBuilder {
Ok(())
}
}
fn collect_script_args_from_env() -> Option<Vec<String>> {
let raw = std::env::var("NYASH_SCRIPT_ARGS_JSON")
.or_else(|_| std::env::var("HAKO_SCRIPT_ARGS_JSON"))
.ok()?;
match serde_json::from_str::<Vec<String>>(&raw) {
Ok(list) if !list.is_empty() => Some(list),
_ => None,
}
}