Enable dev build with the latest repo
[platform/framework/web/chromium-efl.git] / courgette / courgette_flow.cc
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "courgette/courgette_flow.h"
6
7 #include <stdarg.h>
8
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "courgette/assembly_program.h"
14 #include "courgette/disassembler.h"
15 #include "courgette/encoded_program.h"
16 #include "courgette/program_detector.h"
17
18 namespace courgette {
19
20 /******** CourgetteFlow::Data ********/
21
22 CourgetteFlow::Data::Data() = default;
23
24 CourgetteFlow::Data::~Data() = default;
25
26 /******** CourgetteFlow ********/
27
28 CourgetteFlow::CourgetteFlow() = default;
29
30 CourgetteFlow::~CourgetteFlow() = default;
31
32 // static
33 const char* CourgetteFlow::name(Group group) {
34   switch (group) {
35     case ONLY:
36       return "input";
37     case OLD:
38       return "'old' input";
39     case NEW:
40       return "'new' input";
41     default:
42       NOTREACHED();
43       break;
44   }
45   return nullptr;
46 }
47
48 CourgetteFlow::Data* CourgetteFlow::data(Group group) {
49   switch (group) {
50     case ONLY:
51       return &data_only_;
52     case OLD:
53       return &data_old_;
54     case NEW:
55       return &data_new_;
56     default:
57       NOTREACHED();
58       break;
59   }
60   return nullptr;
61 }
62
63 bool CourgetteFlow::ok() {
64   return status_ == C_OK;
65 }
66
67 bool CourgetteFlow::failed() {
68   return status_ != C_OK;
69 }
70
71 Status CourgetteFlow::status() {
72   return status_;
73 }
74
75 const std::string& CourgetteFlow::message() {
76   return message_;
77 }
78
79 void CourgetteFlow::ReadSourceStreamSetFromBuffer(Group group,
80                                                   const BasicBuffer& buffer) {
81   if (failed())
82     return;
83   Data* d = data(group);
84   if (!check(d->sources.Init(buffer.data(), buffer.length()),
85              C_GENERAL_ERROR)) {
86     setMessage("Cannot read %s as SourceStreamSet.", name(group));
87   }
88 }
89
90 void CourgetteFlow::ReadDisassemblerFromBuffer(Group group,
91                                                const BasicBuffer& buffer) {
92   if (failed())
93     return;
94   Data* d = data(group);
95   d->disassembler = DetectDisassembler(buffer.data(), buffer.length());
96   if (!check(d->disassembler.get() != nullptr, C_INPUT_NOT_RECOGNIZED))
97     setMessage("Cannot detect program for %s.", name(group));
98 }
99
100 void CourgetteFlow::ReadEncodedProgramFromSourceStreamSet(
101     Group group,
102     SourceStreamSet* opt_sources /* nullptr */) {
103   if (failed())
104     return;
105   Data* d = data(group);
106   SourceStreamSet* sources = opt_sources ? opt_sources : &d->sources;
107   if (!check(ReadEncodedProgram(sources, &d->encoded)))
108     setMessage("Cannot read %s as encoded program.", name(group));
109 }
110
111 void CourgetteFlow::CreateAssemblyProgramFromDisassembler(Group group,
112                                                           bool annotate) {
113   if (failed())
114     return;
115   Data* d = data(group);
116   d->program = d->disassembler->CreateProgram(annotate);
117   if (!check(d->program.get() != nullptr, C_DISASSEMBLY_FAILED))
118     setMessage("Cannot create AssemblyProgram for %s.", name(group));
119 }
120
121 void CourgetteFlow::CreateEncodedProgramFromDisassemblerAndAssemblyProgram(
122     Group group) {
123   if (failed())
124     return;
125   Data* d = data(group);
126   d->encoded.reset(new EncodedProgram());
127   if (!check(d->disassembler->DisassembleAndEncode(d->program.get(),
128                                                    d->encoded.get()))) {
129     setMessage("Cannot disassemble to form EncodedProgram for %s.",
130                name(group));
131   }
132 }
133
134 void CourgetteFlow::WriteSinkStreamFromSinkStreamSet(Group group,
135                                                      SinkStream* sink) {
136   DCHECK(sink);
137   if (failed())
138     return;
139   if (!check(data(group)->sinks.CopyTo(sink), C_GENERAL_ERROR))
140     setMessage("Cannnot combine serialized streams for %s.", name(group));
141 }
142
143 void CourgetteFlow::WriteSinkStreamSetFromEncodedProgram(
144     Group group,
145     SinkStreamSet* opt_sinks /* nullptr */) {
146   if (failed())
147     return;
148   Data* d = data(group);
149   SinkStreamSet* sinks = opt_sinks ? opt_sinks : &d->sinks;
150   if (!check(WriteEncodedProgram(d->encoded.get(), sinks)))
151     setMessage("Cannot serialize encoded %s.", name(group));
152 }
153
154 void CourgetteFlow::WriteExecutableFromEncodedProgram(Group group,
155                                                       SinkStream* sink) {
156   DCHECK(sink);
157   if (failed())
158     return;
159   if (!check(Assemble(data(group)->encoded.get(), sink)))
160     setMessage("Cannot assemble %s.", name(group));
161 }
162
163 void CourgetteFlow::AdjustNewAssemblyProgramToMatchOld() {
164   if (failed())
165     return;
166   if (!check(Adjust(*data_old_.program, data_new_.program.get())))
167     setMessage("Cannot adjust %s to match %s.", name(OLD), name(NEW));
168 }
169
170 void CourgetteFlow::DestroyDisassembler(Group group) {
171   if (failed())
172     return;
173   data(group)->disassembler.reset();
174 }
175
176 void CourgetteFlow::DestroyAssemblyProgram(Group group) {
177   if (failed())
178     return;
179   data(group)->program.reset();
180 }
181
182 void CourgetteFlow::DestroyEncodedProgram(Group group) {
183   if (failed())
184     return;
185   data(group)->encoded.reset();
186 }
187
188 bool CourgetteFlow::check(Status new_status) {
189   if (new_status == C_OK)
190     return true;
191   status_ = new_status;
192   return false;
193 }
194
195 bool CourgetteFlow::check(bool success, Status failure_mode) {
196   if (success)
197     return true;
198   status_ = failure_mode;
199   return false;
200 }
201
202 void CourgetteFlow::setMessage(const char* format, ...) {
203   va_list args;
204   va_start(args, format);
205   message_ = base::StringPrintV(format, args);
206   va_end(args);
207 }
208
209 }  // namespace courgette