Skip to content

Commit 5823e35

Browse files
committed
Progress and a tiny WASM binary parser
1 parent 06198a3 commit 5823e35

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+12004
-3893
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ A few early examples to get an idea:
2323
* **[PSON decoder](./examples/pson)**<br />
2424
A simple decoder for the PSON binary format.
2525

26+
* **[WASM parser](./lib/parse)**<br />
27+
A WebAssembly binary parser in WebAssembly.
28+
2629
Or browse the [compiler tests](./tests/compiler) for a more in-depth overview of what's supported already. One of them is a [showcase](./tests/compiler/showcase.ts).
2730

2831
Installation

bin/asc.js

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ exports.compileString = (source, extraArgs={}) => new Promise((resolve, reject)
9393
const libDir = path.join(__dirname, "../std", "assembly");
9494
const libFiles = require("glob").sync("**/*.ts", { cwd: libDir });
9595
libFiles.forEach(file =>
96-
exports.libraryFiles["~lib/" + file.replace(/\.ts$/, "")] = readFileNode(path.join(libDir, file), { encoding: "utf8" })
96+
exports.libraryFiles[file.replace(/\.ts$/, "")] = readFileNode(path.join(libDir, file), { encoding: "utf8" })
9797
);
9898
}
9999

@@ -249,54 +249,71 @@ exports.main = function main(argv, options, callback) {
249249

250250
// Load library file if explicitly requested
251251
if (sourcePath.startsWith(exports.libraryPrefix)) {
252-
for (let i = 0, k = libDirs.length; i < k; ++i) {
253-
if (exports.libraryFiles.hasOwnProperty(sourcePath)) {
254-
sourceText = exports.libraryFiles[sourcePath];
255-
sourcePath += ".ts";
256-
} else {
257-
sourceText = readFile(path.join(
258-
libDirs[i],
259-
sourcePath.substring(exports.libraryPrefix.length) + ".ts")
260-
);
252+
const plainName = sourcePath.substring(exports.libraryPrefix.length);
253+
const indexName = sourcePath.substring(exports.libraryPrefix.length) + "/index";
254+
if (exports.libraryFiles.hasOwnProperty(plainName)) {
255+
sourceText = exports.libraryFiles[plainName];
256+
sourcePath = exports.libraryPrefix + plainName + ".ts";
257+
} else if (exports.libraryFiles.hasOwnProperty(indexName)) {
258+
sourceText = exports.libraryFiles[indexName];
259+
sourcePath = exports.libraryPrefix + indexName + ".ts";
260+
} else {
261+
for (let i = 0, k = libDirs.length; i < k; ++i) {
262+
const dir = libDirs[i];
263+
sourceText = readFile(path.join(dir, plainName + ".ts"));
261264
if (sourceText !== null) {
262-
sourcePath += ".ts";
265+
sourcePath = exports.libraryPrefix + plainName + ".ts";
263266
break;
267+
} else {
268+
sourceText = readFile(path.join(dir, indexName + ".ts"));
269+
if (sourceText !== null) {
270+
sourcePath = exports.libraryPrefix + indexName + ".ts";
271+
break;
272+
}
264273
}
265274
}
266275
}
267276

268-
// Otherwise try nextFile.ts, nextFile/index.ts, ~lib/nextFile.ts
277+
// Otherwise try nextFile.ts, nextFile/index.ts, ~lib/nextFile.ts, ~lib/nextFile/index.ts
269278
} else {
270-
sourceText = readFile(path.join(baseDir, sourcePath + ".ts"));
279+
const plainName = sourcePath;
280+
const indexName = sourcePath + "/index";
281+
sourceText = readFile(path.join(baseDir, plainName + ".ts"));
271282
if (sourceText !== null) {
272-
sourcePath += ".ts";
283+
sourcePath = plainName + ".ts";
273284
} else {
274-
sourceText = readFile(path.join(baseDir, sourcePath, "index.ts"));
285+
sourceText = readFile(path.join(baseDir, indexName + ".ts"));
275286
if (sourceText !== null) {
276-
sourcePath += "/index.ts";
277-
} else {
278-
const key = exports.libraryPrefix + sourcePath;
279-
if (exports.libraryFiles.hasOwnProperty(key)) {
280-
sourceText = exports.libraryFiles[key];
281-
sourcePath = key + ".ts";
287+
sourcePath = indexName + ".ts";
288+
} else if (!plainName.startsWith(".")) {
289+
if (exports.libraryFiles.hasOwnProperty(plainName)) {
290+
sourceText = exports.libraryFiles[plainName];
291+
sourcePath = exports.libraryPrefix + plainName + ".ts";
292+
} else if (exports.libraryFiles.hasOwnProperty(indexName)) {
293+
sourceText = exports.libraryFiles[indexName];
294+
sourcePath = exports.libraryPrefix + indexName + ".ts";
282295
} else {
283296
for (let i = 0, k = libDirs.length; i < k; ++i) {
284297
const dir = libDirs[i];
285-
sourceText = readFile(path.join(dir, sourcePath + ".ts"));
298+
sourceText = readFile(path.join(dir, plainName + ".ts"));
286299
if (sourceText !== null) {
287-
sourcePath = exports.libraryPrefix + sourcePath + ".ts";
300+
sourcePath = exports.libraryPrefix + plainName + ".ts";
288301
break;
302+
} else {
303+
sourceText = readFile(path.join(dir, indexName + ".ts"));
304+
if (sourceText !== null) {
305+
sourcePath = exports.libraryPrefix + indexName + ".ts";
306+
break;
307+
}
289308
}
290309
}
291-
if (sourceText === null) {
292-
return callback(
293-
Error("Import file '" + sourcePath + ".ts' not found.")
294-
);
295-
}
296310
}
297311
}
298312
}
299313
}
314+
if (sourceText == null) {
315+
return callback(Error("Import file '" + plainName + ".ts' not found."));
316+
}
300317
stats.parseCount++;
301318
stats.parseTime += measure(() => {
302319
assemblyscript.parseFile(sourceText, sourcePath, false, parser);

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/lint/base.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212
["boolean", "Use `bool` instead."]
1313
]
1414
},
15-
"object-literal-shorthand": {
16-
"severity": "error",
17-
"options": ["never"]
18-
},
1915
"restrict-plus-operands": {
2016
"severity": "error"
2117
},

lib/parse/README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# ![AS](https://avatars1.githubusercontent.com/u/28916798?s=48) parse
2+
3+
A WebAssembly binary parser in WebAssembly.
4+
5+
API
6+
---
7+
8+
* **parse**(binary: `Uint8Array`, options?: `ParseOptions`): `void`<br />
9+
Parses the contents of a WebAssembly binary according to the specified options.
10+
11+
* **ParseOptions**<br />
12+
Options specified to the parser. The `onSection` callback determines the sections being evaluated in detail.
13+
14+
* **onSection**?(id: `SectionId`, payloadOff: `number`, payloadLen: `number`, nameOff: `number`, nameLen: `number`): `boolean`<br />
15+
Called with each section in the binary. Returning `true` evaluates the section.
16+
17+
* **onType**?(index: `number`, form: `number`): `void`<br />
18+
Called with each function type if the type section is evaluated.
19+
20+
* **onTypeParam**?(index: `number`, paramIndex: `number`, paramType: `Type`): `void`<br />
21+
Called with each function parameter if the type section is evaluated.
22+
23+
* **onTypeReturn**?(index: `number`, returnIndex: `number`, returnType: `Type`): `void`<br />
24+
Called with each function return type if the type section is evaluated.
25+
26+
* **onImport**?(index: `number`, kind: `ExternalKind`, moduleOff: `number`, moduleLen: `number`, fieldOff: `number`, fieldLen: `number`): `void`<br />
27+
Called with each import if the import section is evaluated.
28+
29+
* **onFunctionImport**?(index: `number`, type: `number`): `void`<br />
30+
Called with each function import if the import section is evaluated.
31+
32+
* **onTableImport**?(index: `number`, type: `Type`, initial: `number`, maximum: `number`, flags: `number`): `void`<br />
33+
Called with each table import if the import section is evaluated.
34+
35+
* **onMemoryImport**?(index: `number`, initial: `number`, maximum: `number`, flags: `number`): `void`<br />
36+
Called with each memory import if the import section is evaluated.
37+
38+
* **onGlobalImport**?(index: `number`, type: `Type`, mutability: `number`): `void`<br />
39+
Called with each global import if the import section is evaluated.
40+
41+
* **onMemory**?(index: `number`, initial: `number`, maximum: `number`, flags: `number`): `void`<br />
42+
Called with each memory if the memory section is evaluated.
43+
44+
* **onFunction**?(index: `number`, typeIndex: `number`): `void`<br />
45+
Called with each function if the function section is evaluated.
46+
47+
* **onGlobal**?(index: `number`, type: `Type`, mutability: `number`): `void`<br />
48+
Called with each global if the global section is evaluated.
49+
50+
* **onStart**?(index: `number`): `void`<br />
51+
Called with the start function index if the start section is evaluated.
52+
53+
* **onExport**?(index: `number`, kind: `ExternalKind`, kindIndex: `number`, nameOff: `number`, nameLen: `number`): `void`<br />
54+
Called with each export if the export section is evaluated.
55+
56+
* **Type**<br />
57+
A value or element type, depending on context.
58+
59+
| Name | Value
60+
|---------|-------
61+
| i32 | 0x7f
62+
| i64 | 0x7e
63+
| f32 | 0x7d
64+
| f64 | 0x7c
65+
| anyfunc | 0x70
66+
| func | 0x60
67+
| none | 0x40
68+
69+
* **SectionId**<br />
70+
Numerical id of the current section.
71+
72+
| Name | Value
73+
|----------|-------
74+
| Custom | 0
75+
| Type | 1
76+
| Import | 2
77+
| Function | 3
78+
| Table | 4
79+
| Memory | 5
80+
| Global | 6
81+
| Export | 7
82+
| Start | 8
83+
| Element | 9
84+
| Code | 10
85+
| Data | 11
86+
87+
* **ExternalKind**<br />
88+
Kind of an export or import.
89+
90+
| Name | Value
91+
|----------|-------
92+
| Function | 0
93+
| Table | 1
94+
| Memory | 2
95+
| Global | 3

0 commit comments

Comments
 (0)