json-as 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +32 -22
  3. package/SECURITY.md +2 -1
  4. package/assembly/__benches__/large.bench.ts +3 -0
  5. package/assembly/__benches__/vec3.bench.ts +3 -0
  6. package/assembly/__tests__/arbitrary.spec.ts +3 -3
  7. package/assembly/__tests__/array.spec.ts +5 -8
  8. package/assembly/__tests__/box.spec.ts +10 -20
  9. package/assembly/__tests__/custom.spec.ts +7 -6
  10. package/assembly/__tests__/date.spec.ts +4 -6
  11. package/assembly/__tests__/float.spec.ts +3 -3
  12. package/assembly/__tests__/map.spec.ts +1 -1
  13. package/assembly/__tests__/raw.spec.ts +3 -3
  14. package/assembly/__tests__/struct.spec.ts +25 -14
  15. package/assembly/deserialize/simd/string.ts +1 -2
  16. package/assembly/deserialize/simple/array/struct.ts +2 -3
  17. package/assembly/deserialize/simple/array.ts +1 -1
  18. package/assembly/deserialize/simple/bool.ts +1 -1
  19. package/assembly/deserialize/simple/map.ts +3 -4
  20. package/assembly/deserialize/simple/object.ts +2 -3
  21. package/assembly/deserialize/simple/raw.ts +1 -1
  22. package/assembly/deserialize/simple/struct.ts +2 -3
  23. package/assembly/index.ts +26 -10
  24. package/assembly/serialize/simd/string.ts +1 -0
  25. package/assembly/serialize/simple/integer.ts +1 -1
  26. package/assembly/serialize/simple/object.ts +6 -6
  27. package/assembly/test.ts +26 -24
  28. package/bench.js +2 -4
  29. package/index.ts +1 -1
  30. package/lib/as-bs.ts +4 -13
  31. package/package.json +4 -2
  32. package/run-tests.sh +1 -1
  33. package/transform/lib/index.js +61 -63
  34. package/transform/lib/index.js.map +1 -1
  35. package/transform/src/index.ts +73 -138
@@ -1,15 +1,18 @@
1
- import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node, Tokenizer, SourceKind, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression, MethodDeclaration, Statement } from "assemblyscript/dist/assemblyscript.js";
1
+ import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node, Tokenizer, SourceKind, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression, MethodDeclaration, Statement, Program } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { Transform } from "assemblyscript/dist/transform.js";
3
3
  import { Visitor } from "./visitor.js";
4
- import { SimpleParser, toString } from "./util.js";
4
+ import { isStdlib, SimpleParser, toString } from "./util.js";
5
5
  import * as path from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { Property, PropertyFlags, Schema } from "./types.js";
8
8
  import { getClasses, getImportedClass } from "./linker.js";
9
+ import { Feature } from "types:assemblyscript/src/common";
9
10
 
10
11
  let indent = " ";
11
12
 
12
13
  class JSONTransform extends Visitor {
14
+ public program!: Program;
15
+ public baseDir!: string;
13
16
  public parser!: Parser;
14
17
  public schemas: Schema[] = [];
15
18
  public schema!: Schema;
@@ -17,6 +20,7 @@ class JSONTransform extends Visitor {
17
20
  public imports: ImportStatement[] = [];
18
21
 
19
22
  public topStatements: Statement[] = [];
23
+ public simdStatements: string[] = [];
20
24
 
21
25
  visitClassDeclaration(node: ClassDeclaration): void {
22
26
  if (!node.decorators?.length) return;
@@ -37,35 +41,25 @@ class JSONTransform extends Visitor {
37
41
  if (process.env["JSON_DEBUG"]) console.log("Created schema: " + this.schema.name + " in file " + node.range.source.normalizedPath);
38
42
 
39
43
  const members: FieldDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.FieldDeclaration && v.flags !== CommonFlags.Static && v.flags !== CommonFlags.Private && v.flags !== CommonFlags.Protected && !v.decorators?.some((decorator) => (<IdentifierExpression>decorator.name).text === "omit")) as FieldDeclaration[])];
40
- const serializers: MethodDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "serializer")))] as MethodDeclaration[];
41
- const deserializers: MethodDeclaration[] = [...(node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "deserializer")))] as MethodDeclaration[];
44
+ const serializers: MethodDeclaration[] = [...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "serializer"))] as MethodDeclaration[];
45
+ const deserializers: MethodDeclaration[] = [...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration && v.decorators && v.decorators.some((e) => (<IdentifierExpression>e.name).text.toLowerCase() === "deserializer"))] as MethodDeclaration[];
42
46
 
43
47
  if (serializers.length > 1) throwError("Multiple serializers detected for class " + node.name.text + " but schemas can only have one serializer!", serializers[1].range);
44
48
  if (deserializers.length > 1) throwError("Multiple deserializers detected for class " + node.name.text + " but schemas can only have one deserializer!", deserializers[1].range);
45
49
 
46
50
  if (serializers.length) {
47
51
  const serializer = serializers[0];
48
- if (!serializer.signature.parameters.length) throwError("Could not find any parameters in custom serializer for " + this.schema.name + ". Serializers must have one parameter like 'serializer(self: " + this.schema.name + "): string {}'", serializer.range);
52
+ // if (!serializer.signature.parameters.length) throwError("Could not find any parameters in custom serializer for " + this.schema.name + ". Serializers must have one parameter like 'serializer(self: " + this.schema.name + "): string {}'", serializer.range);
49
53
  if (serializer.signature.parameters.length > 1) throwError("Found too many parameters in custom serializer for " + this.schema.name + ", but serializers can only accept one parameter of type '" + this.schema.name + "'!", serializer.signature.parameters[1].range);
50
- if ((<NamedTypeNode>serializer.signature.parameters[0].type).name.identifier.text != node.name.text && (<NamedTypeNode>serializer.signature.parameters[0].type).name.identifier.text != "this") throwError("Type of parameter for custom serializer does not match! It should be 'string'either be 'this' or '" + this.schema.name + "'", serializer.signature.parameters[0].type.range);
54
+ if (serializer.signature.parameters.length > 0 && (<NamedTypeNode>serializer.signature.parameters[0].type).name.identifier.text != node.name.text && (<NamedTypeNode>serializer.signature.parameters[0].type).name.identifier.text != "this") throwError("Type of parameter for custom serializer does not match! It should be 'string'either be 'this' or '" + this.schema.name + "'", serializer.signature.parameters[0].type.range);
51
55
  if (!serializer.signature.returnType || !(<NamedTypeNode>serializer.signature.returnType).name.identifier.text.includes("string")) throwError("Could not find valid return type for serializer in " + this.schema.name + "!. Set the return type to type 'string' and try again", serializer.signature.returnType.range);
52
56
 
53
57
  if (!serializer.decorators.some((v) => (<IdentifierExpression>v.name).text == "inline")) {
54
- serializer.decorators.push(
55
- Node.createDecorator(
56
- Node.createIdentifierExpression(
57
- "inline",
58
- serializer.range
59
- ),
60
- null,
61
- serializer.range
62
- )
63
- );
58
+ serializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", serializer.range), null, serializer.range));
64
59
  }
65
60
  let SERIALIZER = "";
66
- SERIALIZER += " __SERIALIZE_CUSTOM(ptr: usize): void {\n";
67
- SERIALIZER += " const data = this." + serializer.name.text + "(changetype<" + this.schema.name + ">(ptr));\n";
68
- SERIALIZER += " if (isNullable(data) && changetype<usize>(data) == <usize>0) throw new Error(\"Could not serialize data using custom serializer!\");\n";
61
+ SERIALIZER += " __SERIALIZE_CUSTOM(): void {\n";
62
+ SERIALIZER += " const data = this." + serializer.name.text + "(" + (serializer.signature.parameters.length ? "this" : "") + ");\n";
69
63
  SERIALIZER += " const dataSize = data.length << 1;\n";
70
64
  SERIALIZER += " memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
71
65
  SERIALIZER += " bs.offset += dataSize;\n";
@@ -86,22 +80,11 @@ class JSONTransform extends Visitor {
86
80
  if (!deserializer.signature.returnType || !((<NamedTypeNode>deserializer.signature.returnType).name.identifier.text.includes(this.schema.name) || (<NamedTypeNode>deserializer.signature.returnType).name.identifier.text.includes("this"))) throwError("Could not find valid return type for deserializer in " + this.schema.name + "!. Set the return type to type '" + this.schema.name + "' or 'this' and try again", deserializer.signature.returnType.range);
87
81
 
88
82
  if (!deserializer.decorators.some((v) => (<IdentifierExpression>v.name).text == "inline")) {
89
- deserializer.decorators.push(
90
- Node.createDecorator(
91
- Node.createIdentifierExpression(
92
- "inline",
93
- deserializer.range
94
- ),
95
- null,
96
- deserializer.range
97
- )
98
- );
83
+ deserializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", deserializer.range), null, deserializer.range));
99
84
  }
100
85
  let DESERIALIZER = "";
101
- DESERIALIZER += " __DESERIALIZE_CUSTOM(data: string): " + this.schema.name + " {\n";
102
- DESERIALIZER += " const d = this." + deserializer.name.text + "(data)";
103
- DESERIALIZER += " if (isNullable(d) && changetype<usize>(d) == <usize>0) throw new Error(\"Could not deserialize data using custom deserializer!\");\n";
104
- DESERIALIZER += " return d;\n";
86
+ DESERIALIZER += " __DESERIALIZE_CUSTOM(data: string): this {\n";
87
+ DESERIALIZER += " return this." + deserializer.name.text + "(data);\n";
105
88
  DESERIALIZER += " }\n";
106
89
 
107
90
  if (process.env["JSON_DEBUG"]) console.log(DESERIALIZER);
@@ -251,11 +234,12 @@ class JSONTransform extends Visitor {
251
234
  INITIALIZE += ` this.${member.name} = "";\n`;
252
235
  }
253
236
 
237
+ const SIMD_ENABLED = this.program.options.hasFeature(Feature.Simd);
254
238
  if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull)) isRegular = true;
255
239
  if (isRegular && isPure) {
256
240
  const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
257
241
  this.schema.byteSize += keyPart.length << 1;
258
- SERIALIZE += this.getStores(keyPart)
242
+ SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
259
243
  .map((v) => indent + v + "\n")
260
244
  .join("");
261
245
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -263,7 +247,7 @@ class JSONTransform extends Visitor {
263
247
  } else if (isRegular && !isPure) {
264
248
  const keyPart = (isFirst ? "" : ",") + aliasName + ":";
265
249
  this.schema.byteSize += keyPart.length << 1;
266
- SERIALIZE += this.getStores(keyPart)
250
+ SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
267
251
  .map((v) => indent + v + "\n")
268
252
  .join("");
269
253
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -274,7 +258,7 @@ class JSONTransform extends Visitor {
274
258
  indentInc();
275
259
  const keyPart = aliasName + ":";
276
260
  this.schema.byteSize += keyPart.length << 1;
277
- SERIALIZE += this.getStores(keyPart)
261
+ SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
278
262
  .map((v) => indent + v + "\n")
279
263
  .join("");
280
264
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -292,12 +276,7 @@ class JSONTransform extends Visitor {
292
276
  if (member.flags.get(PropertyFlags.OmitIf).kind == NodeKind.Function) {
293
277
  const arg = member.flags.get(PropertyFlags.OmitIf) as FunctionExpression;
294
278
  // @ts-ignore: type
295
- arg.declaration.signature.parameters[0].type = Node.createNamedType(
296
- Node.createSimpleTypeName("this", node.range),
297
- null,
298
- false,
299
- node.range
300
- );
279
+ arg.declaration.signature.parameters[0].type = Node.createNamedType(Node.createSimpleTypeName("this", node.range), null, false, node.range);
301
280
  // @ts-ignore: type
302
281
  arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
303
282
  SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
@@ -305,7 +284,7 @@ class JSONTransform extends Visitor {
305
284
  SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
306
285
  }
307
286
  indentInc();
308
- SERIALIZE += this.getStores(aliasName + ":")
287
+ SERIALIZE += this.getStores(aliasName + ":", SIMD_ENABLED)
309
288
  .map((v) => indent + v + "\n")
310
289
  .join("");
311
290
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -353,7 +332,7 @@ class JSONTransform extends Visitor {
353
332
  for (let i = 0; i < memberGroup.length; i++) {
354
333
  const member = memberGroup[i];
355
334
  const memberName = member.alias || member.name;
356
- const dst = this.schemas.find(v => v.name == member.type) ? "ptr + offsetof<this>(\"" + member.name + "\") + 12" : "0";
335
+ const dst = this.schemas.find((v) => v.name == member.type) ? 'load<usize>(ptr + offsetof<this>("' + member.name + '"))' : "0";
357
336
  if (memberLen == 2) {
358
337
  DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
359
338
  DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
@@ -478,42 +457,22 @@ class JSONTransform extends Visitor {
478
457
  }
479
458
  addRequiredImports(node: Source): void {
480
459
  const filePath = fileURLToPath(import.meta.url);
481
- const baseDir = path.resolve(filePath, '..', '..', '..');
482
- const nodePath = path.resolve(process.cwd(), node.range.source.normalizedPath);
460
+ const baseDir = path.resolve(filePath, "..", "..", "..");
461
+ const nodePath = path.resolve(this.baseDir, node.range.source.normalizedPath);
483
462
 
484
463
  const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
485
464
  const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
486
465
 
487
- let bsPath = path.posix.join(
488
- ...(path.relative(
489
- path.dirname(nodePath),
490
- path.join(baseDir, "lib", "as-bs")
491
- ).split(path.sep))
492
- ).replace(/^.*node_modules\/json-as/, "json-as");
466
+ let bsPath = path.posix.join(...path.relative(path.dirname(nodePath), path.join(baseDir, "lib", "as-bs")).split(path.sep)).replace(/^.*node_modules\/json-as/, "json-as");
493
467
 
494
- let jsonPath = path.posix.join(
495
- ...(path.relative(
496
- path.dirname(nodePath),
497
- path.join(baseDir, "assembly", "index.ts")
498
- ).split(path.sep))
499
- ).replace(/^.*node_modules\/json-as/, "json-as");
468
+ let jsonPath = path.posix.join(...path.relative(path.dirname(nodePath), path.join(baseDir, "assembly", "index.ts")).split(path.sep)).replace(/^.*node_modules\/json-as/, "json-as");
500
469
 
501
470
  if (!bsImport) {
502
471
  if (node.normalizedPath.startsWith("~")) {
503
472
  bsPath = "json-as/lib/as-bs";
504
473
  }
505
474
 
506
- const replaceNode = Node.createImportStatement(
507
- [
508
- Node.createImportDeclaration(
509
- Node.createIdentifierExpression("bs", node.range, false),
510
- null,
511
- node.range
512
- )
513
- ],
514
- Node.createStringLiteralExpression(bsPath, node.range),
515
- node.range
516
- );
475
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range)], Node.createStringLiteralExpression(bsPath, node.range), node.range);
517
476
  this.topStatements.push(replaceNode);
518
477
  if (process.env["JSON_DEBUG"]) console.log("Added as-bs import: " + toString(replaceNode) + "\n");
519
478
  }
@@ -523,35 +482,28 @@ class JSONTransform extends Visitor {
523
482
  jsonPath = "json-as/assembly/index.ts";
524
483
  }
525
484
  const replaceNode = Node.createImportStatement(
526
- [
527
- Node.createImportDeclaration(
528
- Node.createIdentifierExpression("JSON", node.range, false),
529
- null,
530
- node.range
531
- )
532
- ],
533
- Node.createStringLiteralExpression(jsonPath, node.range), // Ensure POSIX-style path for 'assembly'
534
- node.range
485
+ [Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range)],
486
+ Node.createStringLiteralExpression(jsonPath, node.range), // Ensure POSIX-style path for 'assembly'
487
+ node.range,
535
488
  );
536
489
  this.topStatements.push(replaceNode);
537
490
  if (process.env["JSON_DEBUG"]) console.log("Added json-as import: " + toString(replaceNode) + "\n");
538
491
  }
539
492
  }
540
493
 
541
-
542
494
  getStores(data: string, simd: boolean = false): string[] {
543
495
  const out: string[] = [];
544
496
  const sizes = strToNum(data, simd);
545
497
  let offset = 0;
546
498
  for (const [size, num] of sizes) {
547
- // if (size == "v128") {
548
- // // This could be put in its own file
549
- // let index = this.newStmts.simd.findIndex((v) => v.includes(num));
550
- // let name = "SIMD_" + (index == -1 ? this.newStmts.simd.length : index);
551
- // if (index && !this.newStmts.simd.includes(`const ${name} = ${num};`)) this.newStmts.simd.push(`const ${name} = ${num};`);
552
- // out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
553
- // offset += 16;
554
- // }
499
+ if (size == "v128" && simd) {
500
+ // This could be put in its own file
501
+ let index = this.simdStatements.findIndex((v) => v.includes(num));
502
+ let name = "SIMD_" + (index == -1 ? this.simdStatements.length : index);
503
+ if (index && !this.simdStatements.includes(`const ${name} = ${num};`)) this.simdStatements.push(`const ${name} = ${num};`);
504
+ out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
505
+ offset += 16;
506
+ }
555
507
  if (size == "u64") {
556
508
  out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
557
509
  offset += 8;
@@ -567,37 +519,9 @@ class JSONTransform extends Visitor {
567
519
  return out;
568
520
  }
569
521
  isValidType(type: string, node: ClassDeclaration): boolean {
570
- const validTypes = [
571
- "string",
572
- "u8",
573
- "i8",
574
- "u16",
575
- "i16",
576
- "u32",
577
- "i32",
578
- "u64",
579
- "i64",
580
- "f32",
581
- "f64",
582
- "bool",
583
- "boolean",
584
- "Date",
585
- "JSON.Value",
586
- "JSON.Obj",
587
- "JSON.Raw",
588
- "Value",
589
- "Obj",
590
- "Raw",
591
- ...this.schemas.map((v) => v.name)
592
- ];
593
-
594
- const baseTypes = [
595
- "Array",
596
- "Map",
597
- "Set",
598
- "JSON.Box",
599
- "Box"
600
- ]
522
+ const validTypes = ["string", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Date", "JSON.Value", "JSON.Obj", "JSON.Raw", "Value", "Obj", "Raw", ...this.schemas.map((v) => v.name)];
523
+
524
+ const baseTypes = ["Array", "Map", "Set", "JSON.Box", "Box"];
601
525
 
602
526
  if (node && node.isGeneric && node.typeParameters) validTypes.push(...node.typeParameters.map((v) => v.name.text));
603
527
  if (type.endsWith("| null")) {
@@ -611,39 +535,51 @@ class JSONTransform extends Visitor {
611
535
  }
612
536
 
613
537
  export default class Transformer extends Transform {
614
- // Trigger the transform after parse.
615
538
  afterParse(parser: Parser): void {
616
- // Create new transform
617
539
  const transformer = new JSONTransform();
540
+ const sources = parser.sources
541
+ .filter((source) => {
542
+ const p = source.internalPath;
543
+ if (p.startsWith("~lib/rt") || p.startsWith("~lib/performance") || p.startsWith("~lib/wasi_") || p.startsWith("~lib/shared/")) {
544
+ return false;
545
+ }
546
+ return !isStdlib(source);
547
+ })
548
+ .sort((a, b) => {
549
+ if (a.sourceKind >= 2 && b.sourceKind <= 1) {
550
+ return -1;
551
+ } else if (a.sourceKind <= 1 && b.sourceKind >= 2) {
552
+ return 1;
553
+ } else {
554
+ return 0;
555
+ }
556
+ })
557
+ .sort((a, b) => {
558
+ if (a.sourceKind === SourceKind.UserEntry) {
559
+ return 1;
560
+ } else {
561
+ return 0;
562
+ }
563
+ });
618
564
 
619
- // Sort the sources so that user scripts are visited last
620
- const sources = parser.sources.sort((_a, _b) => {
621
- const a = _a.internalPath;
622
- const b = _b.internalPath;
623
- if (a[0] == "~" && b[0] !== "~") {
624
- return -1;
625
- } else if (a[0] !== "~" && b[0] == "~") {
626
- return 1;
627
- } else {
628
- return 0;
629
- }
630
- });
631
-
565
+ transformer.baseDir = path.join(process.cwd(), this.baseDir);
566
+ transformer.program = this.program;
632
567
  transformer.parser = parser;
633
- // Loop over every source
634
568
  for (const source of sources) {
635
- // console.log("Source: " + source.normalizedPath);
636
569
  transformer.imports = [];
637
570
  transformer.currentSource = source;
638
- // Ignore all lib and std. Visit everything else.
639
571
  transformer.visit(source);
640
572
 
641
573
  if (transformer.topStatements.length) {
642
574
  source.statements.unshift(...transformer.topStatements);
643
575
  transformer.topStatements = [];
644
576
  }
577
+ if (transformer.simdStatements.length) {
578
+ for (const simd of transformer.simdStatements) source.statements.unshift(SimpleParser.parseTopLevelStatement(simd));
579
+ }
580
+ transformer.simdStatements = [];
645
581
  }
646
- // Check that every parent and child class is hooked up correctly
582
+
647
583
  const schemas = transformer.schemas;
648
584
  for (const schema of schemas) {
649
585
  if (schema.parent) {
@@ -734,7 +670,6 @@ function strToNum(data: string, simd: boolean = false, offset: number = 0): stri
734
670
 
735
671
  while (n >= 8 && simd) {
736
672
  out.push(["v128", "i16x8(" + data.charCodeAt(offset + 0) + ", " + data.charCodeAt(offset + 1) + ", " + data.charCodeAt(offset + 2) + ", " + data.charCodeAt(offset + 3) + ", " + data.charCodeAt(offset + 4) + ", " + data.charCodeAt(offset + 5) + ", " + data.charCodeAt(offset + 6) + ", " + data.charCodeAt(offset + 7) + ")"]);
737
-
738
673
  offset += 8;
739
674
  n -= 8;
740
675
  }