@@ -128,35 +128,19 @@ Result<PythonCompiler::EvalResult> PythonCompiler::evaluate(
128128 call_run_fn = true ;
129129 }
130130
131- llvm::Type *type = nullptr ;
132- ASR::symbol_t *f = symbol_table->get_symbol (" _" + run_fn);
133- if ((return_type == " struct" ) && (f)) {
134- llvm::Function *fn = m->get_function (run_fn);
135- type = fn->getReturnType ();
136- LCOMPILERS_ASSERT (type->isStructTy ())
131+ ASR::symbol_t *global_underscore_sym = symbol_table->get_symbol (" _" + run_fn);
132+ if ((return_type == " struct" ) && (global_underscore_sym)) {
133+ // we compute the offsets of the struct's attribute here
134+ // we will be using it later in aggregate_type_to_string to print the struct
137135
138- const llvm::DataLayout &dl = e->get_jit_data_layout ();
139- size_t elements_count = type->getStructNumElements ();
140- LCompilers::Vec<size_t > offsets;
141- offsets.reserve (al, elements_count);
142- for (size_t i = 0 ; i < elements_count; i++) {
143- size_t offset = dl.getStructLayout ((llvm::StructType*)type)->getElementOffset (i);
144- offsets.push_back (al, offset);
145- }
146- result.structure .offsets = offsets.p ;
136+ // we compute the offsets here instead of computing it in aggregate_type_to_string
137+ // because once we call `e->add_module`, internally LLVM may deallocate all the
138+ // type info after compiling the IR into machine code
147139
148- result.structure .ttype = ASR::down_cast<ASR::Variable_t>(f)->m_type ;
149- if (result.structure .ttype ->type == ASR::ttypeType::List) {
150- type = type->getStructElementType (2 );
151- LCOMPILERS_ASSERT (type->isPointerTy ())
152- result.structure .element_size = e->get_jit_data_layout ().getTypeAllocSize (
153- #if LLVM_VERSION_MAJOR >= 14
154- type->getNonOpaquePointerElementType ()
155- #else
156- type->getPointerElementType ()
157- #endif
158- );
159- }
140+ llvm::Function *fn = m->get_function (run_fn);
141+ llvm::Type *llvm_type = fn->getReturnType ();
142+ LCOMPILERS_ASSERT (llvm_type->isStructTy ())
143+ compute_offsets (llvm_type, global_underscore_sym, result);
160144 }
161145
162146 e->add_module (std::move (m));
@@ -248,11 +232,11 @@ Result<PythonCompiler::EvalResult> PythonCompiler::evaluate(
248232 result.b = r;
249233 } else if (return_type == " struct" ) {
250234 e->execfn <void >(run_fn);
251- if (f ) {
235+ if (global_underscore_sym ) {
252236 void *r = (void *)e->get_symbol_address (" _" + run_fn);
253237 LCOMPILERS_ASSERT (r)
254238 result.structure .structure = r;
255- result.type = EvalResult::structt ;
239+ result.type = EvalResult::struct_type ;
256240 }
257241 } else if (return_type == " void" ) {
258242 e->execfn <void >(run_fn);
@@ -492,7 +476,7 @@ Result<std::string> PythonCompiler::get_asm(
492476
493477void print_type (ASR::ttype_t *t, void *data, std::string &result);
494478
495- std::string PythonCompiler::string_aggregate_type (const struct EvalResult &r) {
479+ std::string PythonCompiler::aggregate_type_to_string (const struct EvalResult &r) {
496480 ASR::ttype_t *asr_type = r.structure .ttype ;
497481 void *data = r.structure .structure ;
498482 size_t *offsets = r.structure .offsets ;
@@ -522,6 +506,33 @@ std::string PythonCompiler::string_aggregate_type(const struct EvalResult &r) {
522506 return result;
523507}
524508
509+ void PythonCompiler::compute_offsets (llvm::Type *type, ASR::symbol_t *asr_type, EvalResult &result) {
510+ LCOMPILERS_ASSERT (type->isStructTy ())
511+
512+ const llvm::DataLayout &dl = e->get_jit_data_layout ();
513+ size_t elements_count = type->getStructNumElements ();
514+ LCompilers::Vec<size_t > offsets;
515+ offsets.reserve (al, elements_count);
516+ for (size_t i = 0 ; i < elements_count; i++) {
517+ size_t offset = dl.getStructLayout ((llvm::StructType*)type)->getElementOffset (i);
518+ offsets.push_back (al, offset);
519+ }
520+ result.structure .offsets = offsets.p ;
521+
522+ result.structure .ttype = ASR::down_cast<ASR::Variable_t>(asr_type)->m_type ;
523+ if (result.structure .ttype ->type == ASR::ttypeType::List) {
524+ type = type->getStructElementType (2 );
525+ LCOMPILERS_ASSERT (type->isPointerTy ())
526+ result.structure .element_size = e->get_jit_data_layout ().getTypeAllocSize (
527+ #if LLVM_VERSION_MAJOR >= 14
528+ type->getNonOpaquePointerElementType ()
529+ #else
530+ type->getPointerElementType ()
531+ #endif
532+ );
533+ }
534+ }
535+
525536void print_type (ASR::ttype_t *t, void *data, std::string &result) {
526537 switch (t->type ) {
527538 case ASR::ttypeType::Logical:
0 commit comments