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
|
@@ -11,7 +11,10 @@ import {
|
|
|
11
11
|
compositeLitIndices,
|
|
12
12
|
compositeLitMaxIndex,
|
|
13
13
|
} from "../../typechecker/types.js";
|
|
14
|
+
import { goTypeName } from "../shared/fmt-types.js";
|
|
15
|
+
import { emitWasmNative } from "./natives.js";
|
|
14
16
|
import {
|
|
17
|
+
getInterfaceMethodList,
|
|
15
18
|
getMapKeyValTypes,
|
|
16
19
|
isAnyType,
|
|
17
20
|
isArrayType,
|
|
@@ -19,6 +22,7 @@ import {
|
|
|
19
22
|
isComplex64,
|
|
20
23
|
isFuncType,
|
|
21
24
|
isMapType,
|
|
25
|
+
isNonEmptyInterface,
|
|
22
26
|
isPointerToStruct,
|
|
23
27
|
isRuneSlice,
|
|
24
28
|
isScalarType,
|
|
@@ -26,7 +30,7 @@ import {
|
|
|
26
30
|
isSliceType,
|
|
27
31
|
isStringType,
|
|
28
32
|
isStructType,
|
|
29
|
-
|
|
33
|
+
isTaggedSliceType,
|
|
30
34
|
toWasmType,
|
|
31
35
|
} from "./types.js";
|
|
32
36
|
|
|
@@ -101,6 +105,15 @@ export class ExprsEmitter {
|
|
|
101
105
|
return;
|
|
102
106
|
}
|
|
103
107
|
|
|
108
|
+
// A defined func or map type with methods is boxed to keep its identity,
|
|
109
|
+
// so interface dispatch can tell it from the plain func or map type.
|
|
110
|
+
if (this._isMethodNamedRef(goType)) {
|
|
111
|
+
const box = this.mod.getIfaceBoxType(this._resolveTestTarget(goType));
|
|
112
|
+
this._emitRawExpr(expr, box.wType);
|
|
113
|
+
this._emitBoxValue(box);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
104
117
|
if (
|
|
105
118
|
isSliceType(goType, this.mod.checker) ||
|
|
106
119
|
isArrayType(goType, this.mod.checker) ||
|
|
@@ -112,6 +125,8 @@ export class ExprsEmitter {
|
|
|
112
125
|
// An array stored in an interface is a copy.
|
|
113
126
|
if (isArrayType(goType, this.mod.checker))
|
|
114
127
|
this._emitCopyIfValue(expr, goType, refWType);
|
|
128
|
+
if (isTaggedSliceType(goType, this.mod.checker))
|
|
129
|
+
this._emitTagSlice(goType, refWType);
|
|
115
130
|
if (
|
|
116
131
|
isFuncType(goType, this.mod.checker) ||
|
|
117
132
|
isMapType(goType, this.mod.checker)
|
|
@@ -131,6 +146,85 @@ export class ExprsEmitter {
|
|
|
131
146
|
this._emitRawExpr(expr, targetWasmType);
|
|
132
147
|
}
|
|
133
148
|
|
|
149
|
+
// Panics with Go's failed type assertion message: the static interface
|
|
150
|
+
// type, the dynamic type of the value in `anyTmp` and the target type.
|
|
151
|
+
_emitTypeAssertPanic(expr, anyTmp) {
|
|
152
|
+
const checker = this.mod.checker;
|
|
153
|
+
const target = this._resolveTestTarget(expr._type ?? expr.type);
|
|
154
|
+
const iface = isNonEmptyInterface(target, checker);
|
|
155
|
+
this.pushInstruction({ op: "local.get", index: anyTmp });
|
|
156
|
+
if (iface) {
|
|
157
|
+
const names = getInterfaceMethodList(target.underlying ?? target)
|
|
158
|
+
.map((m) => m.name)
|
|
159
|
+
.sort();
|
|
160
|
+
this._pushStringConst(names[0] ?? "");
|
|
161
|
+
} else {
|
|
162
|
+
this._pushStringConst(this._assertSrcName(expr.expr?._type));
|
|
163
|
+
}
|
|
164
|
+
this._pushStringConst(
|
|
165
|
+
target.name === "error" ? "error" : goTypeName(target),
|
|
166
|
+
);
|
|
167
|
+
this.pushInstruction({ op: "i32.const", value: iface ? 1 : 0 });
|
|
168
|
+
this.pushInstruction({
|
|
169
|
+
op: "call",
|
|
170
|
+
funcIndex: this.mod.resolveFuncIndex("__ta_fail"),
|
|
171
|
+
});
|
|
172
|
+
this.pushInstruction("unreachable");
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// The static interface type of an assertion operand as Go names it.
|
|
176
|
+
_assertSrcName(srcType) {
|
|
177
|
+
if (!srcType || !isNonEmptyInterface(srcType, this.mod.checker))
|
|
178
|
+
return "interface {}";
|
|
179
|
+
return srcType.name === "error" ? "error" : goTypeName(srcType);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Pushes the interned string `text` as an externref.
|
|
183
|
+
_pushStringConst(text) {
|
|
184
|
+
this.pushInstruction({
|
|
185
|
+
op: "i32.const",
|
|
186
|
+
value: this.mod.internString(text),
|
|
187
|
+
});
|
|
188
|
+
this.pushInstruction({
|
|
189
|
+
op: "call",
|
|
190
|
+
funcIndex: this.mod.getStringImportIndex(),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// The slice on the stack becomes the tagged subtype of its Go type, so a
|
|
195
|
+
// type test can tell `[]byte` from `[]bool` (see getTaggedSliceType). The
|
|
196
|
+
// copy shares the backing array; slice headers are immutable.
|
|
197
|
+
_emitTagSlice(goType, refWType) {
|
|
198
|
+
const tagged = this.mod.getTaggedSliceType(
|
|
199
|
+
goType,
|
|
200
|
+
this._getSliceElemType(goType),
|
|
201
|
+
);
|
|
202
|
+
const base = tagged.base;
|
|
203
|
+
const tmp = this.acquireTemp(refWType);
|
|
204
|
+
this.pushInstruction({ op: "local.tee", index: tmp });
|
|
205
|
+
this.pushInstruction("ref.is_null");
|
|
206
|
+
this.pushInstruction({
|
|
207
|
+
op: "if",
|
|
208
|
+
blockType: { kind: "ref", nullable: true, typeIndex: base.typeIndex },
|
|
209
|
+
});
|
|
210
|
+
this.pushInstruction({ op: "global.get", index: base.emptyGlobalIndex });
|
|
211
|
+
this.pushInstruction("else");
|
|
212
|
+
this.pushInstruction({ op: "local.get", index: tmp });
|
|
213
|
+
this.pushInstruction("end");
|
|
214
|
+
this.pushInstruction({ op: "local.set", index: tmp });
|
|
215
|
+
for (let i = 0; i < 4; i++) {
|
|
216
|
+
this.pushInstruction({ op: "local.get", index: tmp });
|
|
217
|
+
this.pushInstruction({
|
|
218
|
+
op: "struct.get",
|
|
219
|
+
typeIndex: base.typeIndex,
|
|
220
|
+
fieldIndex: i,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
this.pushInstruction({ op: "ref.null", heapType: tagged.tagTypeIndex });
|
|
224
|
+
this.pushInstruction({ op: "struct.new", typeIndex: tagged.typeIndex });
|
|
225
|
+
this.releaseTemp(tmp, refWType);
|
|
226
|
+
}
|
|
227
|
+
|
|
134
228
|
// The nullable ref on the stack becomes an interface value: a nil map, func
|
|
135
229
|
// or pointer turns into the marker of its type (never a nil interface).
|
|
136
230
|
_emitNilAwareAny(goType, expr) {
|
|
@@ -240,7 +334,8 @@ export class ExprsEmitter {
|
|
|
240
334
|
break;
|
|
241
335
|
|
|
242
336
|
case "CallExpr":
|
|
243
|
-
this
|
|
337
|
+
if (!emitWasmNative(this, expr, targetWasmType))
|
|
338
|
+
this.emitCallExpr(expr, targetWasmType);
|
|
244
339
|
break;
|
|
245
340
|
|
|
246
341
|
case "TypeConversion":
|
|
@@ -254,7 +349,6 @@ export class ExprsEmitter {
|
|
|
254
349
|
case "SelectorExpr": {
|
|
255
350
|
const deq = this._dequalify(expr);
|
|
256
351
|
if (deq) this.emitIdent(deq, targetWasmType);
|
|
257
|
-
else if (this._emitPkgConst(expr, targetWasmType)) break;
|
|
258
352
|
else this.emitSelectorExpr(expr);
|
|
259
353
|
break;
|
|
260
354
|
}
|
|
@@ -286,7 +380,7 @@ export class ExprsEmitter {
|
|
|
286
380
|
this._emitTypeTest(targetGoType);
|
|
287
381
|
this.pushInstruction("i32.eqz");
|
|
288
382
|
this.pushInstruction({ op: "if", blockType: "void" });
|
|
289
|
-
this.
|
|
383
|
+
this._emitTypeAssertPanic(expr, anyTmp);
|
|
290
384
|
this.pushInstruction("end");
|
|
291
385
|
|
|
292
386
|
this.pushInstruction({ op: "local.get", index: anyTmp });
|
|
@@ -316,7 +410,7 @@ export class ExprsEmitter {
|
|
|
316
410
|
if (capturedNames.length === 0) {
|
|
317
411
|
this.pushInstruction({ op: "ref.null", heapType: "any" });
|
|
318
412
|
} else {
|
|
319
|
-
const envFields = this._buildEnvFields(capturedNames);
|
|
413
|
+
const envFields = this._buildEnvFields(capturedNames, funcLit);
|
|
320
414
|
const envInfo = this.mod.getEnvType(envFields);
|
|
321
415
|
|
|
322
416
|
for (const field of envFields) {
|
|
@@ -562,55 +656,7 @@ export class ExprsEmitter {
|
|
|
562
656
|
return this._derefStructInfo(operand) ? operand : null;
|
|
563
657
|
}
|
|
564
658
|
|
|
565
|
-
_emitPkgConst(expr, targetWasmType) {
|
|
566
|
-
if (this._isMathConst(expr)) {
|
|
567
|
-
this.emitMathConst(expr.field, targetWasmType);
|
|
568
|
-
return true;
|
|
569
|
-
}
|
|
570
|
-
if (this._isUtf8Const(expr)) {
|
|
571
|
-
this.emitUtf8Const(expr.field, targetWasmType);
|
|
572
|
-
return true;
|
|
573
|
-
}
|
|
574
|
-
if (this._isStrconvConst(expr)) {
|
|
575
|
-
this.emitStrconvConst(expr.field, targetWasmType);
|
|
576
|
-
return true;
|
|
577
|
-
}
|
|
578
|
-
if (this._isPathConst(expr)) {
|
|
579
|
-
this.emitPathConst(expr.field, targetWasmType);
|
|
580
|
-
return true;
|
|
581
|
-
}
|
|
582
|
-
if (this._isIoConst(expr)) {
|
|
583
|
-
this.emitIoConst(expr.field, targetWasmType);
|
|
584
|
-
return true;
|
|
585
|
-
}
|
|
586
|
-
if (this._isOsConst?.(expr)) {
|
|
587
|
-
this.emitOsConst(expr.field, targetWasmType);
|
|
588
|
-
return true;
|
|
589
|
-
}
|
|
590
|
-
if (this._isTimeConst(expr)) {
|
|
591
|
-
this.emitTimeConst(expr.field, targetWasmType);
|
|
592
|
-
return true;
|
|
593
|
-
}
|
|
594
|
-
if (this._isBitsConst?.(expr)) {
|
|
595
|
-
this.emitBitsConst(expr.field, targetWasmType);
|
|
596
|
-
return true;
|
|
597
|
-
}
|
|
598
|
-
if (this._isExtendedPkgConst?.(expr)) {
|
|
599
|
-
this.emitExtendedPkgConst(expr, targetWasmType);
|
|
600
|
-
return true;
|
|
601
|
-
}
|
|
602
|
-
return false;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
659
|
emitSelectorExpr(expr) {
|
|
606
|
-
if (isTestingT(expr.expr?._type) && expr.field === "N") {
|
|
607
|
-
this.emitExpr(expr.expr, "externref");
|
|
608
|
-
this.pushInstruction({
|
|
609
|
-
op: "call",
|
|
610
|
-
funcIndex: this.mod.getStdlibImportIndex("testing_n"),
|
|
611
|
-
});
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
660
|
const structInfo = this._resolveStructInfo(expr.expr);
|
|
615
661
|
if (!structInfo) {
|
|
616
662
|
if (expr.expr?.kind === "Ident" && expr.expr._type?.kind === "namespace")
|
|
@@ -1296,12 +1342,14 @@ export class ExprsEmitter {
|
|
|
1296
1342
|
constIdx < arrayLen
|
|
1297
1343
|
) {
|
|
1298
1344
|
this.emitExpr(baseNode, arrWType);
|
|
1345
|
+
this._emitNilCheck(rawBaseType);
|
|
1299
1346
|
this.pushInstruction({ op: "i32.const", value: constIdx });
|
|
1300
1347
|
return;
|
|
1301
1348
|
}
|
|
1302
1349
|
|
|
1303
1350
|
const arrTmp = this.acquireTemp(arrWType);
|
|
1304
1351
|
this.emitExpr(baseNode, arrWType);
|
|
1352
|
+
this._emitNilCheck(rawBaseType);
|
|
1305
1353
|
this.pushInstruction({ op: "local.tee", index: arrTmp });
|
|
1306
1354
|
this._emitCheckedIndex(indexNode, () => {
|
|
1307
1355
|
this.pushInstruction({ op: "local.get", index: arrTmp });
|
|
@@ -1376,6 +1424,15 @@ export class ExprsEmitter {
|
|
|
1376
1424
|
return null;
|
|
1377
1425
|
}
|
|
1378
1426
|
|
|
1427
|
+
// True when the target wasm type is the `$complex64` struct, whether it is
|
|
1428
|
+
// named or only carries the struct's type index.
|
|
1429
|
+
_isComplex64Target(w) {
|
|
1430
|
+
return (
|
|
1431
|
+
w?.typeName === "$complex64" ||
|
|
1432
|
+
this._complexKindOfWType(w) === "complex64"
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1379
1436
|
emitBasicLit(lit, targetWasmType) {
|
|
1380
1437
|
const targetComplex = this._complexKindOfWType(targetWasmType);
|
|
1381
1438
|
const isTargetComplex64 =
|
|
@@ -1456,7 +1513,7 @@ export class ExprsEmitter {
|
|
|
1456
1513
|
emitImagLit(lit, targetWasmType) {
|
|
1457
1514
|
const is64 =
|
|
1458
1515
|
lit._type?.name === "complex64" ||
|
|
1459
|
-
targetWasmType
|
|
1516
|
+
this._isComplex64Target(targetWasmType);
|
|
1460
1517
|
const complexName = is64 ? "complex64" : "complex128";
|
|
1461
1518
|
const info = this.mod.getComplexType(complexName);
|
|
1462
1519
|
const imVal = Number(lit.value);
|
|
@@ -1681,7 +1738,7 @@ export class ExprsEmitter {
|
|
|
1681
1738
|
const is64 =
|
|
1682
1739
|
isComplex64(expr._type) ||
|
|
1683
1740
|
isComplex64(operand._type) ||
|
|
1684
|
-
targetWasmType
|
|
1741
|
+
this._isComplex64Target(targetWasmType);
|
|
1685
1742
|
const info = this.mod.getComplexType(is64 ? "complex64" : "complex128");
|
|
1686
1743
|
const cWType = {
|
|
1687
1744
|
kind: "ref",
|
|
@@ -1797,6 +1854,7 @@ export class ExprsEmitter {
|
|
|
1797
1854
|
if (!isScalarType(baseGoType, this.mod.checker, this.mod)) {
|
|
1798
1855
|
const baseWType = this.toWasmType(baseGoType);
|
|
1799
1856
|
this.emitExpr(operand, baseWType);
|
|
1857
|
+
this._emitNilCheck(operandGoType);
|
|
1800
1858
|
return;
|
|
1801
1859
|
}
|
|
1802
1860
|
const box = this.mod.getBoxType(baseGoType);
|
|
@@ -2046,7 +2104,7 @@ export class ExprsEmitter {
|
|
|
2046
2104
|
isComplex64(expr._type) ||
|
|
2047
2105
|
isComplex64(left._type) ||
|
|
2048
2106
|
isComplex64(right._type) ||
|
|
2049
|
-
targetWasmType
|
|
2107
|
+
this._isComplex64Target(targetWasmType);
|
|
2050
2108
|
const info = this.mod.getComplexType(is64 ? "complex64" : "complex128");
|
|
2051
2109
|
const f = info.elemWType;
|
|
2052
2110
|
const cWType = {
|
|
@@ -2599,6 +2657,8 @@ export class ExprsEmitter {
|
|
|
2599
2657
|
emitNarrowIntWrap(goType) {
|
|
2600
2658
|
if (!goType) return;
|
|
2601
2659
|
if (goType.kind === "TypeName" || goType.kind === "Ident") {
|
|
2660
|
+
const declared = this.mod.checker?.types?.get(goType.name);
|
|
2661
|
+
if (declared?.kind === "named") return this.emitNarrowIntWrap(declared);
|
|
2602
2662
|
return this.emitNarrowIntWrap({ kind: "basic", name: goType.name });
|
|
2603
2663
|
}
|
|
2604
2664
|
if (goType.kind === "named" && goType.underlying) {
|
|
@@ -2626,7 +2686,14 @@ export class ExprsEmitter {
|
|
|
2626
2686
|
}
|
|
2627
2687
|
|
|
2628
2688
|
emitDivRem(op, left, right, targetWasmType = null) {
|
|
2629
|
-
|
|
2689
|
+
// An untyped constant left operand takes the type of the typed right
|
|
2690
|
+
// one (`(1<<31) % uint32(n)` divides unsigned).
|
|
2691
|
+
const goType =
|
|
2692
|
+
left._type?.kind === "untyped" &&
|
|
2693
|
+
right._type &&
|
|
2694
|
+
right._type.kind !== "untyped"
|
|
2695
|
+
? right._type
|
|
2696
|
+
: left._type;
|
|
2630
2697
|
const wType = targetWasmType ?? toWasmType(goType, this.mod.checker);
|
|
2631
2698
|
|
|
2632
2699
|
if (wType === "f32" || wType === "f64") {
|