Skip to content

Commit acfef64

Browse files
committed
Update dist files; Also parse name and source mapping sections in lib/parse
1 parent c45a35b commit acfef64

File tree

15 files changed

+292
-91
lines changed

15 files changed

+292
-91
lines changed

dist/asc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/asc.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/parse/README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ![AS](https://avatars1.githubusercontent.com/u/28916798?s=48) parse
22

3-
A WebAssembly binary parser in WebAssembly.
3+
A WebAssembly binary parser in WebAssembly. Super small, super fast, with TypeScript support.
44

55
API
66
---
@@ -53,6 +53,18 @@ API
5353
* **onExport**?(index: `number`, kind: `ExternalKind`, kindIndex: `number`, nameOff: `number`, nameLen: `number`): `void`<br />
5454
Called with each export if the export section is evaluated.
5555

56+
* **onSourceMappingURL**?(offset: `number`, length: `number`): `void`<br />
57+
Called with the source map URL if the 'sourceMappingURL' section is evaluated.
58+
59+
* **onModuleName**?(offset: `number`, length: `number`): `void`<br />
60+
Called with the module name if present and the 'name' section is evaluated.
61+
62+
* **onFunctionName**?(index: `number`, offset: `number`, length: `number`): `void`<br />
63+
Called with each function name if present and the 'name' section is evaluated.
64+
65+
* **onLocalName**?(funcIndex: `number`, index: `number`, offset: `number`, length: `number`): `void`<br />
66+
Called with each local name if present and the 'name' section is evaluated.
67+
5668
* **Type**<br />
5769
A value or element type, depending on context.
5870

lib/parse/assembly/index.ts

Lines changed: 143 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Type,
66
SectionId,
77
ExternalKind,
8+
NameType,
89
MAX_PAGES,
910
MAX_TABLES,
1011
Opcode
@@ -90,28 +91,34 @@ declare function onFunction(index: u32, typeIndex: u32): void;
9091
declare function onGlobal(index: u32, type: u32, mutability: u32): void;
9192
declare function onExport(index: u32, kind: u32, kindIndex: u32, nameOffset: u32, nameLength: u32): void;
9293
declare function onStart(index: u32): void;
94+
declare function onSourceMappingURL(offset: u32, length: u32): void;
95+
declare function onModuleName(offset: u32, length: u32): void;
96+
declare function onFunctionName(index: u32, offset: u32, length: u32): void;
97+
declare function onLocalName(funcIndex: u32, index: u32, offset: u32, length: u32): void;
9398

9499
/** Starts parsing the module that has been placed in memory. */
95-
function parse(): void {
100+
export function parse(begin: usize, end: usize): void {
101+
off = begin;
96102
var magic = readUint<u32>();
97103
if (magic != 0x6D736100) unreachable();
98104
var version = readUint<u32>();
99105
if (version != 1) unreachable();
100-
var end: usize = current_memory() << 16;
106+
var fun_space_index: u32 = 0;
107+
var glo_space_index: u32 = 0;
108+
var mem_space_index: u32 = 0;
109+
var tbl_space_index: u32 = 0;
101110
while (off < end) {
102111
let section_off = off;
103112
let id = readVaruint(7);
104113
let payload_len = readVaruint(32);
105114
let name_off = 0;
106115
let name_len = 0;
107116
if (!id) {
117+
let before = off;
108118
name_len = readVaruint(32);
109-
if (!name_len) {
110-
off = section_off;
111-
break;
112-
}
113119
name_off = off;
114120
off += name_len;
121+
payload_len -= off - before;
115122
} else if (id > <u32>SectionId.Data) unreachable();
116123
let payload_off = off;
117124
if (onSection(
@@ -126,16 +133,27 @@ function parse(): void {
126133
let count = readVaruint(32);
127134
for (let index: u32 = 0; index < count; ++index) {
128135
let form = readVarint(7) & 0x7f;
129-
onType(index, form);
136+
onType(
137+
index,
138+
form
139+
);
130140
let paramCount = readVaruint(32);
131141
for (let paramIndex: u32 = 0; paramIndex < paramCount; ++paramIndex) {
132142
let paramType = readVarint(7) & 0x7f;
133-
onTypeParam(index, paramIndex, paramType);
143+
onTypeParam(
144+
index,
145+
paramIndex,
146+
paramType
147+
);
134148
}
135149
let returnCount = readVaruint(1); // MVP
136150
for (let returnIndex: u32 = 0; returnIndex < returnCount; ++returnIndex) {
137151
let returnType = readVarint(7) & 0x7f;
138-
onTypeReturn(index, returnIndex, returnType);
152+
onTypeReturn(
153+
index,
154+
returnIndex,
155+
returnType
156+
);
139157
}
140158
}
141159
break;
@@ -145,10 +163,10 @@ function parse(): void {
145163
for (let index: u32 = 0; index < count; ++index) {
146164
let module_len = readVaruint(32);
147165
let module_off = off;
148-
off += module_off;
166+
off += module_len;
149167
let field_len = readVaruint(32);
150168
let field_off = off;
151-
off += field_off;
169+
off += field_len;
152170
let kind = readUint<u8>();
153171
onImport(
154172
index,
@@ -161,28 +179,46 @@ function parse(): void {
161179
switch (kind) {
162180
case ExternalKind.Function: {
163181
let type = readVaruint(32);
164-
onFunctionImport(index, type);
182+
onFunctionImport(
183+
fun_space_index++,
184+
type
185+
);
165186
break;
166187
}
167188
case ExternalKind.Table: {
168189
let type = readVarint(7) & 0x7f;
169190
let flags = readVaruint(1);
170191
let initial = readVaruint(32);
171192
let maximum: u32 = flags & 1 ? readVaruint(32) : MAX_TABLES;
172-
onTableImport(index, type, initial, maximum, flags);
193+
onTableImport(
194+
tbl_space_index++,
195+
type,
196+
initial,
197+
maximum,
198+
flags
199+
);
173200
break;
174201
}
175202
case ExternalKind.Memory: {
176203
let flags = readVaruint(1);
177204
let initial = readVaruint(32);
178205
let maximum: u32 = flags & 1 ? readVaruint(32) : MAX_PAGES;
179-
onMemoryImport(index, initial, maximum, flags);
206+
onMemoryImport(
207+
mem_space_index++,
208+
initial,
209+
maximum,
210+
flags
211+
);
180212
break;
181213
}
182214
case ExternalKind.Global: {
183215
let type = readVarint(7) & 0x7f;
184216
let mutability = readVaruint(1);
185-
onGlobalImport(index, type, mutability);
217+
onGlobalImport(
218+
glo_space_index++,
219+
type,
220+
mutability
221+
);
186222
break;
187223
}
188224
default: unreachable();
@@ -192,9 +228,12 @@ function parse(): void {
192228
}
193229
case SectionId.Function: {
194230
let count = readVaruint(32);
195-
for (let index: u32 = 0; index < count; ++index) {
231+
for (let i: u32 = 0; i < count; ++i) {
196232
let typeIndex = readVaruint(32);
197-
onFunction(index, typeIndex);
233+
onFunction(
234+
fun_space_index++,
235+
typeIndex
236+
);
198237
}
199238
break;
200239
}
@@ -204,13 +243,18 @@ function parse(): void {
204243
let flags = readVaruint(1);
205244
let initial = readVaruint(32);
206245
let maximum: u32 = flags ? readVaruint(32) : MAX_PAGES;
207-
onMemory(index, initial, maximum, flags);
246+
onMemory(
247+
mem_space_index++,
248+
initial,
249+
maximum,
250+
flags
251+
);
208252
}
209253
break;
210254
}
211255
case SectionId.Global: {
212256
let count = readVaruint(32);
213-
for (let index: u32 = 0; index < count; ++index) {
257+
for (let i: u32 = 0; i < count; ++i) {
214258
let type = readVarint(7) & 0x7f;
215259
let mutability = readVaruint(1);
216260
let op = readUint<u8>();
@@ -239,7 +283,11 @@ function parse(): void {
239283
}
240284
op = readUint<u8>();
241285
if (op != Opcode.end) unreachable();
242-
onGlobal(index, type, mutability);
286+
onGlobal(
287+
glo_space_index++,
288+
type,
289+
mutability
290+
);
243291
}
244292
break;
245293
}
@@ -268,8 +316,80 @@ function parse(): void {
268316
);
269317
break;
270318
}
271-
case SectionId.Custom:
272-
case SectionId.Code: { // TODO
319+
case SectionId.Custom: {
320+
if (
321+
name_len == 4 &&
322+
load<u32>(name_off) == 0x656D616E // "name"
323+
) {
324+
let name_type = readVaruint(7);
325+
let name_payload_len = readVaruint(32);
326+
let name_payload_off = off;
327+
switch (name_type) {
328+
case NameType.Module: {
329+
let module_name_len = readVaruint(32);
330+
let module_name_off = off;
331+
onModuleName(
332+
module_name_off,
333+
module_name_len
334+
);
335+
break;
336+
}
337+
case NameType.Function: {
338+
let count = readVaruint(32);
339+
for (let i: u32 = 0; i < count; ++i) {
340+
let fn_index = readVaruint(32);
341+
let fn_name_len = readVaruint(32);
342+
let fn_name_off = off;
343+
off += fn_name_len;
344+
onFunctionName(
345+
fn_index,
346+
fn_name_off,
347+
fn_name_len
348+
);
349+
}
350+
break;
351+
}
352+
case NameType.Local: {
353+
let count = readVaruint(32);
354+
for (let i: u32 = 0; i < count; ++i) {
355+
let fn_index = readVaruint(32);
356+
let lc_count = readVaruint(32);
357+
for (let j: u32 = 0; j < lc_count; ++j) {
358+
let lc_index = readVaruint(32);
359+
let lc_name_len = readVaruint(32);
360+
let lc_name_off = off;
361+
off += lc_name_len;
362+
onLocalName(
363+
fn_index,
364+
lc_index,
365+
lc_name_off,
366+
lc_name_len
367+
);
368+
}
369+
}
370+
break;
371+
}
372+
default: unreachable();
373+
}
374+
off = name_payload_off + name_payload_len; // ignore errors
375+
break;
376+
} else if (
377+
name_len == 16 &&
378+
load<u64>(name_off ) == 0x614D656372756F73 && // "sourceMa"
379+
load<u64>(name_off + 8) == 0x4C5255676E697070 // "ppingURL"
380+
) {
381+
let url_len = readVaruint(32);
382+
let url_off = off;
383+
off += url_len;
384+
onSourceMappingURL(
385+
url_off,
386+
url_len
387+
);
388+
}
389+
off = payload_off + payload_len; // ignore errors
390+
break;
391+
}
392+
case SectionId.Code: { // skip
273393
off += payload_len;
274394
break;
275395
}
@@ -279,7 +399,5 @@ function parse(): void {
279399
off += payload_len;
280400
}
281401
}
402+
if (off != end) unreachable();
282403
}
283-
284-
// Start parsing immediately
285-
parse();

0 commit comments

Comments
 (0)