goscript 0.1.3 → 0.1.4
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 +28 -8
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/gotest/runner_test.go +127 -0
- package/compiler/lowering.go +596 -136
- package/compiler/lowering_bench_test.go +350 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/semantic-model-types.go +8 -0
- package/compiler/semantic-model.go +447 -22
- package/compiler/semantic-model_test.go +138 -0
- package/compiler/skeleton_test.go +948 -14
- package/compiler/typescript-emitter.go +19 -2
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.js +5 -0
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +1 -1
- package/dist/gs/builtin/type.js +72 -5
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +3 -3
- package/dist/gs/compress/zlib/index.js +88 -26
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +118 -6
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/io/fs/readdir.js +5 -3
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/io.d.ts +10 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +26 -5
- package/dist/gs/math/bits/index.js +13 -24
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +3 -1
- package/dist/gs/net/http/index.js +18 -1
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +169 -8
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +1 -0
- package/dist/gs/reflect/type.js +80 -51
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +2 -2
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +8 -6
- package/dist/gs/testing/testing.js.map +1 -1
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +45 -0
- package/gs/builtin/slice.ts +7 -0
- package/gs/builtin/type.ts +85 -5
- package/gs/compress/zlib/index.test.ts +97 -0
- package/gs/compress/zlib/index.ts +117 -27
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +8 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +139 -11
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +7 -3
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +114 -52
- package/gs/io/meta.json +7 -1
- package/gs/math/bits/index.ts +52 -28
- package/gs/net/http/index.test.ts +16 -0
- package/gs/net/http/index.ts +19 -2
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/types_js.gs.ts +169 -8
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/type.ts +91 -56
- package/gs/reflect/typefor.test.ts +31 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +32 -3
- package/gs/testing/testing.ts +13 -10
- package/package.json +1 -1
package/gs/io/io.ts
CHANGED
|
@@ -72,67 +72,111 @@ export interface WriteSeeker extends Writer, Seeker {}
|
|
|
72
72
|
export interface ReadWriteSeeker extends Reader, Writer, Seeker {}
|
|
73
73
|
|
|
74
74
|
class pipeState {
|
|
75
|
-
private chunks: Uint8Array[] = []
|
|
76
|
-
private readOffset = 0
|
|
77
75
|
private readerClosed = false
|
|
78
76
|
private writerClosed = false
|
|
79
77
|
private readerErr: $.GoError = null
|
|
80
78
|
private writerErr: $.GoError = null
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
private pendingReads: Array<{
|
|
80
|
+
data: $.Bytes
|
|
81
|
+
resolve: (result: [number, $.GoError]) => void
|
|
82
|
+
}> = []
|
|
83
|
+
private pendingWrites: Array<{
|
|
84
|
+
data: Uint8Array
|
|
85
|
+
offset: number
|
|
86
|
+
resolve: (result: [number, $.GoError]) => void
|
|
87
|
+
}> = []
|
|
88
|
+
|
|
89
|
+
Read(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
90
|
+
return (async (): Promise<[number, $.GoError]> => {
|
|
91
|
+
if (this.readerClosed) {
|
|
92
|
+
return [0, this.readerErr ?? ErrClosedPipe]
|
|
93
|
+
}
|
|
94
|
+
if ($.len(p) === 0) {
|
|
95
|
+
return [0, null]
|
|
96
|
+
}
|
|
97
|
+
if (this.pendingWrites.length > 0) {
|
|
98
|
+
return this.consumeNextWrite(p)
|
|
99
|
+
}
|
|
90
100
|
if (this.writerClosed) {
|
|
91
101
|
return [0, this.writerErr ?? EOF]
|
|
92
102
|
}
|
|
93
|
-
return [
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
while (copied < $.len(p) && this.chunks.length > 0) {
|
|
98
|
-
const chunk = this.chunks[0]
|
|
99
|
-
const available = chunk.length - this.readOffset
|
|
100
|
-
const want = Math.min($.len(p) - copied, available)
|
|
101
|
-
const target = $.goSlice(p, copied, copied + want)
|
|
102
|
-
$.copy(target, chunk.subarray(this.readOffset, this.readOffset + want))
|
|
103
|
-
copied += want
|
|
104
|
-
this.readOffset += want
|
|
105
|
-
if (this.readOffset === chunk.length) {
|
|
106
|
-
this.chunks.shift()
|
|
107
|
-
this.readOffset = 0
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return [copied, null]
|
|
103
|
+
return await new Promise<[number, $.GoError]>((resolve) => {
|
|
104
|
+
this.pendingReads.push({ data: p, resolve })
|
|
105
|
+
})
|
|
106
|
+
})()
|
|
111
107
|
}
|
|
112
108
|
|
|
113
|
-
Write(p: $.Bytes): [number, $.GoError] {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
Write(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
110
|
+
return (async (): Promise<[number, $.GoError]> => {
|
|
111
|
+
if (this.writerClosed || this.readerClosed) {
|
|
112
|
+
return [0, this.readerErr ?? ErrClosedPipe]
|
|
113
|
+
}
|
|
114
|
+
if ($.len(p) === 0) {
|
|
115
|
+
return [0, null]
|
|
116
|
+
}
|
|
117
|
+
const data = new Uint8Array($.len(p))
|
|
118
|
+
$.copy(data, p)
|
|
119
|
+
return await new Promise<[number, $.GoError]>((resolve) => {
|
|
120
|
+
this.pendingWrites.push({ data, offset: 0, resolve })
|
|
121
|
+
this.drain()
|
|
122
|
+
})
|
|
123
|
+
})()
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
CloseReader(err: $.GoError): $.GoError {
|
|
124
127
|
this.readerClosed = true
|
|
125
128
|
this.readerErr = err
|
|
126
|
-
this.
|
|
127
|
-
this.
|
|
129
|
+
this.resolvePendingReads(ErrClosedPipe)
|
|
130
|
+
this.resolvePendingWrites(ErrClosedPipe)
|
|
128
131
|
return null
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
CloseWriter(err: $.GoError): $.GoError {
|
|
132
135
|
this.writerClosed = true
|
|
133
136
|
this.writerErr = err
|
|
137
|
+
if (this.pendingWrites.length === 0) {
|
|
138
|
+
this.resolvePendingReads(err ?? EOF)
|
|
139
|
+
}
|
|
134
140
|
return null
|
|
135
141
|
}
|
|
142
|
+
|
|
143
|
+
private drain(): void {
|
|
144
|
+
while (this.pendingWrites.length > 0 && this.pendingReads.length > 0) {
|
|
145
|
+
if (this.readerClosed) {
|
|
146
|
+
this.resolvePendingWrites(this.readerErr ?? ErrClosedPipe)
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
const pending = this.pendingReads.shift()!
|
|
150
|
+
pending.resolve(this.consumeNextWrite(pending.data))
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private consumeNextWrite(p: $.Bytes): [number, $.GoError] {
|
|
155
|
+
const pending = this.pendingWrites[0]
|
|
156
|
+
const n = Math.min($.len(p), pending.data.length - pending.offset)
|
|
157
|
+
$.copy(p, pending.data.subarray(pending.offset, pending.offset + n))
|
|
158
|
+
pending.offset += n
|
|
159
|
+
if (pending.offset === pending.data.length) {
|
|
160
|
+
this.pendingWrites.shift()
|
|
161
|
+
pending.resolve([pending.data.length, null])
|
|
162
|
+
if (this.writerClosed && this.pendingWrites.length === 0) {
|
|
163
|
+
this.resolvePendingReads(this.writerErr ?? EOF)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return [n, null]
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private resolvePendingReads(err: $.GoError): void {
|
|
170
|
+
while (this.pendingReads.length > 0) {
|
|
171
|
+
this.pendingReads.shift()!.resolve([0, err])
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private resolvePendingWrites(err: $.GoError): void {
|
|
176
|
+
while (this.pendingWrites.length > 0) {
|
|
177
|
+
this.pendingWrites.shift()!.resolve([0, err])
|
|
178
|
+
}
|
|
179
|
+
}
|
|
136
180
|
}
|
|
137
181
|
|
|
138
182
|
// PipeReader is the read half of a pipe.
|
|
@@ -140,7 +184,7 @@ export class PipeReader implements Reader, Closer {
|
|
|
140
184
|
constructor(private pipe: pipeState) {}
|
|
141
185
|
|
|
142
186
|
Read(data: $.Bytes): [number, $.GoError] {
|
|
143
|
-
return this.pipe.Read(data)
|
|
187
|
+
return this.pipe.Read(data) as any
|
|
144
188
|
}
|
|
145
189
|
|
|
146
190
|
Close(): $.GoError {
|
|
@@ -157,7 +201,7 @@ export class PipeWriter implements Writer, Closer {
|
|
|
157
201
|
constructor(private pipe: pipeState) {}
|
|
158
202
|
|
|
159
203
|
Write(data: $.Bytes): [number, $.GoError] {
|
|
160
|
-
return this.pipe.Write(data)
|
|
204
|
+
return this.pipe.Write(data) as any
|
|
161
205
|
}
|
|
162
206
|
|
|
163
207
|
Close(): $.GoError {
|
|
@@ -235,15 +279,18 @@ class DiscardWriter implements Writer {
|
|
|
235
279
|
export const Discard: Writer | null = new DiscardWriter()
|
|
236
280
|
|
|
237
281
|
// WriteString writes the contents of the string s to w, which accepts a slice of bytes
|
|
238
|
-
export function WriteString(
|
|
282
|
+
export async function WriteString(
|
|
283
|
+
w: Writer,
|
|
284
|
+
s: string,
|
|
285
|
+
): Promise<[number, $.GoError]> {
|
|
239
286
|
// Check if w implements StringWriter interface
|
|
240
287
|
if ('WriteString' in w && typeof (w as any).WriteString === 'function') {
|
|
241
|
-
return (w as StringWriter).WriteString(s)
|
|
288
|
+
return await ((w as StringWriter).WriteString(s) as any)
|
|
242
289
|
}
|
|
243
290
|
|
|
244
291
|
// Convert string to bytes and write
|
|
245
292
|
const bytes = new TextEncoder().encode(s)
|
|
246
|
-
return w.Write(bytes)
|
|
293
|
+
return await (w.Write(bytes) as any)
|
|
247
294
|
}
|
|
248
295
|
|
|
249
296
|
// LimitedReader reads from R but limits the amount of data returned to just N bytes
|
|
@@ -251,7 +298,10 @@ export class LimitedReader implements Reader {
|
|
|
251
298
|
public R: Reader | null
|
|
252
299
|
public N: number
|
|
253
300
|
|
|
254
|
-
constructor(
|
|
301
|
+
constructor(
|
|
302
|
+
r?: Reader | { R?: Reader | null; N?: number } | null,
|
|
303
|
+
n?: number,
|
|
304
|
+
) {
|
|
255
305
|
if (r != null && typeof (r as { Read?: unknown }).Read !== 'function') {
|
|
256
306
|
const init = r as { R?: Reader | null; N?: number }
|
|
257
307
|
this.R = init.R ?? null
|
|
@@ -605,7 +655,15 @@ export async function ReadAll(r: Reader): Promise<[$.Bytes, $.GoError]> {
|
|
|
605
655
|
}
|
|
606
656
|
|
|
607
657
|
// NopCloser returns a ReadCloser with a no-op Close method wrapping the provided Reader r
|
|
608
|
-
export function NopCloser(r: Reader): ReadCloser {
|
|
658
|
+
export function NopCloser(r: Reader | null): ReadCloser {
|
|
659
|
+
if (r == null) {
|
|
660
|
+
return {
|
|
661
|
+
Read: () => {
|
|
662
|
+
throw new Error('nil Reader')
|
|
663
|
+
},
|
|
664
|
+
Close: () => null,
|
|
665
|
+
}
|
|
666
|
+
}
|
|
609
667
|
return {
|
|
610
668
|
Read: r.Read.bind(r),
|
|
611
669
|
Close: () => null,
|
|
@@ -655,22 +713,22 @@ class multiReader implements Reader {
|
|
|
655
713
|
|
|
656
714
|
// MultiWriter creates a writer that duplicates its writes to all the provided writers
|
|
657
715
|
export function MultiWriter(...writers: (Writer | null)[]): Writer {
|
|
658
|
-
return new multiWriter(writers.slice())
|
|
716
|
+
return new multiWriter(writers.slice()) as any
|
|
659
717
|
}
|
|
660
718
|
|
|
661
|
-
class multiWriter
|
|
719
|
+
class multiWriter {
|
|
662
720
|
private writers: (Writer | null)[]
|
|
663
721
|
|
|
664
722
|
constructor(writers: (Writer | null)[]) {
|
|
665
723
|
this.writers = writers
|
|
666
724
|
}
|
|
667
725
|
|
|
668
|
-
Write(p: $.Bytes): [number, $.GoError] {
|
|
726
|
+
async Write(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
669
727
|
for (const w of this.writers) {
|
|
670
728
|
if (w == null) {
|
|
671
729
|
throw new Error('io.MultiWriter: nil writer')
|
|
672
730
|
}
|
|
673
|
-
const [n, err] = w.Write(p)
|
|
731
|
+
const [n, err] = await w.Write(p)
|
|
674
732
|
if (err !== null) {
|
|
675
733
|
return [n, err]
|
|
676
734
|
}
|
|
@@ -697,15 +755,19 @@ class teeReader implements Reader {
|
|
|
697
755
|
}
|
|
698
756
|
|
|
699
757
|
Read(p: $.Bytes): [number, $.GoError] {
|
|
758
|
+
return this.read(p) as any
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
private async read(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
700
762
|
if (this.r == null) {
|
|
701
763
|
throw new Error('io.TeeReader: nil reader')
|
|
702
764
|
}
|
|
703
|
-
const [n, err] = this.r.Read(p)
|
|
765
|
+
const [n, err] = await this.r.Read(p)
|
|
704
766
|
if (n > 0) {
|
|
705
767
|
if (this.w == null) {
|
|
706
768
|
throw new Error('io.TeeReader: nil writer')
|
|
707
769
|
}
|
|
708
|
-
const [nw, ew] = this.w.Write($.goSlice(p, 0, n))
|
|
770
|
+
const [nw, ew] = await this.w.Write($.goSlice(p, 0, n))
|
|
709
771
|
if (ew !== null) {
|
|
710
772
|
return [n, ew]
|
|
711
773
|
}
|
package/gs/io/meta.json
CHANGED
package/gs/math/bits/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// This replaces the auto-generated version that has TypeScript syntax errors
|
|
3
3
|
|
|
4
4
|
// UintSize is the size of a uint in bits
|
|
5
|
-
export const UintSize =
|
|
5
|
+
export const UintSize = 64
|
|
6
6
|
|
|
7
7
|
type Word64 = number | bigint
|
|
8
8
|
|
|
@@ -23,8 +23,8 @@ function word64Result(value: bigint, useBigInt: boolean): Word64 {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// --- Leading zeros ---
|
|
26
|
-
export function LeadingZeros(x:
|
|
27
|
-
return
|
|
26
|
+
export function LeadingZeros(x: Word64): number {
|
|
27
|
+
return LeadingZeros64(x)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export function LeadingZeros8(x: number): number {
|
|
@@ -53,9 +53,8 @@ export function LeadingZeros64(x: Word64): number {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// --- Trailing zeros ---
|
|
56
|
-
export function TrailingZeros(x:
|
|
57
|
-
|
|
58
|
-
return TrailingZeros32(x)
|
|
56
|
+
export function TrailingZeros(x: Word64): number {
|
|
57
|
+
return TrailingZeros64(x)
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
export function TrailingZeros8(x: number): number {
|
|
@@ -90,8 +89,8 @@ export function TrailingZeros64(x: Word64): number {
|
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
// --- Ones count ---
|
|
93
|
-
export function OnesCount(x:
|
|
94
|
-
return
|
|
92
|
+
export function OnesCount(x: Word64): number {
|
|
93
|
+
return OnesCount64(x)
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
export function OnesCount8(x: number): number {
|
|
@@ -124,8 +123,11 @@ export function OnesCount64(x: Word64): number {
|
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
// --- Rotate left ---
|
|
127
|
-
export function RotateLeft(x: number, k: number): number
|
|
128
|
-
|
|
126
|
+
export function RotateLeft(x: number, k: number): number
|
|
127
|
+
export function RotateLeft(x: bigint, k: number): bigint
|
|
128
|
+
export function RotateLeft(x: Word64, k: number): number
|
|
129
|
+
export function RotateLeft(x: Word64, k: number): Word64 {
|
|
130
|
+
return RotateLeft64(x, k)
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
export function RotateLeft8(x: number, k: number): number {
|
|
@@ -151,6 +153,7 @@ export function RotateLeft32(x: number, k: number): number {
|
|
|
151
153
|
|
|
152
154
|
export function RotateLeft64(x: number, k: number): number
|
|
153
155
|
export function RotateLeft64(x: bigint, k: number): bigint
|
|
156
|
+
export function RotateLeft64(x: Word64, k: number): number
|
|
154
157
|
export function RotateLeft64(x: Word64, k: number): Word64 {
|
|
155
158
|
const n = 64
|
|
156
159
|
k = k % n
|
|
@@ -163,8 +166,11 @@ export function RotateLeft64(x: Word64, k: number): Word64 {
|
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
// --- Reverse ---
|
|
166
|
-
export function Reverse(x: number): number
|
|
167
|
-
|
|
169
|
+
export function Reverse(x: number): number
|
|
170
|
+
export function Reverse(x: bigint): bigint
|
|
171
|
+
export function Reverse(x: Word64): number
|
|
172
|
+
export function Reverse(x: Word64): Word64 {
|
|
173
|
+
return Reverse64(x)
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
export function Reverse8(x: number): number {
|
|
@@ -196,6 +202,7 @@ export function Reverse32(x: number): number {
|
|
|
196
202
|
|
|
197
203
|
export function Reverse64(x: number): number
|
|
198
204
|
export function Reverse64(x: bigint): bigint
|
|
205
|
+
export function Reverse64(x: Word64): number
|
|
199
206
|
export function Reverse64(x: Word64): Word64 {
|
|
200
207
|
// Implement 64-bit reverse using similar bit manipulation
|
|
201
208
|
const useBigInt = useBigIntResult(x)
|
|
@@ -226,8 +233,11 @@ export function Reverse64(x: Word64): Word64 {
|
|
|
226
233
|
}
|
|
227
234
|
|
|
228
235
|
// --- ReverseBytes ---
|
|
229
|
-
export function ReverseBytes(x: number): number
|
|
230
|
-
|
|
236
|
+
export function ReverseBytes(x: number): number
|
|
237
|
+
export function ReverseBytes(x: bigint): bigint
|
|
238
|
+
export function ReverseBytes(x: Word64): number
|
|
239
|
+
export function ReverseBytes(x: Word64): Word64 {
|
|
240
|
+
return ReverseBytes64(x)
|
|
231
241
|
}
|
|
232
242
|
|
|
233
243
|
export function ReverseBytes16(x: number): number {
|
|
@@ -247,6 +257,7 @@ export function ReverseBytes32(x: number): number {
|
|
|
247
257
|
|
|
248
258
|
export function ReverseBytes64(x: number): number
|
|
249
259
|
export function ReverseBytes64(x: bigint): bigint
|
|
260
|
+
export function ReverseBytes64(x: Word64): number
|
|
250
261
|
export function ReverseBytes64(x: Word64): Word64 {
|
|
251
262
|
const useBigInt = useBigIntResult(x)
|
|
252
263
|
const word = toUint64(x)
|
|
@@ -266,8 +277,8 @@ export function ReverseBytes64(x: Word64): Word64 {
|
|
|
266
277
|
}
|
|
267
278
|
|
|
268
279
|
// --- Len ---
|
|
269
|
-
export function Len(x:
|
|
270
|
-
return
|
|
280
|
+
export function Len(x: Word64): number {
|
|
281
|
+
return Len64(x)
|
|
271
282
|
}
|
|
272
283
|
|
|
273
284
|
export function Len8(x: number): number {
|
|
@@ -287,8 +298,11 @@ export function Len64(x: Word64): number {
|
|
|
287
298
|
}
|
|
288
299
|
|
|
289
300
|
// --- Multiplication functions ---
|
|
290
|
-
export function Mul(x: number, y: number): [number, number]
|
|
291
|
-
|
|
301
|
+
export function Mul(x: number, y: number): [number, number]
|
|
302
|
+
export function Mul(x: bigint, y: bigint): [bigint, bigint]
|
|
303
|
+
export function Mul(x: Word64, y: Word64): [number, number]
|
|
304
|
+
export function Mul(x: Word64, y: Word64): [Word64, Word64] {
|
|
305
|
+
return Mul64(x, y)
|
|
292
306
|
}
|
|
293
307
|
|
|
294
308
|
export function Mul32(x: number, y: number): [number, number] {
|
|
@@ -301,6 +315,7 @@ export function Mul32(x: number, y: number): [number, number] {
|
|
|
301
315
|
|
|
302
316
|
export function Mul64(x: number, y: number): [number, number]
|
|
303
317
|
export function Mul64(x: bigint, y: bigint): [bigint, bigint]
|
|
318
|
+
export function Mul64(x: Word64, y: Word64): [number, number]
|
|
304
319
|
export function Mul64(x: Word64, y: Word64): [Word64, Word64] {
|
|
305
320
|
const useBigInt = useBigIntResult(x, y)
|
|
306
321
|
x = toUint64(x)
|
|
@@ -309,15 +324,15 @@ export function Mul64(x: Word64, y: Word64): [Word64, Word64] {
|
|
|
309
324
|
const lo = product & uint64Mask
|
|
310
325
|
const hi = product >> 64n
|
|
311
326
|
|
|
312
|
-
return [
|
|
313
|
-
word64Result(hi & uint64Mask, useBigInt),
|
|
314
|
-
word64Result(lo, useBigInt),
|
|
315
|
-
]
|
|
327
|
+
return [word64Result(hi & uint64Mask, useBigInt), word64Result(lo, useBigInt)]
|
|
316
328
|
}
|
|
317
329
|
|
|
318
330
|
// --- Division functions ---
|
|
319
|
-
export function Div(hi: number, lo: number, y: number): [number, number]
|
|
320
|
-
|
|
331
|
+
export function Div(hi: number, lo: number, y: number): [number, number]
|
|
332
|
+
export function Div(hi: bigint, lo: bigint, y: bigint): [bigint, bigint]
|
|
333
|
+
export function Div(hi: Word64, lo: Word64, y: Word64): [number, number]
|
|
334
|
+
export function Div(hi: Word64, lo: Word64, y: Word64): [Word64, Word64] {
|
|
335
|
+
return Div64(hi, lo, y)
|
|
321
336
|
}
|
|
322
337
|
|
|
323
338
|
export function Div32(hi: number, lo: number, y: number): [number, number] {
|
|
@@ -337,6 +352,7 @@ export function Div32(hi: number, lo: number, y: number): [number, number] {
|
|
|
337
352
|
|
|
338
353
|
export function Div64(hi: number, lo: number, y: number): [number, number]
|
|
339
354
|
export function Div64(hi: bigint, lo: bigint, y: bigint): [bigint, bigint]
|
|
355
|
+
export function Div64(hi: Word64, lo: Word64, y: Word64): [number, number]
|
|
340
356
|
export function Div64(hi: Word64, lo: Word64, y: Word64): [Word64, Word64] {
|
|
341
357
|
const useBigInt = useBigIntResult(hi, lo, y)
|
|
342
358
|
hi = toUint64(hi)
|
|
@@ -356,8 +372,11 @@ export function Div64(hi: Word64, lo: Word64, y: Word64): [Word64, Word64] {
|
|
|
356
372
|
}
|
|
357
373
|
|
|
358
374
|
// --- Add and Sub with carry ---
|
|
359
|
-
export function Add(x: number, y: number, carry: number): [number, number]
|
|
360
|
-
|
|
375
|
+
export function Add(x: number, y: number, carry: number): [number, number]
|
|
376
|
+
export function Add(x: bigint, y: bigint, carry: bigint): [bigint, bigint]
|
|
377
|
+
export function Add(x: Word64, y: Word64, carry: Word64): [number, number]
|
|
378
|
+
export function Add(x: Word64, y: Word64, carry: Word64): [Word64, Word64] {
|
|
379
|
+
return Add64(x, y, carry)
|
|
361
380
|
}
|
|
362
381
|
|
|
363
382
|
export function Add32(x: number, y: number, carry: number): [number, number] {
|
|
@@ -369,6 +388,7 @@ export function Add32(x: number, y: number, carry: number): [number, number] {
|
|
|
369
388
|
|
|
370
389
|
export function Add64(x: number, y: number, carry: number): [number, number]
|
|
371
390
|
export function Add64(x: bigint, y: bigint, carry: bigint): [bigint, bigint]
|
|
391
|
+
export function Add64(x: Word64, y: Word64, carry: Word64): [number, number]
|
|
372
392
|
export function Add64(x: Word64, y: Word64, carry: Word64): [Word64, Word64] {
|
|
373
393
|
const useBigInt = useBigIntResult(x, y, carry)
|
|
374
394
|
const sum = toUint64(x) + toUint64(y) + toUint64(carry)
|
|
@@ -377,8 +397,11 @@ export function Add64(x: Word64, y: Word64, carry: Word64): [Word64, Word64] {
|
|
|
377
397
|
return [word64Result(result, useBigInt), word64Result(carryOut, useBigInt)]
|
|
378
398
|
}
|
|
379
399
|
|
|
380
|
-
export function Sub(x: number, y: number, borrow: number): [number, number]
|
|
381
|
-
|
|
400
|
+
export function Sub(x: number, y: number, borrow: number): [number, number]
|
|
401
|
+
export function Sub(x: bigint, y: bigint, borrow: bigint): [bigint, bigint]
|
|
402
|
+
export function Sub(x: Word64, y: Word64, borrow: Word64): [number, number]
|
|
403
|
+
export function Sub(x: Word64, y: Word64, borrow: Word64): [Word64, Word64] {
|
|
404
|
+
return Sub64(x, y, borrow)
|
|
382
405
|
}
|
|
383
406
|
|
|
384
407
|
export function Sub32(x: number, y: number, borrow: number): [number, number] {
|
|
@@ -390,6 +413,7 @@ export function Sub32(x: number, y: number, borrow: number): [number, number] {
|
|
|
390
413
|
|
|
391
414
|
export function Sub64(x: number, y: number, borrow: number): [number, number]
|
|
392
415
|
export function Sub64(x: bigint, y: bigint, borrow: bigint): [bigint, bigint]
|
|
416
|
+
export function Sub64(x: Word64, y: Word64, borrow: Word64): [number, number]
|
|
393
417
|
export function Sub64(x: Word64, y: Word64, borrow: Word64): [Word64, Word64] {
|
|
394
418
|
const useBigInt = useBigIntResult(x, y, borrow)
|
|
395
419
|
const diff = toUint64(x) - toUint64(y) - toUint64(borrow)
|
|
@@ -72,6 +72,22 @@ describe('net/http override', () => {
|
|
|
72
72
|
expect(err?.Error()).toBe('net/http: Client.Do is not implemented in GoScript')
|
|
73
73
|
})
|
|
74
74
|
|
|
75
|
+
it('wraps request body readers and keeps response metadata', () => {
|
|
76
|
+
const reader = {
|
|
77
|
+
Read: (p: Uint8Array) => [p.length, null] as [number, null],
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const [req, reqErr] = NewRequest(MethodPost, 'https://example.invalid/upload', reader)
|
|
81
|
+
|
|
82
|
+
expect(reqErr).toBeNull()
|
|
83
|
+
expect(req!.Body).not.toBeNull()
|
|
84
|
+
expect(req!.Body!.Close()).toBeNull()
|
|
85
|
+
|
|
86
|
+
const resp = new Response({ StatusCode: StatusCreated, ContentLength: -1, Request: varRef(req!) })
|
|
87
|
+
expect(resp.ContentLength).toBe(-1)
|
|
88
|
+
expect((resp.Request as any).value).toBe(req)
|
|
89
|
+
})
|
|
90
|
+
|
|
75
91
|
it('exports the default transport surface', async () => {
|
|
76
92
|
const [req] = NewRequest(MethodPost, 'https://example.invalid', null)
|
|
77
93
|
|
package/gs/net/http/index.ts
CHANGED
|
@@ -259,7 +259,7 @@ export interface ResponseWriter {
|
|
|
259
259
|
export class Request {
|
|
260
260
|
public Method: string
|
|
261
261
|
public URL: any
|
|
262
|
-
public Body: io.
|
|
262
|
+
public Body: io.ReadCloser | null
|
|
263
263
|
public Header: Header
|
|
264
264
|
public ContentLength: number
|
|
265
265
|
public RequestURI: string
|
|
@@ -313,12 +313,16 @@ export class Response {
|
|
|
313
313
|
public StatusCode: number
|
|
314
314
|
public Body: io.ReadCloser | null
|
|
315
315
|
public Header: Header
|
|
316
|
+
public ContentLength: number
|
|
317
|
+
public Request: Request | $.VarRef<Request> | null
|
|
316
318
|
|
|
317
319
|
constructor(init?: Partial<Response>) {
|
|
318
320
|
this.Status = init?.Status ?? ''
|
|
319
321
|
this.StatusCode = init?.StatusCode ?? 0
|
|
320
322
|
this.Body = init?.Body ?? null
|
|
321
323
|
this.Header = init?.Header ?? new Header()
|
|
324
|
+
this.ContentLength = init?.ContentLength ?? 0
|
|
325
|
+
this.Request = init?.Request ?? null
|
|
322
326
|
if (this.Status === '' && this.StatusCode !== 0) {
|
|
323
327
|
const text = StatusText(this.StatusCode)
|
|
324
328
|
this.Status = text === '' ? String(this.StatusCode) : `${this.StatusCode} ${text}`
|
|
@@ -331,6 +335,8 @@ export class Response {
|
|
|
331
335
|
Header: this.Header,
|
|
332
336
|
Status: this.Status,
|
|
333
337
|
StatusCode: this.StatusCode,
|
|
338
|
+
ContentLength: this.ContentLength,
|
|
339
|
+
Request: this.Request,
|
|
334
340
|
})
|
|
335
341
|
}
|
|
336
342
|
}
|
|
@@ -573,9 +579,20 @@ export function NewRequestWithContext(
|
|
|
573
579
|
method = MethodGet
|
|
574
580
|
}
|
|
575
581
|
const parsedURL = parseRequestURL(url)
|
|
576
|
-
return [new Request({ Method: method, URL: parsedURL, Body: body, RequestURI: parsedURL.Path, ctx: _ctx }), null]
|
|
582
|
+
return [new Request({ Method: method, URL: parsedURL, Body: readCloserForBody(body), RequestURI: parsedURL.Path, ctx: _ctx }), null]
|
|
577
583
|
}
|
|
578
584
|
|
|
579
585
|
export function Get(_url: string): [Response | null, $.GoError] {
|
|
580
586
|
return [null, errors.New('net/http: Get is not implemented in GoScript')]
|
|
581
587
|
}
|
|
588
|
+
|
|
589
|
+
function readCloserForBody(body: io.Reader | null): io.ReadCloser | null {
|
|
590
|
+
if (body == null) {
|
|
591
|
+
return null
|
|
592
|
+
}
|
|
593
|
+
const closer = body as io.Reader & Partial<io.Closer>
|
|
594
|
+
if (typeof closer.Close === 'function') {
|
|
595
|
+
return closer as io.ReadCloser
|
|
596
|
+
}
|
|
597
|
+
return io.NopCloser(body)
|
|
598
|
+
}
|
|
@@ -286,4 +286,56 @@ describe('os stdio', () => {
|
|
|
286
286
|
expect(readSync).toHaveBeenCalledTimes(1)
|
|
287
287
|
expect(writeSync).toHaveBeenCalledTimes(1)
|
|
288
288
|
})
|
|
289
|
+
|
|
290
|
+
it('copies from File without recursing through io.Copy', async () => {
|
|
291
|
+
const readSync = vi
|
|
292
|
+
.fn<(buffer: Uint8Array) => number>()
|
|
293
|
+
.mockImplementationOnce((buffer) => {
|
|
294
|
+
buffer.set([65, 66, 67], 0)
|
|
295
|
+
return 3
|
|
296
|
+
})
|
|
297
|
+
.mockImplementationOnce(() => 0)
|
|
298
|
+
|
|
299
|
+
const file = createHostFile('descriptor-file', 7, { readSync })
|
|
300
|
+
const chunks: number[] = []
|
|
301
|
+
const writer = {
|
|
302
|
+
Write(p: Uint8Array): [number, null] {
|
|
303
|
+
chunks.push(...Array.from(p))
|
|
304
|
+
return [p.length, null]
|
|
305
|
+
},
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const [n, err] = await io.Copy(writer, file)
|
|
309
|
+
|
|
310
|
+
expect(err).toBeNull()
|
|
311
|
+
expect(n).toBe(3)
|
|
312
|
+
expect(Buffer.from(chunks).toString('utf8')).toBe('ABC')
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
it('copies into File without recursing through io.Copy', async () => {
|
|
316
|
+
const writes: number[] = []
|
|
317
|
+
const writeSync = vi.fn((buffer: Uint8Array) => {
|
|
318
|
+
writes.push(...Array.from(buffer))
|
|
319
|
+
return buffer.length
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
let sent = false
|
|
323
|
+
const reader = {
|
|
324
|
+
Read(p: Uint8Array): [number, typeof io.EOF | null] {
|
|
325
|
+
if (sent) {
|
|
326
|
+
return [0, io.EOF]
|
|
327
|
+
}
|
|
328
|
+
sent = true
|
|
329
|
+
p.set([88, 89, 90], 0)
|
|
330
|
+
return [3, null]
|
|
331
|
+
},
|
|
332
|
+
}
|
|
333
|
+
const file = createHostFile('descriptor-file', 7, { writeSync })
|
|
334
|
+
|
|
335
|
+
const [n, err] = await io.Copy(file, reader)
|
|
336
|
+
|
|
337
|
+
expect(err).toBeNull()
|
|
338
|
+
expect(n).toBe(3)
|
|
339
|
+
expect(Buffer.from(writes).toString('utf8')).toBe('XYZ')
|
|
340
|
+
})
|
|
289
341
|
})
|