gofront 1.8.0 → 1.9.0
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 +5 -4
- package/src/backend/js/expressions.js +849 -371
- package/src/backend/js/index.js +241 -147
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +512 -2547
- package/src/backend/js/statements.js +506 -103
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +177 -13
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +63 -171
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +643 -256
- package/src/backend/wasm/emit-exprs.js +124 -57
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-stmts.js +325 -75
- package/src/backend/wasm/emit.js +104 -13
- package/src/backend/wasm/globals.js +47 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +36 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +92 -717
- package/src/backend/wasm/monomorph.js +103 -6
- package/src/backend/wasm/natives.js +596 -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 +68 -20
- package/src/backend/wasm/variadic.js +3 -3
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +108 -130
- package/src/lexer/lexer.js +105 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +354 -132
- package/src/link/type-names.js +148 -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 +32 -3
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +905 -0
- package/src/lower/functions.js +2 -0
- package/src/lower/gen-types.js +274 -0
- package/src/lower/index.js +7 -1
- package/src/lower/json-codecs.js +228 -247
- 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 +28 -5
- package/src/parser/expressions.js +86 -16
- package/src/parser/statements.js +1 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +1 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +124 -11
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +32 -6
- package/src/typechecker/expressions.js +326 -98
- package/src/typechecker/index.js +208 -33
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +40 -0
- package/src/typechecker/resolve.js +192 -36
- package/src/typechecker/statements.js +122 -11
- 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 +203 -573
- 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
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
// ModuleEmitter: Module IR builder that registers types, imports, globals and functions.
|
|
3
3
|
|
|
4
4
|
import { wTypeKey } from "./boundary.js";
|
|
5
|
-
import { hasErrorUsage
|
|
6
|
-
import { BINARY_MATH_IMPORTS } from "./stdlib/index.js";
|
|
5
|
+
import { hasErrorUsage } from "./prescan.js";
|
|
7
6
|
import {
|
|
8
7
|
ERROR_STRUCT,
|
|
9
8
|
getFuncSignature,
|
|
@@ -14,215 +13,6 @@ import {
|
|
|
14
13
|
toWasmType,
|
|
15
14
|
} from "./types.js";
|
|
16
15
|
|
|
17
|
-
const ERROR_PRODUCING_PKGS = new Set([
|
|
18
|
-
"errors",
|
|
19
|
-
"fmt",
|
|
20
|
-
"strconv",
|
|
21
|
-
"path",
|
|
22
|
-
"path/filepath",
|
|
23
|
-
"io",
|
|
24
|
-
"os",
|
|
25
|
-
"strings",
|
|
26
|
-
"bytes",
|
|
27
|
-
"time",
|
|
28
|
-
"sync",
|
|
29
|
-
"crypto/rand",
|
|
30
|
-
"rand",
|
|
31
|
-
"crypto/sha256",
|
|
32
|
-
"sha256",
|
|
33
|
-
"encoding/binary",
|
|
34
|
-
"binary",
|
|
35
|
-
"encoding/hex",
|
|
36
|
-
"hex",
|
|
37
|
-
"encoding/base64",
|
|
38
|
-
"base64",
|
|
39
|
-
"math/bits",
|
|
40
|
-
"bits",
|
|
41
|
-
]);
|
|
42
|
-
// Packages whose calls lower to the `env.*` imports in STDLIB_IMPORTS (the
|
|
43
|
-
// matching JS lives in WASM_STDLIB_JS). Only modules importing one of them
|
|
44
|
-
// declare the imports and ship that JS block.
|
|
45
|
-
const STDLIB_ENV_PKGS = new Set([
|
|
46
|
-
"strings",
|
|
47
|
-
"strconv",
|
|
48
|
-
"unicode/utf8",
|
|
49
|
-
"fmt",
|
|
50
|
-
"testing",
|
|
51
|
-
"unicode",
|
|
52
|
-
"math/rand",
|
|
53
|
-
"path",
|
|
54
|
-
"path/filepath",
|
|
55
|
-
"html",
|
|
56
|
-
"bytes",
|
|
57
|
-
"io",
|
|
58
|
-
"os",
|
|
59
|
-
"time",
|
|
60
|
-
"sync",
|
|
61
|
-
"crypto/rand",
|
|
62
|
-
"rand",
|
|
63
|
-
"crypto/sha256",
|
|
64
|
-
"sha256",
|
|
65
|
-
"encoding/binary",
|
|
66
|
-
"binary",
|
|
67
|
-
"encoding/hex",
|
|
68
|
-
"hex",
|
|
69
|
-
"encoding/base64",
|
|
70
|
-
"base64",
|
|
71
|
-
"math/bits",
|
|
72
|
-
"bits",
|
|
73
|
-
]);
|
|
74
|
-
|
|
75
|
-
// [name, params, results] for `env.*` imports backing stdlib calls; the JS
|
|
76
|
-
// side lives in WASM_STDLIB_JS (boundary.js). All are registered eagerly
|
|
77
|
-
// (when any STDLIB_ENV_PKGS package is imported) because the import table is
|
|
78
|
-
// locked before function bodies are emitted.
|
|
79
|
-
const S = "externref";
|
|
80
|
-
const STDLIB_IMPORTS = [
|
|
81
|
-
// strings
|
|
82
|
-
["str_trim", [S, S], [S]],
|
|
83
|
-
["str_trim_left", [S, S], [S]],
|
|
84
|
-
["str_trim_right", [S, S], [S]],
|
|
85
|
-
["str_trim_prefix", [S, S], [S]],
|
|
86
|
-
["str_trim_suffix", [S, S], [S]],
|
|
87
|
-
["str_cut", [S, S], ["i32"]],
|
|
88
|
-
["str_cut_before", [], [S]],
|
|
89
|
-
["str_cut_after", [], [S]],
|
|
90
|
-
["str_cut_prefix", [S, S], ["i32"]],
|
|
91
|
-
["str_cut_suffix", [S, S], ["i32"]],
|
|
92
|
-
["str_replace", [S, S, S, "i32"], [S]],
|
|
93
|
-
["str_contains_rune", [S, "i32"], ["i32"]],
|
|
94
|
-
["str_contains_any", [S, S], ["i32"]],
|
|
95
|
-
["str_index_byte", [S, "i32"], ["i32"]],
|
|
96
|
-
["str_index_rune", [S, "i32"], ["i32"]],
|
|
97
|
-
["str_index_any", [S, S], ["i32"]],
|
|
98
|
-
["str_last_index_byte", [S, "i32"], ["i32"]],
|
|
99
|
-
["str_last_index_any", [S, S], ["i32"]],
|
|
100
|
-
["str_title", [S], [S]],
|
|
101
|
-
["str_split", [S, S], ["i32"]],
|
|
102
|
-
["str_split_n", [S, S, "i32"], ["i32"]],
|
|
103
|
-
["str_split_after", [S, S], ["i32"]],
|
|
104
|
-
["str_split_after_n", [S, S, "i32"], ["i32"]],
|
|
105
|
-
["str_fields", [S], ["i32"]],
|
|
106
|
-
["str_part", ["i32"], [S]],
|
|
107
|
-
["str_replacer_init", [S], []],
|
|
108
|
-
["str_replacer_add", [S, S], []],
|
|
109
|
-
["str_replacer_run", [], [S]],
|
|
110
|
-
// strconv
|
|
111
|
-
["strconv_atoi", [S], ["i64"]],
|
|
112
|
-
["strconv_parse_int", [S, "i32", "i32"], ["i64"]],
|
|
113
|
-
["strconv_parse_float", [S], ["f64"]],
|
|
114
|
-
["strconv_parse_bool", [S], ["i32"]],
|
|
115
|
-
["strconv_err", [], [S]],
|
|
116
|
-
["strconv_err_kind", [], ["i32"]],
|
|
117
|
-
["strconv_format_float", ["f64", "i32", "i32", "i32"], [S]],
|
|
118
|
-
["strconv_format_int", ["i64", "i32"], [S]],
|
|
119
|
-
["strconv_format_uint", ["i64", "i32"], [S]],
|
|
120
|
-
["strconv_parse_uint", [S, "i32", "i32"], ["i64"]],
|
|
121
|
-
["strconv_quote", [S], [S]],
|
|
122
|
-
["strconv_unquote", [S], [S]],
|
|
123
|
-
// unicode/utf8
|
|
124
|
-
["utf8_rune_count", [S], ["i32"]],
|
|
125
|
-
["utf8_rune_len", ["i32"], ["i32"]],
|
|
126
|
-
["utf8_valid_string", [S], ["i32"]],
|
|
127
|
-
["utf8_decode_rune", [S, "i32"], ["i32"]],
|
|
128
|
-
["utf8_decode_size", [], ["i32"]],
|
|
129
|
-
["utf8_full_rune", [S], ["i32"]],
|
|
130
|
-
// fmt (arguments travel through the testing_arg_* buffer)
|
|
131
|
-
["fmt_sprintf", [S], [S]],
|
|
132
|
-
["fmt_printf", [S], []],
|
|
133
|
-
["fmt_sprint", ["i32"], [S]],
|
|
134
|
-
["fmt_print", ["i32"], []],
|
|
135
|
-
["fmt_print_raw", [S], []],
|
|
136
|
-
["fmt_format_v", [S], [S]],
|
|
137
|
-
["fmt_sscan_init", [S, "i32"], ["i32"]],
|
|
138
|
-
["fmt_sscanf_init", [S, S], ["i32"]],
|
|
139
|
-
["fmt_sscan_has_err", [], ["i32"]],
|
|
140
|
-
["fmt_sscan_err_msg", [], [S]],
|
|
141
|
-
["fmt_sscan_token_str", ["i32"], [S]],
|
|
142
|
-
["fmt_sscan_token_i64", ["i32"], ["i64"]],
|
|
143
|
-
["fmt_sscan_token_f64", ["i32"], ["f64"]],
|
|
144
|
-
["fmt_sscan_token_bool", ["i32"], ["i32"]],
|
|
145
|
-
// testing.T.Run: the harness calls back into the exported __testing_run_cb
|
|
146
|
-
["testing_run", [S, S, "anyref"], ["i32"]],
|
|
147
|
-
["testing_cleanup", [S, "anyref"], []],
|
|
148
|
-
["testing_n", [S], ["i64"]],
|
|
149
|
-
["testing_elapsed", [S], ["i64"]],
|
|
150
|
-
["testing_context", [S], [S]],
|
|
151
|
-
["testing_output", [S], [S]],
|
|
152
|
-
// unicode
|
|
153
|
-
["unicode_is_letter", ["i32"], ["i32"]],
|
|
154
|
-
["unicode_is_digit", ["i32"], ["i32"]],
|
|
155
|
-
["unicode_is_space", ["i32"], ["i32"]],
|
|
156
|
-
["unicode_is_upper", ["i32"], ["i32"]],
|
|
157
|
-
["unicode_is_lower", ["i32"], ["i32"]],
|
|
158
|
-
["unicode_is_punct", ["i32"], ["i32"]],
|
|
159
|
-
["unicode_is_control", ["i32"], ["i32"]],
|
|
160
|
-
["unicode_is_print", ["i32"], ["i32"]],
|
|
161
|
-
["unicode_is_graphic", ["i32"], ["i32"]],
|
|
162
|
-
["unicode_to_upper", ["i32"], ["i32"]],
|
|
163
|
-
["unicode_to_lower", ["i32"], ["i32"]],
|
|
164
|
-
// html
|
|
165
|
-
["html_escape", [S], [S]],
|
|
166
|
-
["html_unescape", [S], [S]],
|
|
167
|
-
// path
|
|
168
|
-
["path_base", [S], [S]],
|
|
169
|
-
["path_dir", [S], [S]],
|
|
170
|
-
["path_ext", [S], [S]],
|
|
171
|
-
["path_is_abs", [S], ["i32"]],
|
|
172
|
-
["path_clean", [S], [S]],
|
|
173
|
-
["path_split", [S], []],
|
|
174
|
-
["path_split_dir", [], [S]],
|
|
175
|
-
["path_split_file", [], [S]],
|
|
176
|
-
["path_join_init", [], []],
|
|
177
|
-
["path_join_push", [S], []],
|
|
178
|
-
["path_join_run", [], [S]],
|
|
179
|
-
["path_match", [S, S], ["i32"]],
|
|
180
|
-
["path_match_has_err", [], ["i32"]],
|
|
181
|
-
["bytes_trim", [S, S, "i32", "i32"], []],
|
|
182
|
-
["bytes_trim_start", [], ["i32"]],
|
|
183
|
-
["bytes_trim_end", [], ["i32"]],
|
|
184
|
-
// time
|
|
185
|
-
["time_now_ms", [], ["f64"]],
|
|
186
|
-
["time_timezone_offset", ["f64"], ["i32"]],
|
|
187
|
-
["time_parse", [S, S], ["f64"]],
|
|
188
|
-
["time_parse_err", [], [S]],
|
|
189
|
-
["time_parse_offset", [], ["i32"]],
|
|
190
|
-
["time_parse_sub_ns", [], ["i32"]],
|
|
191
|
-
[
|
|
192
|
-
"time_format",
|
|
193
|
-
["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", S],
|
|
194
|
-
[S],
|
|
195
|
-
],
|
|
196
|
-
["time_duration_string", ["i64"], [S]],
|
|
197
|
-
["time_parse_duration", [S], ["i64"]],
|
|
198
|
-
["time_parse_duration_err", [], [S]],
|
|
199
|
-
["time_month_string", ["i32"], [S]],
|
|
200
|
-
["time_weekday_string", ["i32"], [S]],
|
|
201
|
-
// raw binary buffer for crypto/rand, crypto/sha256, hex, base64
|
|
202
|
-
["raw_bytes_init", ["i32"], []],
|
|
203
|
-
["raw_bytes_push", ["i32"], []],
|
|
204
|
-
["raw_bytes_len", [], ["i32"]],
|
|
205
|
-
["raw_bytes_get", ["i32"], ["i32"]],
|
|
206
|
-
// crypto/rand
|
|
207
|
-
["crypto_rand_fill", ["i32"], ["i32"]],
|
|
208
|
-
// crypto/sha256
|
|
209
|
-
["crypto_sha256_sum", [], ["i32"]],
|
|
210
|
-
// encoding/hex
|
|
211
|
-
["hex_encode_to_string", [], [S]],
|
|
212
|
-
["hex_decode_string", [S], ["i32"]],
|
|
213
|
-
["hex_get_err", [], [S]],
|
|
214
|
-
// encoding/base64
|
|
215
|
-
["base64_encode_to_string", ["i32"], [S]],
|
|
216
|
-
["base64_decode_string", ["i32", S], ["i32"]],
|
|
217
|
-
["base64_get_err", [], [S]],
|
|
218
|
-
["bits_div32", ["i32", "i32", "i32"], ["i32"]],
|
|
219
|
-
["bits_div32_rem", [], ["i32"]],
|
|
220
|
-
["bits_rem32", ["i32", "i32", "i32"], ["i32"]],
|
|
221
|
-
["bits_div64", ["i64", "i64", "i64"], ["i64"]],
|
|
222
|
-
["bits_div64_rem", [], ["i64"]],
|
|
223
|
-
["bits_rem64", ["i64", "i64", "i64"], ["i64"]],
|
|
224
|
-
];
|
|
225
|
-
|
|
226
16
|
export class ModuleEmitter {
|
|
227
17
|
constructor(checker, lowerResult = null, programs = [], options = {}) {
|
|
228
18
|
this.checker = checker;
|
|
@@ -230,6 +20,7 @@ export class ModuleEmitter {
|
|
|
230
20
|
// Local package names whose code is linked into this module; selectors
|
|
231
21
|
// like `mathx.NewVec3` are de-qualified to `NewVec3` by the emitter.
|
|
232
22
|
this.bundledPackages = options.bundledPackages ?? new Set();
|
|
23
|
+
this.natives = options.natives !== false; // replace native calls with host code
|
|
233
24
|
this.constCache = new Map(); // name -> BasicLit (package-level literal consts)
|
|
234
25
|
this.nonLiteralConsts = new Set(); // package-level consts the backend cannot evaluate yet
|
|
235
26
|
|
|
@@ -246,6 +37,7 @@ export class ModuleEmitter {
|
|
|
246
37
|
this.arrayTypes = new Map(); // wType key -> array info
|
|
247
38
|
this.sliceTypes = new Map(); // wType key -> slice info
|
|
248
39
|
this.sliceTypesByIndex = new Map(); // typeIndex -> slice info
|
|
40
|
+
this.taggedSliceTypes = new Map(); // Go slice type key -> tagged info
|
|
249
41
|
this.mapTypes = new Map(); // wType key -> map info
|
|
250
42
|
this.mapTypesByIndex = new Map(); // typeIndex -> map info
|
|
251
43
|
this.mapBucketsType = null; // shared (array (mut i32))
|
|
@@ -275,10 +67,7 @@ export class ModuleEmitter {
|
|
|
275
67
|
// `errors.New` / `fmt.Errorf` / strconv parse failures allocate the
|
|
276
68
|
// runtime's own error struct; it joins the struct rec group so the
|
|
277
69
|
// `error.Error` dispatcher can `ref.test` it like any user type.
|
|
278
|
-
this.hasErrorType =
|
|
279
|
-
importsAnyOf(programs, ERROR_PRODUCING_PKGS) || hasErrorUsage(programs);
|
|
280
|
-
this.usesStdlibEnv = importsAnyOf(programs, STDLIB_ENV_PKGS);
|
|
281
|
-
this.importsTesting = importsAnyOf(programs, ["testing"]);
|
|
70
|
+
this.hasErrorType = hasErrorUsage(programs);
|
|
282
71
|
|
|
283
72
|
if (programs && programs.length > 0) {
|
|
284
73
|
this.initTypes(programs);
|
|
@@ -288,6 +77,26 @@ export class ModuleEmitter {
|
|
|
288
77
|
this._initRuntimeImports();
|
|
289
78
|
}
|
|
290
79
|
|
|
80
|
+
// The runtime error struct is not declared in Go source: give the checker a
|
|
81
|
+
// named type with its method set (`Error() string`) so type assertions to
|
|
82
|
+
// `interface{ Error() string }` find it as a candidate.
|
|
83
|
+
_registerRuntimeErrorType() {
|
|
84
|
+
const types = this.checker?.types;
|
|
85
|
+
if (!types || types.has(ERROR_STRUCT)) return;
|
|
86
|
+
const STRING = { kind: "basic", name: "string" };
|
|
87
|
+
types.set(ERROR_STRUCT, {
|
|
88
|
+
kind: "named",
|
|
89
|
+
name: ERROR_STRUCT,
|
|
90
|
+
underlying: {
|
|
91
|
+
kind: "struct",
|
|
92
|
+
fields: new Map(),
|
|
93
|
+
methods: new Map([
|
|
94
|
+
["Error", { kind: "func", params: [], returns: [STRING] }],
|
|
95
|
+
]),
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
291
100
|
initTypes(programs) {
|
|
292
101
|
const progs = Array.isArray(programs) ? programs : [programs];
|
|
293
102
|
const rawStructs = [];
|
|
@@ -295,15 +104,13 @@ export class ModuleEmitter {
|
|
|
295
104
|
const aliases = []; // qualified key (pkg.T) -> unqualified struct name
|
|
296
105
|
|
|
297
106
|
if (this.hasErrorType) {
|
|
107
|
+
this._registerRuntimeErrorType();
|
|
298
108
|
seen.add(ERROR_STRUCT);
|
|
299
109
|
rawStructs.push({
|
|
300
110
|
name: ERROR_STRUCT,
|
|
301
111
|
structType: {
|
|
302
112
|
kind: "struct",
|
|
303
|
-
fields: new Map([
|
|
304
|
-
["msg", { kind: "basic", name: "string" }],
|
|
305
|
-
["cause", { kind: "basic", name: "any" }],
|
|
306
|
-
]),
|
|
113
|
+
fields: new Map([["msg", { kind: "basic", name: "string" }]]),
|
|
307
114
|
},
|
|
308
115
|
});
|
|
309
116
|
}
|
|
@@ -332,11 +139,6 @@ export class ModuleEmitter {
|
|
|
332
139
|
for (const [key, t] of this.checker.types.entries()) {
|
|
333
140
|
if (t.kind === "named" && t.underlying?.kind === "struct") {
|
|
334
141
|
const name = t.name ?? key;
|
|
335
|
-
if (
|
|
336
|
-
name.startsWith("testing.") &&
|
|
337
|
-
(!this.importsTesting || name !== "testing.BenchmarkResult")
|
|
338
|
-
)
|
|
339
|
-
continue;
|
|
340
142
|
if (!seen.has(name)) {
|
|
341
143
|
seen.add(name);
|
|
342
144
|
rawStructs.push({ name, structType: t.underlying });
|
|
@@ -416,8 +218,16 @@ export class ModuleEmitter {
|
|
|
416
218
|
});
|
|
417
219
|
fieldIndexMap.set(n, fIdx);
|
|
418
220
|
if (f.embedded) {
|
|
221
|
+
// The embedded type, when it differs from the field
|
|
222
|
+
// name (`Mutex$$sync` for the field `Mutex`).
|
|
223
|
+
const ref =
|
|
224
|
+
f.type?.kind === "PointerType"
|
|
225
|
+
? f.type.base?.name
|
|
226
|
+
: f.type?.name;
|
|
227
|
+
const typeName = this.checker?.types?.get(ref)?.name;
|
|
419
228
|
embeds.push({
|
|
420
229
|
name: n,
|
|
230
|
+
...(typeName && typeName !== n && { typeName }),
|
|
421
231
|
fieldIndex: fIdx,
|
|
422
232
|
});
|
|
423
233
|
}
|
|
@@ -524,9 +334,11 @@ export class ModuleEmitter {
|
|
|
524
334
|
const typeEntry = {
|
|
525
335
|
form: "struct",
|
|
526
336
|
name: typeName,
|
|
337
|
+
// Mutable so the facade's per-field setters for an exported struct
|
|
338
|
+
// that holds a complex value validate.
|
|
527
339
|
fields: [
|
|
528
|
-
{ type: elemWType, mutable:
|
|
529
|
-
{ type: elemWType, mutable:
|
|
340
|
+
{ type: elemWType, mutable: true },
|
|
341
|
+
{ type: elemWType, mutable: true },
|
|
530
342
|
],
|
|
531
343
|
};
|
|
532
344
|
this._pushType(typeEntry);
|
|
@@ -704,6 +516,10 @@ export class ModuleEmitter {
|
|
|
704
516
|
const typeIndex = this._getTotalTypeCount();
|
|
705
517
|
const typeEntry = {
|
|
706
518
|
form: "struct",
|
|
519
|
+
// Slice types are open: each defined slice type, and each Go type among
|
|
520
|
+
// the 32-bit-or-smaller elements, gets a tagged subtype when it
|
|
521
|
+
// reaches an interface.
|
|
522
|
+
sub: true,
|
|
707
523
|
fields: [
|
|
708
524
|
{
|
|
709
525
|
type: {
|
|
@@ -750,6 +566,43 @@ export class ModuleEmitter {
|
|
|
750
566
|
return sliceInfo;
|
|
751
567
|
}
|
|
752
568
|
|
|
569
|
+
// The subtype of the slice struct a value of Go slice type `sliceGoType`
|
|
570
|
+
// takes inside an interface. Slices of booleans and small integers share
|
|
571
|
+
// one WebAssembly type, so the extra tag field (a nullable ref to a struct
|
|
572
|
+
// with one immutable i32 field per tag index) is what tells `[]byte` from
|
|
573
|
+
// `[]bool` and `json.RawMessage` from `[]byte` in a type test.
|
|
574
|
+
getTaggedSliceType(sliceGoType, elemGoType) {
|
|
575
|
+
const key = goTypeKey(sliceGoType);
|
|
576
|
+
const known = this.taggedSliceTypes.get(key);
|
|
577
|
+
if (known) return known;
|
|
578
|
+
const base = this.getSliceType(elemGoType);
|
|
579
|
+
const tagIndex = this.taggedSliceTypes.size + 1;
|
|
580
|
+
const tagTypeIndex = this._getTotalTypeCount();
|
|
581
|
+
this._pushType({
|
|
582
|
+
form: "struct",
|
|
583
|
+
fields: Array.from({ length: tagIndex }, () => ({
|
|
584
|
+
type: "i32",
|
|
585
|
+
mutable: false,
|
|
586
|
+
})),
|
|
587
|
+
});
|
|
588
|
+
const typeIndex = this._getTotalTypeCount();
|
|
589
|
+
this._pushType({
|
|
590
|
+
form: "struct",
|
|
591
|
+
sub: true,
|
|
592
|
+
superTypeIndex: base.typeIndex,
|
|
593
|
+
fields: [
|
|
594
|
+
...base.typeEntry.fields,
|
|
595
|
+
{
|
|
596
|
+
type: { kind: "ref", nullable: true, typeIndex: tagTypeIndex },
|
|
597
|
+
mutable: false,
|
|
598
|
+
},
|
|
599
|
+
],
|
|
600
|
+
});
|
|
601
|
+
const info = { key, typeIndex, tagTypeIndex, base, goType: sliceGoType };
|
|
602
|
+
this.taggedSliceTypes.set(key, info);
|
|
603
|
+
return info;
|
|
604
|
+
}
|
|
605
|
+
|
|
753
606
|
getSliceTypeByIndex(typeIndex) {
|
|
754
607
|
return this.sliceTypesByIndex?.get(typeIndex) ?? null;
|
|
755
608
|
}
|
|
@@ -848,17 +701,12 @@ export class ModuleEmitter {
|
|
|
848
701
|
clearFuncName: `__map_clear_${suffix}`,
|
|
849
702
|
keysFuncName: `__map_keys_${suffix}`,
|
|
850
703
|
valuesFuncName: `__map_values_${suffix}`,
|
|
851
|
-
cloneFuncName: `__map_clone_${suffix}`,
|
|
852
704
|
};
|
|
853
705
|
this.mapTypes.set(key, mapInfo);
|
|
854
706
|
this.mapTypesByIndex.set(mapTypeIndex, mapInfo);
|
|
855
707
|
return mapInfo;
|
|
856
708
|
}
|
|
857
709
|
|
|
858
|
-
getMapTypeByIndex(typeIndex) {
|
|
859
|
-
return this.mapTypesByIndex?.get(typeIndex) ?? null;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
710
|
getClosureType(goType) {
|
|
863
711
|
const sig = getFuncSignature(goType, this.checker);
|
|
864
712
|
const paramWTypes = sig.params
|
|
@@ -971,19 +819,6 @@ export class ModuleEmitter {
|
|
|
971
819
|
this.getStringFromCodePointImportIndex(); // env.str_from_code_point
|
|
972
820
|
this.getStringCodePointAtImportIndex(); // env.str_code_point_at
|
|
973
821
|
this.getStringHashImportIndex(); // env.str_hash
|
|
974
|
-
this.getStringToUpperImportIndex();
|
|
975
|
-
this.getStringToLowerImportIndex();
|
|
976
|
-
this.getStringTrimSpaceImportIndex();
|
|
977
|
-
this.getStringContainsImportIndex();
|
|
978
|
-
this.getStringHasPrefixImportIndex();
|
|
979
|
-
this.getStringHasSuffixImportIndex();
|
|
980
|
-
this.getStringIndexImportIndex();
|
|
981
|
-
this.getStringLastIndexImportIndex();
|
|
982
|
-
this.getStringRepeatImportIndex();
|
|
983
|
-
this.getStringReplaceAllImportIndex();
|
|
984
|
-
this.getStringEqualFoldImportIndex();
|
|
985
|
-
this.getStringCountImportIndex();
|
|
986
|
-
this.getStringToValidUTF8ImportIndex();
|
|
987
822
|
this.getStrFromI64ImportIndex();
|
|
988
823
|
this.getStrFromI32ImportIndex();
|
|
989
824
|
this.getStrFromF64ImportIndex();
|
|
@@ -993,35 +828,6 @@ export class ModuleEmitter {
|
|
|
993
828
|
this.getBytesToStrInitImportIndex();
|
|
994
829
|
this.getBytesToStrPushImportIndex();
|
|
995
830
|
this.getBytesToStrFinishImportIndex();
|
|
996
|
-
this.getTestingCallImportIndex();
|
|
997
|
-
this.getTestingNameImportIndex();
|
|
998
|
-
this.getTestingFlagImportIndex();
|
|
999
|
-
for (const t of ["i32", "i64", "f32", "f64", "externref", "anyref"]) {
|
|
1000
|
-
this.getTestingArgImportIndex(t, false);
|
|
1001
|
-
}
|
|
1002
|
-
this.getTestingArgImportIndex("i32", true);
|
|
1003
|
-
this.getTestingArgErrImportIndex();
|
|
1004
|
-
this.getTestingArgSpreadImportIndex();
|
|
1005
|
-
this.getTestingArgU64ImportIndex();
|
|
1006
|
-
this.getFmtArgTypeImportIndex();
|
|
1007
|
-
this.getFmtStructTypeImportIndex();
|
|
1008
|
-
this.getFmtNewArrayIndex();
|
|
1009
|
-
this.getFmtArrayPushIndex();
|
|
1010
|
-
this.getFmtNewMapIndex();
|
|
1011
|
-
this.getFmtMapSetIndex();
|
|
1012
|
-
this.getFmtNewStructIndex();
|
|
1013
|
-
this.getFmtStructSetIndex();
|
|
1014
|
-
this.getFmtBoxI32Index();
|
|
1015
|
-
this.getFmtBoxI64Index();
|
|
1016
|
-
this.getFmtBoxF64Index();
|
|
1017
|
-
this.getFmtBoxBoolIndex();
|
|
1018
|
-
this.getFmtNewBoxIndex();
|
|
1019
|
-
this.getFmtNewStringerIndex();
|
|
1020
|
-
if (this.usesStdlibEnv) {
|
|
1021
|
-
for (const [name, params, results] of STDLIB_IMPORTS) {
|
|
1022
|
-
this.getOrAddFuncImport("env", name, params, results);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
831
|
|
|
1026
832
|
// Logging built-ins
|
|
1027
833
|
this.getPrintlnEmptyIndex(); // env.println_empty
|
|
@@ -1032,30 +838,6 @@ export class ModuleEmitter {
|
|
|
1032
838
|
}
|
|
1033
839
|
this.getLogImportIndex("i32", false, true); // env.print_bool
|
|
1034
840
|
this.getLogImportIndex("i32", true, true); // env.println_bool
|
|
1035
|
-
|
|
1036
|
-
// Math built-ins
|
|
1037
|
-
const unaryMath = [
|
|
1038
|
-
"sin",
|
|
1039
|
-
"cos",
|
|
1040
|
-
"tan",
|
|
1041
|
-
"asin",
|
|
1042
|
-
"acos",
|
|
1043
|
-
"atan",
|
|
1044
|
-
"exp",
|
|
1045
|
-
"log",
|
|
1046
|
-
"log2",
|
|
1047
|
-
"log10",
|
|
1048
|
-
"round",
|
|
1049
|
-
"cbrt",
|
|
1050
|
-
"log1p",
|
|
1051
|
-
"expm1",
|
|
1052
|
-
];
|
|
1053
|
-
for (const m of unaryMath) {
|
|
1054
|
-
this.getMathImportIndex(m, false);
|
|
1055
|
-
}
|
|
1056
|
-
for (const m of BINARY_MATH_IMPORTS) {
|
|
1057
|
-
this.getMathImportIndex(m, true);
|
|
1058
|
-
}
|
|
1059
841
|
}
|
|
1060
842
|
|
|
1061
843
|
_initPanicTag() {
|
|
@@ -1137,93 +919,6 @@ export class ModuleEmitter {
|
|
|
1137
919
|
return gIdx;
|
|
1138
920
|
}
|
|
1139
921
|
|
|
1140
|
-
getRandStateGlobalIndex() {
|
|
1141
|
-
if (this.randStateGlobalIndex !== undefined) {
|
|
1142
|
-
return this.randStateGlobalIndex;
|
|
1143
|
-
}
|
|
1144
|
-
const gIdx = this.globals.length;
|
|
1145
|
-
this.globals.push({
|
|
1146
|
-
type: "i64",
|
|
1147
|
-
mutable: true,
|
|
1148
|
-
init: [{ op: "i64.const", value: 1n }],
|
|
1149
|
-
});
|
|
1150
|
-
this.randStateGlobalIndex = gIdx;
|
|
1151
|
-
return gIdx;
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
getStrconvErrGlobalIndex(field) {
|
|
1155
|
-
if (!this.strconvErrGlobals) this.strconvErrGlobals = new Map();
|
|
1156
|
-
if (this.strconvErrGlobals.has(field)) {
|
|
1157
|
-
return this.strconvErrGlobals.get(field);
|
|
1158
|
-
}
|
|
1159
|
-
const gIdx = this.globals.length;
|
|
1160
|
-
this.globals.push({
|
|
1161
|
-
type: "anyref",
|
|
1162
|
-
mutable: true,
|
|
1163
|
-
init: [{ op: "ref.null", heapType: "any" }],
|
|
1164
|
-
});
|
|
1165
|
-
this.strconvErrGlobals.set(field, gIdx);
|
|
1166
|
-
return gIdx;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
getPathErrGlobalIndex(field) {
|
|
1170
|
-
if (!this.pathErrGlobals) this.pathErrGlobals = new Map();
|
|
1171
|
-
if (this.pathErrGlobals.has(field)) {
|
|
1172
|
-
return this.pathErrGlobals.get(field);
|
|
1173
|
-
}
|
|
1174
|
-
const gIdx = this.globals.length;
|
|
1175
|
-
this.globals.push({
|
|
1176
|
-
type: "anyref",
|
|
1177
|
-
mutable: true,
|
|
1178
|
-
init: [{ op: "ref.null", heapType: "any" }],
|
|
1179
|
-
});
|
|
1180
|
-
this.pathErrGlobals.set(field, gIdx);
|
|
1181
|
-
return gIdx;
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
getIoErrGlobalIndex(field) {
|
|
1185
|
-
if (!this.ioErrGlobals) this.ioErrGlobals = new Map();
|
|
1186
|
-
if (this.ioErrGlobals.has(field)) {
|
|
1187
|
-
return this.ioErrGlobals.get(field);
|
|
1188
|
-
}
|
|
1189
|
-
const gIdx = this.globals.length;
|
|
1190
|
-
this.globals.push({
|
|
1191
|
-
type: "anyref",
|
|
1192
|
-
mutable: true,
|
|
1193
|
-
init: [{ op: "ref.null", heapType: "any" }],
|
|
1194
|
-
});
|
|
1195
|
-
this.ioErrGlobals.set(field, gIdx);
|
|
1196
|
-
return gIdx;
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
getIoDiscardGlobalIndex() {
|
|
1200
|
-
if (this.ioDiscardGlobalIndex !== undefined) {
|
|
1201
|
-
return this.ioDiscardGlobalIndex;
|
|
1202
|
-
}
|
|
1203
|
-
this.getStructType("io.discard");
|
|
1204
|
-
const gIdx = this.globals.length;
|
|
1205
|
-
this.globals.push({
|
|
1206
|
-
type: "anyref",
|
|
1207
|
-
mutable: true,
|
|
1208
|
-
init: [{ op: "ref.null", heapType: "any" }],
|
|
1209
|
-
});
|
|
1210
|
-
this.ioDiscardGlobalIndex = gIdx;
|
|
1211
|
-
return gIdx;
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
getOsGlobalIndex(field) {
|
|
1215
|
-
this.osGlobals ??= new Map();
|
|
1216
|
-
if (this.osGlobals.has(field)) return this.osGlobals.get(field);
|
|
1217
|
-
const gIdx = this.globals.length;
|
|
1218
|
-
this.globals.push({
|
|
1219
|
-
type: "anyref",
|
|
1220
|
-
mutable: true,
|
|
1221
|
-
init: [{ op: "ref.null", heapType: "any" }],
|
|
1222
|
-
});
|
|
1223
|
-
this.osGlobals.set(field, gIdx);
|
|
1224
|
-
return gIdx;
|
|
1225
|
-
}
|
|
1226
|
-
|
|
1227
922
|
getDeferNodeTypeIndex() {
|
|
1228
923
|
if (this.deferNodeTypeIndex !== undefined) {
|
|
1229
924
|
return this.deferNodeTypeIndex;
|
|
@@ -1361,190 +1056,8 @@ export class ModuleEmitter {
|
|
|
1361
1056
|
return this.getOrAddFuncImport("env", "println_empty", [], []);
|
|
1362
1057
|
}
|
|
1363
1058
|
|
|
1364
|
-
|
|
1365
|
-
return this.getOrAddFuncImport("env", "
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
getFmtArrayPushIndex() {
|
|
1369
|
-
return this.getOrAddFuncImport(
|
|
1370
|
-
"env",
|
|
1371
|
-
"fmt_array_push",
|
|
1372
|
-
["externref", "externref"],
|
|
1373
|
-
[],
|
|
1374
|
-
);
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
getFmtNewMapIndex() {
|
|
1378
|
-
return this.getOrAddFuncImport("env", "fmt_new_map", [], ["externref"]);
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
getFmtMapSetIndex() {
|
|
1382
|
-
return this.getOrAddFuncImport(
|
|
1383
|
-
"env",
|
|
1384
|
-
"fmt_map_set",
|
|
1385
|
-
["externref", "externref", "externref"],
|
|
1386
|
-
[],
|
|
1387
|
-
);
|
|
1388
|
-
}
|
|
1389
|
-
|
|
1390
|
-
getFmtNewStringerIndex() {
|
|
1391
|
-
return this.getOrAddFuncImport(
|
|
1392
|
-
"env",
|
|
1393
|
-
"fmt_new_stringer",
|
|
1394
|
-
["externref", "externref", "i32"],
|
|
1395
|
-
["externref"],
|
|
1396
|
-
);
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
getFmtNewStructIndex() {
|
|
1400
|
-
return this.getOrAddFuncImport(
|
|
1401
|
-
"env",
|
|
1402
|
-
"fmt_new_struct",
|
|
1403
|
-
["anyref", "i32"],
|
|
1404
|
-
["externref"],
|
|
1405
|
-
);
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
// Names the Go type of a struct built for fmt (`%T`, `%#v` of an any).
|
|
1409
|
-
getFmtStructTypeImportIndex() {
|
|
1410
|
-
return this.getOrAddFuncImport(
|
|
1411
|
-
"env",
|
|
1412
|
-
"fmt_struct_type",
|
|
1413
|
-
["externref", "i32"],
|
|
1414
|
-
[],
|
|
1415
|
-
);
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
getFmtStructSetIndex() {
|
|
1419
|
-
return this.getOrAddFuncImport(
|
|
1420
|
-
"env",
|
|
1421
|
-
"fmt_struct_set",
|
|
1422
|
-
["externref", "i32", "externref"],
|
|
1423
|
-
[],
|
|
1424
|
-
);
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
getFmtBoxI32Index() {
|
|
1428
|
-
return this.getOrAddFuncImport(
|
|
1429
|
-
"env",
|
|
1430
|
-
"fmt_box_i32",
|
|
1431
|
-
["i32"],
|
|
1432
|
-
["externref"],
|
|
1433
|
-
);
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
getFmtBoxI64Index() {
|
|
1437
|
-
return this.getOrAddFuncImport(
|
|
1438
|
-
"env",
|
|
1439
|
-
"fmt_box_i64",
|
|
1440
|
-
["i64"],
|
|
1441
|
-
["externref"],
|
|
1442
|
-
);
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
// Registered only for programs whose fmt operands may hold a uint64
|
|
1446
|
-
// (see scanFmtU64), so other modules keep their import table.
|
|
1447
|
-
getFmtBoxU64Index() {
|
|
1448
|
-
return this.getOrAddFuncImport(
|
|
1449
|
-
"env",
|
|
1450
|
-
"fmt_box_u64",
|
|
1451
|
-
["i64"],
|
|
1452
|
-
["externref"],
|
|
1453
|
-
);
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
getFmtBoxF64Index() {
|
|
1457
|
-
return this.getOrAddFuncImport(
|
|
1458
|
-
"env",
|
|
1459
|
-
"fmt_box_f64",
|
|
1460
|
-
["f64"],
|
|
1461
|
-
["externref"],
|
|
1462
|
-
);
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
getFmtBoxBoolIndex() {
|
|
1466
|
-
return this.getOrAddFuncImport(
|
|
1467
|
-
"env",
|
|
1468
|
-
"fmt_box_bool",
|
|
1469
|
-
["i32"],
|
|
1470
|
-
["externref"],
|
|
1471
|
-
);
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
getFmtNewBoxIndex() {
|
|
1475
|
-
return this.getOrAddFuncImport("env", "fmt_new_box", [], ["externref"]);
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
// `*testing.T` method calls: args are pushed one by one to a JS-side
|
|
1479
|
-
// buffer, then `testing_call(t, methodNameStrIdx)` invokes the method.
|
|
1480
|
-
getTestingArgImportIndex(wType, isBool = false) {
|
|
1481
|
-
if (isBool)
|
|
1482
|
-
return this.getOrAddFuncImport("env", "testing_arg_bool", ["i32"], []);
|
|
1483
|
-
const suffix =
|
|
1484
|
-
wType === "externref" ? "str" : wType === "anyref" ? "any" : wType;
|
|
1485
|
-
if (!["i32", "i64", "f32", "f64", "str", "any"].includes(suffix)) {
|
|
1486
|
-
throw new Error(
|
|
1487
|
-
"only primitive, string, error and any arguments are supported for fmt and testing.T calls in wasm packages (format slices/structs field by field)",
|
|
1488
|
-
);
|
|
1489
|
-
}
|
|
1490
|
-
return this.getOrAddFuncImport(
|
|
1491
|
-
"env",
|
|
1492
|
-
`testing_arg_${suffix}`,
|
|
1493
|
-
[suffix === "str" ? "externref" : suffix === "any" ? "anyref" : wType],
|
|
1494
|
-
[],
|
|
1495
|
-
);
|
|
1496
|
-
}
|
|
1497
|
-
|
|
1498
|
-
// Error operands of fmt.Sprint/Print/Append: a non-string for the host.
|
|
1499
|
-
getTestingArgSpreadImportIndex() {
|
|
1500
|
-
return this.getOrAddFuncImport(
|
|
1501
|
-
"env",
|
|
1502
|
-
"testing_arg_spread",
|
|
1503
|
-
["externref"],
|
|
1504
|
-
[],
|
|
1505
|
-
);
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
// An unsigned 64-bit operand: the host reinterprets the i64 as unsigned.
|
|
1509
|
-
getTestingArgU64ImportIndex() {
|
|
1510
|
-
return this.getOrAddFuncImport("env", "testing_arg_u64", ["i64"], []);
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
// Tags the last operand in the argument buffer with the static type
|
|
1514
|
-
// descriptor (JSON) held in string table entry `i32`, for `%T` and `%#v`.
|
|
1515
|
-
getFmtArgTypeImportIndex() {
|
|
1516
|
-
return this.getOrAddFuncImport("env", "fmt_arg_type", ["i32"], []);
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
getTestingArgErrImportIndex() {
|
|
1520
|
-
return this.getOrAddFuncImport("env", "testing_arg_err", ["externref"], []);
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
getTestingCallImportIndex() {
|
|
1524
|
-
return this.getOrAddFuncImport(
|
|
1525
|
-
"env",
|
|
1526
|
-
"testing_call",
|
|
1527
|
-
["externref", "i32"],
|
|
1528
|
-
[],
|
|
1529
|
-
);
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
getTestingNameImportIndex() {
|
|
1533
|
-
return this.getOrAddFuncImport(
|
|
1534
|
-
"env",
|
|
1535
|
-
"testing_name",
|
|
1536
|
-
["externref"],
|
|
1537
|
-
["externref"],
|
|
1538
|
-
);
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
getTestingFlagImportIndex() {
|
|
1542
|
-
return this.getOrAddFuncImport(
|
|
1543
|
-
"env",
|
|
1544
|
-
"testing_flag",
|
|
1545
|
-
["externref", "i32"],
|
|
1546
|
-
["i32"],
|
|
1547
|
-
);
|
|
1059
|
+
getPrintResetIndex() {
|
|
1060
|
+
return this.getOrAddFuncImport("env", "print_reset", [], []);
|
|
1548
1061
|
}
|
|
1549
1062
|
|
|
1550
1063
|
getLogImportIndex(wType, isLast = false, isBool = false) {
|
|
@@ -1557,6 +1070,8 @@ export class ModuleEmitter {
|
|
|
1557
1070
|
return this.getOrAddFuncImport("env", `${prefix}_i32`, ["i32"], []);
|
|
1558
1071
|
case "i64":
|
|
1559
1072
|
return this.getOrAddFuncImport("env", `${prefix}_i64`, ["i64"], []);
|
|
1073
|
+
case "u64":
|
|
1074
|
+
return this.getOrAddFuncImport("env", `${prefix}_u64`, ["i64"], []);
|
|
1560
1075
|
case "f32":
|
|
1561
1076
|
return this.getOrAddFuncImport("env", `${prefix}_f32`, ["f32"], []);
|
|
1562
1077
|
case "f64":
|
|
@@ -1656,123 +1171,6 @@ export class ModuleEmitter {
|
|
|
1656
1171
|
return this.getOrAddFuncImport("env", "str_hash", ["externref"], ["i32"]);
|
|
1657
1172
|
}
|
|
1658
1173
|
|
|
1659
|
-
getStringToUpperImportIndex() {
|
|
1660
|
-
return this.getOrAddFuncImport(
|
|
1661
|
-
"env",
|
|
1662
|
-
"str_to_upper",
|
|
1663
|
-
["externref"],
|
|
1664
|
-
["externref"],
|
|
1665
|
-
);
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
getStringToLowerImportIndex() {
|
|
1669
|
-
return this.getOrAddFuncImport(
|
|
1670
|
-
"env",
|
|
1671
|
-
"str_to_lower",
|
|
1672
|
-
["externref"],
|
|
1673
|
-
["externref"],
|
|
1674
|
-
);
|
|
1675
|
-
}
|
|
1676
|
-
|
|
1677
|
-
getStringTrimSpaceImportIndex() {
|
|
1678
|
-
return this.getOrAddFuncImport(
|
|
1679
|
-
"env",
|
|
1680
|
-
"str_trim_space",
|
|
1681
|
-
["externref"],
|
|
1682
|
-
["externref"],
|
|
1683
|
-
);
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
getStringContainsImportIndex() {
|
|
1687
|
-
return this.getOrAddFuncImport(
|
|
1688
|
-
"env",
|
|
1689
|
-
"str_contains",
|
|
1690
|
-
["externref", "externref"],
|
|
1691
|
-
["i32"],
|
|
1692
|
-
);
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1695
|
-
getStringHasPrefixImportIndex() {
|
|
1696
|
-
return this.getOrAddFuncImport(
|
|
1697
|
-
"env",
|
|
1698
|
-
"str_has_prefix",
|
|
1699
|
-
["externref", "externref"],
|
|
1700
|
-
["i32"],
|
|
1701
|
-
);
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
getStringHasSuffixImportIndex() {
|
|
1705
|
-
return this.getOrAddFuncImport(
|
|
1706
|
-
"env",
|
|
1707
|
-
"str_has_suffix",
|
|
1708
|
-
["externref", "externref"],
|
|
1709
|
-
["i32"],
|
|
1710
|
-
);
|
|
1711
|
-
}
|
|
1712
|
-
|
|
1713
|
-
getStringIndexImportIndex() {
|
|
1714
|
-
return this.getOrAddFuncImport(
|
|
1715
|
-
"env",
|
|
1716
|
-
"str_index",
|
|
1717
|
-
["externref", "externref"],
|
|
1718
|
-
["i32"],
|
|
1719
|
-
);
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
getStringLastIndexImportIndex() {
|
|
1723
|
-
return this.getOrAddFuncImport(
|
|
1724
|
-
"env",
|
|
1725
|
-
"str_last_index",
|
|
1726
|
-
["externref", "externref"],
|
|
1727
|
-
["i32"],
|
|
1728
|
-
);
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
|
-
getStringRepeatImportIndex() {
|
|
1732
|
-
return this.getOrAddFuncImport(
|
|
1733
|
-
"env",
|
|
1734
|
-
"str_repeat",
|
|
1735
|
-
["externref", "i32"],
|
|
1736
|
-
["externref"],
|
|
1737
|
-
);
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
getStringReplaceAllImportIndex() {
|
|
1741
|
-
return this.getOrAddFuncImport(
|
|
1742
|
-
"env",
|
|
1743
|
-
"str_replace_all",
|
|
1744
|
-
["externref", "externref", "externref"],
|
|
1745
|
-
["externref"],
|
|
1746
|
-
);
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
getStringEqualFoldImportIndex() {
|
|
1750
|
-
return this.getOrAddFuncImport(
|
|
1751
|
-
"env",
|
|
1752
|
-
"str_equal_fold",
|
|
1753
|
-
["externref", "externref"],
|
|
1754
|
-
["i32"],
|
|
1755
|
-
);
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
getStringCountImportIndex() {
|
|
1759
|
-
return this.getOrAddFuncImport(
|
|
1760
|
-
"env",
|
|
1761
|
-
"str_count",
|
|
1762
|
-
["externref", "externref"],
|
|
1763
|
-
["i32"],
|
|
1764
|
-
);
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
getStringToValidUTF8ImportIndex() {
|
|
1768
|
-
return this.getOrAddFuncImport(
|
|
1769
|
-
"env",
|
|
1770
|
-
"str_to_valid_utf8",
|
|
1771
|
-
["externref", "externref"],
|
|
1772
|
-
["externref"],
|
|
1773
|
-
);
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
1174
|
getStrFromI64ImportIndex() {
|
|
1777
1175
|
return this.getOrAddFuncImport(
|
|
1778
1176
|
"env",
|
|
@@ -1839,35 +1237,6 @@ export class ModuleEmitter {
|
|
|
1839
1237
|
return this.getOrAddFuncImport("Math", "random", [], ["f64"]);
|
|
1840
1238
|
}
|
|
1841
1239
|
|
|
1842
|
-
// Imports from the STDLIB_IMPORTS table (strings/strconv/utf8/fmt/testing.Run).
|
|
1843
|
-
getStdlibImportIndex(name) {
|
|
1844
|
-
const idx = this.importCache.get(`env.${name}`);
|
|
1845
|
-
if (idx === undefined) throw new Error(`Unknown runtime import: ${name}`);
|
|
1846
|
-
return idx;
|
|
1847
|
-
}
|
|
1848
|
-
|
|
1849
|
-
getTimezoneOffsetImportIndex() {
|
|
1850
|
-
return this.getStdlibImportIndex("time_timezone_offset");
|
|
1851
|
-
}
|
|
1852
|
-
|
|
1853
|
-
// Closure type of `func(*testing.T)` (the t.Run body).
|
|
1854
|
-
getTestingRunClosureType() {
|
|
1855
|
-
return this.getClosureType({
|
|
1856
|
-
kind: "func",
|
|
1857
|
-
params: [{ kind: "pointer", base: { kind: "named", name: "testing.T" } }],
|
|
1858
|
-
returns: [],
|
|
1859
|
-
});
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
// Closure type of `func()` (the t.Cleanup body).
|
|
1863
|
-
getTestingCleanupClosureType() {
|
|
1864
|
-
return this.getClosureType({
|
|
1865
|
-
kind: "func",
|
|
1866
|
-
params: [],
|
|
1867
|
-
returns: [],
|
|
1868
|
-
});
|
|
1869
|
-
}
|
|
1870
|
-
|
|
1871
1240
|
resolveFuncIndex(name) {
|
|
1872
1241
|
return this.funcMap.get(name) ?? null;
|
|
1873
1242
|
}
|
|
@@ -1963,13 +1332,14 @@ export class ModuleEmitter {
|
|
|
1963
1332
|
// Promoted methods on sName
|
|
1964
1333
|
if (sInfo.embeds && sInfo.embeds.length > 0) {
|
|
1965
1334
|
for (const embed of sInfo.embeds) {
|
|
1966
|
-
const
|
|
1335
|
+
const embedType = embed.typeName ?? embed.name;
|
|
1336
|
+
const embedMethodName = `${embedType}.${methodName}`;
|
|
1967
1337
|
if (this.funcMap.has(embedMethodName)) {
|
|
1968
1338
|
const fIdx = this.resolveFuncIndex(embedMethodName);
|
|
1969
1339
|
const paramGoTypes = this.getFuncParamGoTypes(embedMethodName);
|
|
1970
1340
|
const paramWTypes = this.getFuncParamTypes(embedMethodName);
|
|
1971
1341
|
const isPtrRecv = paramGoTypes[0]?.kind === "pointer";
|
|
1972
|
-
const embedSInfo = this.getStructType(
|
|
1342
|
+
const embedSInfo = this.getStructType(embedType);
|
|
1973
1343
|
|
|
1974
1344
|
const ptrKey = `ptr:${sName}`;
|
|
1975
1345
|
if (!seenKeys.has(ptrKey)) {
|
|
@@ -2180,7 +1550,12 @@ export class ModuleEmitter {
|
|
|
2180
1550
|
if (this.checker?.implements?.(ptrType, ifaceResolved)) {
|
|
2181
1551
|
if (!seen.has(sInfo.typeIndex)) {
|
|
2182
1552
|
seen.add(sInfo.typeIndex);
|
|
2183
|
-
|
|
1553
|
+
// A typed nil `*S` is a marker object, which also satisfies it.
|
|
1554
|
+
candidates.push({
|
|
1555
|
+
name: `*${sName}`,
|
|
1556
|
+
typeIndex: sInfo.typeIndex,
|
|
1557
|
+
nilTypeIndex: this.getNilBoxType(ptrType).typeIndex,
|
|
1558
|
+
});
|
|
2184
1559
|
}
|
|
2185
1560
|
}
|
|
2186
1561
|
|