goscript 0.1.4 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +7 -0
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript-wasm/main.go +38 -6
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/diagnostic.go +104 -12
- package/compiler/diagnostic_test.go +106 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +354 -44
- package/compiler/gotest/runner_test.go +293 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/index.test.ts +23 -0
- package/compiler/lowered-program.go +33 -24
- package/compiler/lowering.go +746 -194
- package/compiler/lowering_bench_test.go +42 -27
- package/compiler/lowering_internal_test.go +18 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/protobuf-ts-binding.go +567 -0
- package/compiler/protobuf-ts-binding_test.go +402 -0
- package/compiler/runtime-contract.go +4 -0
- package/compiler/runtime-contract_test.go +2 -0
- package/compiler/semantic-model-types.go +9 -4
- package/compiler/semantic-model.go +282 -70
- package/compiler/semantic-model_test.go +82 -1
- package/compiler/service.go +21 -1
- package/compiler/skeleton_test.go +118 -10
- package/compiler/typescript-emitter.go +128 -13
- package/compiler/wasm/compile_test.go +37 -4
- package/compiler/{wasm_api.go → wasm-api.go} +57 -7
- package/dist/gs/builtin/hostio.js +5 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +13 -2
- package/dist/gs/builtin/slice.js +187 -6
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +13 -5
- package/dist/gs/builtin/type.js +153 -60
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +10 -3
- package/dist/gs/compress/zlib/index.js +50 -16
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +101 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +589 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +17 -11
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +4 -2
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +2 -0
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +5 -0
- package/dist/gs/math/bits/index.js +16 -4
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +300 -5
- package/dist/gs/net/http/index.js +1598 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +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.js +1 -1
- package/dist/gs/os/types_js.gs.js.map +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/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +25 -6
- package/dist/gs/reflect/type.js +1475 -228
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.js +9 -5
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.js +7 -6
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/testing/testing.js +55 -13
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/hostio.test.ts +16 -0
- package/gs/builtin/hostio.ts +7 -0
- package/gs/builtin/runtime-contract.test.ts +246 -21
- package/gs/builtin/slice.ts +269 -24
- package/gs/builtin/type.ts +226 -59
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +62 -1
- package/gs/compress/zlib/index.ts +53 -16
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +373 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +893 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +18 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +17 -11
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/byteorder/index.test.ts +2 -2
- package/gs/internal/byteorder/index.ts +2 -2
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.ts +4 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.ts +1 -0
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +23 -4
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +781 -12
- package/gs/net/http/index.ts +1860 -139
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +1 -1
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1961 -317
- package/gs/reflect/typefor.test.ts +530 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.ts +9 -5
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/doc_64.gs.ts +6 -7
- package/gs/sync/atomic/doc_64.test.ts +43 -0
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/syscall/env.ts +29 -14
- package/gs/testing/testing.test.ts +67 -0
- package/gs/testing/testing.ts +87 -19
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
package/gs/builtin/slice.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isOwnedPointerHandle,
|
|
3
|
+
isVarRef,
|
|
4
|
+
varRef,
|
|
5
|
+
type OwnedPointerHandle,
|
|
6
|
+
type VarRef,
|
|
7
|
+
} from './varRef.js'
|
|
2
8
|
|
|
3
9
|
export class GoBinaryString extends String {
|
|
4
10
|
readonly bytes: Uint8Array
|
|
@@ -70,6 +76,14 @@ interface GoSliceObject<T> {
|
|
|
70
76
|
const addressStride = 0x100000000
|
|
71
77
|
let nextAddressBase = 1
|
|
72
78
|
const addressBases = new WeakMap<object, number>()
|
|
79
|
+
const byteAddressBases = new WeakMap<object, number>()
|
|
80
|
+
const byteAddressSources = new globalThis.Map<number, ByteAddressSource>()
|
|
81
|
+
|
|
82
|
+
interface ByteAddressSource {
|
|
83
|
+
byteLength: number
|
|
84
|
+
getByte(offset: number): number
|
|
85
|
+
setByte(offset: number, value: number): void
|
|
86
|
+
}
|
|
73
87
|
|
|
74
88
|
/**
|
|
75
89
|
* SliceProxy is a proxy object for complex slices
|
|
@@ -123,9 +137,7 @@ function wrapSliceProxy<T>(proxy: SliceProxy<T>): SliceProxy<T> {
|
|
|
123
137
|
if (index < meta.length) {
|
|
124
138
|
return meta.backing[meta.offset + index]
|
|
125
139
|
}
|
|
126
|
-
throw new Error(
|
|
127
|
-
`Slice index out of range: ${index} >= ${meta.length}`,
|
|
128
|
-
)
|
|
140
|
+
throw new Error(`Slice index out of range: ${index} >= ${meta.length}`)
|
|
129
141
|
}
|
|
130
142
|
|
|
131
143
|
if (prop === 'length') {
|
|
@@ -147,9 +159,7 @@ function wrapSliceProxy<T>(proxy: SliceProxy<T>): SliceProxy<T> {
|
|
|
147
159
|
target[index] = value // Also update the proxy target for consistency
|
|
148
160
|
return true
|
|
149
161
|
}
|
|
150
|
-
throw new Error(
|
|
151
|
-
`Slice index out of range: ${index} >= ${meta.length}`,
|
|
152
|
-
)
|
|
162
|
+
throw new Error(`Slice index out of range: ${index} >= ${meta.length}`)
|
|
153
163
|
}
|
|
154
164
|
|
|
155
165
|
if (prop === 'length' || prop === '__meta__') {
|
|
@@ -323,7 +333,12 @@ export const makeSlice = <T>(
|
|
|
323
333
|
return new Uint8Array(length) as Slice<T>
|
|
324
334
|
}
|
|
325
335
|
|
|
326
|
-
return byteSliceView(
|
|
336
|
+
return byteSliceView(
|
|
337
|
+
new Uint8Array(actualCapacity),
|
|
338
|
+
0,
|
|
339
|
+
length,
|
|
340
|
+
actualCapacity,
|
|
341
|
+
) as Slice<T>
|
|
327
342
|
}
|
|
328
343
|
|
|
329
344
|
const actualCapacity = capacity === undefined ? length : capacity
|
|
@@ -529,8 +544,7 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
529
544
|
if (s instanceof Uint8Array) {
|
|
530
545
|
const meta = byteSliceMeta(s)
|
|
531
546
|
const metaBacking = meta?.backing as unknown
|
|
532
|
-
const backing =
|
|
533
|
-
metaBacking instanceof Uint8Array ? metaBacking : s
|
|
547
|
+
const backing = metaBacking instanceof Uint8Array ? metaBacking : s
|
|
534
548
|
const baseOffset = meta?.offset ?? 0
|
|
535
549
|
const baseCapacity = meta?.capacity ?? s.length
|
|
536
550
|
const actualLow = low ?? 0
|
|
@@ -997,8 +1011,7 @@ export function append<T>(
|
|
|
997
1011
|
function appendByteSlice(slice: Uint8Array, elements: any[]): Uint8Array {
|
|
998
1012
|
const meta = byteSliceMeta(slice)
|
|
999
1013
|
const metaBacking = meta?.backing as unknown
|
|
1000
|
-
const backing =
|
|
1001
|
-
metaBacking instanceof Uint8Array ? metaBacking : slice
|
|
1014
|
+
const backing = metaBacking instanceof Uint8Array ? metaBacking : slice
|
|
1002
1015
|
const offset = meta?.offset ?? 0
|
|
1003
1016
|
const oldLength = slice.length
|
|
1004
1017
|
const oldCapacity = meta?.capacity ?? oldLength
|
|
@@ -1026,12 +1039,18 @@ function byteElementLength(item: any): number {
|
|
|
1026
1039
|
return len(item as Slice<any>)
|
|
1027
1040
|
}
|
|
1028
1041
|
if (typeof item !== 'number') {
|
|
1029
|
-
throw new Error(
|
|
1042
|
+
throw new Error(
|
|
1043
|
+
'Cannot produce Uint8Array: appended elements contain non-numbers.',
|
|
1044
|
+
)
|
|
1030
1045
|
}
|
|
1031
1046
|
return 1
|
|
1032
1047
|
}
|
|
1033
1048
|
|
|
1034
|
-
function writeByteElements(
|
|
1049
|
+
function writeByteElements(
|
|
1050
|
+
dst: Uint8Array,
|
|
1051
|
+
offset: number,
|
|
1052
|
+
elements: any[],
|
|
1053
|
+
): void {
|
|
1035
1054
|
let cursor = offset
|
|
1036
1055
|
for (const item of elements) {
|
|
1037
1056
|
if (item instanceof Uint8Array) {
|
|
@@ -1054,7 +1073,9 @@ function writeByteElements(dst: Uint8Array, offset: number, elements: any[]): vo
|
|
|
1054
1073
|
continue
|
|
1055
1074
|
}
|
|
1056
1075
|
if (typeof item !== 'number') {
|
|
1057
|
-
throw new Error(
|
|
1076
|
+
throw new Error(
|
|
1077
|
+
'Cannot produce Uint8Array: appended elements contain non-numbers.',
|
|
1078
|
+
)
|
|
1058
1079
|
}
|
|
1059
1080
|
dst[cursor] = item
|
|
1060
1081
|
cursor++
|
|
@@ -1291,7 +1312,7 @@ export function indexRef<T>(
|
|
|
1291
1312
|
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1292
1313
|
)
|
|
1293
1314
|
}
|
|
1294
|
-
|
|
1315
|
+
const ref: VarRef<T> = {
|
|
1295
1316
|
get value() {
|
|
1296
1317
|
return collection[index] as T
|
|
1297
1318
|
},
|
|
@@ -1303,6 +1324,8 @@ export function indexRef<T>(
|
|
|
1303
1324
|
__goCollection: collection,
|
|
1304
1325
|
__goIndex: index,
|
|
1305
1326
|
}
|
|
1327
|
+
ref.__goPointer = collectionPointer(ref, collection, index)
|
|
1328
|
+
return ref
|
|
1306
1329
|
}
|
|
1307
1330
|
if (isComplexSlice(collection)) {
|
|
1308
1331
|
if (index < 0 || index >= collection.__meta__.length) {
|
|
@@ -1311,7 +1334,7 @@ export function indexRef<T>(
|
|
|
1311
1334
|
)
|
|
1312
1335
|
}
|
|
1313
1336
|
const backingIndex = collection.__meta__.offset + index
|
|
1314
|
-
|
|
1337
|
+
const ref: VarRef<T> = {
|
|
1315
1338
|
get value() {
|
|
1316
1339
|
return collection.__meta__.backing[backingIndex]
|
|
1317
1340
|
},
|
|
@@ -1323,6 +1346,8 @@ export function indexRef<T>(
|
|
|
1323
1346
|
__goCollection: collection,
|
|
1324
1347
|
__goIndex: index,
|
|
1325
1348
|
}
|
|
1349
|
+
ref.__goPointer = collectionPointer(ref, collection, index)
|
|
1350
|
+
return ref
|
|
1326
1351
|
}
|
|
1327
1352
|
if (Array.isArray(collection)) {
|
|
1328
1353
|
if (index < 0 || index >= collection.length) {
|
|
@@ -1330,7 +1355,7 @@ export function indexRef<T>(
|
|
|
1330
1355
|
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1331
1356
|
)
|
|
1332
1357
|
}
|
|
1333
|
-
|
|
1358
|
+
const ref: VarRef<T> = {
|
|
1334
1359
|
get value() {
|
|
1335
1360
|
return collection[index]
|
|
1336
1361
|
},
|
|
@@ -1342,10 +1367,40 @@ export function indexRef<T>(
|
|
|
1342
1367
|
__goCollection: collection,
|
|
1343
1368
|
__goIndex: index,
|
|
1344
1369
|
}
|
|
1370
|
+
ref.__goPointer = collectionPointer(ref, collection, index)
|
|
1371
|
+
return ref
|
|
1345
1372
|
}
|
|
1346
1373
|
throw new Error('runtime error: index on unsupported type')
|
|
1347
1374
|
}
|
|
1348
1375
|
|
|
1376
|
+
function collectionPointer<T>(
|
|
1377
|
+
ref: VarRef<T>,
|
|
1378
|
+
collection: Slice<T> | T[] | Uint8Array,
|
|
1379
|
+
index: number,
|
|
1380
|
+
): OwnedPointerHandle<T> {
|
|
1381
|
+
return {
|
|
1382
|
+
__goOwnedPointer: true,
|
|
1383
|
+
__goAddress: () => indexAddress(collection, index),
|
|
1384
|
+
__goRef: () => ref,
|
|
1385
|
+
__goSlice: (length: number) => {
|
|
1386
|
+
if (length < 0) {
|
|
1387
|
+
throw new Error('runtime error: unsafe slice length out of range')
|
|
1388
|
+
}
|
|
1389
|
+
return goSlice(collection as any, index, index + length, index + length)
|
|
1390
|
+
},
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
export function sliceFromOwnedPointer<T>(
|
|
1395
|
+
pointer: OwnedPointerHandle<T>,
|
|
1396
|
+
length: number,
|
|
1397
|
+
): Slice<T> | Uint8Array {
|
|
1398
|
+
if (!isOwnedPointerHandle(pointer) || pointer.__goSlice === undefined) {
|
|
1399
|
+
throw new Error('reflect.SliceAt requires a GoScript-owned pointer')
|
|
1400
|
+
}
|
|
1401
|
+
return pointer.__goSlice(length) as Slice<T> | Uint8Array
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1349
1404
|
/**
|
|
1350
1405
|
* arrayPointerFromIndexRef turns &slice[i] into a pointer to an N-element array
|
|
1351
1406
|
* view. This models unsafe conversions such as (*[64]byte)(unsafe.Pointer(&b[0]))
|
|
@@ -1354,6 +1409,8 @@ export function indexRef<T>(
|
|
|
1354
1409
|
export function arrayPointerFromIndexRef<T>(
|
|
1355
1410
|
ref: VarRef<T>,
|
|
1356
1411
|
length: number,
|
|
1412
|
+
sourceElementByteSize = 1,
|
|
1413
|
+
targetElementByteSize = sourceElementByteSize,
|
|
1357
1414
|
): VarRef<Slice<T> | T[] | Uint8Array> {
|
|
1358
1415
|
const collection = ref.__goCollection as
|
|
1359
1416
|
| Slice<T>
|
|
@@ -1366,12 +1423,25 @@ export function arrayPointerFromIndexRef<T>(
|
|
|
1366
1423
|
)
|
|
1367
1424
|
}
|
|
1368
1425
|
const index = ref.__goIndex ?? 0
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1426
|
+
const view =
|
|
1427
|
+
targetElementByteSize === 1 && sourceElementByteSize > 1 ?
|
|
1428
|
+
byteArrayFromAddress(
|
|
1429
|
+
indexByteAddress(collection, index, sourceElementByteSize),
|
|
1430
|
+
length,
|
|
1431
|
+
)
|
|
1432
|
+
: (goSlice(collection as any, index, index + length) as
|
|
1433
|
+
| Slice<T>
|
|
1434
|
+
| T[]
|
|
1435
|
+
| Uint8Array)
|
|
1436
|
+
return {
|
|
1437
|
+
get value() {
|
|
1438
|
+
return view as Slice<T> | T[] | Uint8Array
|
|
1439
|
+
},
|
|
1440
|
+
set value(value: Slice<T> | T[] | Uint8Array) {
|
|
1441
|
+
copy(view as any, value as any)
|
|
1442
|
+
},
|
|
1443
|
+
__isVarRef: true,
|
|
1444
|
+
}
|
|
1375
1445
|
}
|
|
1376
1446
|
|
|
1377
1447
|
/**
|
|
@@ -1420,6 +1490,181 @@ export function indexAddress<T>(
|
|
|
1420
1490
|
return base + backingIndex
|
|
1421
1491
|
}
|
|
1422
1492
|
|
|
1493
|
+
function uintElementValue(value: unknown, byteSize: number): bigint {
|
|
1494
|
+
const bits = BigInt(byteSize * 8)
|
|
1495
|
+
if (typeof value === 'bigint') {
|
|
1496
|
+
return BigInt.asUintN(Number(bits), value)
|
|
1497
|
+
}
|
|
1498
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
1499
|
+
return BigInt.asUintN(Number(bits), BigInt(Math.trunc(value)))
|
|
1500
|
+
}
|
|
1501
|
+
return 0n
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
function uintElementResult(value: bigint, byteSize: number): number {
|
|
1505
|
+
const normalized = BigInt.asUintN(byteSize * 8, value)
|
|
1506
|
+
if (normalized <= BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
1507
|
+
return Number(normalized)
|
|
1508
|
+
}
|
|
1509
|
+
return normalized as unknown as number
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
function byteAddressBase(backing: object, source: ByteAddressSource): number {
|
|
1513
|
+
let base = byteAddressBases.get(backing)
|
|
1514
|
+
if (base === undefined) {
|
|
1515
|
+
base = nextAddressBase * addressStride
|
|
1516
|
+
nextAddressBase++
|
|
1517
|
+
byteAddressBases.set(backing, base)
|
|
1518
|
+
}
|
|
1519
|
+
byteAddressSources.set(base, source)
|
|
1520
|
+
return base
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
function numericByteSource(
|
|
1524
|
+
backing: number[],
|
|
1525
|
+
elementByteSize: number,
|
|
1526
|
+
): ByteAddressSource {
|
|
1527
|
+
const byteSize = Math.max(1, Math.trunc(elementByteSize))
|
|
1528
|
+
return {
|
|
1529
|
+
byteLength: backing.length * byteSize,
|
|
1530
|
+
getByte(offset: number): number {
|
|
1531
|
+
const elementIndex = Math.trunc(offset / byteSize)
|
|
1532
|
+
const byteOffset = offset % byteSize
|
|
1533
|
+
const value = uintElementValue(backing[elementIndex], byteSize)
|
|
1534
|
+
return Number((value >> BigInt(byteOffset * 8)) & 0xffn)
|
|
1535
|
+
},
|
|
1536
|
+
setByte(offset: number, value: number): void {
|
|
1537
|
+
const elementIndex = Math.trunc(offset / byteSize)
|
|
1538
|
+
const byteOffset = offset % byteSize
|
|
1539
|
+
const shift = BigInt(byteOffset * 8)
|
|
1540
|
+
const mask = 0xffn << shift
|
|
1541
|
+
const current = uintElementValue(backing[elementIndex], byteSize)
|
|
1542
|
+
const next = (current & ~mask) | ((BigInt(value) & 0xffn) << shift)
|
|
1543
|
+
backing[elementIndex] = uintElementResult(next, byteSize)
|
|
1544
|
+
},
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
/**
|
|
1549
|
+
* indexByteAddress returns a byte-addressed synthetic address for unsafe
|
|
1550
|
+
* uintptr arithmetic rooted at a slice or array element.
|
|
1551
|
+
*/
|
|
1552
|
+
export function indexByteAddress<T>(
|
|
1553
|
+
collection: Slice<T> | T[] | Uint8Array,
|
|
1554
|
+
index: number,
|
|
1555
|
+
elementByteSize: number,
|
|
1556
|
+
): number {
|
|
1557
|
+
if (collection === null || collection === undefined) {
|
|
1558
|
+
throw new Error('runtime error: index on nil or undefined collection')
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
if (collection instanceof Uint8Array) {
|
|
1562
|
+
if (index < 0 || index >= collection.length) {
|
|
1563
|
+
throw new Error(
|
|
1564
|
+
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1565
|
+
)
|
|
1566
|
+
}
|
|
1567
|
+
const view = new Uint8Array(collection.buffer)
|
|
1568
|
+
const base = byteAddressBase(collection.buffer, {
|
|
1569
|
+
byteLength: view.length,
|
|
1570
|
+
getByte(offset: number): number {
|
|
1571
|
+
return view[offset]
|
|
1572
|
+
},
|
|
1573
|
+
setByte(offset: number, value: number): void {
|
|
1574
|
+
view[offset] = value
|
|
1575
|
+
},
|
|
1576
|
+
})
|
|
1577
|
+
return base + collection.byteOffset + index
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
if (isComplexSlice(collection)) {
|
|
1581
|
+
if (index < 0 || index >= collection.__meta__.length) {
|
|
1582
|
+
throw new Error(
|
|
1583
|
+
`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`,
|
|
1584
|
+
)
|
|
1585
|
+
}
|
|
1586
|
+
const backing = collection.__meta__.backing as unknown as number[]
|
|
1587
|
+
const byteSize = Math.max(1, Math.trunc(elementByteSize))
|
|
1588
|
+
const base = byteAddressBase(backing, numericByteSource(backing, byteSize))
|
|
1589
|
+
return base + (collection.__meta__.offset + index) * byteSize
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
if (Array.isArray(collection)) {
|
|
1593
|
+
if (index < 0 || index >= collection.length) {
|
|
1594
|
+
throw new Error(
|
|
1595
|
+
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1596
|
+
)
|
|
1597
|
+
}
|
|
1598
|
+
const byteSize = Math.max(1, Math.trunc(elementByteSize))
|
|
1599
|
+
const base = byteAddressBase(
|
|
1600
|
+
collection,
|
|
1601
|
+
numericByteSource(collection as unknown as number[], byteSize),
|
|
1602
|
+
)
|
|
1603
|
+
return base + index * byteSize
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
throw new Error('runtime error: index on unsupported type')
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
/**
|
|
1610
|
+
* unsafePointerRef resolves a byte-addressed synthetic unsafe pointer created
|
|
1611
|
+
* by indexByteAddress back to an addressable byte reference.
|
|
1612
|
+
*/
|
|
1613
|
+
export function unsafePointerRef<T>(address: number | bigint): VarRef<T> {
|
|
1614
|
+
const numericAddress = Number(address)
|
|
1615
|
+
const base = Math.floor(numericAddress / addressStride) * addressStride
|
|
1616
|
+
const source = byteAddressSources.get(base)
|
|
1617
|
+
if (source === undefined) {
|
|
1618
|
+
throw new Error(
|
|
1619
|
+
'unsafe pointer dereference is not supported in JavaScript/TypeScript',
|
|
1620
|
+
)
|
|
1621
|
+
}
|
|
1622
|
+
const offset = numericAddress - base
|
|
1623
|
+
if (offset < 0 || offset >= source.byteLength) {
|
|
1624
|
+
throw new Error('runtime error: unsafe pointer address out of range')
|
|
1625
|
+
}
|
|
1626
|
+
return {
|
|
1627
|
+
get value(): T {
|
|
1628
|
+
return source.getByte(offset) as T
|
|
1629
|
+
},
|
|
1630
|
+
set value(value: T) {
|
|
1631
|
+
source.setByte(offset, value as number)
|
|
1632
|
+
},
|
|
1633
|
+
__isVarRef: true,
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
function byteArrayFromAddress(
|
|
1638
|
+
address: number | bigint,
|
|
1639
|
+
length: number,
|
|
1640
|
+
): number[] {
|
|
1641
|
+
const start = Number(address)
|
|
1642
|
+
const target = new Array<number>(length)
|
|
1643
|
+
return new Proxy(target, {
|
|
1644
|
+
get(arrayTarget, prop, receiver) {
|
|
1645
|
+
const index = sliceIndexProperty(prop)
|
|
1646
|
+
if (index >= 0) {
|
|
1647
|
+
if (index >= length) {
|
|
1648
|
+
throw new Error(`Slice index out of range: ${index} >= ${length}`)
|
|
1649
|
+
}
|
|
1650
|
+
return unsafePointerRef<number>(start + index).value
|
|
1651
|
+
}
|
|
1652
|
+
return Reflect.get(arrayTarget, prop, receiver)
|
|
1653
|
+
},
|
|
1654
|
+
set(arrayTarget, prop, value, receiver) {
|
|
1655
|
+
const index = sliceIndexProperty(prop)
|
|
1656
|
+
if (index >= 0) {
|
|
1657
|
+
if (index >= length) {
|
|
1658
|
+
throw new Error(`Slice index out of range: ${index} >= ${length}`)
|
|
1659
|
+
}
|
|
1660
|
+
unsafePointerRef<number>(start + index).value = value
|
|
1661
|
+
return true
|
|
1662
|
+
}
|
|
1663
|
+
return Reflect.set(arrayTarget, prop, value, receiver)
|
|
1664
|
+
},
|
|
1665
|
+
})
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1423
1668
|
/**
|
|
1424
1669
|
* Converts a string to an array of Unicode code points (runes).
|
|
1425
1670
|
* @param str The input string.
|