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

Side by Side Diff: mojo/public/bindings/js/codec.js

Issue 69843003: Implement Mojo message codec in JavaScript (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Structs Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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 // Memory ---------------------------------------------------------------------
6
7 function store8(memory, ptr, val) {
Aaron Boodman 2013/11/13 19:32:36 What is intended to be the public API out of all t
abarth-chromium 2013/11/13 19:41:51 Definitely! I was hoping we'd have a module syste
8 memory[ptr] = val;
9 }
10
11 function load8(memory, ptr, val) {
12 return memory[ptr];
13 }
14
15 function store16(memory, ptr, val) {
16 memory[ptr + 0] = val >> 0;
17 memory[ptr + 1] = val >> 8;
18 }
19
20 function load16(memory, ptr, val) {
21 return memory[ptr + 0] << 0 +
22 memory[ptr + 1] << 8;
23 }
24
25 function store32(memory, ptr, val) {
26 memory[ptr + 0] = val >> 0;
27 memory[ptr + 1] = val >> 8;
28 memory[ptr + 2] = val >> 16;
29 memory[ptr + 3] = val >> 24;
30 }
31
32 function load32(memory, ptr, val) {
33 return memory[ptr + 0] << 0 +
34 memory[ptr + 1] << 8 +
35 memory[ptr + 2] << 16 +
36 memory[ptr + 3] << 24;
37 }
38
39 function store64(memory, ptr, val) {
40 memory[ptr + 0] = val >> 0;
41 memory[ptr + 1] = val >> 8;
42 memory[ptr + 2] = val >> 16;
43 memory[ptr + 3] = val >> 24;
44 memory[ptr + 4] = val >> 32;
45 memory[ptr + 5] = val >> 40;
46 memory[ptr + 6] = val >> 48;
47 memory[ptr + 7] = val >> 56;
48 }
49
50 function load64(memory, ptr, val) {
51 return memory[ptr + 0] << 0 +
52 memory[ptr + 1] << 8 +
53 memory[ptr + 2] << 16 +
54 memory[ptr + 3] << 24 +
55 memory[ptr + 4] << 32 +
56 memory[ptr + 5] << 40 +
57 memory[ptr + 6] << 48 +
58 memory[ptr + 7] << 56;
59 }
60
61 function align(size) {
62 var kAlignment = 8;
63 return size + (kAlignment - (size % kAlignment)) % kAlignment;
Aaron Boodman 2013/11/13 19:32:36 I think the "% kAlignment" at the end is unnecessa
abarth-chromium 2013/11/13 19:41:51 I haven't found any callers for this function, so
64 }
65
66 // Serialization --------------------------------------------------------------
67
68 function encodePointer(memory, ptr, offsetPtr) {
Aaron Boodman 2013/11/13 19:32:36 Weird to use both 'ptr' and 'pointer'. Google styl
abarth-chromium 2013/11/13 19:41:51 Ok. I was thinking about switching to addr, but w
69 if (!ptr) {
70 store64(memory, offsetPtr, 0);
71 return;
72 }
73 var offset = ptr - offsetPtr;
74 store64(memory, offsetPtr, offset);
75 }
76
77 function decodePointer(memory, offsetPtr) {
78 var offset = load64(memory, offsetPtr);
79 if (!offset)
80 return 0;
81 return offsetPtr + offset;
82 }
83
84 function encodeHandle(memory, handlePtr, handles) {
85 handles.push(load32(memory, handlePtr));
86 store32(memory, handlePtr, handles.length - 1);
87 }
88
89 function decodeHandle(memory, handlePtr, handles) {
90 var index = load32(memory, handlePtr);
91 store32(memory, handlePtr, handles[index]);
92 }
93
94 // Record ---------------------------------------------------------------------
95
96 function Record(memory, ptr) {
97 this.memory = memory;
98 this.base = ptr;
99 this.next = ptr;
100 }
101
102 Record.prototype.advance = function(offset) {
103 this.next += offset;
104 }
105
106 Record.prototype.readPtr = function() {
107 var ptr = decodePointer(this.memory, this.next);
108 this.next += 8;
109 return ptr;
110 }
111
112 Record.prototype.writePtr = function(ptr) {
113 encodePointer(this.memory, ptr, this.next);
114 this.next += 8;
115 }
116
117 Record.prototype.readRecord = function() {
118 return new Record(this.memory, this.readPtr());
119 }
120
121 Record.prototype.readString = function(len) {
122 // TODO(abarth): We should really support UTF-8. We might want to
123 // jump out of the VM to decode the string directly from the array
124 // buffer using v8::String::NewFromUtf8.
Aaron Boodman 2013/11/13 19:32:36 There are javascript implementations of utf8! I wr
abarth-chromium 2013/11/13 19:41:51 Link? :) I'd like to start with a pure JS implem
Aaron Boodman 2013/11/18 18:34:48 I believe that there is one I wrote internally as
125 var result = "";
126 var memory = this.memory;
127 var base = this.next;
128 for (var i = 0; i < len; ++i) {
129 result += String.fromCharCode(memory[base + i] & 0x7F);
130 }
131 this.next += len;
132 return result;
133 }
134
135 Record.prototype.read8 = function() {
136 var result = load8(this.memory, this.next);
137 this.next += 1;
138 return result;
139 }
140
141 Record.prototype.read32 = function() {
142 var result = load32(this.memory, this.next);
143 this.next += 4;
144 return result;
145 }
146
147 Record.prototype.read64 = function() {
148 var result = load64(this.memory, this.next);
149 this.next += 8;
150 return result;
151 }
152
153 Record.prototype.write8 = function(val) {
154 store8(this.memory, this.next, val);
155 this.next += 1;
156 }
157
158 Record.prototype.write32 = function(val) {
159 var after = this.next + 4;
160 store32(this.memory, this.next, val);
161 this.next += 4;
162 };
163
164 Record.prototype.write64 = function(val) {
165 store64(this.memory, this.next, val);
166 this.next += 8;
167 };
168
169 // Buffer ---------------------------------------------------------------------
170
171 function Buffer(size) {
172 this.memory = new Uint8Array(size);
173 this.nextAllocation = 0;
174 }
175
176 Buffer.prototype.alloc = function(size) {
177 var ptr = this.nextAllocation;
178 this.nextAllocation += size;
179 if (this.nextAllocation > this.memory.length)
180 throw "Buffer full.";
181 return new Record(this.memory, ptr);
182 };
183
184 // Fields ---------------------------------------------------------------------
185
186 var kArrayHeaderSize = 8;
187 var kStructHeaderSize = 8;
188
189 function encodeArray(record, class, val) {
190 var numberOfElements = val.length;
191 record.write32(kArrayHeaderSize + class.encodedSize * numberOfElements);
192 record.write32(numberOfElements);
193 for (var i = 0; i < numberOfElements; ++i) {
194 class.encode(record, val[i]);
195 }
196 // TODO(abarth): We should sanity check that everthing fits.
197 }
198
199 function decodeArray(record, class) {
200 var numberOfBytes = record.read32();
201 var numberOfElements = record.read32();
202 var val = [];
203 for (var i = 0; i < numberOfElements; ++i) {
204 val.push(class.decode(record));
205 }
206 // TODO(abarth): We should sanity check that everthing fits.
207 return val;
208 }
209
210 function decodeString(record) {
211 var numberOfBytes = record.read32();
212 var numberOfElements = record.read32();
213 return record.readString(numberOfElements);
214 }
215
216 // Message --------------------------------------------------------------------
217
218 var kMessageHeaderSize = 8;
219
220 function Message() {
221 this.memory = null;
222 this.handles = [];
223 }
224
225 Message.prototype.dispose = function() {
226 var len = this.handles.length;
227 for (var i = 0; i < len; ++i) {
228 mojo.core.close(this.handles[i]);
229 this.handles[i] = mojo.core.HANDLE_INVALID;
230 }
231 };
232
233 // MessageBuilder -------------------------------------------------------------
234
235 function MessageBuilder(messageName, payloadSize) {
236 var buffer = new Buffer(kMessageHeaderSize + payloadSize);
237 var header = buffer.alloc(kMessageHeaderSize);
238 header.write32(buffer.length);
239 header.write32(messageName);
240
241 this.buffer = buffer;
242 }
243
244 MessageBuilder.prototype.takeBuffer = function() {
245 var buffer = this.buffer;
246 this.buffer = null;
247 return buffer;
248 };
249
250 // Basic types ----------------------------------------------------------------
251
252 function Uint8() {
253 }
254
255 Uint8.encodedSize = 1;
256
257 Uint8.decode = function(record) {
258 return record.read8();
259 };
260
261 Uint8.encode = function(record, val) {
262 record.write8(val);
263 };
264
265 function Ptr(class) {
266 this.class = class;
267 };
268
269 Ptr.prototype.encodedSize = 8;
270
271 Ptr.prototype.decode = function(record) {
272 return class.decode(record.readRecord());
273 };
274
275 Ptr.prototype.encode = function(record, val) {
276 // TODO(abarth): Where does |buffer| come from?
277 objectRecord = buffer.alloc(class.encodedSize);
278 class.encode(objectRecord, val);
279 record.writePtr(objectRecord.base);
280 };
281
282 function Handle() {
283 }
284
285 // TOOD(abarth): Implement handles.
286
287 // "Generated" code ===========================================================
288
289 function Bar() {
290 this.alpha = 0;
291 this.beta = 0;
292 this.gamma = 0;
293 }
294
295 Bar.encodedSize = kStructHeaderSize + 8;
296
297 Bar.decode = function(record) {
298 var val = new Bar();
299 // TODO(abarth): We need to support optional fields.
300 record.advance(kStructHeaderSize);
301 val.alpha = record.read8();
302 val.beta = record.read8();
303 val.gamma = record.read8();
304 record.advance(5);
305 return val;
306 };
307
308 Bar.encode = function(record, val) {
309 record.write32(Bar.encodedSize);
310 record.write32(3);
311 record.write8(val.alpha);
312 record.write8(val.beta);
313 record.write8(val.gamma);
314 record.advance(5);
315 };
316
317 // int32_t x_;
318 // int32_t y_;
319 // uint8_t a_ : 1;
320 // uint8_t b_ : 1;
321 // uint8_t c_ : 1;
322 // uint8_t _pad0_[7];
323 // mojo::internal::StructPointer<Bar> bar_;
324 // mojo::internal::ArrayPointer<uint8_t> data_;
325 // mojo::internal::ArrayPointer<Bar*> extra_bars_;
326 // mojo::internal::StringPointer name_;
327 // mojo::internal::ArrayPointer<mojo::Handle> files_;
328
329 function Foo() {
330 this.x = 0;
331 this.y = 0;
332 this.a = 0;
333 this.b = 0;
334 this.c = 0;
335 this.bar = null;
336 this.data = null;
337 this.extra_bars = null;
338 this.name = null;
339 this.files = null;
340 }
341
342 Foo.encodedSize = 64;
343
344 Foo.decode = function(record) {
345 var val = new Foo();
346 // TODO(abarth): We need to support optional fields.
347 record.advance(kStructHeaderSize);
348 val.x = record.read32();
349 val.y = record.read32();
350 var packed = record.read8();
351 val.a = (packed >> 0) & 1;
352 val.b = (packed >> 1) & 1;
353 val.c = (packed >> 2) & 1;
354 record.advance(7);
355 val.bar = Bar.decode(record.readRecord());
356 val.data = decodeArray(record.readRecord(), Uint8);
357 val.extra_bars = decodeArray(record.readRecord(), new Ptr(Bar));
358 val.name = decodeString(record.readRecord());
359 val.files = decodeArray(record.readRecord(), Handle);
360 }
361
362 Foo.encode = function(record, val) {
363 record.write32(Foo.encodedSize);
364 record.write32(10);
365 record.write32(val.x);
366 record.write32(val.y);
367 var packed = (val.a & 1) << 0 |
368 (val.b & 1) << 1 |
369 (val.c & 1) << 2;
370 record.write8(packed);
371 record.advance(7);
372
373 // TODO(abarth): Where does buffer come from?
374 var barRecord = buffer.alloc(Bar.encodedSize);
375 Bar.encode(barRecord, val.bar);
376 record.writePtr(barRecord.base);
377
378 var dataRecord = buffer.alloc(Uint8.encodedSize);
379 encodeArray(dataRecord, Uint8, this.data);
380 record.writePtr(dataRecord.base);
381
382 var extra_barsClass = new Ptr(Bar);
383 var extra_barsRecord = buffer.alloc(extra_barsClass.encodedSize);
384 encodeArray(dataRecord, extra_barsClass, this.data);
385 record.writePtr(extra_barsRecord.base);
386
387 // TODO(abarth): We'll need something fancier here to support UTF-8.
388 var nameLength = val.name.length;
389 nameRecord = buffer.alloc(nameLength);
390 encodeString(nameRecord, val.name);
391 record.writePtr(nameRecord.base);
392
393 // TODO(abarth): We need to be able to encode handles.
394 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698