Enable dev build with the latest repo
[platform/framework/web/chromium-efl.git] / courgette / courgette_flow.h
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 #ifndef COURGETTE_COURGETTE_FLOW_H_
6 #define COURGETTE_COURGETTE_FLOW_H_
7
8 #include <memory>
9 #include <string>
10
11 #include "base/macros.h"
12 #include "courgette/courgette.h"
13 #include "courgette/region.h"
14 #include "courgette/streams.h"
15
16 namespace courgette {
17
18 class AssemblyProgram;
19 class Disassembler;
20 class EncodedProgram;
21
22 // An adaptor for Region as BasicBuffer.
23 class RegionBuffer : public BasicBuffer {
24  public:
25   explicit RegionBuffer(const Region& region) : region_(region) {}
26   ~RegionBuffer() override {}
27
28   // BasicBuffer:
29   const uint8_t* data() const override { return region_.start(); }
30   size_t length() const override { return region_.length(); }
31
32  private:
33   Region region_;
34
35   DISALLOW_COPY_AND_ASSIGN(RegionBuffer);
36 };
37
38 // CourgetteFlow stores Courgette data arranged into groups, and exposes
39 // "commands" that operate on them. On the first occurrence of an error, the
40 // Courgette error code is recorded, error messages are generated and stored,
41 // and all subsequent commands become no-op. This allows callers to concisely
42 // specify high-level logic with minimal code for error handling.
43 class CourgetteFlow {
44  public:
45   // A group of Courgette data, for a single executable. Takes negligible space
46   // when unused.
47   struct Data {
48     Data();
49     ~Data();
50
51     std::unique_ptr<Disassembler> disassembler;
52     std::unique_ptr<AssemblyProgram> program;
53     std::unique_ptr<EncodedProgram> encoded;
54     SinkStreamSet sinks;
55     SourceStreamSet sources;
56   };
57
58   // Group enumeration into |data_*_| fields.
59   enum Group {
60     ONLY,  // The only file processed.
61     OLD,   // The "old" file during patching.
62     NEW,   // The "new" file during patching.
63   };
64
65   CourgetteFlow();
66   ~CourgetteFlow();
67
68   static const char* name(Group group);
69   Data* data(Group group);  // Allows caller to modify.
70   bool ok();
71   bool failed();
72   Status status();
73   const std::string& message();
74
75   // Commands that perform no-op on error. This allows caller to concisely
76   // specify high-level logic, and perform a single error check at the end. Care
77   // must be taken w.r.t. error handling if |data()| is harvested between
78   // commands.
79
80   // Reads |buffer| to initialize |data(group)->sources|.
81   void ReadSourceStreamSetFromBuffer(Group group, const BasicBuffer& buffer);
82
83   // Reads |buffer| to initialize |data(group)->disassembler|.
84   void ReadDisassemblerFromBuffer(Group group, const BasicBuffer& buffer);
85
86   // Reads |opt_sources| if given, or else |data(group)->sources| to initialize
87   // |data(group).encoded|.
88   void ReadEncodedProgramFromSourceStreamSet(
89       Group group,
90       SourceStreamSet* opt_sources = nullptr);
91
92   // Uses |data(group)->disassembler| to initialize |data(group)->program|,
93   // passing |annotate| as initialization parameter (should be true if
94   // AdjustNewAssemblyProgramToMatchOld() gets called later).
95   void CreateAssemblyProgramFromDisassembler(Group group, bool annotate);
96
97   // Uses |data(group)->disassembler| and |data(group)->program| to initialize
98   // |data(group)->encoded|.
99   void CreateEncodedProgramFromDisassemblerAndAssemblyProgram(Group group);
100
101   // Serializese |data(group)->sinks| to |sink|.
102   void WriteSinkStreamFromSinkStreamSet(Group group, SinkStream* sink);
103
104   // Serializes |data(group)->encoded| to |opt_sinks| if given, or else to
105   // |data(group)->sinks|.
106   void WriteSinkStreamSetFromEncodedProgram(Group group,
107                                             SinkStreamSet* opt_sinks = nullptr);
108
109   // Converts |data(group)->encoded| to an exectuable and writes the result to
110   // |sink|.
111   void WriteExecutableFromEncodedProgram(Group group, SinkStream* sink);
112
113   // Adjusts |data(NEW)->program| Labels to match |data(OLD)->program| Labels.
114   void AdjustNewAssemblyProgramToMatchOld();
115
116   // Destructor commands to reduce memory usage.
117
118   void DestroyDisassembler(Group group);
119
120   void DestroyAssemblyProgram(Group group);
121
122   void DestroyEncodedProgram(Group group);
123
124  private:
125   // Utilities to process return values from Courgette functions, and assign
126   // |status_| and |message_|. Usage:
127   //   if (!check(some_courgette_function(param1, ...)))
128   //     setMessage("format string %s...", value1, ...);
129
130   // Reassigns |status_|, and returns true if |C_OK|.
131   bool check(Status new_status);
132
133   // check() alternative for functions that return true on success. On failure
134   // assigns |status_| to |failure_mode|.
135   bool check(bool success, Status failure_mode);
136
137   void setMessage(const char* format, ...);
138
139   Status status_ = C_OK;
140   std::string message_;
141   Data data_only_;
142   Data data_old_;
143   Data data_new_;
144
145   DISALLOW_COPY_AND_ASSIGN(CourgetteFlow);
146 };
147
148 }  // namespace courgette
149
150 #endif  // COURGETTE_COURGETTE_FLOW_H_