@@ -11,8 +11,10 @@ pub fn main() !void {
11
11
return ExtractError .BadArguments ;
12
12
}
13
13
14
- var funcs = std .ArrayList ([]const u8 ).init (alloc );
15
- defer funcs .deinit ();
14
+ var imports = std .ArrayList ([]const u8 ).init (alloc );
15
+ defer imports .deinit ();
16
+ var exports = std .ArrayList ([]const u8 ).init (alloc );
17
+ defer exports .deinit ();
16
18
17
19
{
18
20
var file = try std .fs .openFileAbsolute (args [3 ], .{});
@@ -54,7 +56,21 @@ pub fn main() !void {
54
56
if (desc_type != 0 ) { // Not a function?
55
57
return ExtractError .ImportTypeNotSupported ;
56
58
}
57
- try funcs .append (try alloc .dupe (u8 , name ));
59
+ try imports .append (try alloc .dupe (u8 , name ));
60
+ }
61
+ }
62
+ } else if (section_id == 7 ) {
63
+ const export_count = try r .getU32 ();
64
+ for (0.. export_count ) | _ | {
65
+ const name_length = try r .getU32 ();
66
+ const name = try r .bytes (name_length );
67
+
68
+ const desc_type = try r .byte ();
69
+ const desc_index = try r .getU32 ();
70
+ _ = desc_index ;
71
+
72
+ if (desc_type == 0 and std .mem .startsWith (u8 , name , "zjb_fn" )) {
73
+ try exports .append (try alloc .dupe (u8 , name ));
58
74
}
59
75
}
60
76
} else {
@@ -63,7 +79,8 @@ pub fn main() !void {
63
79
}
64
80
}
65
81
66
- std .sort .insertion ([]const u8 , funcs .items , {}, strBefore );
82
+ std .sort .insertion ([]const u8 , imports .items , {}, strBefore );
83
+ std .sort .insertion ([]const u8 , exports .items , {}, strBefore );
67
84
68
85
var out_file = try std .fs .createFileAbsolute (args [1 ], .{});
69
86
defer out_file .close ();
@@ -84,11 +101,6 @@ pub fn main() !void {
84
101
\\ }
85
102
\\ constructor() {
86
103
\\ this._decoder = new TextDecoder();
87
- \\ this._handles = new Map();
88
- \\ this._handles.set(0, null);
89
- \\ this._handles.set(1, window);
90
- \\ this._handles.set(2, "");
91
- \\ this._next_handle = 3;
92
104
\\ this.imports = {
93
105
\\
94
106
);
@@ -97,7 +109,7 @@ pub fn main() !void {
97
109
var func_args = std .ArrayList (ArgType ).init (alloc );
98
110
defer func_args .deinit ();
99
111
100
- implement_functions : for (funcs .items ) | func | {
112
+ implement_functions : for (imports .items ) | func | {
101
113
if (std .mem .eql (u8 , lastFunc , func )) {
102
114
continue ;
103
115
}
@@ -256,10 +268,119 @@ pub fn main() !void {
256
268
257
269
try writer .writeAll (";\n },\n " );
258
270
}
271
+ try writer .writeAll (" };\n " ); // end imports
272
+
273
+ try writer .writeAll (" this.exports = {\n " );
274
+
275
+ var export_names = std .ArrayList ([]const u8 ).init (alloc );
276
+ defer export_names .deinit ();
277
+
278
+ for (exports .items ) | func | {
279
+ func_args .clearRetainingCapacity ();
280
+
281
+ var np = NameParser { .slice = func };
282
+ try np .must ("zjb_fn_" );
283
+
284
+ while (! (np .maybe ("_" ) or np .slice .len == 0 )) {
285
+ try func_args .append (try np .mustType ());
286
+ }
287
+
288
+ const ret_type = try np .mustType ();
289
+ try np .must ("_" );
290
+
291
+ const name = np .slice ;
292
+ try export_names .append (name );
293
+
294
+ //////////////////////////////////
295
+
296
+ try writer .writeAll (" \" " );
297
+ try writer .writeAll (name );
298
+ try writer .writeAll ("\" : (" );
299
+
300
+ for (0.. func_args .items .len ) | i | {
301
+ if (i > 0 ) {
302
+ try writer .writeAll (", " );
303
+ }
304
+ try writer .print ("arg{d}" , .{i });
305
+ }
306
+
307
+ try writer .writeAll (") => {\n " );
308
+ switch (ret_type ) {
309
+ .void = > {},
310
+ .bool = > {
311
+ try writer .writeAll ("return Boolean(" );
312
+ },
313
+ .object = > {
314
+ try writer .writeAll ("return this._handles.get(" );
315
+ },
316
+ .number = > {
317
+ try writer .writeAll ("return " );
318
+ },
319
+ }
320
+
321
+ try writer .writeAll ("this.instance.exports." );
322
+ try writer .writeAll (func );
323
+ try writer .writeAll ("(" );
324
+
325
+ for (func_args .items , 0.. ) | arg , i | {
326
+ if (i > 0 ) {
327
+ try writer .writeAll (", " );
328
+ }
329
+ switch (arg ) {
330
+ .void = > {
331
+ return ExtractError .InvalidExportedName ;
332
+ },
333
+ .bool = > {
334
+ try writer .print ("Boolean(arg{d})" , .{i });
335
+ },
336
+ .object = > {
337
+ try writer .print ("this.new_handle(arg{d})" , .{i });
338
+ },
339
+ .number = > {
340
+ try writer .print ("arg{d}" , .{i });
341
+ },
342
+ }
343
+ }
344
+
345
+ try writer .writeAll (")" );
346
+
347
+ switch (ret_type ) {
348
+ .bool , .object = > {
349
+ try writer .writeAll (")" );
350
+ },
351
+ .void , .number = > {},
352
+ }
353
+ try writer .writeAll (";\n },\n " );
354
+ }
355
+ try writer .writeAll (" };\n " ); // end exports
356
+
357
+ try writer .writeAll (
358
+ \\ this._export_reverse_handles = {};
359
+ \\ this._handles = new Map();
360
+ \\ this._handles.set(0, null);
361
+ \\ this._handles.set(1, window);
362
+ \\ this._handles.set(2, "");
363
+ \\ this._handles.set(3, this.exports);
364
+ \\ this._next_handle = 4;
365
+ \\
366
+ );
367
+
368
+ try writer .writeAll (
369
+ \\ }
370
+ \\};
371
+ \\
372
+ );
373
+
374
+ std .sort .insertion ([]const u8 , export_names .items , {}, strBefore );
375
+ if (export_names .items .len > 1 ) {
376
+ for (0.. export_names .items .len - 1 ) | i | {
377
+ if (std .mem .eql (u8 , export_names .items [i ], export_names .items [i + 1 ])) {
378
+ std .debug .print ("ERROR: function export name used twice: {s}.\n " , .{export_names .items [i ]});
379
+ std .posix .exit (1 );
380
+ }
381
+ }
382
+ }
259
383
260
- try writer .writeAll (" };\n " );
261
- try writer .writeAll (" }\n " );
262
- try writer .writeAll ("};\n " );
263
384
try out_file .sync ();
264
385
}
265
386
0 commit comments