goscript 0.2.5 → 0.2.7
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/cmd/goscript/cmd-compile.go +7 -0
- package/cmd/goscript/cmd_compile_test.go +83 -0
- package/compiler/compile-request.go +3 -0
- package/compiler/compiler-cache.go +828 -0
- package/compiler/compiler-cache_test.go +705 -0
- package/compiler/config.go +2 -0
- package/compiler/index.test.ts +26 -1
- package/compiler/index.ts +5 -0
- package/compiler/lowered-program.go +31 -20
- package/compiler/lowering.go +349 -93
- package/compiler/lowering_bench_test.go +1 -0
- package/compiler/override-facts.go +309 -8
- package/compiler/override-parity-verifier.go +45 -1
- package/compiler/override-parity-verifier_test.go +100 -0
- package/compiler/override-registry_test.go +1 -0
- package/compiler/package-graph.go +40 -12
- package/compiler/package-graph_test.go +29 -0
- package/compiler/runtime-contract.go +8 -0
- package/compiler/service.go +98 -11
- package/compiler/skeleton_test.go +110 -14
- package/compiler/typescript-emitter.go +120 -23
- package/dist/compiler/index.d.ts +2 -0
- package/dist/compiler/index.js +3 -0
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/builtin/builtin.d.ts +24 -33
- package/dist/gs/builtin/builtin.js +54 -61
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +1 -0
- package/dist/gs/builtin/hostio.js +1 -1
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/index.d.ts +1 -0
- package/dist/gs/builtin/index.js +1 -0
- package/dist/gs/builtin/index.js.map +1 -1
- package/dist/gs/builtin/panic.d.ts +18 -0
- package/dist/gs/builtin/panic.js +98 -0
- package/dist/gs/builtin/panic.js.map +1 -0
- package/dist/gs/builtin/slice.d.ts +10 -0
- package/dist/gs/builtin/slice.js +110 -53
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.js +15 -3
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +1 -1
- package/dist/gs/builtin/varRef.js +3 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/bytes.gs.js +51 -38
- package/dist/gs/bytes/bytes.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.d.ts +1 -1
- package/dist/gs/bytes/reader.gs.js +6 -7
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/cmp/index.d.ts +1 -1
- package/dist/gs/cmp/index.js +43 -10
- package/dist/gs/cmp/index.js.map +1 -1
- package/dist/gs/context/context.d.ts +2 -2
- package/dist/gs/context/context.js +1 -1
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/embed/index.js +1 -1
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/binary/index.js +201 -8
- package/dist/gs/encoding/binary/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +5 -0
- package/dist/gs/encoding/json/index.js +388 -25
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.js +17 -24
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.js +129 -35
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.js +43 -8
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +2 -2
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/io/fs/format.js +2 -2
- package/dist/gs/io/fs/format.js.map +1 -1
- package/dist/gs/io/fs/fs.d.ts +1 -1
- package/dist/gs/io/fs/fs.js +1 -1
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/io.d.ts +21 -21
- package/dist/gs/io/io.js +49 -50
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.js +26 -8
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/copysign.gs.js +10 -17
- package/dist/gs/math/copysign.gs.js.map +1 -1
- package/dist/gs/math/pow.gs.js +5 -0
- package/dist/gs/math/pow.gs.js.map +1 -1
- package/dist/gs/math/signbit.gs.js +6 -2
- package/dist/gs/math/signbit.gs.js.map +1 -1
- package/dist/gs/mime/index.js +1 -0
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +6 -6
- package/dist/gs/net/http/index.js +507 -43
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/stat.gs.d.ts +2 -2
- package/dist/gs/os/types.gs.d.ts +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +1 -1
- package/dist/gs/os/types_js.gs.js +7 -7
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.d.ts +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/os/zero_copy_posix.gs.d.ts +1 -1
- package/dist/gs/os/zero_copy_posix.gs.js +1 -1
- package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +8 -4
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.js +216 -42
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/match.js +6 -3
- package/dist/gs/path/match.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +5 -4
- package/dist/gs/reflect/type.js +29 -11
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/slices/slices.js +11 -11
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/strconv/atof.gs.js +156 -43
- package/dist/gs/strconv/atof.gs.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.d.ts +3 -2
- package/dist/gs/strconv/atoi.gs.js +86 -67
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/ftoa.gs.js +73 -3
- package/dist/gs/strconv/ftoa.gs.js.map +1 -1
- package/dist/gs/strconv/itoa.gs.d.ts +4 -4
- package/dist/gs/strconv/itoa.gs.js +5 -4
- package/dist/gs/strconv/itoa.gs.js.map +1 -1
- package/dist/gs/strconv/quote.gs.d.ts +1 -1
- package/dist/gs/strconv/quote.gs.js +311 -103
- package/dist/gs/strconv/quote.gs.js.map +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +8 -8
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/strings.js +87 -61
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.d.ts +14 -14
- package/dist/gs/sync/atomic/doc_64.gs.js +10 -10
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +22 -22
- package/dist/gs/sync/atomic/type.gs.js +4 -4
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.js +50 -12
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +6 -6
- package/dist/gs/syscall/fs.js +1 -1
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/time/time.d.ts +18 -18
- package/dist/gs/time/time.js +58 -55
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/tables.d.ts +11 -0
- package/dist/gs/unicode/tables.js +635 -0
- package/dist/gs/unicode/tables.js.map +1 -0
- package/dist/gs/unicode/unicode.d.ts +58 -38
- package/dist/gs/unicode/unicode.js +362 -278
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/go.sum +13 -0
- package/gs/builtin/builtin.ts +83 -93
- package/gs/builtin/hostio.ts +1 -1
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/panic.test.ts +189 -0
- package/gs/builtin/panic.ts +107 -0
- package/gs/builtin/runtime-contract.test.ts +5 -5
- package/gs/builtin/slice.test.ts +23 -0
- package/gs/builtin/slice.ts +133 -95
- package/gs/builtin/type.ts +16 -3
- package/gs/builtin/varRef.ts +4 -2
- package/gs/builtin/wide-int.test.ts +41 -0
- package/gs/bytes/bytes.gs.ts +54 -41
- package/gs/bytes/bytes.test.ts +18 -1
- package/gs/bytes/reader.gs.ts +7 -8
- package/gs/cmp/index.test.ts +55 -0
- package/gs/cmp/index.ts +45 -9
- package/gs/context/context.ts +3 -3
- package/gs/embed/index.ts +2 -2
- package/gs/encoding/binary/index.test.ts +104 -0
- package/gs/encoding/binary/index.ts +259 -11
- package/gs/encoding/json/index.test.ts +107 -0
- package/gs/encoding/json/index.ts +400 -29
- package/gs/errors/errors.test.ts +44 -1
- package/gs/errors/errors.ts +15 -31
- package/gs/fmt/fmt.test.ts +70 -2
- package/gs/fmt/fmt.ts +128 -34
- package/gs/golang.org/x/crypto/cryptobyte/index.ts +1 -1
- package/gs/internal/bytealg/index.test.ts +26 -1
- package/gs/internal/bytealg/index.ts +44 -8
- package/gs/internal/byteorder/index.ts +6 -4
- package/gs/io/fs/format.ts +2 -2
- package/gs/io/fs/fs.ts +2 -2
- package/gs/io/fs/stat.test.ts +2 -2
- package/gs/io/fs/sub.test.ts +2 -2
- package/gs/io/fs/walk.test.ts +2 -2
- package/gs/io/io.test.ts +47 -5
- package/gs/io/io.ts +73 -73
- package/gs/io/limit.test.ts +103 -0
- package/gs/math/bits/index.test.ts +128 -0
- package/gs/math/bits/index.ts +26 -8
- package/gs/math/copysign.gs.test.ts +3 -1
- package/gs/math/copysign.gs.ts +10 -22
- package/gs/math/pow.gs.test.ts +4 -5
- package/gs/math/pow.gs.ts +5 -0
- package/gs/math/signbit.gs.test.ts +2 -1
- package/gs/math/signbit.gs.ts +6 -3
- package/gs/mime/index.ts +1 -0
- package/gs/net/http/index.test.ts +683 -2
- package/gs/net/http/index.ts +598 -57
- package/gs/net/http/meta.json +3 -0
- package/gs/os/stat.gs.ts +2 -2
- package/gs/os/types.gs.ts +2 -2
- package/gs/os/types_js.gs.ts +9 -9
- package/gs/os/types_unix.gs.ts +2 -2
- package/gs/os/zero_copy_posix.gs.ts +2 -2
- package/gs/path/filepath/match.test.ts +16 -0
- package/gs/path/filepath/match.ts +8 -4
- package/gs/path/filepath/path.test.ts +91 -9
- package/gs/path/filepath/path.ts +223 -49
- package/gs/path/match.test.ts +32 -0
- package/gs/path/match.ts +6 -3
- package/gs/reflect/deepequal.test.ts +1 -1
- package/gs/reflect/field.test.ts +1 -1
- package/gs/reflect/function-types.test.ts +6 -6
- package/gs/reflect/sliceat.test.ts +13 -13
- package/gs/reflect/structof.test.ts +4 -4
- package/gs/reflect/type.ts +34 -14
- package/gs/reflect/typefor.test.ts +5 -5
- package/gs/runtime/pprof/index.test.ts +20 -0
- package/gs/runtime/trace/index.test.ts +3 -0
- package/gs/slices/slices.test.ts +31 -0
- package/gs/slices/slices.ts +11 -11
- package/gs/strconv/append.test.ts +99 -0
- package/gs/strconv/atof.gs.ts +156 -42
- package/gs/strconv/atof.test.ts +45 -0
- package/gs/strconv/atoi.gs.ts +87 -69
- package/gs/strconv/atoi.test.ts +49 -0
- package/gs/strconv/ftoa.gs.ts +85 -10
- package/gs/strconv/ftoa.test.ts +43 -0
- package/gs/strconv/itoa.gs.ts +10 -9
- package/gs/strconv/quote.gs.ts +335 -108
- package/gs/strconv/quote.test.ts +111 -0
- package/gs/strings/reader.test.ts +10 -10
- package/gs/strings/reader.ts +9 -9
- package/gs/strings/strings.test.ts +18 -5
- package/gs/strings/strings.ts +81 -68
- package/gs/sync/atomic/doc_64.gs.ts +24 -24
- package/gs/sync/atomic/doc_64.test.ts +5 -5
- package/gs/sync/atomic/type.gs.ts +28 -28
- package/gs/sync/sync.test.ts +109 -1
- package/gs/sync/sync.ts +46 -12
- package/gs/syscall/fs.ts +8 -8
- package/gs/syscall/net.test.ts +1 -1
- package/gs/time/parse.test.ts +45 -0
- package/gs/time/time.test.ts +46 -23
- package/gs/time/time.ts +69 -66
- package/gs/unicode/gen.go +198 -0
- package/gs/unicode/tables.ts +646 -0
- package/gs/unicode/unicode.test.ts +69 -0
- package/gs/unicode/unicode.ts +396 -312
- package/package.json +2 -2
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +0 -20
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +0 -134
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +0 -30
- package/gs/github.com/aperturerobotics/util/conc/index.ts +0 -172
- package/gs/github.com/aperturerobotics/util/conc/meta.json +0 -9
package/gs/builtin/slice.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { runtimePanic } from './panic.js'
|
|
1
2
|
import {
|
|
2
3
|
isOwnedPointerHandle,
|
|
3
4
|
isVarRef,
|
|
@@ -123,6 +124,18 @@ export type Slice<T> =
|
|
|
123
124
|
| null
|
|
124
125
|
| (T extends number ? Uint8Array : never)
|
|
125
126
|
|
|
127
|
+
// outOfRangeIndex panics with Go's index-out-of-range runtime message. Go omits
|
|
128
|
+
// the "with length" suffix for negative indices and includes it otherwise, so
|
|
129
|
+
// callers route every element bounds failure through here to stay byte-faithful.
|
|
130
|
+
function outOfRangeIndex(index: number, length: number): never {
|
|
131
|
+
if (index < 0) {
|
|
132
|
+
runtimePanic(`runtime error: index out of range [${index}]`)
|
|
133
|
+
}
|
|
134
|
+
runtimePanic(
|
|
135
|
+
`runtime error: index out of range [${index}] with length ${length}`,
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
126
139
|
/**
|
|
127
140
|
* wrapSliceProxy wraps a SliceProxy in a Proxy to intercept index access
|
|
128
141
|
* and route it through the backing array.
|
|
@@ -137,7 +150,7 @@ function wrapSliceProxy<T>(proxy: SliceProxy<T>): SliceProxy<T> {
|
|
|
137
150
|
if (index < meta.length) {
|
|
138
151
|
return meta.backing[meta.offset + index]
|
|
139
152
|
}
|
|
140
|
-
|
|
153
|
+
outOfRangeIndex(index, meta.length)
|
|
141
154
|
}
|
|
142
155
|
|
|
143
156
|
if (prop === 'length') {
|
|
@@ -159,7 +172,7 @@ function wrapSliceProxy<T>(proxy: SliceProxy<T>): SliceProxy<T> {
|
|
|
159
172
|
target[index] = value // Also update the proxy target for consistency
|
|
160
173
|
return true
|
|
161
174
|
}
|
|
162
|
-
|
|
175
|
+
outOfRangeIndex(index, meta.length)
|
|
163
176
|
}
|
|
164
177
|
|
|
165
178
|
if (prop === 'length' || prop === '__meta__') {
|
|
@@ -222,8 +235,8 @@ export function sliceToArray<T>(
|
|
|
222
235
|
typeHint?: string,
|
|
223
236
|
): T[] | Uint8Array {
|
|
224
237
|
if (len(slice) < length) {
|
|
225
|
-
|
|
226
|
-
`runtime error: cannot convert slice with length ${len(slice)} to array with length ${length}`,
|
|
238
|
+
runtimePanic(
|
|
239
|
+
`runtime error: cannot convert slice with length ${len(slice)} to array or pointer to array with length ${length}`,
|
|
227
240
|
)
|
|
228
241
|
}
|
|
229
242
|
if (typeHint === 'byte') {
|
|
@@ -240,8 +253,8 @@ export function sliceToArrayPointer<T>(
|
|
|
240
253
|
typeHint?: string,
|
|
241
254
|
): VarRef<T[] | Uint8Array> {
|
|
242
255
|
if (len(slice) < length) {
|
|
243
|
-
|
|
244
|
-
`runtime error: cannot convert slice with length ${len(slice)} to array pointer with length ${length}`,
|
|
256
|
+
runtimePanic(
|
|
257
|
+
`runtime error: cannot convert slice with length ${len(slice)} to array or pointer to array with length ${length}`,
|
|
245
258
|
)
|
|
246
259
|
}
|
|
247
260
|
if (typeHint === 'byte') {
|
|
@@ -323,8 +336,10 @@ export const makeSlice = <T>(
|
|
|
323
336
|
if (typeHint === 'byte') {
|
|
324
337
|
const actualCapacity = capacity === undefined ? length : capacity
|
|
325
338
|
if (length < 0 || actualCapacity < 0 || length > actualCapacity) {
|
|
326
|
-
|
|
327
|
-
|
|
339
|
+
runtimePanic(
|
|
340
|
+
actualCapacity < 0 ?
|
|
341
|
+
'runtime error: makeslice: cap out of range'
|
|
342
|
+
: 'runtime error: makeslice: len out of range',
|
|
328
343
|
)
|
|
329
344
|
}
|
|
330
345
|
|
|
@@ -343,8 +358,10 @@ export const makeSlice = <T>(
|
|
|
343
358
|
|
|
344
359
|
const actualCapacity = capacity === undefined ? length : capacity
|
|
345
360
|
if (length < 0 || actualCapacity < 0 || length > actualCapacity) {
|
|
346
|
-
|
|
347
|
-
|
|
361
|
+
runtimePanic(
|
|
362
|
+
actualCapacity < 0 ?
|
|
363
|
+
'runtime error: makeslice: cap out of range'
|
|
364
|
+
: 'runtime error: makeslice: len out of range',
|
|
348
365
|
)
|
|
349
366
|
}
|
|
350
367
|
|
|
@@ -399,7 +416,7 @@ export const makeSlice = <T>(
|
|
|
399
416
|
if (index < target.__meta__.length) {
|
|
400
417
|
return target.__meta__.backing[target.__meta__.offset + index]
|
|
401
418
|
}
|
|
402
|
-
|
|
419
|
+
runtimePanic(
|
|
403
420
|
`Slice index out of range: ${index} >= ${target.__meta__.length}`,
|
|
404
421
|
)
|
|
405
422
|
}
|
|
@@ -423,7 +440,7 @@ export const makeSlice = <T>(
|
|
|
423
440
|
target[index] = value // Also update the proxy target for consistency
|
|
424
441
|
return true
|
|
425
442
|
}
|
|
426
|
-
|
|
443
|
+
runtimePanic(
|
|
427
444
|
`Slice index out of range: ${index} >= ${target.__meta__.length}`,
|
|
428
445
|
)
|
|
429
446
|
}
|
|
@@ -480,7 +497,7 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
480
497
|
if (index < target.__meta__.length) {
|
|
481
498
|
return target.__meta__.backing[target.__meta__.offset + index]
|
|
482
499
|
}
|
|
483
|
-
|
|
500
|
+
runtimePanic(
|
|
484
501
|
`Slice index out of range: ${index} >= ${target.__meta__.length}`,
|
|
485
502
|
)
|
|
486
503
|
}
|
|
@@ -528,7 +545,7 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
528
545
|
target.__meta__.length++
|
|
529
546
|
return true
|
|
530
547
|
}
|
|
531
|
-
|
|
548
|
+
runtimePanic(
|
|
532
549
|
`Slice index out of range: ${index} >= ${target.__meta__.length}`,
|
|
533
550
|
)
|
|
534
551
|
}
|
|
@@ -556,8 +573,8 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
556
573
|
actualLow > baseCapacity ||
|
|
557
574
|
actualHigh > baseCapacity
|
|
558
575
|
) {
|
|
559
|
-
|
|
560
|
-
`
|
|
576
|
+
runtimePanic(
|
|
577
|
+
`runtime error: slice bounds out of range [${actualLow}:${actualHigh}] with capacity ${baseCapacity}`,
|
|
561
578
|
)
|
|
562
579
|
}
|
|
563
580
|
|
|
@@ -566,8 +583,8 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
566
583
|
if (max !== undefined) {
|
|
567
584
|
if (max < actualHigh || max > baseCapacity) {
|
|
568
585
|
// max is relative to the original s.length (capacity)
|
|
569
|
-
|
|
570
|
-
`
|
|
586
|
+
runtimePanic(
|
|
587
|
+
`runtime error: slice bounds out of range [:${actualHigh}:${max}] with capacity ${baseCapacity}`,
|
|
571
588
|
)
|
|
572
589
|
}
|
|
573
590
|
|
|
@@ -594,17 +611,17 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
594
611
|
high = high ?? 0
|
|
595
612
|
|
|
596
613
|
if (low < 0 || high < low) {
|
|
597
|
-
|
|
614
|
+
runtimePanic(`runtime error: slice bounds out of range [${low}:${high}]`)
|
|
598
615
|
}
|
|
599
616
|
|
|
600
617
|
if (low !== 0 || high !== 0) {
|
|
601
|
-
|
|
618
|
+
runtimePanic(
|
|
602
619
|
`runtime error: slice bounds out of range [:${high}] with capacity 0`,
|
|
603
620
|
)
|
|
604
621
|
}
|
|
605
622
|
|
|
606
623
|
if (max !== undefined && max !== 0) {
|
|
607
|
-
|
|
624
|
+
runtimePanic(
|
|
608
625
|
`runtime error: slice bounds out of range [::${max}] with capacity 0`,
|
|
609
626
|
)
|
|
610
627
|
}
|
|
@@ -617,13 +634,13 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
617
634
|
high = high ?? slen
|
|
618
635
|
|
|
619
636
|
if (low < 0 || high < low) {
|
|
620
|
-
|
|
637
|
+
runtimePanic(`runtime error: slice bounds out of range [${low}:${high}]`)
|
|
621
638
|
}
|
|
622
639
|
|
|
623
640
|
// In Go, high can be up to capacity, not just length
|
|
624
641
|
const scap = cap(s)
|
|
625
642
|
if (high > scap) {
|
|
626
|
-
|
|
643
|
+
runtimePanic(`Slice index out of range: ${high} > ${scap}`)
|
|
627
644
|
}
|
|
628
645
|
|
|
629
646
|
if (
|
|
@@ -652,15 +669,13 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
652
669
|
let newCap
|
|
653
670
|
if (max !== undefined) {
|
|
654
671
|
if (max < high) {
|
|
655
|
-
|
|
672
|
+
runtimePanic(`runtime error: slice bounds out of range [:${high}:${max}]`)
|
|
656
673
|
}
|
|
657
674
|
if (isComplexSlice(s) && max > oldOffset + oldCap) {
|
|
658
|
-
|
|
659
|
-
`Slice index out of range: ${max} > ${oldOffset + oldCap}`,
|
|
660
|
-
)
|
|
675
|
+
runtimePanic(`Slice index out of range: ${max} > ${oldOffset + oldCap}`)
|
|
661
676
|
}
|
|
662
677
|
if (!isComplexSlice(s) && max > s.length) {
|
|
663
|
-
|
|
678
|
+
runtimePanic(`Slice index out of range: ${max} > ${s.length}`)
|
|
664
679
|
}
|
|
665
680
|
newCap = max - low
|
|
666
681
|
} else {
|
|
@@ -735,7 +750,7 @@ export const arrayToSlice = <T>(
|
|
|
735
750
|
if (index < target.__meta__.length) {
|
|
736
751
|
return target.__meta__.backing[target.__meta__.offset + index]
|
|
737
752
|
}
|
|
738
|
-
|
|
753
|
+
runtimePanic(
|
|
739
754
|
`Slice index out of range: ${index} >= ${target.__meta__.length}`,
|
|
740
755
|
)
|
|
741
756
|
}
|
|
@@ -781,7 +796,7 @@ export const arrayToSlice = <T>(
|
|
|
781
796
|
target.__meta__.length++
|
|
782
797
|
return true
|
|
783
798
|
}
|
|
784
|
-
|
|
799
|
+
runtimePanic(
|
|
785
800
|
`Slice index out of range: ${index} >= ${target.__meta__.length}`,
|
|
786
801
|
)
|
|
787
802
|
}
|
|
@@ -1330,34 +1345,66 @@ export function index<T>(
|
|
|
1330
1345
|
index: number,
|
|
1331
1346
|
): T | number {
|
|
1332
1347
|
if (collection === null || collection === undefined) {
|
|
1333
|
-
|
|
1348
|
+
runtimePanic('runtime error: index on nil or undefined collection')
|
|
1334
1349
|
}
|
|
1335
1350
|
|
|
1336
1351
|
if (isGoStringValue(collection)) {
|
|
1337
1352
|
return indexString(collection, index) // Use the existing indexString for byte access
|
|
1338
1353
|
} else if (collection instanceof Uint8Array) {
|
|
1339
1354
|
if (index < 0 || index >= collection.length) {
|
|
1340
|
-
|
|
1341
|
-
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1342
|
-
)
|
|
1355
|
+
outOfRangeIndex(index, collection.length)
|
|
1343
1356
|
}
|
|
1344
1357
|
return collection[index]
|
|
1345
1358
|
} else if (isComplexSlice(collection)) {
|
|
1346
1359
|
if (index < 0 || index >= collection.__meta__.length) {
|
|
1347
|
-
|
|
1348
|
-
`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`,
|
|
1349
|
-
)
|
|
1360
|
+
outOfRangeIndex(index, collection.__meta__.length)
|
|
1350
1361
|
}
|
|
1351
1362
|
return collection.__meta__.backing[collection.__meta__.offset + index]
|
|
1352
1363
|
} else if (Array.isArray(collection)) {
|
|
1353
1364
|
if (index < 0 || index >= collection.length) {
|
|
1354
|
-
|
|
1355
|
-
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1356
|
-
)
|
|
1365
|
+
outOfRangeIndex(index, collection.length)
|
|
1357
1366
|
}
|
|
1358
1367
|
return collection[index]
|
|
1359
1368
|
}
|
|
1360
|
-
|
|
1369
|
+
runtimePanic('runtime error: index on unsupported type')
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
/**
|
|
1373
|
+
* arrayIndex reads collection[index] with Go bounds-check semantics, panicking
|
|
1374
|
+
* with the Go runtime message when index is out of range. Strings and maps are
|
|
1375
|
+
* lowered through their own helpers, so this covers Go arrays and slices. The
|
|
1376
|
+
* overloads reproduce the element type of a direct collection[index]: a byte
|
|
1377
|
+
* collection yields number, an element slice yields its element type.
|
|
1378
|
+
*/
|
|
1379
|
+
export function arrayIndex(collection: Uint8Array, index: number): number
|
|
1380
|
+
export function arrayIndex<T>(collection: Slice<T> | T[], index: number): T
|
|
1381
|
+
export function arrayIndex<T>(
|
|
1382
|
+
collection: Slice<T> | T[] | Uint8Array,
|
|
1383
|
+
index: number,
|
|
1384
|
+
): T | number {
|
|
1385
|
+
if (collection === null || collection === undefined) {
|
|
1386
|
+
outOfRangeIndex(index, 0)
|
|
1387
|
+
}
|
|
1388
|
+
if (collection instanceof Uint8Array) {
|
|
1389
|
+
if (index < 0 || index >= collection.length) {
|
|
1390
|
+
outOfRangeIndex(index, collection.length)
|
|
1391
|
+
}
|
|
1392
|
+
return collection[index]
|
|
1393
|
+
}
|
|
1394
|
+
if (isComplexSlice(collection)) {
|
|
1395
|
+
const length = collection.__meta__.length
|
|
1396
|
+
if (index < 0 || index >= length) {
|
|
1397
|
+
outOfRangeIndex(index, length)
|
|
1398
|
+
}
|
|
1399
|
+
return collection.__meta__.backing[collection.__meta__.offset + index]
|
|
1400
|
+
}
|
|
1401
|
+
if (Array.isArray(collection)) {
|
|
1402
|
+
if (index < 0 || index >= collection.length) {
|
|
1403
|
+
outOfRangeIndex(index, collection.length)
|
|
1404
|
+
}
|
|
1405
|
+
return collection[index]
|
|
1406
|
+
}
|
|
1407
|
+
runtimePanic('runtime error: index on unsupported type')
|
|
1361
1408
|
}
|
|
1362
1409
|
|
|
1363
1410
|
/**
|
|
@@ -1368,13 +1415,11 @@ export function indexRef<T>(
|
|
|
1368
1415
|
index: number,
|
|
1369
1416
|
): VarRef<T> {
|
|
1370
1417
|
if (collection === null || collection === undefined) {
|
|
1371
|
-
|
|
1418
|
+
runtimePanic('runtime error: index on nil or undefined collection')
|
|
1372
1419
|
}
|
|
1373
1420
|
if (collection instanceof Uint8Array) {
|
|
1374
1421
|
if (index < 0 || index >= collection.length) {
|
|
1375
|
-
|
|
1376
|
-
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1377
|
-
)
|
|
1422
|
+
outOfRangeIndex(index, collection.length)
|
|
1378
1423
|
}
|
|
1379
1424
|
const ref: VarRef<T> = {
|
|
1380
1425
|
get value() {
|
|
@@ -1393,9 +1438,7 @@ export function indexRef<T>(
|
|
|
1393
1438
|
}
|
|
1394
1439
|
if (isComplexSlice(collection)) {
|
|
1395
1440
|
if (index < 0 || index >= collection.__meta__.length) {
|
|
1396
|
-
|
|
1397
|
-
`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`,
|
|
1398
|
-
)
|
|
1441
|
+
outOfRangeIndex(index, collection.__meta__.length)
|
|
1399
1442
|
}
|
|
1400
1443
|
const backingIndex = collection.__meta__.offset + index
|
|
1401
1444
|
const ref: VarRef<T> = {
|
|
@@ -1415,9 +1458,7 @@ export function indexRef<T>(
|
|
|
1415
1458
|
}
|
|
1416
1459
|
if (Array.isArray(collection)) {
|
|
1417
1460
|
if (index < 0 || index >= collection.length) {
|
|
1418
|
-
|
|
1419
|
-
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1420
|
-
)
|
|
1461
|
+
outOfRangeIndex(index, collection.length)
|
|
1421
1462
|
}
|
|
1422
1463
|
const ref: VarRef<T> = {
|
|
1423
1464
|
get value() {
|
|
@@ -1434,7 +1475,7 @@ export function indexRef<T>(
|
|
|
1434
1475
|
ref.__goPointer = collectionPointer(ref, collection, index)
|
|
1435
1476
|
return ref
|
|
1436
1477
|
}
|
|
1437
|
-
|
|
1478
|
+
runtimePanic('runtime error: index on unsupported type')
|
|
1438
1479
|
}
|
|
1439
1480
|
|
|
1440
1481
|
function collectionPointer<T>(
|
|
@@ -1448,7 +1489,7 @@ function collectionPointer<T>(
|
|
|
1448
1489
|
__goRef: () => ref,
|
|
1449
1490
|
__goSlice: (length: number) => {
|
|
1450
1491
|
if (length < 0) {
|
|
1451
|
-
|
|
1492
|
+
runtimePanic('runtime error: unsafe slice length out of range')
|
|
1452
1493
|
}
|
|
1453
1494
|
return goSlice(collection as any, index, index + length, index + length)
|
|
1454
1495
|
},
|
|
@@ -1517,7 +1558,7 @@ export function indexAddress<T>(
|
|
|
1517
1558
|
index: number,
|
|
1518
1559
|
): number {
|
|
1519
1560
|
if (collection === null || collection === undefined) {
|
|
1520
|
-
|
|
1561
|
+
runtimePanic('runtime error: index on nil or undefined collection')
|
|
1521
1562
|
}
|
|
1522
1563
|
|
|
1523
1564
|
let backing: object
|
|
@@ -1536,13 +1577,11 @@ export function indexAddress<T>(
|
|
|
1536
1577
|
backingIndex = index
|
|
1537
1578
|
length = collection.length
|
|
1538
1579
|
} else {
|
|
1539
|
-
|
|
1580
|
+
runtimePanic('runtime error: index on unsupported type')
|
|
1540
1581
|
}
|
|
1541
1582
|
|
|
1542
1583
|
if (index < 0 || index >= length) {
|
|
1543
|
-
|
|
1544
|
-
`runtime error: index out of range [${index}] with length ${length}`,
|
|
1545
|
-
)
|
|
1584
|
+
outOfRangeIndex(index, length)
|
|
1546
1585
|
}
|
|
1547
1586
|
|
|
1548
1587
|
let base = addressBases.get(backing)
|
|
@@ -1619,14 +1658,12 @@ export function indexByteAddress<T>(
|
|
|
1619
1658
|
elementByteSize: number,
|
|
1620
1659
|
): number {
|
|
1621
1660
|
if (collection === null || collection === undefined) {
|
|
1622
|
-
|
|
1661
|
+
runtimePanic('runtime error: index on nil or undefined collection')
|
|
1623
1662
|
}
|
|
1624
1663
|
|
|
1625
1664
|
if (collection instanceof Uint8Array) {
|
|
1626
1665
|
if (index < 0 || index >= collection.length) {
|
|
1627
|
-
|
|
1628
|
-
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1629
|
-
)
|
|
1666
|
+
outOfRangeIndex(index, collection.length)
|
|
1630
1667
|
}
|
|
1631
1668
|
const view = new Uint8Array(collection.buffer)
|
|
1632
1669
|
const base = byteAddressBase(collection.buffer, {
|
|
@@ -1643,9 +1680,7 @@ export function indexByteAddress<T>(
|
|
|
1643
1680
|
|
|
1644
1681
|
if (isComplexSlice(collection)) {
|
|
1645
1682
|
if (index < 0 || index >= collection.__meta__.length) {
|
|
1646
|
-
|
|
1647
|
-
`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`,
|
|
1648
|
-
)
|
|
1683
|
+
outOfRangeIndex(index, collection.__meta__.length)
|
|
1649
1684
|
}
|
|
1650
1685
|
const backing = collection.__meta__.backing as unknown as number[]
|
|
1651
1686
|
const byteSize = Math.max(1, Math.trunc(elementByteSize))
|
|
@@ -1655,9 +1690,7 @@ export function indexByteAddress<T>(
|
|
|
1655
1690
|
|
|
1656
1691
|
if (Array.isArray(collection)) {
|
|
1657
1692
|
if (index < 0 || index >= collection.length) {
|
|
1658
|
-
|
|
1659
|
-
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1660
|
-
)
|
|
1693
|
+
outOfRangeIndex(index, collection.length)
|
|
1661
1694
|
}
|
|
1662
1695
|
const byteSize = Math.max(1, Math.trunc(elementByteSize))
|
|
1663
1696
|
const base = byteAddressBase(
|
|
@@ -1667,7 +1700,7 @@ export function indexByteAddress<T>(
|
|
|
1667
1700
|
return base + index * byteSize
|
|
1668
1701
|
}
|
|
1669
1702
|
|
|
1670
|
-
|
|
1703
|
+
runtimePanic('runtime error: index on unsupported type')
|
|
1671
1704
|
}
|
|
1672
1705
|
|
|
1673
1706
|
/**
|
|
@@ -1685,7 +1718,7 @@ export function unsafePointerRef<T>(address: number | bigint): VarRef<T> {
|
|
|
1685
1718
|
}
|
|
1686
1719
|
const offset = numericAddress - base
|
|
1687
1720
|
if (offset < 0 || offset >= source.byteLength) {
|
|
1688
|
-
|
|
1721
|
+
runtimePanic('runtime error: unsafe pointer address out of range')
|
|
1689
1722
|
}
|
|
1690
1723
|
return {
|
|
1691
1724
|
get value(): T {
|
|
@@ -1709,7 +1742,7 @@ function byteArrayFromAddress(
|
|
|
1709
1742
|
const index = sliceIndexProperty(prop)
|
|
1710
1743
|
if (index >= 0) {
|
|
1711
1744
|
if (index >= length) {
|
|
1712
|
-
|
|
1745
|
+
runtimePanic(`Slice index out of range: ${index} >= ${length}`)
|
|
1713
1746
|
}
|
|
1714
1747
|
return unsafePointerRef<number>(start + index).value
|
|
1715
1748
|
}
|
|
@@ -1719,7 +1752,7 @@ function byteArrayFromAddress(
|
|
|
1719
1752
|
const index = sliceIndexProperty(prop)
|
|
1720
1753
|
if (index >= 0) {
|
|
1721
1754
|
if (index >= length) {
|
|
1722
|
-
|
|
1755
|
+
runtimePanic(`Slice index out of range: ${index} >= ${length}`)
|
|
1723
1756
|
}
|
|
1724
1757
|
unsafePointerRef<number>(start + index).value = value
|
|
1725
1758
|
return true
|
|
@@ -1773,7 +1806,26 @@ export const stringToRune = (str: string): number => {
|
|
|
1773
1806
|
* @returns The resulting string.
|
|
1774
1807
|
*/
|
|
1775
1808
|
export const runesToString = (runes: Slice<number>): string => {
|
|
1776
|
-
|
|
1809
|
+
if (!runes?.length) {
|
|
1810
|
+
return ''
|
|
1811
|
+
}
|
|
1812
|
+
let out = ''
|
|
1813
|
+
for (const r of runes) {
|
|
1814
|
+
out += runeToString(r)
|
|
1815
|
+
}
|
|
1816
|
+
return out
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
// runeToString encodes one rune as Go's string(rune) does: a valid Unicode
|
|
1820
|
+
// scalar value becomes its character including code points above U+FFFF (astral
|
|
1821
|
+
// planes), and a negative, out-of-range, or surrogate rune becomes U+FFFD
|
|
1822
|
+
// (utf8.RuneError), never a throw. String.fromCharCode truncated astral runes to
|
|
1823
|
+
// a single broken UTF-16 unit; String.fromCodePoint preserves the full rune.
|
|
1824
|
+
export function runeToString(r: number): string {
|
|
1825
|
+
if (r < 0 || r > 0x10ffff || (r >= 0xd800 && r <= 0xdfff)) {
|
|
1826
|
+
return '�'
|
|
1827
|
+
}
|
|
1828
|
+
return String.fromCodePoint(r)
|
|
1777
1829
|
}
|
|
1778
1830
|
|
|
1779
1831
|
/**
|
|
@@ -1802,30 +1854,22 @@ export const indexString = (
|
|
|
1802
1854
|
// Bytes - access directly
|
|
1803
1855
|
if (str instanceof Uint8Array) {
|
|
1804
1856
|
if (index < 0 || index >= str.length) {
|
|
1805
|
-
|
|
1806
|
-
`runtime error: index out of range [${index}] with length ${str.length}`,
|
|
1807
|
-
)
|
|
1857
|
+
outOfRangeIndex(index, str.length)
|
|
1808
1858
|
}
|
|
1809
1859
|
return str[index]
|
|
1810
1860
|
}
|
|
1811
1861
|
// Array or null
|
|
1812
1862
|
if (str === null || str === undefined) {
|
|
1813
|
-
|
|
1814
|
-
`runtime error: index out of range [${index}] with length 0`,
|
|
1815
|
-
)
|
|
1863
|
+
outOfRangeIndex(index, 0)
|
|
1816
1864
|
}
|
|
1817
1865
|
if (index < 0 || index >= str.length) {
|
|
1818
|
-
|
|
1819
|
-
`runtime error: index out of range [${index}] with length ${str.length}`,
|
|
1820
|
-
)
|
|
1866
|
+
outOfRangeIndex(index, str.length)
|
|
1821
1867
|
}
|
|
1822
1868
|
return str[index]
|
|
1823
1869
|
}
|
|
1824
1870
|
const bytes = goStringBytes(str)
|
|
1825
1871
|
if (index < 0 || index >= bytes.length) {
|
|
1826
|
-
|
|
1827
|
-
`runtime error: index out of range [${index}] with length ${bytes.length}`,
|
|
1828
|
-
)
|
|
1872
|
+
outOfRangeIndex(index, bytes.length)
|
|
1829
1873
|
}
|
|
1830
1874
|
return bytes[index]
|
|
1831
1875
|
}
|
|
@@ -1871,7 +1915,7 @@ export const sliceString = (
|
|
|
1871
1915
|
) {
|
|
1872
1916
|
return ''
|
|
1873
1917
|
}
|
|
1874
|
-
|
|
1918
|
+
runtimePanic(
|
|
1875
1919
|
`runtime error: slice bounds out of range [${actualLow}:${actualHigh}] with length ${bytes.length}`,
|
|
1876
1920
|
)
|
|
1877
1921
|
}
|
|
@@ -2142,22 +2186,16 @@ export function indexStringOrBytes(
|
|
|
2142
2186
|
} else if (value instanceof Uint8Array) {
|
|
2143
2187
|
// For Uint8Array, direct access returns the byte value
|
|
2144
2188
|
if (index < 0 || index >= value.length) {
|
|
2145
|
-
|
|
2146
|
-
`runtime error: index out of range [${index}] with length ${value.length}`,
|
|
2147
|
-
)
|
|
2189
|
+
outOfRangeIndex(index, value.length)
|
|
2148
2190
|
}
|
|
2149
2191
|
return value[index]
|
|
2150
2192
|
} else if (value === null) {
|
|
2151
|
-
|
|
2152
|
-
`runtime error: index out of range [${index}] with length 0`,
|
|
2153
|
-
)
|
|
2193
|
+
outOfRangeIndex(index, 0)
|
|
2154
2194
|
} else {
|
|
2155
2195
|
// For Slice<number> (including SliceProxy)
|
|
2156
2196
|
const length = len(value)
|
|
2157
2197
|
if (index < 0 || index >= length) {
|
|
2158
|
-
|
|
2159
|
-
`runtime error: index out of range [${index}] with length ${length}`,
|
|
2160
|
-
)
|
|
2198
|
+
outOfRangeIndex(index, length)
|
|
2161
2199
|
}
|
|
2162
2200
|
return (value as any)[index] as number
|
|
2163
2201
|
}
|
package/gs/builtin/type.ts
CHANGED
|
@@ -285,6 +285,19 @@ export const registerInterfaceType = (
|
|
|
285
285
|
return typeInfo
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
// The builtin error interface is predeclared in Go. Register it so a bare
|
|
289
|
+
// "error" type assertion (x.(error)), which the compiler emits by the universe
|
|
290
|
+
// type name, resolves to its method set instead of an unmatched basic type. Any
|
|
291
|
+
// value with an Error() string method, including recovered runtime panics,
|
|
292
|
+
// then satisfies it.
|
|
293
|
+
registerInterfaceType('error', null, [
|
|
294
|
+
{
|
|
295
|
+
name: 'Error',
|
|
296
|
+
args: [],
|
|
297
|
+
returns: [{ type: { kind: TypeKind.Basic, name: 'string' } }],
|
|
298
|
+
},
|
|
299
|
+
])
|
|
300
|
+
|
|
288
301
|
/**
|
|
289
302
|
* Gets a registered type by name from the type registry.
|
|
290
303
|
* Returns undefined if the type is not registered.
|
|
@@ -632,20 +645,20 @@ function validateMapKey(key: any, keyTypeInfo: TypeInfo): boolean {
|
|
|
632
645
|
*/
|
|
633
646
|
function matchesBasicType(value: any, info: TypeInfo): boolean {
|
|
634
647
|
if (info.name === 'string') return typeof value === 'string'
|
|
648
|
+
if (info.name === 'int64' || info.name === 'uint64')
|
|
649
|
+
return typeof value === 'bigint'
|
|
635
650
|
if (
|
|
636
651
|
info.name === 'number' ||
|
|
637
652
|
info.name === 'int' ||
|
|
638
653
|
info.name === 'int8' ||
|
|
639
654
|
info.name === 'int16' ||
|
|
640
655
|
info.name === 'int32' ||
|
|
641
|
-
info.name === 'int64' ||
|
|
642
656
|
info.name === 'uint' ||
|
|
657
|
+
info.name === 'uintptr' ||
|
|
643
658
|
info.name === 'uint8' ||
|
|
644
659
|
info.name === 'byte' ||
|
|
645
660
|
info.name === 'uint16' ||
|
|
646
661
|
info.name === 'uint32' ||
|
|
647
|
-
info.name === 'uint64' ||
|
|
648
|
-
info.name === 'uintptr' ||
|
|
649
662
|
info.name === 'float32' ||
|
|
650
663
|
info.name === 'float64'
|
|
651
664
|
)
|
package/gs/builtin/varRef.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { runtimePanic } from './panic.js'
|
|
2
|
+
|
|
1
3
|
export interface OwnedPointerHandle<T = unknown> {
|
|
2
4
|
readonly __goOwnedPointer: true
|
|
3
5
|
__goAddress: () => number
|
|
@@ -126,10 +128,10 @@ export function ownedPointerRef<T>(pointer: OwnedPointerHandle<T>): VarRef<T> {
|
|
|
126
128
|
return pointer.__goRef()
|
|
127
129
|
}
|
|
128
130
|
|
|
129
|
-
/** Dereference a variable reference
|
|
131
|
+
/** Dereference a variable reference; a null ref raises a Go runtime panic. */
|
|
130
132
|
export function unref<T>(b: VarRef<T>): T {
|
|
131
133
|
if (b === null) {
|
|
132
|
-
|
|
134
|
+
runtimePanic(
|
|
133
135
|
'runtime error: invalid memory address or nil pointer dereference',
|
|
134
136
|
)
|
|
135
137
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { uint, uint64, uint64Add, uint64Shr } from './builtin.js'
|
|
4
|
+
|
|
5
|
+
// Go represents uint/uintptr as a TypeScript number, but values above 2^53
|
|
6
|
+
// cannot round-trip through a JS number. uint() keeps those as a runtime bigint
|
|
7
|
+
// (typed number) so full 64-bit width survives, matching Go semantics such as
|
|
8
|
+
// ^uint(0) == 2^64-1. int64/uint64 stay bigint unconditionally.
|
|
9
|
+
describe('uint full 64-bit width (Go uint semantics)', () => {
|
|
10
|
+
const maxUint = 18446744073709551615n // ^uint(0)
|
|
11
|
+
|
|
12
|
+
it('preserves ^uint(0) without precision loss', () => {
|
|
13
|
+
const v = uint(maxUint, 64)
|
|
14
|
+
expect(v).toBe(maxUint as unknown as number)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('keeps small uint values as plain numbers', () => {
|
|
18
|
+
expect(uint(5n, 64)).toBe(5)
|
|
19
|
+
expect(typeof uint(5n, 64)).toBe('number')
|
|
20
|
+
expect(typeof uint(maxUint, 64)).toBe('bigint')
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('right-shifting ^uint(0) yields a 64-bit-wide result, not 0 or 1', () => {
|
|
24
|
+
// uintBitLen-style loop: repeated >>1 from 2^64-1 must count 64 bits.
|
|
25
|
+
let n: number | bigint = uint(maxUint, 64)
|
|
26
|
+
let bits = 0
|
|
27
|
+
while ((n as bigint) !== 0n && (n as number) !== 0) {
|
|
28
|
+
bits++
|
|
29
|
+
n = uint(uint64Shr(n, 1), 64)
|
|
30
|
+
}
|
|
31
|
+
expect(bits).toBe(64)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('uint64 modular wraparound preserves full width', () => {
|
|
35
|
+
// (2^64-1) + 1 wraps to 0 under uint64.
|
|
36
|
+
expect(uint64Add(maxUint, 1n)).toBe(0n)
|
|
37
|
+
// uint64 always yields bigint regardless of magnitude.
|
|
38
|
+
expect(uint64(7)).toBe(7n)
|
|
39
|
+
expect(typeof uint64(7)).toBe('bigint')
|
|
40
|
+
})
|
|
41
|
+
})
|