From b268544955fb95d0d7ace992b23bddc88bb97d4c Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 18 Oct 2024 21:24:10 +0200
Subject: [PATCH] ltcc: output separate runtime.lt.o to avoid duplication when
 loading multiple object files in ltvm

---
 ltcc/src/main.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/ltcc/src/main.rs b/ltcc/src/main.rs
index 813134b..12992aa 100644
--- a/ltcc/src/main.rs
+++ b/ltcc/src/main.rs
@@ -32,7 +32,60 @@ fn main() {
     let args = Args::parse();
 
     let mut linker = tisc::Linker::new();
-    let root_scope = ltcore::runtime::init_runtime(&mut linker);
+    let mut runtime_linker = tisc::Linker::new();
+
+    let root_scope = ltcore::runtime::init_runtime(&mut runtime_linker);
+    let runtime_obj_file = tisc::linker::ObjectFile {
+        symbols: root_scope.read().unwrap().clone()
+            .export()
+            .into_iter()
+            .filter_map(|(symbol, def)| match def {
+                ltcore::symbols::SymbolDef::Procedure { in_types:_, out_types:_, link_addr, export } => {
+                    if true {
+                        match link_addr {
+                            tisc::LinkAddr::Absolute(w) => {
+                                // eprintln!("add symbol {} -> {}", symbol, w);
+                                Some(( symbol, w ))
+                            }
+                            tisc::LinkAddr::Relative{ symbol: b, offset } => {
+                                let addr = runtime_linker.get_link_addr(&b).unwrap_or(-1);
+                                // eprintln!("relative symbol {} -> {}({})+{}", symbol, b, addr, offset);
+                                Some((symbol, addr + offset))
+                            }
+                        }
+                    } else {
+                        None
+                    }
+                }
+                _ => None
+            })
+            .collect(),
+
+        code: runtime_linker.link_partial().expect("Link error:")
+            .into_iter()
+            .map(|w| match w {
+                tisc::assembler::AssemblyWord::Symbol(
+                    tisc::LinkAddr::Absolute(a)
+                ) => {
+                    tisc::assembler::AssemblyWord::Symbol(
+                        tisc::LinkAddr::Relative{
+                            symbol: "runtime.lt.o".into(),
+                            offset: a
+                        }
+                    )
+                },
+
+                w => w
+            })
+            .collect()
+    };
+    let mut runtime_output = std::io::BufWriter::new(
+        std::fs::File::create("runtime.lt.o").expect("Failed to open file")
+    );
+    bincode::serialize_into( runtime_output, &runtime_obj_file );
+
+
+
     let mut main_scope = Scope::with_parent(&root_scope);
 
     for path in args.sources {