[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / courgette / encoded_program_unittest.cc
1 // Copyright 2012 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 #include "courgette/encoded_program.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11 #include <vector>
12
13 #include "courgette/image_utils.h"
14 #include "courgette/label_manager.h"
15 #include "courgette/streams.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace courgette {
19
20 namespace {
21
22 // Helper class to instantiate RVAToLabel while managing allocation.
23 class TestLabelManager : public LabelManager {
24  public:
25   void RawAddLabel(int index, RVA rva) {
26     labels_.push_back(Label(rva, index));  // Don't care about |count_|.
27   }
28 };
29
30 // Creates a simple new program with given addresses. The orders of elements
31 // in |abs32_specs| and |rel32_specs| are important.
32 std::unique_ptr<EncodedProgram> CreateTestProgram(
33     const TestLabelManager& abs32_label_manager,
34     const TestLabelManager& rel32_label_manager) {
35   std::unique_ptr<EncodedProgram> program(new EncodedProgram());
36
37   uint32_t base = 0x00900000;
38   program->set_image_base(base);
39
40   EXPECT_TRUE(program->ImportLabels(abs32_label_manager, rel32_label_manager));
41
42   EXPECT_TRUE(program->AddOrigin(0));  // Start at base.
43
44   // Add instructions. Since we're using TestLabelManager, Labels are sorted in
45   // the order they're added via Add().
46   for (const Label& label : abs32_label_manager.Labels())
47     EXPECT_TRUE(program->AddAbs32(label.index_));
48   for (const Label& label : rel32_label_manager.Labels())
49     EXPECT_TRUE(program->AddRel32(label.index_));
50
51   return program;
52 }
53
54 bool CompareSink(const uint8_t expected[],
55                  size_t num_expected,
56                  SinkStream* ss) {
57   size_t n = ss->Length();
58   if (num_expected != n)
59     return false;
60   const uint8_t* buffer = ss->Buffer();
61   return memcmp(&expected[0], buffer, n) == 0;
62 }
63
64 }  // namespace
65
66 // Create a simple program with a few addresses and references and
67 // check that the bits produced are as expected.
68 TEST(EncodedProgramTest, Test) {
69   // ABS32 index 7 <-- base + 4.
70   TestLabelManager abs32_label_manager;
71   abs32_label_manager.RawAddLabel(7, 4);
72   // REL32 index 5 <-- base + 0.
73   TestLabelManager rel32_label_manager;
74   rel32_label_manager.RawAddLabel(5, 0);
75
76   std::unique_ptr<EncodedProgram> program(
77       CreateTestProgram(abs32_label_manager, rel32_label_manager));
78
79   // Serialize and deserialize.
80   SinkStreamSet sinks;
81   EXPECT_TRUE(program->WriteTo(&sinks));
82   program.reset();
83
84   SinkStream sink;
85   bool can_collect = sinks.CopyTo(&sink);
86   EXPECT_TRUE(can_collect);
87
88   const void* buffer = sink.Buffer();
89   size_t length = sink.Length();
90
91   SourceStreamSet sources;
92   bool can_get_source_streams = sources.Init(buffer, length);
93   EXPECT_TRUE(can_get_source_streams);
94
95   std::unique_ptr<EncodedProgram> encoded2(new EncodedProgram());
96   bool can_read = encoded2->ReadFrom(&sources);
97   EXPECT_TRUE(can_read);
98
99   // Finally, try to assemble.
100   SinkStream assembled;
101   bool can_assemble = encoded2->AssembleTo(&assembled);
102   EXPECT_TRUE(can_assemble);
103   encoded2.reset();
104
105   const uint8_t golden[] = {
106       0x04, 0x00, 0x90,
107       0x00,  // ABS32 to base + 4
108       0xF8, 0xFF, 0xFF,
109       0xFF  // REL32 from next line to base + 2
110   };
111   EXPECT_TRUE(CompareSink(golden, std::size(golden), &assembled));
112 }
113
114 // A larger test with multiple addresses. We encode the program and check the
115 // contents of the address streams.
116 TEST(EncodedProgramTest, TestWriteAddress) {
117   // Absolute addresses by index: [_, _, _, 2, _, 23, _, 11].
118   TestLabelManager abs32_label_manager;
119   abs32_label_manager.RawAddLabel(7, 11);
120   abs32_label_manager.RawAddLabel(3, 2);
121   abs32_label_manager.RawAddLabel(5, 23);
122   // Relative addresses by index: [16, 7, _, 32].
123   TestLabelManager rel32_label_manager;
124   rel32_label_manager.RawAddLabel(0, 16);
125   rel32_label_manager.RawAddLabel(3, 32);
126   rel32_label_manager.RawAddLabel(1, 7);
127
128   std::unique_ptr<EncodedProgram> program(
129       CreateTestProgram(abs32_label_manager, rel32_label_manager));
130
131   SinkStreamSet sinks;
132   EXPECT_TRUE(program->WriteTo(&sinks));
133   program.reset();
134
135   // Check indexes and addresses in sinks.
136   const uint8_t golden_abs32_indexes[] = {
137       0x03, 0x07, 0x03, 0x05  // 3 indexes: [7, 3, 5].
138   };
139   EXPECT_TRUE(CompareSink(golden_abs32_indexes, std::size(golden_abs32_indexes),
140                           sinks.stream(kStreamAbs32Indexes)));
141
142   const uint8_t golden_rel32_indexes[] = {
143       0x03, 0x00, 0x03, 0x01  // 3 indexes: [0, 3, 1].
144   };
145   EXPECT_TRUE(CompareSink(golden_rel32_indexes, std::size(golden_rel32_indexes),
146                           sinks.stream(kStreamRel32Indexes)));
147
148   // Addresses: [_, _, _, 2, _, 23, _, 11].
149   // Padded:    [0, 0, 0, 2, 2, 23, 23, 11].
150   // Delta:     [0, 0, 0, 2, 0, 21, 0, -12].
151   // Hex:       [0, 0, 0, 0x02, 0, 0x15, 0, 0xFFFFFFF4].
152   // Complement neg:  [0, 0, 0, 0x02, 0, 0x15, 0, (0x0B)].
153   // Varint32 Signed: [0, 0, 0, 0x04, 0, 0x2A, 0, 0x17].
154   const uint8_t golden_abs32_addresses[] = {
155       0x08,  // 8 address deltas.
156       0x00, 0x00, 0x00, 0x04, 0x00, 0x2A, 0x00, 0x17,
157   };
158   EXPECT_TRUE(CompareSink(golden_abs32_addresses,
159                           std::size(golden_abs32_addresses),
160                           sinks.stream(kStreamAbs32Addresses)));
161
162   // Addresses: [16, 7, _, 32].
163   // Padded:    [16, 7, 7, 32].
164   // Delta:     [16, -9, 0, 25].
165   // Hex:       [0x10, 0xFFFFFFF7, 0, 0x19].
166   // Complement Neg:  [0x10, (0x08), 0, 0x19].
167   // Varint32 Signed: [0x20, 0x11, 0, 0x32].
168   const uint8_t golden_rel32_addresses[] = {
169       0x04,  // 4 address deltas.
170       0x20, 0x11, 0x00, 0x32,
171   };
172   EXPECT_TRUE(CompareSink(golden_rel32_addresses,
173                           std::size(golden_rel32_addresses),
174                           sinks.stream(kStreamRel32Addresses)));
175 }
176
177 }  // namespace courgette