diff --git a/libpandafile/debug_info_extractor.cpp b/libpandafile/debug_info_extractor.cpp index 4b7c18bea6..bda6d84871 100644 --- a/libpandafile/debug_info_extractor.cpp +++ b/libpandafile/debug_info_extractor.cpp @@ -180,6 +180,47 @@ private: ColumnNumberTable cnt_; }; +void ExtractMethodParams(const File *pf, DebugInfoDataAccessor &dda, ProtoDataAccessor &pda, MethodDataAccessor &mda, + ClassDataAccessor &cda, std::vector ¶m_info) +{ + size_t idx = 0; + size_t idx_ref = (mda.HasValidProto() && pda.GetReturnType().IsReference()) ? 1 : 0; + bool first_param = true; + const char *class_name = utf::Mutf8AsCString(pf->GetStringData(cda.GetClassId()).data); + dda.EnumerateParameters([&](File::EntityId ¶m_id) { + DebugInfoExtractor::ParamInfo info; + if (param_id.IsValid() && !mda.HasValidProto()) { + info.name = utf::Mutf8AsCString(pf->GetStringData(param_id).data); + // get signature of type + info.signature = Type::GetSignatureByTypeId(Type(Type::TypeId::TAGGED)); + param_info.emplace_back(info); + return; + } + + if (!param_id.IsValid()) { + first_param = false; + param_info.emplace_back(info); + return; + } + + info.name = utf::Mutf8AsCString(pf->GetStringData(param_id).data); + if (first_param && !mda.IsStatic()) { + info.signature = class_name; + } else { + Type param_type = pda.GetArgType(idx++); + if (param_type.IsPrimitive()) { + info.signature = Type::GetSignatureByTypeId(param_type); + } else { + auto ref_type = pda.GetReferenceType(idx_ref++); + info.signature = utf::Mutf8AsCString(pf->GetStringData(ref_type).data); + } + } + + first_param = false; + param_info.emplace_back(info); + }); +} + void DebugInfoExtractor::Extract(const File *pf) { const auto &panda_file = *pf; @@ -205,38 +246,7 @@ void DebugInfoExtractor::Extract(const File *pf) ProtoDataAccessor pda(panda_file, mda.GetProtoId()); std::vector param_info; - - size_t idx = 0; - size_t idx_ref = (mda.HasValidProto() && pda.GetReturnType().IsReference()) ? 1 : 0; - bool first_param = true; - const char *class_name = utf::Mutf8AsCString(pf->GetStringData(cda.GetClassId()).data); - dda.EnumerateParameters([&](File::EntityId ¶m_id) { - ParamInfo info; - if (param_id.IsValid() && !mda.HasValidProto()) { - info.name = utf::Mutf8AsCString(pf->GetStringData(param_id).data); - // get signature of type - info.signature = Type::GetSignatureByTypeId(Type(Type::TypeId::TAGGED)); - param_info.emplace_back(info); - return; - } - - if (param_id.IsValid()) { - info.name = utf::Mutf8AsCString(pf->GetStringData(param_id).data); - if (first_param && !mda.IsStatic()) { - info.signature = class_name; - } else { - Type param_type = pda.GetArgType(idx++); - if (param_type.IsPrimitive()) { - info.signature = Type::GetSignatureByTypeId(param_type); - } else { - auto ref_type = pda.GetReferenceType(idx_ref++); - info.signature = utf::Mutf8AsCString(pf->GetStringData(ref_type).data); - } - } - } - first_param = false; - param_info.emplace_back(info); - }); + ExtractMethodParams(pf, dda, pda, mda, cda, param_info); const uint8_t *program = dda.GetLineNumberProgram(); diff --git a/libpandafile/file.cpp b/libpandafile/file.cpp index d9038ad789..04996bce48 100644 --- a/libpandafile/file.cpp +++ b/libpandafile/file.cpp @@ -183,6 +183,54 @@ std::unique_ptr HandleArchive(ZipArchiveHandle &handle, return file; } +std::unique_ptr OpenPandaFileFromZip(FILE *fp, std::string_view location, + std::string_view archive_filename, + panda_file::File::OpenMode open_mode) +{ + // Open Zipfile and do the extraction. + ZipArchiveHandle zipfile = nullptr; + if (OpenArchiveFile(zipfile, fp) != ZIPARCHIVE_OK) { + LOG(ERROR, PANDAFILE) << "Can't open archive " << location; + return nullptr; + } + bool try_default = archive_filename.empty(); + if (!try_default && LocateFile(zipfile, archive_filename.data()) != ZIPARCHIVE_OK) { + LOG(INFO, PANDAFILE) << "Can't find entry with name '" << + archive_filename << "', will try " << ARCHIVE_FILENAME; + try_default = true; + } + if (try_default && LocateFile(zipfile, ARCHIVE_FILENAME) != ZIPARCHIVE_OK) { + OpenPandaFileFromZipErrorHandler(zipfile); + LOG(ERROR, PANDAFILE) << "Can't find entry with " << ARCHIVE_FILENAME; + return nullptr; + } + + EntryFileStat entry = EntryFileStat(); + if (GetCurrentFileInfo(zipfile, &entry) != ZIPARCHIVE_OK) { + OpenPandaFileFromZipErrorHandler(zipfile); + LOG(ERROR, PANDAFILE) << "GetCurrentFileInfo error"; + return nullptr; + } + // check that file is not empty, otherwise crash at CloseArchiveFile + if (entry.GetUncompressedSize() == 0) { + OpenPandaFileFromZipErrorHandler(zipfile); + LOG(ERROR, PANDAFILE) << "Invalid panda file '" << (try_default ? ARCHIVE_FILENAME : archive_filename) << "'"; + return nullptr; + } + if (OpenCurrentFile(zipfile) != ZIPARCHIVE_OK) { + CloseCurrentFile(zipfile); + OpenPandaFileFromZipErrorHandler(zipfile); + LOG(ERROR, PANDAFILE) << "Can't OpenCurrentFile!"; + return nullptr; + } + GetCurrentFileOffset(zipfile, &entry); + std::unique_ptr file = HandleArchive(zipfile, fp, location, entry, + archive_filename, open_mode); + CloseCurrentFile(zipfile); + OpenPandaFileFromZipErrorHandler(zipfile); + return file; +} + std::unique_ptr OpenPandaFile(std::string_view location, std::string_view archive_filename, panda_file::File::OpenMode open_mode) { @@ -209,57 +257,7 @@ std::unique_ptr OpenPandaFile(std::string_view location, (void)fseek(fp, 0, SEEK_SET); std::unique_ptr file; if (IsZipMagic(magic)) { - // Open Zipfile and do the extraction. - ZipArchiveHandle zipfile = nullptr; - auto open_error = OpenArchiveFile(zipfile, fp); - if (open_error != ZIPARCHIVE_OK) { - LOG(ERROR, PANDAFILE) << "Can't open archive " << location; - fclose(fp); - return nullptr; - } - bool try_default = archive_filename.empty(); - if (!try_default) { - if (LocateFile(zipfile, archive_filename.data()) != ZIPARCHIVE_OK) { - LOG(INFO, PANDAFILE) << "Can't find entry with name '" << archive_filename << "', will try " - << ARCHIVE_FILENAME; - try_default = true; - } - } - if (try_default) { - if (LocateFile(zipfile, ARCHIVE_FILENAME) != ZIPARCHIVE_OK) { - OpenPandaFileFromZipErrorHandler(zipfile); - LOG(ERROR, PANDAFILE) << "Can't find entry with " << ARCHIVE_FILENAME; - fclose(fp); - return nullptr; - } - } - - EntryFileStat entry = EntryFileStat(); - if (GetCurrentFileInfo(zipfile, &entry) != ZIPARCHIVE_OK) { - OpenPandaFileFromZipErrorHandler(zipfile); - LOG(ERROR, PANDAFILE) << "GetCurrentFileInfo error"; - fclose(fp); - return nullptr; - } - // check that file is not empty, otherwise crash at CloseArchiveFile - if (entry.GetUncompressedSize() == 0) { - OpenPandaFileFromZipErrorHandler(zipfile); - LOG(ERROR, PANDAFILE) << "Invalid panda file '" << (try_default ? ARCHIVE_FILENAME : archive_filename) - << "'"; - fclose(fp); - return nullptr; - } - if (OpenCurrentFile(zipfile) != ZIPARCHIVE_OK) { - CloseCurrentFile(zipfile); - OpenPandaFileFromZipErrorHandler(zipfile); - LOG(ERROR, PANDAFILE) << "Can't OpenCurrentFile!"; - fclose(fp); - return nullptr; - } - GetCurrentFileOffset(zipfile, &entry); - file = HandleArchive(zipfile, fp, location, entry, archive_filename, open_mode); - CloseCurrentFile(zipfile); - OpenPandaFileFromZipErrorHandler(zipfile); + file = OpenPandaFileFromZip(fp, location, archive_filename, open_mode); } else { file = panda_file::File::Open(location, open_mode); } @@ -286,7 +284,7 @@ std::unique_ptr OpenPandaFileFromMemory(const void *buffer, size_t s } auto ret = os::mem::TagAnonymousMemory(mem, size_to_mmap, tag.c_str()); if (ret.has_value()) { - PLOG(ERROR, PANDAFILE) << "Can't tag mmap anonymous, errno: " << errno; + PLOG(DEBUG, PANDAFILE) << "Can't tag mmap anonymous, errno: " << errno; } } diff --git a/libpandafile/file_reader.cpp b/libpandafile/file_reader.cpp index 5505ce3352..3e65e161c9 100644 --- a/libpandafile/file_reader.cpp +++ b/libpandafile/file_reader.cpp @@ -897,6 +897,26 @@ ForeignClassItem *FileReader::CreateForeignClassItem(File::EntityId class_id) return class_item; } +void FileReader::CreateSuperClassItem(ClassDataAccessor& class_acc, + ClassItem* class_item, + const std::string& class_name) +{ + auto super_class_id = class_acc.GetSuperClassId(); + if (super_class_id.GetOffset() != 0) { + if (super_class_id.GetOffset() == class_id.GetOffset()) { + LOG(FATAL, PANDAFILE) << "Class " << class_name << " has cyclic inheritance"; + } + + if (file_->IsExternal(super_class_id)) { + auto *super_class_item = CreateForeignClassItem(super_class_id); + class_item->SetSuperClass(super_class_item); + } else { + auto *super_class_item = CreateClassItem(super_class_id); + class_item->SetSuperClass(super_class_item); + } + } +} + ClassItem *FileReader::CreateClassItem(File::EntityId class_id) { auto it = items_done_.find(class_id); @@ -917,21 +937,7 @@ ClassItem *FileReader::CreateClassItem(File::EntityId class_id) class_item->SetSourceLang(source_lang_opt.value()); } - auto super_class_id = class_acc.GetSuperClassId(); - - if (super_class_id.GetOffset() != 0) { - if (super_class_id.GetOffset() == class_id.GetOffset()) { - LOG(FATAL, PANDAFILE) << "Class " << class_name << " has cyclic inheritance"; - } - - if (file_->IsExternal(super_class_id)) { - auto *super_class_item = CreateForeignClassItem(super_class_id); - class_item->SetSuperClass(super_class_item); - } else { - auto *super_class_item = CreateClassItem(super_class_id); - class_item->SetSuperClass(super_class_item); - } - } + CreateSuperClassItem(class_acc, class_item, class_name); class_acc.EnumerateInterfaces([&](File::EntityId iface_id) { if (file_->IsExternal(iface_id)) { @@ -1259,10 +1265,52 @@ void FileReader::UpdateDebugInfo(DebugInfoItem *debug_info_item, File::EntityId lnp_item->EmitEnd(); } -void FileReader::UpdateCodeAndDebugInfoDependencies(const std::map &reverse_done) +void AddIndexDependencyInstFlag(CodeItem *code_item, MethodItem *method_item, + const std::unordered_map &reverse_done) { using Flags = panda::BytecodeInst::Flags; + size_t offset = 0; + BytecodeInstruction inst(code_item->GetInstructions()->data()); + while (offset < code_item->GetCodeSize()) { + if (inst.HasFlag(Flags::TYPE_ID)) { + BytecodeId b_id = inst.GetId(); + File::Index idx = b_id.AsIndex(); + File::EntityId method_id = reverse_done.find(method_item)->second; + File::EntityId old_id = file_->ResolveClassIndex(method_id, idx); + ASSERT(items_done_.find(old_id) != items_done_.end()); + auto *idx_item = static_cast(items_done_.find(old_id)->second); + method_item->AddIndexDependency(idx_item); + } else if (inst.HasFlag(Flags::METHOD_ID)) { + BytecodeId b_id = inst.GetId(); + File::Index idx = b_id.AsIndex(); + File::EntityId method_id = reverse_done.find(method_item)->second; + File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx); + ASSERT(items_done_.find(old_id) != items_done_.end()); + auto *idx_item = static_cast(items_done_.find(old_id)->second); + method_item->AddIndexDependency(idx_item); + } else if (inst.HasFlag(Flags::FIELD_ID)) { + BytecodeId b_id = inst.GetId(); + File::Index idx = b_id.AsIndex(); + File::EntityId method_id = reverse_done.find(method_item)->second; + File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx); + ASSERT(items_done_.find(old_id) != items_done_.end()); + auto *idx_item = static_cast(items_done_.find(old_id)->second); + method_item->AddIndexDependency(idx_item); + } else if (inst.HasFlag(Flags::STRING_ID)) { + BytecodeId b_id = inst.GetId(); + File::EntityId old_id = b_id.AsFileId(); + auto data = file_->GetStringData(old_id); + std::string item_str(utf::Mutf8AsCString(data.data)); + container_.GetOrCreateStringItem(item_str); + } + offset += inst.GetSize(); + inst = inst.GetNext(); + } +} + +void FileReader::UpdateCodeAndDebugInfoDependencies(const std::map &reverse_done) +{ auto *class_map = container_.GetClassMap(); // First pass, add dependencies bytecode -> new items @@ -1284,53 +1332,69 @@ void FileReader::UpdateCodeAndDebugInfoDependencies(const std::mapsecond); } - size_t offset = 0; - BytecodeInstruction inst(code_item->GetInstructions()->data()); - while (offset < code_item->GetCodeSize()) { - if (inst.HasFlag(Flags::TYPE_ID)) { - BytecodeId b_id = inst.GetId(); - File::Index idx = b_id.AsIndex(); - File::EntityId method_id = reverse_done.find(method_item)->second; - File::EntityId old_id = file_->ResolveClassIndex(method_id, idx); - ASSERT(items_done_.find(old_id) != items_done_.end()); - auto *idx_item = static_cast(items_done_.find(old_id)->second); - method_item->AddIndexDependency(idx_item); - } else if (inst.HasFlag(Flags::METHOD_ID)) { - BytecodeId b_id = inst.GetId(); - File::Index idx = b_id.AsIndex(); - File::EntityId method_id = reverse_done.find(method_item)->second; - File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx); - ASSERT(items_done_.find(old_id) != items_done_.end()); - auto *idx_item = static_cast(items_done_.find(old_id)->second); - method_item->AddIndexDependency(idx_item); - } else if (inst.HasFlag(Flags::FIELD_ID)) { - BytecodeId b_id = inst.GetId(); - File::Index idx = b_id.AsIndex(); - File::EntityId method_id = reverse_done.find(method_item)->second; - File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx); - ASSERT(items_done_.find(old_id) != items_done_.end()); - auto *idx_item = static_cast(items_done_.find(old_id)->second); - method_item->AddIndexDependency(idx_item); - } else if (inst.HasFlag(Flags::STRING_ID)) { - BytecodeId b_id = inst.GetId(); - File::EntityId old_id = b_id.AsFileId(); - auto data = file_->GetStringData(old_id); - std::string item_str(utf::Mutf8AsCString(data.data)); - container_.GetOrCreateStringItem(item_str); - } + AddIndexDependencyInstFlag(inst, method_item, reverse_done); - offset += inst.GetSize(); - inst = inst.GetNext(); - } return true; }); } } -void FileReader::ComputeLayoutAndUpdateIndices() +void UpdateIdInstFlag(CodeItem *code_item, MethodItem *method_item, + const std::unordered_map &reverse_done) { using Flags = panda::BytecodeInst::Flags; + size_t offset = 0; + BytecodeInstruction inst(code_item->GetInstructions()->data()); + while (offset < code_item->GetCodeSize()) { + if (inst.HasFlag(Flags::TYPE_ID)) { + BytecodeId b_id = inst.GetId(); + File::Index idx = b_id.AsIndex(); + File::EntityId method_id = reverse_done.find(method_item)->second; + File::EntityId old_id = file_->ResolveClassIndex(method_id, idx); + ASSERT(items_done_.find(old_id) != items_done_.end()); + auto *idx_item = static_cast(items_done_.find(old_id)->second); + uint32_t index = idx_item->GetIndex(method_item); + inst.UpdateId(BytecodeId(index)); + } else if (inst.HasFlag(Flags::METHOD_ID)) { + BytecodeId b_id = inst.GetId(); + File::Index idx = b_id.AsIndex(); + File::EntityId method_id = reverse_done.find(method_item)->second; + File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx); + ASSERT(items_done_.find(old_id) != items_done_.end()); + auto *idx_item = static_cast(items_done_.find(old_id)->second); + uint32_t index = idx_item->GetIndex(method_item); + inst.UpdateId(BytecodeId(index)); + } else if (inst.HasFlag(Flags::FIELD_ID)) { + BytecodeId b_id = inst.GetId(); + File::Index idx = b_id.AsIndex(); + File::EntityId method_id = reverse_done.find(method_item)->second; + File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx); + ASSERT(items_done_.find(old_id) != items_done_.end()); + auto *idx_item = static_cast(items_done_.find(old_id)->second); + uint32_t index = idx_item->GetIndex(method_item); + inst.UpdateId(BytecodeId(index)); + } else if (inst.HasFlag(Flags::STRING_ID)) { + BytecodeId b_id = inst.GetId(); + File::EntityId old_id = b_id.AsFileId(); + auto data = file_->GetStringData(old_id); + std::string item_str(utf::Mutf8AsCString(data.data)); + auto *string_item = container_.GetOrCreateStringItem(item_str); + inst.UpdateId(BytecodeId(string_item->GetFileId().GetOffset())); + } else if (inst.HasFlag(Flags::LITERALARRAY_ID)) { + BytecodeId b_id = inst.GetId(); + File::EntityId old_id = b_id.AsFileId(); + ASSERT(items_done_.find(old_id) != items_done_.end()); + auto *array_item = items_done_.find(old_id)->second; + inst.UpdateId(BytecodeId(array_item->GetFileId().GetOffset())); + } + offset += inst.GetSize(); + inst = inst.GetNext(); + } +} + +void FileReader::ComputeLayoutAndUpdateIndices() +{ std::map reverse_done; for (const auto &it : items_done_) { reverse_done.insert({it.second, it.first}); @@ -1382,54 +1446,8 @@ void FileReader::ComputeLayoutAndUpdateIndices() return true; } - size_t offset = 0; - BytecodeInstruction inst(code_item->GetInstructions()->data()); - while (offset < code_item->GetCodeSize()) { - if (inst.HasFlag(Flags::TYPE_ID)) { - BytecodeId b_id = inst.GetId(); - File::Index idx = b_id.AsIndex(); - File::EntityId method_id = reverse_done.find(method_item)->second; - File::EntityId old_id = file_->ResolveClassIndex(method_id, idx); - ASSERT(items_done_.find(old_id) != items_done_.end()); - auto *idx_item = static_cast(items_done_.find(old_id)->second); - uint32_t index = idx_item->GetIndex(method_item); - inst.UpdateId(BytecodeId(index)); - } else if (inst.HasFlag(Flags::METHOD_ID)) { - BytecodeId b_id = inst.GetId(); - File::Index idx = b_id.AsIndex(); - File::EntityId method_id = reverse_done.find(method_item)->second; - File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx); - ASSERT(items_done_.find(old_id) != items_done_.end()); - auto *idx_item = static_cast(items_done_.find(old_id)->second); - uint32_t index = idx_item->GetIndex(method_item); - inst.UpdateId(BytecodeId(index)); - } else if (inst.HasFlag(Flags::FIELD_ID)) { - BytecodeId b_id = inst.GetId(); - File::Index idx = b_id.AsIndex(); - File::EntityId method_id = reverse_done.find(method_item)->second; - File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx); - ASSERT(items_done_.find(old_id) != items_done_.end()); - auto *idx_item = static_cast(items_done_.find(old_id)->second); - uint32_t index = idx_item->GetIndex(method_item); - inst.UpdateId(BytecodeId(index)); - } else if (inst.HasFlag(Flags::STRING_ID)) { - BytecodeId b_id = inst.GetId(); - File::EntityId old_id = b_id.AsFileId(); - auto data = file_->GetStringData(old_id); - std::string item_str(utf::Mutf8AsCString(data.data)); - auto *string_item = container_.GetOrCreateStringItem(item_str); - inst.UpdateId(BytecodeId(string_item->GetFileId().GetOffset())); - } else if (inst.HasFlag(Flags::LITERALARRAY_ID)) { - BytecodeId b_id = inst.GetId(); - File::EntityId old_id = b_id.AsFileId(); - ASSERT(items_done_.find(old_id) != items_done_.end()); - auto *array_item = items_done_.find(old_id)->second; - inst.UpdateId(BytecodeId(array_item->GetFileId().GetOffset())); - } + UpdateIdInstFlag(code_item, method_item, reverse_done); - offset += inst.GetSize(); - inst = inst.GetNext(); - } return true; }); } diff --git a/libpandafile/file_reader.h b/libpandafile/file_reader.h index 636437076c..bbbcf41811 100644 --- a/libpandafile/file_reader.h +++ b/libpandafile/file_reader.h @@ -86,6 +86,11 @@ private: DebugInfoItem *CreateDebugInfoItem(File::EntityId debug_info_id); void UpdateDebugInfoDependecies(File::EntityId debug_info_id); void UpdateDebugInfo(DebugInfoItem *debug_info_item, File::EntityId debug_info_id); + void CreateSuperClassItem(ClassDataAccessor& class_acc, ClassItem* class_item, const std::string& class_name); + void AddIndexDependencyInstFlag(CodeItem *code_item, MethodItem *method_item, + const std::unordered_map &reverse_done); + void UpdateIdInstFlag(CodeItem *code_item, MethodItem *method_item, + const std::unordered_map &reverse_done); template , bool> = true> void SetIntegerFieldValue(FieldDataAccessor *field_acc, FieldItem *field_item) diff --git a/panda/panda.cpp b/panda/panda.cpp index fde226b8c4..e3ec44c4fb 100644 --- a/panda/panda.cpp +++ b/panda/panda.cpp @@ -138,6 +138,54 @@ bool PrepareArguments(panda::PandArgParser *pa_parser, const RuntimeOptions &run return true; } +int ExecutePandaFile(panda::PandArg &options, panda::PandArgParser &pa_parser, panda::PandArg &file, + panda::PandArg &entrypoint, RuntimeOptions &runtime_options) +{ + if (!Runtime::Create(runtime_options)) { + std::cerr << "Error: cannot create runtime" << std::endl; + return -1; + } + + int ret = 0; + + if (options.GetValue()) { + std::cout << pa_parser.GetRegularArgs() << std::endl; + } + + std::string file_name = file.GetValue(); + std::string entry = entrypoint.GetValue(); + + auto &runtime = *Runtime::GetCurrent(); + auto &verif_opts = runtime.GetVerificationOptions(); + ASSERT(!verif_opts.IsOnlyVerify()); + + if (verif_opts.IsEnabled()) { + verifier::ThreadPool::GetCache()->FastAPI().ProcessFiles(runtime.GetClassLinker()->GetBootPandaFiles()); + } + + arg_list_t arguments = pa_parser.GetRemainder(); + auto res = runtime.ExecutePandaFile(file_name, entry, arguments); + if (!res) { + std::cerr << "Cannot execute panda file '" << file_name << "' with entry '" << entry << "'" << std::endl; + ret = -1; + } else { + ret = res.Value(); + } + + if (runtime_options.IsPrintMemoryStatistics()) { + std::cout << runtime.GetMemoryStatistics(); + } + if (runtime_options.IsPrintGcStatistics()) { + std::cout << runtime.GetFinalStatistics(); + } + if (!Runtime::Destroy()) { + std::cerr << "Error: cannot destroy runtime" << std::endl; + return -1; + } + pa_parser.DisableTail(); + return ret; +} + int Main(int argc, const char **argv) { BlockSignals(); @@ -174,8 +222,6 @@ int Main(int argc, const char **argv) runtime_options.SetVerificationMode(runtime_options.IsVerificationEnabled() ? VerificationMode::ON_THE_FLY : VerificationMode::DISABLED); - arg_list_t arguments = pa_parser.GetRemainder(); - panda::compiler::CompilerLogger::SetComponents(panda::compiler::options.GetCompilerLog()); if (compiler::options.IsCompilerEnableEvents()) { panda::compiler::EventWriter::Init(panda::compiler::options.GetCompilerEventsPath()); @@ -197,48 +243,7 @@ int Main(int argc, const char **argv) runtime_options.SetBootPandaFiles(boot_panda_files); - if (!Runtime::Create(runtime_options)) { - std::cerr << "Error: cannot create runtime" << std::endl; - return -1; - } - - int ret = 0; - - if (options.GetValue()) { - std::cout << pa_parser.GetRegularArgs() << std::endl; - } - - std::string file_name = file.GetValue(); - std::string entry = entrypoint.GetValue(); - - auto &runtime = *Runtime::GetCurrent(); - auto &verif_opts = runtime.GetVerificationOptions(); - ASSERT(!verif_opts.IsOnlyVerify()); - - if (verif_opts.IsEnabled()) { - verifier::ThreadPool::GetCache()->FastAPI().ProcessFiles(runtime.GetClassLinker()->GetBootPandaFiles()); - } - - auto res = runtime.ExecutePandaFile(file_name, entry, arguments); - if (!res) { - std::cerr << "Cannot execute panda file '" << file_name << "' with entry '" << entry << "'" << std::endl; - ret = -1; - } else { - ret = res.Value(); - } - - if (runtime_options.IsPrintMemoryStatistics()) { - std::cout << runtime.GetMemoryStatistics(); - } - if (runtime_options.IsPrintGcStatistics()) { - std::cout << runtime.GetFinalStatistics(); - } - if (!Runtime::Destroy()) { - std::cerr << "Error: cannot destroy runtime" << std::endl; - return -1; - } - pa_parser.DisableTail(); - return ret; + return ExecutePandaFile(options, pa_parser, file, entrypoint, runtime_options); } } // namespace panda