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

Side by Side Diff: test/mjsunit/wasm/wasm-module-builder.js

Issue 1771553002: Revert of [wasm] Add a JavaScript utility to make it easier to build WASM modules from JavaScript. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « test/mjsunit/wasm/test-wasm-module-builder.js ('k') | 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 2016 the V8 project 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 function StringRef(string) {
6 this.pos = -1;
7 this.string = string;
8 }
9
10 function DataRef(data) {
11 this.pos = -1;
12 this.data = data;
13 }
14
15 function WasmFunctionBuilder(name, sig_index) {
16 this.name = name;
17 this.sig_index = sig_index;
18 this.exports = [];
19 }
20
21 WasmFunctionBuilder.prototype.exportAs = function(name) {
22 this.exports.push(name);
23 return this;
24 }
25
26 WasmFunctionBuilder.prototype.addBody = function(body) {
27 this.body = body;
28 return this;
29 }
30
31 WasmFunctionBuilder.prototype.addLocals = function(locals) {
32 this.locals = locals;
33 return this;
34 }
35
36 function WasmModuleBuilder() {
37 this.signatures = [];
38 this.imports = [];
39 this.functions = [];
40 this.exports = [];
41 this.function_table = [];
42 this.data_segments = [];
43 return this;
44 }
45
46 WasmModuleBuilder.prototype.addMemory = function(min, max, exp) {
47 this.memory = {min: min, max: max, exp: exp};
48 return this;
49 }
50
51 // Add a signature; format is [rettype, param0, param1, ...]
52 WasmModuleBuilder.prototype.addSignature = function(sig) {
53 // TODO: canonicalize signatures?
54 this.signatures.push(sig);
55 return this.signatures.length - 1;
56 }
57
58 WasmModuleBuilder.prototype.addFunction = function(name, sig) {
59 var sig_index = (typeof sig) == "number" ? sig : this.addSignature(sig);
60 var func = new WasmFunctionBuilder(name, sig_index);
61 func.index = this.functions.length;
62 this.functions.push(func);
63 return func;
64 }
65
66 WasmModuleBuilder.prototype.addImport = function(name, sig) {
67 var sig_index = (typeof sig) == "number" ? sig : this.addSignature(sig);
68 this.imports.push({name: name, sig_index: sig_index});
69 return this.imports.length - 1;
70 }
71
72 WasmModuleBuilder.prototype.addDataSegment = function(addr, data, init) {
73 this.data_segments.push({addr: addr, data: data, init: init});
74 return this.data_segments.length - 1;
75 }
76
77 WasmModuleBuilder.prototype.appendToFunctionTable = function(array) {
78 this.function_table = this.function_table.concat(array);
79 return this;
80 }
81
82 function emit_u8(bytes, val) {
83 bytes.push(val & 0xff);
84 }
85
86 function emit_u16(bytes, val) {
87 bytes.push(val & 0xff);
88 bytes.push((val >> 8) & 0xff);
89 }
90
91 function emit_u32(bytes, val) {
92 bytes.push(val & 0xff);
93 bytes.push((val >> 8) & 0xff);
94 bytes.push((val >> 16) & 0xff);
95 bytes.push((val >> 24) & 0xff);
96 }
97
98 function emit_string(bytes, string) {
99 bytes.push(new StringRef(string));
100 bytes.push(0);
101 bytes.push(0);
102 bytes.push(0);
103 }
104
105 function emit_data_ref(bytes, string) {
106 bytes.push(new DataRef(string));
107 bytes.push(0);
108 bytes.push(0);
109 bytes.push(0);
110 }
111
112 function emit_varint(bytes, val) {
113 while (true) {
114 var v = val & 0xff;
115 val = val >>> 7;
116 if (val == 0) {
117 bytes.push(v);
118 break;
119 }
120 bytes.push(v | 0x80);
121 }
122 }
123
124 WasmModuleBuilder.prototype.toArray = function(debug) {
125 // Add header bytes
126 var bytes = [];
127 bytes = bytes.concat([kWasmH0, kWasmH1, kWasmH2, kWasmH3,
128 kWasmV0, kWasmV1, kWasmV2, kWasmV3]);
129
130 // Add memory section
131 if (this.memory != undefined) {
132 if (debug) print("emitting memory @ " + bytes.length);
133 emit_u8(bytes, kDeclMemory);
134 emit_varint(bytes, this.memory.min);
135 emit_varint(bytes, this.memory.max);
136 emit_u8(bytes, this.memory.exp ? 1 : 0);
137 }
138
139 // Add signatures section
140 if (this.signatures.length > 0) {
141 if (debug) print("emitting signatures @ " + bytes.length);
142 emit_u8(bytes, kDeclSignatures);
143 emit_varint(bytes, this.signatures.length);
144 for (sig of this.signatures) {
145 var params = sig.length - 1;
146 emit_u8(bytes, params);
147 for (var j = 0; j < sig.length; j++) {
148 emit_u8(bytes, sig[j]);
149 }
150 }
151 }
152
153 // Add imports section
154 if (this.imports.length > 0) {
155 if (debug) print("emitting imports @ " + bytes.length);
156 emit_u8(bytes, kDeclImportTable);
157 emit_varint(bytes, this.imports.length);
158 for (imp of this.imports) {
159 emit_u16(bytes, imp.sig_index);
160 emit_string(bytes, "");
161 emit_string(bytes, imp.name);
162 }
163 }
164
165 // Add functions section
166 var names = false;
167 var exports = 0;
168 if (this.functions.length > 0) {
169 if (debug) print("emitting functions @ " + bytes.length);
170 emit_u8(bytes, kDeclFunctions);
171 emit_varint(bytes, this.functions.length);
172 var index = 0;
173 for (func of this.functions) {
174 var flags = 0;
175 var hasName = func.name != undefined && func.name.length > 0;
176 names = names || hasName;
177 if (hasName) flags |= kDeclFunctionName;
178 if (func.locals != undefined) flags |= kDeclFunctionLocals;
179 exports += func.exports.length;
180
181 emit_u8(bytes, flags);
182 emit_u16(bytes, func.sig_index);
183
184 if (hasName) {
185 emit_string(bytes, func.name);
186 }
187 if (func.locals != undefined) {
188 emit_u16(bytes, func.locals.i32_count);
189 emit_u16(bytes, func.locals.i64_count);
190 emit_u16(bytes, func.locals.f32_count);
191 emit_u16(bytes, func.locals.f64_count);
192 }
193 emit_u16(bytes, func.body.length);
194 for (var i = 0; i < func.body.length; i++) {
195 emit_u8(bytes, func.body[i]);
196 }
197
198 index++;
199 }
200 }
201
202 if (this.function_table.length > 0) {
203 if (debug) print("emitting function table @ " + bytes.length);
204 emit_u8(bytes, kDeclFunctionTable);
205 emit_varint(bytes, this.function_table.length);
206 for (index of this.function_table) {
207 emit_u16(bytes, index);
208 }
209 }
210
211 if (exports > 0) {
212 if (debug) print("emitting exports @ " + bytes.length);
213 emit_u8(bytes, kDeclExportTable);
214 emit_varint(bytes, exports);
215 for (func of this.functions) {
216 for (exp of func.exports) {
217 emit_u16(bytes, func.index);
218 emit_string(bytes, exp);
219 }
220 }
221 }
222
223 if (this.data_segments.length > 0) {
224 if (debug) print("emitting data segments @ " + bytes.length);
225 emit_u8(bytes, kDeclDataSegments);
226 emit_varint(bytes, this.data_segments.length);
227 for (seg of this.data_segments) {
228 emit_u32(bytes, seg.addr);
229 emit_data_ref(bytes, seg.data);
230 emit_u32(bytes, seg.data.length);
231 emit_u8(bytes, seg.init ? 1 : 0);
232 }
233 }
234
235 // End the module.
236 if (debug) print("emitting end @ " + bytes.length);
237 emit_u8(bytes, kDeclEnd);
238
239 // Collect references and canonicalize strings.
240 var strings = new Object();
241 var data_segments = [];
242 var count = 0;
243 for (var i = 0; i < bytes.length; i++) {
244 var b = bytes[i];
245 if (b instanceof StringRef) {
246 count++;
247 var prev = strings[b.string];
248 if (prev) {
249 bytes[i] = prev;
250 } else {
251 strings[b.string] = b;
252 }
253 }
254 if (b instanceof DataRef) {
255 data_segments.push(b);
256 count++;
257 }
258 }
259
260 if (count > 0) {
261 // Emit strings.
262 if (debug) print("emitting strings @ " + bytes.length);
263 for (str in strings) {
264 var ref = strings[str];
265 if (!(ref instanceof StringRef)) continue;
266 if (debug) print(" \"" + str + "\" @ " + bytes.length);
267 ref.pos = bytes.length;
268 for (var i = 0; i < str.length; i++) {
269 emit_u8(bytes, str.charCodeAt(i));
270 }
271 emit_u8(bytes, 0); // null terminator.
272 }
273 // Emit data.
274 if (debug) print("emitting data @ " + bytes.length);
275 for (ref of data_segments) {
276 ref.pos = bytes.length;
277 for (var i = 0; i < ref.data.length; i++) {
278 emit_u8(bytes, ref.data[i]);
279 }
280 }
281 // Update references to strings and data.
282 for (var i = 0; i < bytes.length; i++) {
283 var b = bytes[i];
284 if (b instanceof StringRef || b instanceof DataRef) {
285 bytes[i] = b.pos & 0xFF;
286 bytes[i + 1] = (b.pos >> 8) & 0xFF;
287 bytes[i + 2] = (b.pos >> 16) & 0xFF;
288 bytes[i + 3] = (b.pos >> 24) & 0xFF;
289 }
290 }
291 }
292
293 return bytes;
294 }
295
296 WasmModuleBuilder.prototype.toBuffer = function(debug) {
297 var bytes = this.toArray(debug);
298 var buffer = new ArrayBuffer(bytes.length);
299 var view = new Uint8Array(buffer);
300 for (var i = 0; i < bytes.length; i++) {
301 var val = bytes[i];
302 if ((typeof val) == "string") val = val.charCodeAt(0);
303 view[i] = val | 0;
304 }
305 return buffer;
306 }
307
308 WasmModuleBuilder.prototype.instantiate = function(ffi) {
309 var buffer = this.toBuffer();
310 return _WASMEXP_.instantiateModule(buffer, ffi);
311 }
OLDNEW
« no previous file with comments | « test/mjsunit/wasm/test-wasm-module-builder.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698