1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "emitFiles.h"
17
18 #include <assembly-emitter.h>
19 #include <es2panda.h>
20 #include <mem/arena_allocator.h>
21 #include <protobufSnapshotGenerator.h>
22
23 namespace panda::es2panda::aot {
Schedule()24 void EmitFileQueue::Schedule()
25 {
26 ASSERT(jobsCount_ == 0);
27 std::unique_lock<std::mutex> lock(m_);
28
29 // generate abcs
30 if (mergeAbc_) {
31 auto emitMergedAbcJob = new EmitMergedAbcJob(options_->CompilerOutput(), progsInfo_);
32 jobs_.push_back(emitMergedAbcJob);
33 jobsCount_++;
34 } else {
35 for (const auto &info: progsInfo_) {
36 try {
37 auto outputFileName = options_->OutputFiles().empty() ? options_->CompilerOutput() :
38 options_->OutputFiles().at(info.first);
39 auto emitSingleAbcJob = new EmitSingleAbcJob(outputFileName, &(info.second->program), statp_);
40 jobs_.push_back(emitSingleAbcJob);
41 jobsCount_++;
42 } catch (std::exception &error) {
43 throw Error(ErrorType::GENERIC, error.what());
44 }
45 }
46 }
47
48 // generate cache protoBins
49 for (const auto &info: progsInfo_) {
50 if (!info.second->needUpdateCache) {
51 continue;
52 }
53 auto outputCacheIter = options_->CompilerOptions().cacheFiles.find(info.first);
54 if (outputCacheIter != options_->CompilerOptions().cacheFiles.end()) {
55 auto emitProtoJob = new EmitCacheJob(outputCacheIter->second, info.second);
56 jobs_.push_back(emitProtoJob);
57 jobsCount_++;
58 }
59 }
60
61 lock.unlock();
62 jobsAvailable_.notify_all();
63 }
64
Run()65 void EmitSingleAbcJob::Run()
66 {
67 if (!panda::pandasm::AsmEmitter::Emit(panda::os::file::File::GetExtendedFilePath(outputFileName_), *prog_, statp_,
68 nullptr, true)) {
69 throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " +
70 panda::pandasm::AsmEmitter::GetLastError());
71 }
72 }
73
Run()74 void EmitMergedAbcJob::Run()
75 {
76 std::vector<panda::pandasm::Program*> progs;
77 progs.reserve(progsInfo_.size());
78 for (const auto &info: progsInfo_) {
79 progs.push_back(&(info.second->program));
80 }
81 if (!panda::pandasm::AsmEmitter::EmitPrograms(panda::os::file::File::GetExtendedFilePath(outputFileName_), progs,
82 true)) {
83 throw Error(ErrorType::GENERIC, "Failed to emit " + outputFileName_ + ", error: " +
84 panda::pandasm::AsmEmitter::GetLastError());
85 }
86 }
87
Run()88 void EmitCacheJob::Run()
89 {
90 panda::proto::ProtobufSnapshotGenerator::UpdateCacheFile(progCache_, outputProtoName_);
91 }
92
93 } // namespace panda::es2panda::util
94