gofront 1.8.0 → 1.9.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.
- package/README.md +3 -3
- package/package.json +6 -5
- package/src/backend/js/expressions.js +1157 -408
- package/src/backend/js/index.js +327 -153
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +559 -2552
- package/src/backend/js/statements.js +670 -158
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +298 -19
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +91 -170
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +884 -256
- package/src/backend/wasm/emit-exprs.js +185 -77
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-shared.js +4 -1
- package/src/backend/wasm/emit-stmts.js +524 -240
- package/src/backend/wasm/emit.js +176 -38
- package/src/backend/wasm/globals.js +48 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +44 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +299 -770
- package/src/backend/wasm/monomorph.js +139 -8
- package/src/backend/wasm/natives.js +600 -0
- package/src/backend/wasm/prescan.js +5 -153
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -32
- package/src/backend/wasm/types.js +97 -20
- package/src/backend/wasm/variadic.js +9 -4
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +113 -130
- package/src/lexer/lexer.js +106 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +355 -132
- package/src/link/type-names.js +204 -0
- package/src/link/wasm.js +30 -6
- package/src/lower/bounds.js +153 -0
- package/src/lower/captures.js +92 -33
- package/src/lower/embedding.js +62 -5
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +929 -0
- package/src/lower/functions.js +225 -7
- package/src/lower/gen-types.js +293 -0
- package/src/lower/index.js +14 -2
- package/src/lower/json-codecs.js +334 -245
- package/src/lower/ownership.js +25 -7
- package/src/lower/reachability.js +69 -51
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +30 -5
- package/src/parser/expressions.js +111 -57
- package/src/parser/statements.js +108 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +12 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +214 -19
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +156 -8
- package/src/typechecker/expressions.js +490 -108
- package/src/typechecker/index.js +346 -42
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +41 -0
- package/src/typechecker/resolve.js +490 -65
- package/src/typechecker/statements.js +288 -27
- package/src/typechecker/stdlib/excluded.js +9 -5
- package/src/typechecker/stdlib/index.js +25 -9
- package/src/typechecker/termination.js +10 -1
- package/src/typechecker/types.js +287 -575
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +171 -38
- package/stdlib/internal/jsonrt/enc.go +186 -36
- package/stdlib/internal/jsonrt/scanner.go +17 -8
- package/stdlib/io/io.go +157 -1
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +16 -14
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +391 -452
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +235 -50
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +141 -3
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/fmt-runtime.js +0 -573
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -119
- package/src/backend/js/stdlib/builder.js +0 -98
- package/src/backend/js/stdlib/bytes.js +0 -368
- package/src/backend/js/stdlib/errors.js +0 -45
- package/src/backend/js/stdlib/fmt.js +0 -517
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -1167
- package/src/backend/js/stdlib/maps.js +0 -37
- package/src/backend/js/stdlib/math.js +0 -85
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -34
- package/src/backend/js/stdlib/slices.js +0 -107
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -79
- package/src/backend/js/stdlib/strings.js +0 -301
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -41
- package/src/backend/js/stdlib/time.js +0 -152
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/stdlib/bytes.js +0 -6716
- package/src/backend/wasm/stdlib/core.js +0 -10278
- package/src/backend/wasm/stdlib/io.js +0 -3578
- package/src/backend/wasm/stdlib/packages.js +0 -2402
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -2229
- package/src/typechecker/stdlib/core.js +0 -1079
- package/src/typechecker/stdlib/extended.js +0 -1210
- package/stdlib/bytes/iter.go +0 -192
- package/stdlib/bytes/search.go +0 -240
- package/stdlib/bytes/split.go +0 -218
- package/stdlib/errors/overlay.go +0 -12
- package/stdlib/maps/iter.go +0 -65
- package/stdlib/slices/extra.go +0 -73
- package/stdlib/slices/iter.go +0 -113
- package/stdlib/strings/extra.go +0 -35
- package/stdlib/strings/iter.go +0 -122
- package/stdlib/sync/extra.go +0 -105
- package/stdlib/unicode/utf8/bytes.go +0 -239
|
@@ -23,18 +23,17 @@ import {
|
|
|
23
23
|
import { desugarMethodExprs } from "./method-expr.js";
|
|
24
24
|
import { ModuleEmitter } from "./module-emitter.js";
|
|
25
25
|
import { hasGenerics, monomorphise } from "./monomorph.js";
|
|
26
|
+
import { emitWasmIntrinsic, prepareWasmIntrinsic } from "./natives.js";
|
|
26
27
|
import { hasNativeWasmOpt, optimizeWasm } from "./optimize.js";
|
|
27
28
|
import {
|
|
28
29
|
_scanFuncSigInterfaces,
|
|
29
30
|
_scanImportsInBody,
|
|
30
31
|
_scanInterfaceCallNodes,
|
|
31
32
|
_scanInterfaceTypeDecls,
|
|
33
|
+
_someNode,
|
|
32
34
|
_usesAnyEq,
|
|
33
|
-
_usesFmtAny,
|
|
34
|
-
_usesTestingCleanup,
|
|
35
|
-
_usesTestingRun,
|
|
36
|
-
importsAnyOf,
|
|
37
35
|
} from "./prescan.js";
|
|
36
|
+
import { pruneUnusedFuncs } from "./prune-funcs.js";
|
|
38
37
|
import {
|
|
39
38
|
ERROR_STRUCT,
|
|
40
39
|
getMapKeyValTypes,
|
|
@@ -84,8 +83,7 @@ function emitIndexPanicBody(mod, emitter) {
|
|
|
84
83
|
concat();
|
|
85
84
|
emitter.pushInstruction("end");
|
|
86
85
|
concat();
|
|
87
|
-
emitter.
|
|
88
|
-
emitter.emitPanicThrow();
|
|
86
|
+
emitter.emitRuntimePanicThrow();
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
function peepholeOptimize(instructions) {
|
|
@@ -176,6 +174,7 @@ export function compileWasmModule(
|
|
|
176
174
|
|
|
177
175
|
const mod = new ModuleEmitter(resolvedChecker, resolvedLowerResult, progs, {
|
|
178
176
|
bundledPackages: options.bundledPackages,
|
|
177
|
+
natives: options.natives,
|
|
179
178
|
});
|
|
180
179
|
|
|
181
180
|
// 1. Collect all functions, methods, and package-level globals
|
|
@@ -260,6 +259,7 @@ export function compileWasmModule(
|
|
|
260
259
|
_isClosure: true,
|
|
261
260
|
_isYieldClosure: Boolean(node._isYieldClosure),
|
|
262
261
|
_iterStateName: node._iterStateName ?? null,
|
|
262
|
+
_forStmt: node._forStmt ?? null,
|
|
263
263
|
_funcLit: node,
|
|
264
264
|
_rootFuncDecl: rootFn,
|
|
265
265
|
_srcFile: rootFn?._srcFile ?? null,
|
|
@@ -591,18 +591,6 @@ export function compileWasmModule(
|
|
|
591
591
|
_mapInfo: mapInfo,
|
|
592
592
|
_rootFuncDecl: null,
|
|
593
593
|
});
|
|
594
|
-
// clone
|
|
595
|
-
funcDecls.push({
|
|
596
|
-
kind: "FuncDecl",
|
|
597
|
-
name: mapInfo.cloneFuncName,
|
|
598
|
-
params: [{ name: "m", type: mapInfo.wType }],
|
|
599
|
-
returnType: mapInfo.wType,
|
|
600
|
-
body: { kind: "Block", stmts: [], list: [] },
|
|
601
|
-
_isMapHelper: true,
|
|
602
|
-
_mapHelperKind: "clone",
|
|
603
|
-
_mapInfo: mapInfo,
|
|
604
|
-
_rootFuncDecl: null,
|
|
605
|
-
});
|
|
606
594
|
}
|
|
607
595
|
|
|
608
596
|
// 1e2. `gofront/shared` linear-memory helpers (only when imported).
|
|
@@ -650,9 +638,7 @@ export function compileWasmModule(
|
|
|
650
638
|
});
|
|
651
639
|
}
|
|
652
640
|
|
|
653
|
-
// 1e3. Runtime helpers: error values
|
|
654
|
-
mod.usesTestingRun = funcDecls.some((fn) => _usesTestingRun(fn.body));
|
|
655
|
-
mod.usesTestingCleanup = funcDecls.some((fn) => _usesTestingCleanup(fn.body));
|
|
641
|
+
// 1e3. Runtime helpers: error values and interface equality.
|
|
656
642
|
mod.usesAnyEq = _usesAnyEq(funcDecls, mod);
|
|
657
643
|
const ANY_T = { kind: "basic", name: "any" };
|
|
658
644
|
const STR_T = { kind: "basic", name: "string" };
|
|
@@ -680,6 +666,25 @@ export function compileWasmModule(
|
|
|
680
666
|
),
|
|
681
667
|
);
|
|
682
668
|
}
|
|
669
|
+
// `x.(T)` outside comma-ok form panics with the dynamic type's name.
|
|
670
|
+
mod.usesTypeAssertFail = funcDecls.some((fn) =>
|
|
671
|
+
_someNode(fn.body, (n) => n.kind === "TypeAssertExpr" && !n._commaOk),
|
|
672
|
+
);
|
|
673
|
+
if (mod.usesTypeAssertFail) {
|
|
674
|
+
funcDecls.push(
|
|
675
|
+
helper(
|
|
676
|
+
"__ta_fail",
|
|
677
|
+
[
|
|
678
|
+
{ name: "v", type: ANY_T },
|
|
679
|
+
{ name: "src", type: STR_T },
|
|
680
|
+
{ name: "target", type: STR_T },
|
|
681
|
+
{ name: "iface", type: BOOL_T },
|
|
682
|
+
],
|
|
683
|
+
null,
|
|
684
|
+
"ta_fail",
|
|
685
|
+
),
|
|
686
|
+
);
|
|
687
|
+
}
|
|
683
688
|
mod.usesAnyHash = false;
|
|
684
689
|
for (const info of mod.mapTypes.values()) {
|
|
685
690
|
if (isInterfaceType(info.keyGoType, checker)) {
|
|
@@ -697,6 +702,13 @@ export function compileWasmModule(
|
|
|
697
702
|
),
|
|
698
703
|
);
|
|
699
704
|
}
|
|
705
|
+
// fmt's %p identity of a reference in an `any`: a defined map or func type
|
|
706
|
+
// is boxed there, so the helper hands the host the boxed reference.
|
|
707
|
+
if (funcDecls.some((fn) => fn.intrinsic === "fmt_ptr_id")) {
|
|
708
|
+
funcDecls.push(
|
|
709
|
+
helper("__any_ref", [{ name: "a", type: ANY_T }], ANY_T, "any_ref"),
|
|
710
|
+
);
|
|
711
|
+
}
|
|
700
712
|
if (mod.hasErrorType) {
|
|
701
713
|
const errPtr = {
|
|
702
714
|
kind: "pointer",
|
|
@@ -714,88 +726,8 @@ export function compileWasmModule(
|
|
|
714
726
|
_methodName: "Error",
|
|
715
727
|
},
|
|
716
728
|
),
|
|
717
|
-
helper(
|
|
718
|
-
`${ERROR_STRUCT}.Unwrap`,
|
|
719
|
-
[{ name: "e", type: errPtr }],
|
|
720
|
-
ANY_T,
|
|
721
|
-
"error_cause",
|
|
722
|
-
{
|
|
723
|
-
_isMethod: true,
|
|
724
|
-
_recvTypeName: ERROR_STRUCT,
|
|
725
|
-
_methodName: "Unwrap",
|
|
726
|
-
},
|
|
727
|
-
),
|
|
728
|
-
helper(
|
|
729
|
-
"__mk_error",
|
|
730
|
-
[
|
|
731
|
-
{ name: "msg", type: STR_T },
|
|
732
|
-
{ name: "cause", type: ANY_T },
|
|
733
|
-
],
|
|
734
|
-
ANY_T,
|
|
735
|
-
"mk_error",
|
|
736
|
-
),
|
|
729
|
+
helper("__mk_error", [{ name: "msg", type: STR_T }], ANY_T, "mk_error"),
|
|
737
730
|
helper("__error_str", [{ name: "e", type: ANY_T }], STR_T, "error_str"),
|
|
738
|
-
{
|
|
739
|
-
kind: "FuncDecl",
|
|
740
|
-
name: "__errors_unwrap",
|
|
741
|
-
params: [{ name: "__recv", type: ANY_T }],
|
|
742
|
-
returnType: ANY_T,
|
|
743
|
-
body: { kind: "Block", stmts: [], list: [] },
|
|
744
|
-
_isInterfaceDispatcher: true,
|
|
745
|
-
_softDispatch: true,
|
|
746
|
-
_ifaceName: "error",
|
|
747
|
-
_ifaceType: null,
|
|
748
|
-
_methodName: "Unwrap",
|
|
749
|
-
_rootFuncDecl: null,
|
|
750
|
-
},
|
|
751
|
-
helper(
|
|
752
|
-
"__errors_is",
|
|
753
|
-
[
|
|
754
|
-
{ name: "err", type: ANY_T },
|
|
755
|
-
{ name: "target", type: ANY_T },
|
|
756
|
-
],
|
|
757
|
-
BOOL_T,
|
|
758
|
-
"errors_is",
|
|
759
|
-
),
|
|
760
|
-
);
|
|
761
|
-
}
|
|
762
|
-
if (mod.usesTestingRun) {
|
|
763
|
-
funcDecls.push(
|
|
764
|
-
helper(
|
|
765
|
-
"__testing_run_cb",
|
|
766
|
-
[
|
|
767
|
-
{ name: "fn", type: ANY_T },
|
|
768
|
-
{
|
|
769
|
-
name: "t",
|
|
770
|
-
type: {
|
|
771
|
-
kind: "pointer",
|
|
772
|
-
base: { kind: "named", name: "testing.T" },
|
|
773
|
-
},
|
|
774
|
-
},
|
|
775
|
-
],
|
|
776
|
-
null,
|
|
777
|
-
"testing_run_cb",
|
|
778
|
-
{ _forceExport: true },
|
|
779
|
-
),
|
|
780
|
-
);
|
|
781
|
-
}
|
|
782
|
-
if (mod.usesTestingCleanup) {
|
|
783
|
-
funcDecls.push(
|
|
784
|
-
helper(
|
|
785
|
-
"__testing_cleanup_cb",
|
|
786
|
-
[{ name: "fn", type: ANY_T }],
|
|
787
|
-
null,
|
|
788
|
-
"testing_cleanup_cb",
|
|
789
|
-
{ _forceExport: true },
|
|
790
|
-
),
|
|
791
|
-
);
|
|
792
|
-
}
|
|
793
|
-
_registerIoSyntheticMethods(funcDecls, mod, STR_T, progs);
|
|
794
|
-
// `__any_fmt` turns an `any` operand of fmt into the host value; its body
|
|
795
|
-
// is emitted last-but-one so every type registered by user code is seen.
|
|
796
|
-
if (_usesFmtAny(funcDecls, mod)) {
|
|
797
|
-
funcDecls.push(
|
|
798
|
-
helper("__any_fmt", [{ name: "a", type: ANY_T }], STR_T, "any_fmt"),
|
|
799
731
|
);
|
|
800
732
|
}
|
|
801
733
|
|
|
@@ -806,6 +738,7 @@ export function compileWasmModule(
|
|
|
806
738
|
|
|
807
739
|
// 2. Pre-scan for needed imports so import func indices are fixed
|
|
808
740
|
for (const fn of funcDecls) {
|
|
741
|
+
if (fn.intrinsic) prepareWasmIntrinsic(mod, fn);
|
|
809
742
|
_scanImportsInBody(fn.body, mod);
|
|
810
743
|
}
|
|
811
744
|
if (boundaryMeta) scanBoundaryImports(mod, boundaryMeta);
|
|
@@ -859,8 +792,11 @@ export function compileWasmModule(
|
|
|
859
792
|
fn._forceExport ||
|
|
860
793
|
(!fn._isGlobalInit &&
|
|
861
794
|
!fn._isRuntimeHelper &&
|
|
862
|
-
!fn.
|
|
863
|
-
!fn.
|
|
795
|
+
!fn._isMapHelper &&
|
|
796
|
+
!fn._isInterfaceDispatcher &&
|
|
797
|
+
!fn._isSharedHelper &&
|
|
798
|
+
!fn._isRuntimePanic &&
|
|
799
|
+
!fn._isIndexPanic &&
|
|
864
800
|
(options.exportAll ||
|
|
865
801
|
fn.name === "main" ||
|
|
866
802
|
(fn.name[0] >= "A" && fn.name[0] <= "Z") ||
|
|
@@ -899,8 +835,7 @@ export function compileWasmModule(
|
|
|
899
835
|
const funcIdx = mod.getStringImportIndex();
|
|
900
836
|
emitter.pushInstruction({ op: "i32.const", value: strIdx });
|
|
901
837
|
emitter.pushInstruction({ op: "call", funcIndex: funcIdx });
|
|
902
|
-
emitter.
|
|
903
|
-
emitter.emitPanicThrow();
|
|
838
|
+
emitter.emitRuntimePanicThrow();
|
|
904
839
|
} else if (fn._isPushPanic) {
|
|
905
840
|
const panicNodeTypeIndex = mod.getPanicNodeTypeIndex();
|
|
906
841
|
const panicGlobal = mod.getPanicGlobalIndex();
|
|
@@ -922,8 +857,8 @@ export function compileWasmModule(
|
|
|
922
857
|
emitter.emitSharedHelper(fn);
|
|
923
858
|
} else if (fn._isRuntimeHelper) {
|
|
924
859
|
emitter.emitRuntimeHelper(fn);
|
|
925
|
-
} else if (fn.
|
|
926
|
-
emitter
|
|
860
|
+
} else if (fn.intrinsic) {
|
|
861
|
+
emitWasmIntrinsic(emitter, fn);
|
|
927
862
|
} else if (fn.body) {
|
|
928
863
|
emitter.emitFunctionBody(fn.body);
|
|
929
864
|
}
|
|
@@ -961,7 +896,6 @@ export function compileWasmModule(
|
|
|
961
896
|
facade = generateFacade(boundaryMeta, {
|
|
962
897
|
stringTable: mod.stringTable,
|
|
963
898
|
callMain: Boolean(options.callMain) && mod.funcMap.has("main"),
|
|
964
|
-
stdlibEnv: mod.usesStdlibEnv,
|
|
965
899
|
});
|
|
966
900
|
}
|
|
967
901
|
|
|
@@ -978,6 +912,7 @@ export function compileWasmModule(
|
|
|
978
912
|
sourceMappingURL: options.sourceMappingURL ?? null,
|
|
979
913
|
};
|
|
980
914
|
|
|
915
|
+
pruneUnusedFuncs(moduleIR);
|
|
981
916
|
const wasmBytes = encodeModule(moduleIR);
|
|
982
917
|
const watText = options.emitWat ? emitWat(moduleIR) : null;
|
|
983
918
|
|
|
@@ -1037,428 +972,7 @@ function _collectInterfaceDispatchers(progs, funcDecls, mod, checker) {
|
|
|
1037
972
|
});
|
|
1038
973
|
}
|
|
1039
974
|
|
|
1040
|
-
const hasIo = importsAnyOf(progs, [
|
|
1041
|
-
"io",
|
|
1042
|
-
"fmt",
|
|
1043
|
-
"strings",
|
|
1044
|
-
"bytes",
|
|
1045
|
-
"crypto/sha256",
|
|
1046
|
-
"sha256",
|
|
1047
|
-
"encoding/binary",
|
|
1048
|
-
"binary",
|
|
1049
|
-
"encoding/hex",
|
|
1050
|
-
"hex",
|
|
1051
|
-
"encoding/base64",
|
|
1052
|
-
"base64",
|
|
1053
|
-
]);
|
|
1054
|
-
if (hasIo) {
|
|
1055
|
-
const byteSliceType = {
|
|
1056
|
-
kind: "slice",
|
|
1057
|
-
elem: { kind: "basic", name: "byte" },
|
|
1058
|
-
};
|
|
1059
|
-
const intErrReturns = [
|
|
1060
|
-
{ kind: "basic", name: "int" },
|
|
1061
|
-
{ kind: "interface", name: "error" },
|
|
1062
|
-
];
|
|
1063
|
-
if (!interfaceCalls.has("io.Reader.Read")) {
|
|
1064
|
-
interfaceCalls.set("io.Reader.Read", {
|
|
1065
|
-
ifaceName: "io.Reader",
|
|
1066
|
-
ifaceType: checker?.types?.get("io.Reader"),
|
|
1067
|
-
methodName: "Read",
|
|
1068
|
-
methodSig: {
|
|
1069
|
-
kind: "func",
|
|
1070
|
-
params: [byteSliceType],
|
|
1071
|
-
returns: intErrReturns,
|
|
1072
|
-
},
|
|
1073
|
-
});
|
|
1074
|
-
}
|
|
1075
|
-
if (!interfaceCalls.has("io.Writer.Write")) {
|
|
1076
|
-
interfaceCalls.set("io.Writer.Write", {
|
|
1077
|
-
ifaceName: "io.Writer",
|
|
1078
|
-
ifaceType: checker?.types?.get("io.Writer"),
|
|
1079
|
-
methodName: "Write",
|
|
1080
|
-
methodSig: {
|
|
1081
|
-
kind: "func",
|
|
1082
|
-
params: [byteSliceType],
|
|
1083
|
-
returns: intErrReturns,
|
|
1084
|
-
},
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
975
|
for (const info of interfaceCalls.values()) {
|
|
1090
976
|
funcDecls.push(_makeInterfaceDispatcher(info, checker));
|
|
1091
977
|
}
|
|
1092
978
|
}
|
|
1093
|
-
|
|
1094
|
-
function _registerIoSyntheticMethods(funcDecls, mod, strType, programs) {
|
|
1095
|
-
const progs = Array.isArray(programs) ? programs : [programs];
|
|
1096
|
-
const hasStrings = importsAnyOf(progs, ["strings"]);
|
|
1097
|
-
const hasBytes = importsAnyOf(progs, ["bytes"]);
|
|
1098
|
-
const hasIo = importsAnyOf(progs, ["io"]);
|
|
1099
|
-
|
|
1100
|
-
const BYTE_SLICE_T = {
|
|
1101
|
-
kind: "slice",
|
|
1102
|
-
elem: { kind: "basic", name: "byte" },
|
|
1103
|
-
};
|
|
1104
|
-
const INT_T = { kind: "basic", name: "int" };
|
|
1105
|
-
const ERR_T = { kind: "interface", name: "error" };
|
|
1106
|
-
const INT_ERR_RET = { kind: "tuple", types: [INT_T, ERR_T] };
|
|
1107
|
-
const ioHelper = (name, params, returnType, kind, extra = {}) => ({
|
|
1108
|
-
kind: "FuncDecl",
|
|
1109
|
-
name,
|
|
1110
|
-
params,
|
|
1111
|
-
returnType,
|
|
1112
|
-
body: { kind: "Block", stmts: [], list: [] },
|
|
1113
|
-
_isIoHelper: kind,
|
|
1114
|
-
_rootFuncDecl: null,
|
|
1115
|
-
...extra,
|
|
1116
|
-
});
|
|
1117
|
-
|
|
1118
|
-
if (hasStrings && mod.structTypes.has("strings.Builder")) {
|
|
1119
|
-
const bPtr = {
|
|
1120
|
-
kind: "pointer",
|
|
1121
|
-
base: { kind: "named", name: "strings.Builder" },
|
|
1122
|
-
};
|
|
1123
|
-
funcDecls.push(
|
|
1124
|
-
ioHelper(
|
|
1125
|
-
"strings.Builder.Write",
|
|
1126
|
-
[
|
|
1127
|
-
{ name: "b", type: bPtr },
|
|
1128
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1129
|
-
],
|
|
1130
|
-
INT_ERR_RET,
|
|
1131
|
-
"builder_write",
|
|
1132
|
-
{
|
|
1133
|
-
_isMethod: true,
|
|
1134
|
-
_recvTypeName: "strings.Builder",
|
|
1135
|
-
_methodName: "Write",
|
|
1136
|
-
},
|
|
1137
|
-
),
|
|
1138
|
-
ioHelper(
|
|
1139
|
-
"strings.Builder.WriteString",
|
|
1140
|
-
[
|
|
1141
|
-
{ name: "b", type: bPtr },
|
|
1142
|
-
{ name: "s", type: strType },
|
|
1143
|
-
],
|
|
1144
|
-
INT_ERR_RET,
|
|
1145
|
-
"builder_write_string",
|
|
1146
|
-
{
|
|
1147
|
-
_isMethod: true,
|
|
1148
|
-
_recvTypeName: "strings.Builder",
|
|
1149
|
-
_methodName: "WriteString",
|
|
1150
|
-
},
|
|
1151
|
-
),
|
|
1152
|
-
);
|
|
1153
|
-
}
|
|
1154
|
-
if (hasBytes && mod.structTypes.has("bytes.Buffer")) {
|
|
1155
|
-
const bPtr = {
|
|
1156
|
-
kind: "pointer",
|
|
1157
|
-
base: { kind: "named", name: "bytes.Buffer" },
|
|
1158
|
-
};
|
|
1159
|
-
funcDecls.push(
|
|
1160
|
-
ioHelper(
|
|
1161
|
-
"bytes.Buffer.Write",
|
|
1162
|
-
[
|
|
1163
|
-
{ name: "b", type: bPtr },
|
|
1164
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1165
|
-
],
|
|
1166
|
-
INT_ERR_RET,
|
|
1167
|
-
"buffer_write",
|
|
1168
|
-
{
|
|
1169
|
-
_isMethod: true,
|
|
1170
|
-
_recvTypeName: "bytes.Buffer",
|
|
1171
|
-
_methodName: "Write",
|
|
1172
|
-
},
|
|
1173
|
-
),
|
|
1174
|
-
ioHelper(
|
|
1175
|
-
"bytes.Buffer.WriteString",
|
|
1176
|
-
[
|
|
1177
|
-
{ name: "b", type: bPtr },
|
|
1178
|
-
{ name: "s", type: strType },
|
|
1179
|
-
],
|
|
1180
|
-
INT_ERR_RET,
|
|
1181
|
-
"buffer_write_string",
|
|
1182
|
-
{
|
|
1183
|
-
_isMethod: true,
|
|
1184
|
-
_recvTypeName: "bytes.Buffer",
|
|
1185
|
-
_methodName: "WriteString",
|
|
1186
|
-
},
|
|
1187
|
-
),
|
|
1188
|
-
ioHelper(
|
|
1189
|
-
"bytes.Buffer.Read",
|
|
1190
|
-
[
|
|
1191
|
-
{ name: "b", type: bPtr },
|
|
1192
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1193
|
-
],
|
|
1194
|
-
INT_ERR_RET,
|
|
1195
|
-
"buffer_read",
|
|
1196
|
-
{
|
|
1197
|
-
_isMethod: true,
|
|
1198
|
-
_recvTypeName: "bytes.Buffer",
|
|
1199
|
-
_methodName: "Read",
|
|
1200
|
-
},
|
|
1201
|
-
),
|
|
1202
|
-
);
|
|
1203
|
-
}
|
|
1204
|
-
if (hasStrings && mod.structTypes.has("strings.Reader")) {
|
|
1205
|
-
const rPtr = {
|
|
1206
|
-
kind: "pointer",
|
|
1207
|
-
base: { kind: "named", name: "strings.Reader" },
|
|
1208
|
-
};
|
|
1209
|
-
funcDecls.push(
|
|
1210
|
-
ioHelper(
|
|
1211
|
-
"strings.Reader.Read",
|
|
1212
|
-
[
|
|
1213
|
-
{ name: "r", type: rPtr },
|
|
1214
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1215
|
-
],
|
|
1216
|
-
INT_ERR_RET,
|
|
1217
|
-
"strings_reader_read",
|
|
1218
|
-
{
|
|
1219
|
-
_isMethod: true,
|
|
1220
|
-
_recvTypeName: "strings.Reader",
|
|
1221
|
-
_methodName: "Read",
|
|
1222
|
-
},
|
|
1223
|
-
),
|
|
1224
|
-
ioHelper(
|
|
1225
|
-
"strings.Reader.Len",
|
|
1226
|
-
[{ name: "r", type: rPtr }],
|
|
1227
|
-
INT_T,
|
|
1228
|
-
"strings_reader_len",
|
|
1229
|
-
{
|
|
1230
|
-
_isMethod: true,
|
|
1231
|
-
_recvTypeName: "strings.Reader",
|
|
1232
|
-
_methodName: "Len",
|
|
1233
|
-
},
|
|
1234
|
-
),
|
|
1235
|
-
ioHelper(
|
|
1236
|
-
"strings.Reader.Reset",
|
|
1237
|
-
[
|
|
1238
|
-
{ name: "r", type: rPtr },
|
|
1239
|
-
{ name: "s", type: strType },
|
|
1240
|
-
],
|
|
1241
|
-
null,
|
|
1242
|
-
"strings_reader_reset",
|
|
1243
|
-
{
|
|
1244
|
-
_isMethod: true,
|
|
1245
|
-
_recvTypeName: "strings.Reader",
|
|
1246
|
-
_methodName: "Reset",
|
|
1247
|
-
},
|
|
1248
|
-
),
|
|
1249
|
-
);
|
|
1250
|
-
}
|
|
1251
|
-
if (hasBytes && mod.structTypes.has("bytes.Reader")) {
|
|
1252
|
-
const rPtr = {
|
|
1253
|
-
kind: "pointer",
|
|
1254
|
-
base: { kind: "named", name: "bytes.Reader" },
|
|
1255
|
-
};
|
|
1256
|
-
funcDecls.push(
|
|
1257
|
-
ioHelper(
|
|
1258
|
-
"bytes.Reader.Read",
|
|
1259
|
-
[
|
|
1260
|
-
{ name: "r", type: rPtr },
|
|
1261
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1262
|
-
],
|
|
1263
|
-
INT_ERR_RET,
|
|
1264
|
-
"bytes_reader_read",
|
|
1265
|
-
{ _isMethod: true, _recvTypeName: "bytes.Reader", _methodName: "Read" },
|
|
1266
|
-
),
|
|
1267
|
-
ioHelper(
|
|
1268
|
-
"bytes.Reader.Len",
|
|
1269
|
-
[{ name: "r", type: rPtr }],
|
|
1270
|
-
INT_T,
|
|
1271
|
-
"bytes_reader_len",
|
|
1272
|
-
{ _isMethod: true, _recvTypeName: "bytes.Reader", _methodName: "Len" },
|
|
1273
|
-
),
|
|
1274
|
-
ioHelper(
|
|
1275
|
-
"bytes.Reader.Reset",
|
|
1276
|
-
[
|
|
1277
|
-
{ name: "r", type: rPtr },
|
|
1278
|
-
{ name: "b", type: BYTE_SLICE_T },
|
|
1279
|
-
],
|
|
1280
|
-
null,
|
|
1281
|
-
"bytes_reader_reset",
|
|
1282
|
-
{
|
|
1283
|
-
_isMethod: true,
|
|
1284
|
-
_recvTypeName: "bytes.Reader",
|
|
1285
|
-
_methodName: "Reset",
|
|
1286
|
-
},
|
|
1287
|
-
),
|
|
1288
|
-
);
|
|
1289
|
-
}
|
|
1290
|
-
if (hasIo && mod.structTypes.has("io.discard")) {
|
|
1291
|
-
const dPtr = {
|
|
1292
|
-
kind: "pointer",
|
|
1293
|
-
base: { kind: "named", name: "io.discard" },
|
|
1294
|
-
};
|
|
1295
|
-
funcDecls.push(
|
|
1296
|
-
ioHelper(
|
|
1297
|
-
"io.discard.Write",
|
|
1298
|
-
[
|
|
1299
|
-
{ name: "d", type: dPtr },
|
|
1300
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1301
|
-
],
|
|
1302
|
-
INT_ERR_RET,
|
|
1303
|
-
"discard_write",
|
|
1304
|
-
{ _isMethod: true, _recvTypeName: "io.discard", _methodName: "Write" },
|
|
1305
|
-
),
|
|
1306
|
-
ioHelper(
|
|
1307
|
-
"io.discard.WriteString",
|
|
1308
|
-
[
|
|
1309
|
-
{ name: "d", type: dPtr },
|
|
1310
|
-
{ name: "s", type: strType },
|
|
1311
|
-
],
|
|
1312
|
-
INT_ERR_RET,
|
|
1313
|
-
"discard_write_string",
|
|
1314
|
-
{
|
|
1315
|
-
_isMethod: true,
|
|
1316
|
-
_recvTypeName: "io.discard",
|
|
1317
|
-
_methodName: "WriteString",
|
|
1318
|
-
},
|
|
1319
|
-
),
|
|
1320
|
-
);
|
|
1321
|
-
}
|
|
1322
|
-
if (hasIo && mod.structTypes.has("io.LimitedReader")) {
|
|
1323
|
-
const lrPtr = {
|
|
1324
|
-
kind: "pointer",
|
|
1325
|
-
base: { kind: "named", name: "io.LimitedReader" },
|
|
1326
|
-
};
|
|
1327
|
-
funcDecls.push(
|
|
1328
|
-
ioHelper(
|
|
1329
|
-
"io.LimitedReader.Read",
|
|
1330
|
-
[
|
|
1331
|
-
{ name: "l", type: lrPtr },
|
|
1332
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1333
|
-
],
|
|
1334
|
-
INT_ERR_RET,
|
|
1335
|
-
"limited_reader_read",
|
|
1336
|
-
{
|
|
1337
|
-
_isMethod: true,
|
|
1338
|
-
_recvTypeName: "io.LimitedReader",
|
|
1339
|
-
_methodName: "Read",
|
|
1340
|
-
},
|
|
1341
|
-
),
|
|
1342
|
-
);
|
|
1343
|
-
}
|
|
1344
|
-
const hasOs = importsAnyOf(progs, ["os"]);
|
|
1345
|
-
if (hasOs && mod.structTypes.has("os.File")) {
|
|
1346
|
-
const fPtr = {
|
|
1347
|
-
kind: "pointer",
|
|
1348
|
-
base: { kind: "named", name: "os.File" },
|
|
1349
|
-
};
|
|
1350
|
-
funcDecls.push(
|
|
1351
|
-
ioHelper(
|
|
1352
|
-
"os.File.Write",
|
|
1353
|
-
[
|
|
1354
|
-
{ name: "f", type: fPtr },
|
|
1355
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1356
|
-
],
|
|
1357
|
-
INT_ERR_RET,
|
|
1358
|
-
"os_file_write",
|
|
1359
|
-
{ _isMethod: true, _recvTypeName: "os.File", _methodName: "Write" },
|
|
1360
|
-
),
|
|
1361
|
-
ioHelper(
|
|
1362
|
-
"os.File.WriteString",
|
|
1363
|
-
[
|
|
1364
|
-
{ name: "f", type: fPtr },
|
|
1365
|
-
{ name: "s", type: strType },
|
|
1366
|
-
],
|
|
1367
|
-
INT_ERR_RET,
|
|
1368
|
-
"os_file_write_string",
|
|
1369
|
-
{
|
|
1370
|
-
_isMethod: true,
|
|
1371
|
-
_recvTypeName: "os.File",
|
|
1372
|
-
_methodName: "WriteString",
|
|
1373
|
-
},
|
|
1374
|
-
),
|
|
1375
|
-
ioHelper(
|
|
1376
|
-
"os.File.Read",
|
|
1377
|
-
[
|
|
1378
|
-
{ name: "f", type: fPtr },
|
|
1379
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1380
|
-
],
|
|
1381
|
-
INT_ERR_RET,
|
|
1382
|
-
"os_file_read",
|
|
1383
|
-
{ _isMethod: true, _recvTypeName: "os.File", _methodName: "Read" },
|
|
1384
|
-
),
|
|
1385
|
-
ioHelper(
|
|
1386
|
-
"os.File.Close",
|
|
1387
|
-
[{ name: "f", type: fPtr }],
|
|
1388
|
-
ERR_T,
|
|
1389
|
-
"os_file_close",
|
|
1390
|
-
{ _isMethod: true, _recvTypeName: "os.File", _methodName: "Close" },
|
|
1391
|
-
),
|
|
1392
|
-
);
|
|
1393
|
-
}
|
|
1394
|
-
const hasSha256 = importsAnyOf(progs, ["crypto/sha256", "sha256"]);
|
|
1395
|
-
if (
|
|
1396
|
-
hasSha256 &&
|
|
1397
|
-
(mod.structTypes.has("sha256.digest") ||
|
|
1398
|
-
mod.structTypes.has("crypto/sha256.digest"))
|
|
1399
|
-
) {
|
|
1400
|
-
const dPtr = {
|
|
1401
|
-
kind: "pointer",
|
|
1402
|
-
base: { kind: "named", name: "sha256.digest" },
|
|
1403
|
-
};
|
|
1404
|
-
funcDecls.push(
|
|
1405
|
-
ioHelper(
|
|
1406
|
-
"sha256.digest.Write",
|
|
1407
|
-
[
|
|
1408
|
-
{ name: "d", type: dPtr },
|
|
1409
|
-
{ name: "p", type: BYTE_SLICE_T },
|
|
1410
|
-
],
|
|
1411
|
-
INT_ERR_RET,
|
|
1412
|
-
"sha256_write",
|
|
1413
|
-
{
|
|
1414
|
-
_isMethod: true,
|
|
1415
|
-
_recvTypeName: "sha256.digest",
|
|
1416
|
-
_methodName: "Write",
|
|
1417
|
-
},
|
|
1418
|
-
),
|
|
1419
|
-
ioHelper(
|
|
1420
|
-
"sha256.digest.Sum",
|
|
1421
|
-
[
|
|
1422
|
-
{ name: "d", type: dPtr },
|
|
1423
|
-
{ name: "b", type: BYTE_SLICE_T },
|
|
1424
|
-
],
|
|
1425
|
-
BYTE_SLICE_T,
|
|
1426
|
-
"sha256_sum",
|
|
1427
|
-
{ _isMethod: true, _recvTypeName: "sha256.digest", _methodName: "Sum" },
|
|
1428
|
-
),
|
|
1429
|
-
ioHelper(
|
|
1430
|
-
"sha256.digest.Reset",
|
|
1431
|
-
[{ name: "d", type: dPtr }],
|
|
1432
|
-
null,
|
|
1433
|
-
"sha256_reset",
|
|
1434
|
-
{
|
|
1435
|
-
_isMethod: true,
|
|
1436
|
-
_recvTypeName: "sha256.digest",
|
|
1437
|
-
_methodName: "Reset",
|
|
1438
|
-
},
|
|
1439
|
-
),
|
|
1440
|
-
ioHelper(
|
|
1441
|
-
"sha256.digest.Size",
|
|
1442
|
-
[{ name: "d", type: dPtr }],
|
|
1443
|
-
INT_T,
|
|
1444
|
-
"sha256_size",
|
|
1445
|
-
{
|
|
1446
|
-
_isMethod: true,
|
|
1447
|
-
_recvTypeName: "sha256.digest",
|
|
1448
|
-
_methodName: "Size",
|
|
1449
|
-
},
|
|
1450
|
-
),
|
|
1451
|
-
ioHelper(
|
|
1452
|
-
"sha256.digest.BlockSize",
|
|
1453
|
-
[{ name: "d", type: dPtr }],
|
|
1454
|
-
INT_T,
|
|
1455
|
-
"sha256_block_size",
|
|
1456
|
-
{
|
|
1457
|
-
_isMethod: true,
|
|
1458
|
-
_recvTypeName: "sha256.digest",
|
|
1459
|
-
_methodName: "BlockSize",
|
|
1460
|
-
},
|
|
1461
|
-
),
|
|
1462
|
-
);
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
@@ -96,6 +96,10 @@ function forwardingFuncLit(sel, recvName = "recv$") {
|
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
function isInterfaceRecv(t) {
|
|
100
|
+
return (t?.underlying ?? t)?.kind === "interface";
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
function methodValueLit(sel) {
|
|
100
104
|
const fnType = sel._type;
|
|
101
105
|
let recvType = sel.expr._type;
|
|
@@ -143,7 +147,14 @@ function methodValueLit(sel) {
|
|
|
143
147
|
returnType: typeToTypeNode(fnType),
|
|
144
148
|
body: {
|
|
145
149
|
kind: "Block",
|
|
146
|
-
stmts: [
|
|
150
|
+
stmts: [
|
|
151
|
+
// A method value on a nil interface panics when it is
|
|
152
|
+
// evaluated, not when it is called.
|
|
153
|
+
...(isInterfaceRecv(recvType)
|
|
154
|
+
? [{ kind: "NilCheckStmt", expr: ident(recvName, recvType, sel) }]
|
|
155
|
+
: []),
|
|
156
|
+
{ kind: "ReturnStmt", values: [inner] },
|
|
157
|
+
],
|
|
147
158
|
},
|
|
148
159
|
_type: outerType,
|
|
149
160
|
_line: sel._line,
|