Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(514)

Side by Side Diff: tools/servicec/lib/src/resources/cc/struct.cc

Issue 2035023003: Remove service-compiler related code. (Closed) Base URL: git@github.com:dartino/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE.md file.
4
5 #include "struct.h"
6
7 #include <stdlib.h>
8 #include <stddef.h>
9
10 #include "unicode.h"
11
12 static const int HEADER_SIZE = 56;
13
14 char* pointerToArgument(char* buffer, int offset) {
15 return buffer + HEADER_SIZE + offset;
16 }
17
18 int64_t* pointerToInt64Argument(char* buffer, int offset) {
19 return reinterpret_cast<int64_t*>(pointerToArgument(buffer, offset));
20 }
21
22 int64_t* pointerToResult(char* buffer) {
23 return pointerToInt64Argument(buffer, 0);
24 }
25
26 int64_t* pointerToSegments(char* buffer) {
27 return pointerToInt64Argument(buffer, -8);
28 }
29
30 void** pointerToCallbackFunction(char* buffer) {
31 return reinterpret_cast<void**>(pointerToArgument(buffer, -16));
32 }
33
34 void** pointerToCallbackData(char* buffer) {
35 return reinterpret_cast<void**>(pointerToArgument(buffer, -24));
36 }
37
38 MessageBuilder::MessageBuilder(int space)
39 : first_(this, 0, space),
40 last_(&first_),
41 segments_(1) {
42 }
43
44 int MessageBuilder::ComputeUsed() const {
45 int result = 0;
46 const BuilderSegment* current = &first_;
47 while (current != NULL) {
48 result += current->used();
49 current = current->next();
50 }
51 return result;
52 }
53
54 Builder MessageBuilder::InternalInitRoot(int size) {
55 // Return value and arguments use the same space. Therefore,
56 // the size of any struct needs to be at least 8 bytes in order
57 // to have room for the return address.
58 if (size == 0) size = 8;
59 int offset = first_.Allocate(HEADER_SIZE + size);
60 if (offset < 0) abort();
61 return Builder(&first_, offset + HEADER_SIZE);
62 }
63
64 BuilderSegment* MessageBuilder::FindSegmentForBytes(int bytes) {
65 if (last_->HasSpaceForBytes(bytes)) return last_;
66 int capacity = (bytes > 8192) ? bytes : 8192;
67 BuilderSegment* segment = new BuilderSegment(this, segments_++, capacity);
68 last_->set_next(segment);
69 last_ = segment;
70 return segment;
71 }
72
73 void MessageBuilder::DeleteMessage(char* buffer) {
74 int64_t segments = *pointerToSegments(buffer);
75 for (int i = 0; i < segments; i++) {
76 int64_t address = *pointerToInt64Argument(buffer, 8 + (i * 16));
77 char* memory = reinterpret_cast<char*>(address);
78 free(memory);
79 }
80 free(buffer);
81 }
82
83 MessageReader::MessageReader(int segments, char* memory)
84 : segment_count_(segments),
85 segments_(new Segment*[segments]) {
86 for (int i = 0; i < segments; i++) {
87 int64_t address = *reinterpret_cast<int64_t*>(memory + (i * 16));
88 int size = *reinterpret_cast<int*>(memory + 8 + (i * 16));
89 segments_[i] = new Segment(this, reinterpret_cast<char*>(address), size);
90 }
91 }
92
93 MessageReader::~MessageReader() {
94 for (int i = 0; i < segment_count_; ++i) {
95 delete segments_[i];
96 }
97 delete[] segments_;
98 }
99
100 Segment* MessageReader::GetRootSegment(char* memory) {
101 int32_t segments = *reinterpret_cast<int32_t*>(memory);
102 if (segments == 0) {
103 int32_t size = *reinterpret_cast<int32_t*>(memory + 4);
104 return new Segment(memory, size);
105 } else {
106 MessageReader* reader = new MessageReader(segments, memory + 8);
107 free(memory);
108 return new Segment(reader);
109 }
110 }
111
112 Segment::Segment(char* memory, int size)
113 : reader_(NULL),
114 memory_(memory),
115 size_(size),
116 is_root_(false) {
117 }
118
119 Segment::Segment(MessageReader* reader, char* memory, int size)
120 : reader_(reader),
121 memory_(memory),
122 size_(size),
123 is_root_(false) {
124 }
125
126 Segment::Segment(MessageReader* reader)
127 : reader_(reader),
128 is_root_(true) {
129 Segment* first = reader->GetSegment(0);
130 memory_ = first->memory();
131 size_ = first->size();
132 }
133
134 Segment::~Segment() {
135 if (is_root_) {
136 delete reader_;
137 } else {
138 free(memory_);
139 }
140 }
141
142 BuilderSegment::BuilderSegment(MessageBuilder* builder, int id, int capacity)
143 : Segment(reinterpret_cast<char*>(calloc(capacity, 1)), capacity),
144 builder_(builder),
145 id_(id),
146 next_(NULL),
147 used_(0) {
148 }
149
150 BuilderSegment::~BuilderSegment() {
151 if (next_ != NULL) {
152 delete next_;
153 next_ = NULL;
154 }
155 }
156
157 int BuilderSegment::Allocate(int bytes) {
158 if (!HasSpaceForBytes(bytes)) return -1;
159 int result = used_;
160 used_ += bytes;
161 return result;
162 }
163
164 void BuilderSegment::Detach() {
165 Segment::Detach();
166 if (next_ != NULL) next_->Detach();
167 }
168
169 static int ComputeStructBuffer(BuilderSegment* segment,
170 char** buffer) {
171 if (segment->HasNext()) {
172 // Build a segmented message. The segmented message has the
173 // usual 48-byte header, room for a result, and then a list
174 // of all the segments in the message. The segments in the
175 // message are extracted and freed on return from the service
176 // call.
177 int segments = segment->builder()->segments();
178 int size = HEADER_SIZE + 8 + (segments * 16);
179 *buffer = reinterpret_cast<char*>(malloc(size));
180 int offset = HEADER_SIZE + 8;
181 do {
182 *reinterpret_cast<void**>(*buffer + offset) = segment->At(0);
183 *reinterpret_cast<int*>(*buffer + offset + 8) = segment->used();
184 segment = segment->next();
185 offset += 16;
186 } while (segment != NULL);
187
188 // Mark the request as being segmented.
189 *pointerToSegments(*buffer) = segments;
190 return size;
191 }
192
193 *buffer = reinterpret_cast<char*>(segment->At(0));
194 int size = segment->used();
195 // Mark the request as being non-segmented.
196 *pointerToSegments(*buffer) = 0;
197 return size;
198 }
199
200 int64_t Builder::InvokeMethod(ServiceId service, MethodId method) {
201 BuilderSegment* segment = this->segment();
202 char* buffer;
203 int size = ComputeStructBuffer(segment, &buffer);
204 segment->Detach();
205 ServiceApiInvoke(service, method, buffer, size);
206 int64_t result = *pointerToResult(buffer);
207 MessageBuilder::DeleteMessage(buffer);
208 return result;
209 }
210
211 void Builder::InvokeMethodAsync(ServiceId service,
212 MethodId method,
213 ServiceApiCallback api_callback,
214 void* callback_function,
215 void* callback_data) {
216 BuilderSegment* segment = this->segment();
217 char* buffer;
218 int size = ComputeStructBuffer(segment, &buffer);
219 segment->Detach();
220 // Set the callback function (the user supplied callback).
221 *pointerToCallbackFunction(buffer) = callback_function;
222 *pointerToCallbackData(buffer) = callback_data;
223 ServiceApiInvokeAsync(service, method, api_callback, buffer, size);
224 }
225
226 Builder Builder::NewStruct(int offset, int size) {
227 offset += this->offset();
228 BuilderSegment* segment = this->segment();
229 while (true) {
230 int* lo = reinterpret_cast<int*>(segment->At(offset + 0));
231 int* hi = reinterpret_cast<int*>(segment->At(offset + 4));
232 int result = segment->Allocate(size);
233 if (result >= 0) {
234 *lo = (result << 2) | 1;
235 *hi = 0;
236 return Builder(segment, result);
237 }
238
239 BuilderSegment* other = segment->builder()->FindSegmentForBytes(size + 8);
240 int target = other->Allocate(8);
241 *lo = (target << 2) | 3;
242 *hi = other->id();
243
244 segment = other;
245 offset = target;
246 }
247 }
248
249 Reader Builder::NewList(int offset, int length, int size) {
250 offset += this->offset();
251 size *= length;
252 BuilderSegment* segment = this->segment();
253 while (true) {
254 int* lo = reinterpret_cast<int*>(segment->At(offset + 0));
255 int* hi = reinterpret_cast<int*>(segment->At(offset + 4));
256 int result = segment->Allocate(size);
257 if (result >= 0) {
258 *lo = (result << 2) | 2;
259 *hi = length;
260 return Reader(segment, result);
261 }
262
263 BuilderSegment* other = segment->builder()->FindSegmentForBytes(size + 8);
264 int target = other->Allocate(8);
265 *lo = (target << 2) | 3;
266 *hi = other->id();
267
268 segment = other;
269 offset = target;
270 }
271 }
272
273 void Builder::NewString(int offset, const char* value) {
274 size_t value_len = strlen(value);
275 Utf8::Type type;
276 intptr_t len = Utf8::CodeUnitCount(value, value_len, &type);
277 Reader reader = NewList(offset, len, 2);
278 uint16_t* dst =
279 reinterpret_cast<uint16_t*>(reader.segment()->memory() + reader.offset());
280 Utf8::DecodeToUTF16(value, value_len, dst, len);
281 }
282
283 int Reader::ComputeUsed() const {
284 MessageReader* reader = segment_->reader();
285 int used = 0;
286 for (int i = 0; i < reader->segment_count(); i++) {
287 used += reader->GetSegment(i)->size();
288 }
289 return used;
290 }
291
292 char* Reader::ReadString(int offset) const {
293 List<uint16_t> data = ReadList<uint16_t>(offset);
294 intptr_t len = Utf8::Length(data);
295 char* result = reinterpret_cast<char*>(malloc(len + 1));
296 Utf8::Encode(data, result, len);
297 result[len] = 0;
298 return result;
299 }
OLDNEW
« no previous file with comments | « tools/servicec/lib/src/resources/cc/struct.h ('k') | tools/servicec/lib/src/resources/cc/unicode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698