[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / courgette / patch_generator_x86_32.h
1 // Copyright 2011 The Chromium Authors
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_PATCH_GENERATOR_X86_32_H_
6 #define COURGETTE_PATCH_GENERATOR_X86_32_H_
7
8 #include "base/logging.h"
9 #include "courgette/courgette_flow.h"
10 #include "courgette/ensemble.h"
11 #include "courgette/patcher_x86_32.h"
12
13 namespace courgette {
14
15 // PatchGeneratorX86_32 is the universal patch generator for all executables,
16 // performing transformation and adjustment. The executable type is determined
17 // by the program detector.
18 class PatchGeneratorX86_32 : public TransformationPatchGenerator {
19  public:
20   PatchGeneratorX86_32(Element* old_element,
21                        Element* new_element,
22                        PatcherX86_32* patcher,
23                        ExecutableType kind)
24       : TransformationPatchGenerator(old_element, new_element, patcher),
25         kind_(kind) {
26   }
27
28   PatchGeneratorX86_32(const PatchGeneratorX86_32&) = delete;
29   PatchGeneratorX86_32& operator=(const PatchGeneratorX86_32&) = delete;
30
31   virtual ExecutableType Kind() { return kind_; }
32
33   Status WriteInitialParameters(SinkStream* parameter_stream) {
34     if (!parameter_stream->WriteSizeVarint32(
35             old_element_->offset_in_ensemble()) ||
36         !parameter_stream->WriteSizeVarint32(old_element_->region().length())) {
37       return C_STREAM_ERROR;
38     }
39     return C_OK;
40     // TODO(sra): Initialize |patcher_| with these parameters.
41   }
42
43   Status PredictTransformParameters(SinkStreamSet* prediction) {
44     return TransformationPatchGenerator::PredictTransformParameters(prediction);
45   }
46
47   Status CorrectedTransformParameters(SinkStreamSet* parameters) {
48     // No code needed to write an 'empty' parameter set.
49     return C_OK;
50   }
51
52   // The format of a transformed_element is a serialized EncodedProgram. Steps:
53   // - Form Disassembler for the old and new Elements.
54   // - Extract AssemblyPrograms from old and new Disassemblers.
55   // - Adjust the new AssemblyProgram to make it as much like the old one as
56   //   possible.
57   // - Serialize old and new Disassembler to EncodedProgram, using the old
58   //   AssemblyProgram and the adjusted new AssemblyProgram.
59   // The steps are performed in an order to reduce peak memory.
60   Status Transform(SourceStreamSet* corrected_parameters,
61                    SinkStreamSet* old_transformed_element,
62                    SinkStreamSet* new_transformed_element) {
63     // Don't expect any corrected parameters.
64     if (!corrected_parameters->Empty())
65       return C_GENERAL_ERROR;
66
67     // Flow graph and process sequence (DA = Disassembler, AP = AssemblyProgram,
68     // EP = EncodedProgram, Adj = Adjusted):
69     //   [1 Old DA] --> [2 Old AP]   [6 New AP] <-- [5 New DA]
70     //       |            |   |          |              |
71     //       v            |   |          v (move)       v
72     //   [3 Old EP] <-----+   +->[7 Adj New AP] --> [8 New EP]
73     //   (4 Write)                                  (9 Write)
74     CourgetteFlow flow;
75     RegionBuffer old_buffer(old_element_->region());
76     RegionBuffer new_buffer(new_element_->region());
77     flow.ReadDisassemblerFromBuffer(flow.OLD, old_buffer);                  // 1
78     flow.CreateAssemblyProgramFromDisassembler(flow.OLD, true);             // 2
79     flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.OLD);  // 3
80     flow.DestroyDisassembler(flow.OLD);
81     flow.WriteSinkStreamSetFromEncodedProgram(flow.OLD,
82                                               old_transformed_element);  // 4
83     flow.DestroyEncodedProgram(flow.OLD);
84     flow.ReadDisassemblerFromBuffer(flow.NEW, new_buffer);       // 5
85     flow.CreateAssemblyProgramFromDisassembler(flow.NEW, true);  // 6
86     flow.AdjustNewAssemblyProgramToMatchOld();                   // 7
87     flow.DestroyAssemblyProgram(flow.OLD);
88     flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.NEW);  // 8
89     flow.DestroyAssemblyProgram(flow.NEW);
90     flow.DestroyDisassembler(flow.NEW);
91     flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW,
92                                               new_transformed_element);  // 9
93     if (flow.failed()) {
94       LOG(ERROR) << flow.message() << " (" << old_element_->Name() << " => "
95                  << new_element_->Name() << ")";
96     }
97     return flow.status();
98   }
99
100   Status Reform(SourceStreamSet* transformed_element,
101                 SinkStream* reformed_element) {
102     return TransformationPatchGenerator::Reform(transformed_element,
103                                                 reformed_element);
104   }
105
106  private:
107   virtual ~PatchGeneratorX86_32() { }
108
109   ExecutableType kind_;
110 };
111
112 }  // namespace courgette
113
114 #endif  // COURGETTE_PATCH_GENERATOR_X86_32_H_