gofront 1.5.1 → 1.6.1

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 (91) hide show
  1. package/README.md +174 -466
  2. package/package.json +16 -20
  3. package/src/backend/js/expressions.js +288 -128
  4. package/src/backend/js/index.js +138 -56
  5. package/src/backend/js/runtime.js +1055 -53
  6. package/src/backend/js/source-map.js +32 -0
  7. package/src/backend/js/statements.js +151 -83
  8. package/src/backend/js/stdlib/base64.js +12 -0
  9. package/src/backend/js/stdlib/binary.js +102 -0
  10. package/src/backend/js/stdlib/bits.js +15 -1
  11. package/src/backend/js/stdlib/builder.js +28 -9
  12. package/src/backend/js/stdlib/bytes.js +75 -18
  13. package/src/backend/js/stdlib/errors.js +22 -3
  14. package/src/backend/js/stdlib/fmt.js +95 -20
  15. package/src/backend/js/stdlib/hex.js +17 -0
  16. package/src/backend/js/stdlib/html.js +1 -1
  17. package/src/backend/js/stdlib/index.js +19 -0
  18. package/src/backend/js/stdlib/io.js +105 -3
  19. package/src/backend/js/stdlib/maps.js +1 -1
  20. package/src/backend/js/stdlib/math.js +13 -1
  21. package/src/backend/js/stdlib/path.js +20 -6
  22. package/src/backend/js/stdlib/rand.js +10 -5
  23. package/src/backend/js/stdlib/sha256.js +12 -0
  24. package/src/backend/js/stdlib/shared.js +17 -0
  25. package/src/backend/js/stdlib/slices.js +53 -27
  26. package/src/backend/js/stdlib/sort.js +1 -1
  27. package/src/backend/js/stdlib/strconv.js +52 -11
  28. package/src/backend/js/stdlib/strings.js +152 -16
  29. package/src/backend/js/stdlib/sync.js +13 -0
  30. package/src/backend/js/stdlib/testing.js +2 -2
  31. package/src/backend/js/stdlib/time.js +93 -22
  32. package/src/backend/js/stdlib/unicode.js +2 -2
  33. package/src/backend/js/templ.js +1 -1
  34. package/src/backend/wasm/boundary.js +1677 -58
  35. package/src/backend/wasm/const-fold.js +205 -0
  36. package/src/backend/wasm/emit-builtins.js +1230 -0
  37. package/src/backend/wasm/emit-exprs.js +2096 -0
  38. package/src/backend/wasm/emit-maps.js +1999 -0
  39. package/src/backend/wasm/emit-shared.js +519 -0
  40. package/src/backend/wasm/emit-stdlib.js +13 -0
  41. package/src/backend/wasm/emit-stmts.js +2466 -0
  42. package/src/backend/wasm/emit.js +656 -5031
  43. package/src/backend/wasm/encode.js +259 -85
  44. package/src/backend/wasm/glue.js +19 -5
  45. package/src/backend/wasm/index.js +2432 -86
  46. package/src/backend/wasm/monomorph.js +711 -0
  47. package/src/backend/wasm/optimize.js +236 -0
  48. package/src/backend/wasm/stdlib/bytes.js +5039 -0
  49. package/src/backend/wasm/stdlib/core.js +8903 -0
  50. package/src/backend/wasm/stdlib/index.js +40 -0
  51. package/src/backend/wasm/stdlib/io.js +2161 -0
  52. package/src/backend/wasm/stdlib/packages.js +2400 -0
  53. package/src/backend/wasm/stdlib/pure.js +720 -0
  54. package/src/backend/wasm/stdlib/time.js +1200 -0
  55. package/src/backend/wasm/types.js +312 -36
  56. package/src/backend/wasm/wat.js +49 -2
  57. package/src/cli-core.js +276 -73
  58. package/src/compiler.js +162 -25
  59. package/src/dts-parser.js +79 -126
  60. package/src/index.js +88 -121
  61. package/src/lexer.js +80 -29
  62. package/src/lower/boxing.js +4 -6
  63. package/src/lower/captures.js +12 -23
  64. package/src/lower/escape.js +4 -9
  65. package/src/lower/functions.js +277 -5
  66. package/src/lower/globals.js +7 -15
  67. package/src/lower/index.js +5 -2
  68. package/src/lower/ownership.js +35 -19
  69. package/src/lower/range.js +2 -5
  70. package/src/lower/walk.js +25 -0
  71. package/src/minifier.js +20 -68
  72. package/src/parser/declarations.js +3 -6
  73. package/src/parser/expressions.js +3 -8
  74. package/src/parser/index.js +18 -3
  75. package/src/parser/statements.js +25 -38
  76. package/src/parser/types.js +1 -2
  77. package/src/resolver.js +3 -27
  78. package/src/templ-lexer.js +29 -63
  79. package/src/templ-parser.js +22 -45
  80. package/src/test-runner.js +20 -0
  81. package/src/typechecker/assignability.js +123 -14
  82. package/src/typechecker/expressions.js +244 -4
  83. package/src/typechecker/index.js +27 -1
  84. package/src/typechecker/resolve.js +71 -12
  85. package/src/typechecker/statements.js +0 -7
  86. package/src/typechecker/stdlib/core.js +292 -103
  87. package/src/typechecker/stdlib/extended.js +471 -4
  88. package/src/typechecker/stdlib/shared.js +53 -0
  89. package/src/typechecker/stdlib.js +2 -0
  90. package/src/typechecker/types.js +545 -8
  91. package/src/vendor.js +2 -2
@@ -8,8 +8,13 @@ import {
8
8
  FLOAT32,
9
9
  FLOAT64,
10
10
  INT,
11
+ INT32,
12
+ INT64,
11
13
  STRING,
12
14
  UINT8,
15
+ UINT16,
16
+ UINT32,
17
+ UINT64,
13
18
  VOID,
14
19
  } from "../types.js";
15
20
 
@@ -160,9 +165,24 @@ export function setupExtendedGlobals(globals, types) {
160
165
  kind: "namespace",
161
166
  name: "maps",
162
167
  members: {
163
- Keys: { kind: "func", params: [ANY], returns: [ANY] },
164
- Values: { kind: "func", params: [ANY], returns: [ANY] },
165
- Clone: { kind: "func", params: [ANY], returns: [ANY] },
168
+ Keys: {
169
+ kind: "func",
170
+ params: [ANY],
171
+ returns: [ANY],
172
+ _derivedReturn: "keysOfArg0",
173
+ },
174
+ Values: {
175
+ kind: "func",
176
+ params: [ANY],
177
+ returns: [ANY],
178
+ _derivedReturn: "valuesOfArg0",
179
+ },
180
+ Clone: {
181
+ kind: "func",
182
+ params: [ANY],
183
+ returns: [ANY],
184
+ _derivedReturn: "arg0",
185
+ },
166
186
  Copy: { kind: "func", params: [ANY, ANY], returns: [VOID] },
167
187
  Equal: { kind: "func", params: [ANY, ANY], returns: [BOOL] },
168
188
  EqualFunc: { kind: "func", params: [ANY, ANY, ANY], returns: [BOOL] },
@@ -236,15 +256,27 @@ export function setupExtendedGlobals(globals, types) {
236
256
  ["Write", { kind: "func", params: [BYTE_SLICE_T], returns: [INT, ERROR] }],
237
257
  ["String", { kind: "func", params: [], returns: [STRING] }],
238
258
  ["Len", { kind: "func", params: [], returns: [INT] }],
259
+ ["Cap", { kind: "func", params: [], returns: [INT] }],
239
260
  ["Reset", { kind: "func", params: [], returns: [VOID] }],
240
261
  ["Grow", { kind: "func", params: [INT], returns: [VOID] }],
241
262
  ];
263
+ const STR_SLICE_T = { kind: "slice", elem: STRING };
242
264
  const _makeBuilderType = (name, extra = []) => ({
243
265
  kind: "named",
244
266
  name,
245
267
  underlying: {
246
268
  kind: "struct",
247
- fields: new Map(),
269
+ fields: new Map(
270
+ name === "strings.Builder"
271
+ ? [
272
+ ["_buf", STR_SLICE_T],
273
+ ["_len", INT],
274
+ ["_self", ANY],
275
+ ]
276
+ : name === "bytes.Buffer"
277
+ ? [["_buf", BYTE_SLICE_T]]
278
+ : [],
279
+ ),
248
280
  methods: new Map([..._builderBase, ...extra]),
249
281
  },
250
282
  });
@@ -257,9 +289,107 @@ export function setupExtendedGlobals(globals, types) {
257
289
  types.set(
258
290
  "bytes.Buffer",
259
291
  _makeBuilderType("bytes.Buffer", [
292
+ ["WriteRune", { kind: "func", params: [INT], returns: [INT, ERROR] }],
260
293
  ["Bytes", { kind: "func", params: [], returns: [BYTE_SLICE_T] }],
294
+ ["Read", { kind: "func", params: [BYTE_SLICE_T], returns: [INT, ERROR] }],
261
295
  ]),
262
296
  );
297
+ types.set("strings.Replacer", {
298
+ kind: "named",
299
+ name: "strings.Replacer",
300
+ underlying: {
301
+ kind: "struct",
302
+ fields: new Map([["_pairs", STR_SLICE_T]]),
303
+ methods: new Map([
304
+ ["Replace", { kind: "func", params: [STRING], returns: [STRING] }],
305
+ ]),
306
+ },
307
+ });
308
+ const _makeReaderType = (name, srcType, resetArgType = srcType) => ({
309
+ kind: "named",
310
+ name,
311
+ underlying: {
312
+ kind: "struct",
313
+ fields: new Map([
314
+ ["_src", srcType],
315
+ ["_pos", INT],
316
+ ]),
317
+ methods: new Map([
318
+ [
319
+ "Read",
320
+ { kind: "func", params: [BYTE_SLICE_T], returns: [INT, ERROR] },
321
+ ],
322
+ ["Len", { kind: "func", params: [], returns: [INT] }],
323
+ ["Reset", { kind: "func", params: [resetArgType], returns: [VOID] }],
324
+ ]),
325
+ },
326
+ });
327
+ types.set(
328
+ "strings.Reader",
329
+ _makeReaderType("strings.Reader", BYTE_SLICE_T, STRING),
330
+ );
331
+ types.set("bytes.Reader", _makeReaderType("bytes.Reader", BYTE_SLICE_T));
332
+ types.set("io.discard", {
333
+ kind: "named",
334
+ name: "io.discard",
335
+ underlying: {
336
+ kind: "struct",
337
+ fields: new Map(),
338
+ methods: new Map([
339
+ [
340
+ "Write",
341
+ { kind: "func", params: [BYTE_SLICE_T], returns: [INT, ERROR] },
342
+ ],
343
+ [
344
+ "WriteString",
345
+ { kind: "func", params: [STRING], returns: [INT, ERROR] },
346
+ ],
347
+ ]),
348
+ },
349
+ });
350
+ const ioPkg = globals.lookup("io");
351
+ const IO_READER = ioPkg?.members?.Reader ?? {
352
+ kind: "interface",
353
+ name: "io.Reader",
354
+ };
355
+ types.set("io.LimitedReader", {
356
+ kind: "named",
357
+ name: "io.LimitedReader",
358
+ underlying: {
359
+ kind: "struct",
360
+ fields: new Map([
361
+ ["R", IO_READER],
362
+ ["N", INT64],
363
+ ]),
364
+ methods: new Map([
365
+ [
366
+ "Read",
367
+ { kind: "func", params: [BYTE_SLICE_T], returns: [INT, ERROR] },
368
+ ],
369
+ ]),
370
+ },
371
+ });
372
+ if (ioPkg?.members) {
373
+ ioPkg.members.LimitedReader = types.get("io.LimitedReader");
374
+ }
375
+ const stringsPkg = globals.lookup("strings");
376
+ if (stringsPkg?.members) {
377
+ stringsPkg.members.NewReader = {
378
+ kind: "func",
379
+ params: [STRING],
380
+ returns: [{ kind: "pointer", base: types.get("strings.Reader") }],
381
+ };
382
+ stringsPkg.members.Reader = types.get("strings.Reader");
383
+ }
384
+ const bytesPkg = globals.lookup("bytes");
385
+ if (bytesPkg?.members) {
386
+ bytesPkg.members.NewReader = {
387
+ kind: "func",
388
+ params: [BYTE_SLICE_T],
389
+ returns: [{ kind: "pointer", base: types.get("bytes.Reader") }],
390
+ };
391
+ bytesPkg.members.Reader = types.get("bytes.Reader");
392
+ }
263
393
 
264
394
  globals.define("rand", {
265
395
  kind: "namespace",
@@ -280,6 +410,25 @@ export function setupExtendedGlobals(globals, types) {
280
410
  params: [INT],
281
411
  returns: [{ kind: "slice", elem: INT }],
282
412
  },
413
+ Read: {
414
+ kind: "func",
415
+ params: [{ kind: "slice", elem: UINT8 }],
416
+ returns: [INT, ERROR],
417
+ },
418
+ Reader: {
419
+ kind: "interface",
420
+ name: "io.Reader",
421
+ methods: new Map([
422
+ [
423
+ "Read",
424
+ {
425
+ kind: "func",
426
+ params: [{ kind: "slice", elem: UINT8 }],
427
+ returns: [INT, ERROR],
428
+ },
429
+ ],
430
+ ]),
431
+ },
283
432
  },
284
433
  });
285
434
 
@@ -325,9 +474,16 @@ export function setupExtendedGlobals(globals, types) {
325
474
  IsAbs: { kind: "func", params: [STRING], returns: [BOOL] },
326
475
  Split: { kind: "func", params: [STRING], returns: [STRING, STRING] },
327
476
  Match: { kind: "func", params: [STRING, STRING], returns: [BOOL, ERROR] },
477
+ ErrBadPattern: ERROR,
328
478
  },
329
479
  });
330
480
 
481
+ globals.define("filepath", {
482
+ kind: "namespace",
483
+ name: "filepath",
484
+ members: globals.lookup("path").members,
485
+ });
486
+
331
487
  const TESTING_T = {
332
488
  kind: "named",
333
489
  name: "testing.T",
@@ -386,6 +542,317 @@ export function setupExtendedGlobals(globals, types) {
386
542
  });
387
543
  types.set("testing.T", TESTING_T);
388
544
 
545
+ // ── sync ──────────────────────────────────────────────────────
546
+ const MUTEX_T = {
547
+ kind: "named",
548
+ name: "sync.Mutex",
549
+ underlying: { kind: "struct", fields: new Map([["state", INT32]]) },
550
+ methods: new Map([
551
+ ["Lock", { kind: "func", params: [], returns: [VOID] }],
552
+ ["Unlock", { kind: "func", params: [], returns: [VOID] }],
553
+ ["TryLock", { kind: "func", params: [], returns: [BOOL] }],
554
+ ]),
555
+ };
556
+ const RWMUTEX_T = {
557
+ kind: "named",
558
+ name: "sync.RWMutex",
559
+ underlying: { kind: "struct", fields: new Map([["state", INT32]]) },
560
+ methods: new Map([
561
+ ["Lock", { kind: "func", params: [], returns: [VOID] }],
562
+ ["Unlock", { kind: "func", params: [], returns: [VOID] }],
563
+ ["RLock", { kind: "func", params: [], returns: [VOID] }],
564
+ ["RUnlock", { kind: "func", params: [], returns: [VOID] }],
565
+ ["TryLock", { kind: "func", params: [], returns: [BOOL] }],
566
+ ["TryRLock", { kind: "func", params: [], returns: [BOOL] }],
567
+ ]),
568
+ };
569
+ const ONCE_T = {
570
+ kind: "named",
571
+ name: "sync.Once",
572
+ underlying: { kind: "struct", fields: new Map([["done", UINT32]]) },
573
+ methods: new Map([
574
+ [
575
+ "Do",
576
+ {
577
+ kind: "func",
578
+ params: [{ kind: "func", params: [], returns: [VOID] }],
579
+ returns: [VOID],
580
+ },
581
+ ],
582
+ ]),
583
+ };
584
+ const WAITGROUP_T = {
585
+ kind: "named",
586
+ name: "sync.WaitGroup",
587
+ underlying: { kind: "struct", fields: new Map([["counter", INT]]) },
588
+ methods: new Map([
589
+ ["Add", { kind: "func", params: [INT], returns: [VOID] }],
590
+ ["Done", { kind: "func", params: [], returns: [VOID] }],
591
+ ["Wait", { kind: "func", params: [], returns: [VOID] }],
592
+ ]),
593
+ };
594
+ const LOCKER_T = {
595
+ kind: "interface",
596
+ name: "sync.Locker",
597
+ methods: new Map([
598
+ ["Lock", { kind: "func", params: [], returns: [VOID] }],
599
+ ["Unlock", { kind: "func", params: [], returns: [VOID] }],
600
+ ]),
601
+ };
602
+ globals.define("sync", {
603
+ kind: "namespace",
604
+ name: "sync",
605
+ members: {
606
+ Mutex: MUTEX_T,
607
+ RWMutex: RWMUTEX_T,
608
+ Once: ONCE_T,
609
+ WaitGroup: WAITGROUP_T,
610
+ Locker: LOCKER_T,
611
+ },
612
+ });
613
+ types.set("sync.Mutex", MUTEX_T);
614
+ types.set("sync.RWMutex", RWMUTEX_T);
615
+ types.set("sync.Once", ONCE_T);
616
+ types.set("sync.WaitGroup", WAITGROUP_T);
617
+ types.set("sync.Locker", LOCKER_T);
618
+
619
+ // ── crypto/sha256 ─────────────────────────────────────────────
620
+ const BYTE_SLICE = { kind: "slice", elem: UINT8 };
621
+ const HASH_T = {
622
+ kind: "interface",
623
+ methods: new Map([
624
+ ["Write", { kind: "func", params: [BYTE_SLICE], returns: [INT, ERROR] }],
625
+ ["Sum", { kind: "func", params: [BYTE_SLICE], returns: [BYTE_SLICE] }],
626
+ ["Reset", { kind: "func", params: [], returns: [VOID] }],
627
+ ["Size", { kind: "func", params: [], returns: [INT] }],
628
+ ["BlockSize", { kind: "func", params: [], returns: [INT] }],
629
+ ]),
630
+ };
631
+ const SHA256_DIGEST_T = {
632
+ kind: "named",
633
+ name: "sha256.digest",
634
+ underlying: { kind: "struct", fields: new Map([["buf", BYTE_SLICE]]) },
635
+ methods: new Map([
636
+ ["Write", { kind: "func", params: [BYTE_SLICE], returns: [INT, ERROR] }],
637
+ ["Sum", { kind: "func", params: [BYTE_SLICE], returns: [BYTE_SLICE] }],
638
+ ["Reset", { kind: "func", params: [], returns: [VOID] }],
639
+ ["Size", { kind: "func", params: [], returns: [INT] }],
640
+ ["BlockSize", { kind: "func", params: [], returns: [INT] }],
641
+ ]),
642
+ };
643
+ globals.define("sha256", {
644
+ kind: "namespace",
645
+ name: "sha256",
646
+ members: {
647
+ Size: INT,
648
+ BlockSize: INT,
649
+ Sum256: {
650
+ kind: "func",
651
+ params: [BYTE_SLICE],
652
+ returns: [{ kind: "array", size: 32, elem: UINT8 }],
653
+ },
654
+ New: { kind: "func", params: [], returns: [HASH_T] },
655
+ },
656
+ });
657
+ types.set("hash.Hash", HASH_T);
658
+ types.set("sha256.digest", SHA256_DIGEST_T);
659
+ types.set("crypto/sha256.digest", SHA256_DIGEST_T);
660
+
661
+ // ── encoding/binary ───────────────────────────────────────────
662
+ const BYTE_ORDER_METHODS = [
663
+ ["Uint16", { kind: "func", params: [BYTE_SLICE], returns: [UINT16] }],
664
+ ["Uint32", { kind: "func", params: [BYTE_SLICE], returns: [UINT32] }],
665
+ ["Uint64", { kind: "func", params: [BYTE_SLICE], returns: [UINT64] }],
666
+ [
667
+ "PutUint16",
668
+ { kind: "func", params: [BYTE_SLICE, UINT16], returns: [VOID] },
669
+ ],
670
+ [
671
+ "PutUint32",
672
+ { kind: "func", params: [BYTE_SLICE, UINT32], returns: [VOID] },
673
+ ],
674
+ [
675
+ "PutUint64",
676
+ { kind: "func", params: [BYTE_SLICE, UINT64], returns: [VOID] },
677
+ ],
678
+ ["String", { kind: "func", params: [], returns: [STRING] }],
679
+ ];
680
+ const BYTE_ORDER_T = {
681
+ kind: "interface",
682
+ methods: new Map(BYTE_ORDER_METHODS),
683
+ };
684
+ const LITTLE_ENDIAN_METHODS = new Map([
685
+ ...BYTE_ORDER_METHODS,
686
+ [
687
+ "AppendUint16",
688
+ { kind: "func", params: [BYTE_SLICE, UINT16], returns: [BYTE_SLICE] },
689
+ ],
690
+ [
691
+ "AppendUint32",
692
+ { kind: "func", params: [BYTE_SLICE, UINT32], returns: [BYTE_SLICE] },
693
+ ],
694
+ [
695
+ "AppendUint64",
696
+ { kind: "func", params: [BYTE_SLICE, UINT64], returns: [BYTE_SLICE] },
697
+ ],
698
+ ]);
699
+ const LITTLE_ENDIAN_T = {
700
+ kind: "named",
701
+ name: "binary.LittleEndian",
702
+ underlying: {
703
+ kind: "struct",
704
+ fields: new Map([["order", INT32]]),
705
+ methods: LITTLE_ENDIAN_METHODS,
706
+ },
707
+ methods: LITTLE_ENDIAN_METHODS,
708
+ };
709
+ const BIG_ENDIAN_METHODS = new Map([
710
+ ...BYTE_ORDER_METHODS,
711
+ [
712
+ "AppendUint16",
713
+ { kind: "func", params: [BYTE_SLICE, UINT16], returns: [BYTE_SLICE] },
714
+ ],
715
+ [
716
+ "AppendUint32",
717
+ { kind: "func", params: [BYTE_SLICE, UINT32], returns: [BYTE_SLICE] },
718
+ ],
719
+ [
720
+ "AppendUint64",
721
+ { kind: "func", params: [BYTE_SLICE, UINT64], returns: [BYTE_SLICE] },
722
+ ],
723
+ ]);
724
+ const BIG_ENDIAN_T = {
725
+ kind: "named",
726
+ name: "binary.BigEndian",
727
+ underlying: {
728
+ kind: "struct",
729
+ fields: new Map([["order", INT32]]),
730
+ methods: BIG_ENDIAN_METHODS,
731
+ },
732
+ methods: BIG_ENDIAN_METHODS,
733
+ };
734
+ globals.define("binary", {
735
+ kind: "namespace",
736
+ name: "binary",
737
+ members: {
738
+ ByteOrder: BYTE_ORDER_T,
739
+ LittleEndian: LITTLE_ENDIAN_T,
740
+ BigEndian: BIG_ENDIAN_T,
741
+ Read: {
742
+ kind: "func",
743
+ params: [ANY, BYTE_ORDER_T, ANY],
744
+ returns: [ERROR],
745
+ },
746
+ Write: {
747
+ kind: "func",
748
+ params: [ANY, BYTE_ORDER_T, ANY],
749
+ returns: [ERROR],
750
+ },
751
+ Size: { kind: "func", params: [ANY], returns: [INT] },
752
+ AppendUint16: {
753
+ kind: "func",
754
+ params: [BYTE_SLICE, UINT16],
755
+ returns: [BYTE_SLICE],
756
+ },
757
+ AppendUint32: {
758
+ kind: "func",
759
+ params: [BYTE_SLICE, UINT32],
760
+ returns: [BYTE_SLICE],
761
+ },
762
+ AppendUint64: {
763
+ kind: "func",
764
+ params: [BYTE_SLICE, UINT64],
765
+ returns: [BYTE_SLICE],
766
+ },
767
+ },
768
+ });
769
+ types.set("encoding/binary.ByteOrder", BYTE_ORDER_T);
770
+ types.set("binary.ByteOrder", BYTE_ORDER_T);
771
+ types.set("encoding/binary.LittleEndian", LITTLE_ENDIAN_T);
772
+ types.set("binary.LittleEndian", LITTLE_ENDIAN_T);
773
+ types.set("encoding/binary.BigEndian", BIG_ENDIAN_T);
774
+ types.set("binary.BigEndian", BIG_ENDIAN_T);
775
+
776
+ // ── encoding/hex ──────────────────────────────────────────────
777
+ globals.define("hex", {
778
+ kind: "namespace",
779
+ name: "hex",
780
+ members: {
781
+ EncodeToString: { kind: "func", params: [BYTE_SLICE], returns: [STRING] },
782
+ DecodeString: {
783
+ kind: "func",
784
+ params: [STRING],
785
+ returns: [BYTE_SLICE, ERROR],
786
+ },
787
+ Encode: {
788
+ kind: "func",
789
+ params: [BYTE_SLICE, BYTE_SLICE],
790
+ returns: [INT],
791
+ },
792
+ Decode: {
793
+ kind: "func",
794
+ params: [BYTE_SLICE, BYTE_SLICE],
795
+ returns: [INT, ERROR],
796
+ },
797
+ EncodedLen: { kind: "func", params: [INT], returns: [INT] },
798
+ DecodedLen: { kind: "func", params: [INT], returns: [INT] },
799
+ ErrLength: ERROR,
800
+ },
801
+ });
802
+
803
+ // ── encoding/base64 ───────────────────────────────────────────
804
+ const BASE64_ENCODING_METHODS = new Map([
805
+ [
806
+ "EncodeToString",
807
+ { kind: "func", params: [BYTE_SLICE], returns: [STRING] },
808
+ ],
809
+ [
810
+ "DecodeString",
811
+ { kind: "func", params: [STRING], returns: [BYTE_SLICE, ERROR] },
812
+ ],
813
+ [
814
+ "Encode",
815
+ { kind: "func", params: [BYTE_SLICE, BYTE_SLICE], returns: [VOID] },
816
+ ],
817
+ [
818
+ "Decode",
819
+ { kind: "func", params: [BYTE_SLICE, BYTE_SLICE], returns: [INT, ERROR] },
820
+ ],
821
+ ["EncodedLen", { kind: "func", params: [INT], returns: [INT] }],
822
+ ["DecodedLen", { kind: "func", params: [INT], returns: [INT] }],
823
+ ["WithPadding", { kind: "func", params: [INT], returns: [ANY] }],
824
+ ]);
825
+ const BASE64_ENCODING_T = {
826
+ kind: "named",
827
+ name: "base64.Encoding",
828
+ underlying: {
829
+ kind: "struct",
830
+ fields: new Map([["mode", INT32]]),
831
+ methods: BASE64_ENCODING_METHODS,
832
+ },
833
+ methods: BASE64_ENCODING_METHODS,
834
+ };
835
+ globals.define("base64", {
836
+ kind: "namespace",
837
+ name: "base64",
838
+ members: {
839
+ Encoding: BASE64_ENCODING_T,
840
+ StdEncoding: BASE64_ENCODING_T,
841
+ URLEncoding: BASE64_ENCODING_T,
842
+ RawStdEncoding: BASE64_ENCODING_T,
843
+ RawURLEncoding: BASE64_ENCODING_T,
844
+ NewEncoding: {
845
+ kind: "func",
846
+ params: [STRING],
847
+ returns: [BASE64_ENCODING_T],
848
+ },
849
+ StdPadding: INT,
850
+ NoPadding: INT,
851
+ },
852
+ });
853
+ types.set("encoding/base64.Encoding", BASE64_ENCODING_T);
854
+ types.set("base64.Encoding", BASE64_ENCODING_T);
855
+
389
856
  for (const name of [
390
857
  "append",
391
858
  "len",
@@ -0,0 +1,53 @@
1
+ // `gofront/shared` — fixed-size linear-memory buffers shared zero-copy between
2
+ // wasm packages and JS. Each `shared.Xxx` is a named type whose underlying kind
3
+ // is "shared" (not a slice): it supports indexing, len() and `.Subarray(lo, hi)`
4
+ // but not slicing, append or implicit conversion to GC slices.
5
+
6
+ import {
7
+ FLOAT32,
8
+ FLOAT64,
9
+ INT,
10
+ INT8,
11
+ INT16,
12
+ INT32,
13
+ UINT8,
14
+ UINT16,
15
+ UINT32,
16
+ } from "../types.js";
17
+
18
+ // key → [elem type, JS TypedArray ctor, byte size]
19
+ export const SHARED_KINDS = {
20
+ Float32: { elem: FLOAT32, ctor: "Float32Array", bytes: 4, key: "f32" },
21
+ Float64: { elem: FLOAT64, ctor: "Float64Array", bytes: 8, key: "f64" },
22
+ Int8: { elem: INT8, ctor: "Int8Array", bytes: 1, key: "i8" },
23
+ Int16: { elem: INT16, ctor: "Int16Array", bytes: 2, key: "i16" },
24
+ Int32: { elem: INT32, ctor: "Int32Array", bytes: 4, key: "i32" },
25
+ Uint8: { elem: UINT8, ctor: "Uint8Array", bytes: 1, key: "u8" },
26
+ Uint16: { elem: UINT16, ctor: "Uint16Array", bytes: 2, key: "u16" },
27
+ Uint32: { elem: UINT32, ctor: "Uint32Array", bytes: 4, key: "u32" },
28
+ };
29
+
30
+ export function setupSharedGlobals(globals, types) {
31
+ const members = {};
32
+ for (const [name, info] of Object.entries(SHARED_KINDS)) {
33
+ const t = {
34
+ kind: "named",
35
+ name: `shared.${name}`,
36
+ underlying: { kind: "shared", elem: info.elem, shared: name },
37
+ };
38
+ t.underlying.methods = new Map([
39
+ ["Subarray", { kind: "func", params: [INT, INT], returns: [t] }],
40
+ ]);
41
+ types.set(t.name, t);
42
+ members[name] = t;
43
+ members[`New${name}`] = { kind: "func", params: [INT], returns: [t] };
44
+ }
45
+ globals.define("shared", { kind: "namespace", name: "shared", members });
46
+ }
47
+
48
+ // Returns the SHARED_KINDS entry for a (possibly named) shared type, or null.
49
+ export function sharedInfo(t) {
50
+ const u = t?.kind === "named" ? t.underlying : t;
51
+ if (u?.kind !== "shared") return null;
52
+ return { name: u.shared, ...SHARED_KINDS[u.shared] };
53
+ }
@@ -9,10 +9,12 @@
9
9
 
10
10
  import { setupCoreGlobals } from "./stdlib/core.js";
11
11
  import { setupExtendedGlobals } from "./stdlib/extended.js";
12
+ import { setupSharedGlobals } from "./stdlib/shared.js";
12
13
  import { setupWebGlobals } from "./stdlib/web.js";
13
14
 
14
15
  export function setupGlobals(globals, types) {
15
16
  setupCoreGlobals(globals, types);
16
17
  setupExtendedGlobals(globals, types);
18
+ setupSharedGlobals(globals, types);
17
19
  setupWebGlobals(globals, types);
18
20
  }