goscript 0.2.1 → 0.2.3
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/compiler/gotest/runner.go +98 -0
- package/compiler/gotest/runner_test.go +45 -0
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +36 -0
- package/compiler/lowering.go +227 -11
- package/compiler/override-registry_test.go +50 -0
- package/compiler/protobuf-ts-binding.go +155 -7
- package/compiler/protobuf-ts-binding_test.go +116 -2
- package/compiler/runtime-contract.go +2 -0
- package/compiler/runtime-contract_test.go +1 -0
- package/compiler/semantic-model.go +16 -0
- package/compiler/semantic-model_test.go +38 -0
- package/compiler/skeleton_test.go +477 -16
- package/compiler/typescript-emitter.go +4 -0
- package/dist/gs/builtin/builtin.js +7 -9
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/defer.js +2 -2
- package/dist/gs/builtin/hostio.js +5 -5
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/map.js +2 -1
- package/dist/gs/builtin/map.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +3 -0
- package/dist/gs/builtin/slice.js +39 -0
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.js +49 -0
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/compress/zlib/index.js +5 -2
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/aes/index.d.ts +15 -0
- package/dist/gs/crypto/aes/index.js +57 -0
- package/dist/gs/crypto/aes/index.js.map +1 -0
- package/dist/gs/crypto/cipher/index.d.ts +41 -0
- package/dist/gs/crypto/cipher/index.js +255 -0
- package/dist/gs/crypto/cipher/index.js.map +1 -0
- package/dist/gs/crypto/ecdh/index.js +27 -8
- package/dist/gs/crypto/ecdh/index.js.map +1 -1
- package/dist/gs/crypto/ed25519/index.js +3 -3
- package/dist/gs/crypto/ed25519/index.js.map +1 -1
- package/dist/gs/crypto/rand/index.js +6 -3
- package/dist/gs/crypto/rand/index.js.map +1 -1
- package/dist/gs/embed/index.js +9 -3
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +33 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/mr-tron/base58/base58/index.js +4 -1
- package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.d.ts +31 -0
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.js +117 -0
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.js.map +1 -0
- package/dist/gs/golang.org/x/crypto/scrypt/index.d.ts +2 -0
- package/dist/gs/golang.org/x/crypto/scrypt/index.js +39 -0
- package/dist/gs/golang.org/x/crypto/scrypt/index.js.map +1 -0
- package/dist/gs/hash/fnv/index.js +13 -5
- package/dist/gs/hash/fnv/index.js.map +1 -1
- package/dist/gs/io/fs/glob.d.ts +3 -3
- package/dist/gs/io/fs/glob.js +8 -8
- package/dist/gs/io/fs/glob.js.map +1 -1
- package/dist/gs/io/fs/readdir.d.ts +2 -2
- package/dist/gs/io/fs/readdir.js +13 -74
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +4 -4
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/fs/walk.js +1 -1
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.js +18 -2
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.js.map +1 -1
- package/dist/gs/mime/index.js +5 -2
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.js +6 -3
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +16 -4
- package/dist/gs/net/http/index.js +236 -40
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/net/http/pprof/index.js.map +1 -1
- package/dist/gs/reflect/iter.js +1 -1
- package/dist/gs/reflect/iter.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +2 -0
- package/dist/gs/reflect/type.js +53 -21
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/runtime/debug/index.js +2 -1
- package/dist/gs/runtime/debug/index.js.map +1 -1
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +2 -2
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +1 -1
- package/dist/gs/slices/slices.js +37 -4
- package/dist/gs/slices/slices.js.map +1 -1
- package/go.mod +2 -2
- package/go.sum +2 -0
- package/gs/builtin/builtin.ts +11 -14
- package/gs/builtin/defer.ts +2 -2
- package/gs/builtin/hostio.test.ts +8 -3
- package/gs/builtin/hostio.ts +5 -7
- package/gs/builtin/map.ts +4 -1
- package/gs/builtin/slice.test.ts +14 -0
- package/gs/builtin/slice.ts +64 -0
- package/gs/builtin/type.ts +72 -0
- package/gs/bytes/bytes.test.ts +14 -13
- package/gs/compress/zlib/index.test.ts +19 -5
- package/gs/compress/zlib/index.ts +16 -7
- package/gs/context/context.test.ts +3 -1
- package/gs/crypto/aes/index.test.ts +120 -0
- package/gs/crypto/aes/index.ts +76 -0
- package/gs/crypto/cipher/index.ts +345 -0
- package/gs/crypto/cipher/meta.json +6 -0
- package/gs/crypto/ecdh/index.test.ts +6 -2
- package/gs/crypto/ecdh/index.ts +49 -12
- package/gs/crypto/ed25519/index.ts +20 -7
- package/gs/crypto/rand/index.ts +6 -3
- package/gs/embed/index.test.ts +3 -3
- package/gs/embed/index.ts +9 -3
- package/gs/fmt/fmt.test.ts +29 -4
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +126 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +46 -0
- package/gs/github.com/mr-tron/base58/base58/index.ts +9 -3
- package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +2 -8
- package/gs/golang.org/x/crypto/chacha20poly1305/index.test.ts +91 -0
- package/gs/golang.org/x/crypto/chacha20poly1305/index.ts +245 -0
- package/gs/golang.org/x/crypto/scrypt/index.test.ts +81 -0
- package/gs/golang.org/x/crypto/scrypt/index.ts +54 -0
- package/gs/golang.org/x/crypto/scrypt/meta.json +5 -0
- package/gs/hash/fnv/index.test.ts +1 -8
- package/gs/hash/fnv/index.ts +27 -10
- package/gs/io/fs/glob.ts +13 -10
- package/gs/io/fs/meta.json +2 -0
- package/gs/io/fs/readdir.test.ts +63 -2
- package/gs/io/fs/readdir.ts +33 -30
- package/gs/io/fs/sub.ts +4 -4
- package/gs/io/fs/walk.ts +1 -1
- package/gs/io/io.test.ts +56 -1
- package/gs/io/io.ts +19 -2
- package/gs/maps/iter.ts +9 -9
- package/gs/maps/maps.ts +4 -4
- package/gs/math/bits/index.test.ts +10 -1
- package/gs/mime/index.test.ts +33 -15
- package/gs/mime/index.ts +9 -2
- package/gs/net/http/httptest/index.test.ts +17 -3
- package/gs/net/http/httptest/index.ts +8 -3
- package/gs/net/http/index.test.ts +645 -123
- package/gs/net/http/index.ts +548 -113
- package/gs/net/http/pprof/index.ts +24 -6
- package/gs/os/file_unix_js.test.ts +22 -0
- package/gs/reflect/iter.ts +4 -2
- package/gs/reflect/map.test.ts +56 -1
- package/gs/reflect/type.ts +76 -37
- package/gs/runtime/debug/index.test.ts +32 -4
- package/gs/runtime/debug/index.ts +5 -2
- package/gs/runtime/pprof/index.test.ts +7 -1
- package/gs/runtime/pprof/index.ts +5 -1
- package/gs/runtime/runtime.test.ts +7 -0
- package/gs/runtime/runtime.ts +2 -4
- package/gs/runtime/trace/index.test.ts +9 -1
- package/gs/runtime/trace/index.ts +5 -1
- package/gs/slices/meta.json +3 -0
- package/gs/slices/slices.test.ts +59 -21
- package/gs/slices/slices.ts +61 -20
- package/gs/strconv/complex.test.ts +17 -3
- package/gs/sync/atomic/doc_64.test.ts +2 -9
- package/gs/sync/sync.test.ts +18 -8
- package/gs/syscall/js/index.test.ts +9 -4
- package/package.json +13 -5
|
@@ -6,15 +6,24 @@ function writeString(w: http.ResponseWriter | null, value: string): void {
|
|
|
6
6
|
w?.Write($.stringToBytes(value))
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export function Index(
|
|
9
|
+
export function Index(
|
|
10
|
+
w: http.ResponseWriter | null,
|
|
11
|
+
_r: http.Request | $.VarRef<http.Request> | null,
|
|
12
|
+
): void {
|
|
10
13
|
const header = w?.Header()
|
|
11
14
|
if (header != null) {
|
|
12
15
|
http.Header_Set(header, 'Content-Type', 'text/html; charset=utf-8')
|
|
13
16
|
}
|
|
14
|
-
writeString(
|
|
17
|
+
writeString(
|
|
18
|
+
w,
|
|
19
|
+
'<html><body><a href="goroutine?debug=2">full goroutine stack dump</a></body></html>',
|
|
20
|
+
)
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
export function Cmdline(
|
|
23
|
+
export function Cmdline(
|
|
24
|
+
w: http.ResponseWriter | null,
|
|
25
|
+
_r: http.Request | $.VarRef<http.Request> | null,
|
|
26
|
+
): void {
|
|
18
27
|
const header = w?.Header()
|
|
19
28
|
if (header != null) {
|
|
20
29
|
http.Header_Set(header, 'Content-Type', 'text/plain; charset=utf-8')
|
|
@@ -22,7 +31,10 @@ export function Cmdline(w: http.ResponseWriter | null, _r: http.Request | $.VarR
|
|
|
22
31
|
writeString(w, 'goscript')
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
export function Profile(
|
|
34
|
+
export function Profile(
|
|
35
|
+
w: http.ResponseWriter | null,
|
|
36
|
+
_r: http.Request | $.VarRef<http.Request> | null,
|
|
37
|
+
): void {
|
|
26
38
|
const header = w?.Header()
|
|
27
39
|
if (header != null) {
|
|
28
40
|
http.Header_Set(header, 'Content-Type', 'application/octet-stream')
|
|
@@ -30,7 +42,10 @@ export function Profile(w: http.ResponseWriter | null, _r: http.Request | $.VarR
|
|
|
30
42
|
writeString(w, 'cpu profile\n')
|
|
31
43
|
}
|
|
32
44
|
|
|
33
|
-
export function Symbol(
|
|
45
|
+
export function Symbol(
|
|
46
|
+
w: http.ResponseWriter | null,
|
|
47
|
+
_r: http.Request | $.VarRef<http.Request> | null,
|
|
48
|
+
): void {
|
|
34
49
|
const header = w?.Header()
|
|
35
50
|
if (header != null) {
|
|
36
51
|
http.Header_Set(header, 'Content-Type', 'text/plain; charset=utf-8')
|
|
@@ -38,7 +53,10 @@ export function Symbol(w: http.ResponseWriter | null, _r: http.Request | $.VarRe
|
|
|
38
53
|
writeString(w, 'num_symbols: 0\n')
|
|
39
54
|
}
|
|
40
55
|
|
|
41
|
-
export function Trace(
|
|
56
|
+
export function Trace(
|
|
57
|
+
w: http.ResponseWriter | null,
|
|
58
|
+
_r: http.Request | $.VarRef<http.Request> | null,
|
|
59
|
+
): void {
|
|
42
60
|
const header = w?.Header()
|
|
43
61
|
if (header != null) {
|
|
44
62
|
http.Header_Set(header, 'Content-Type', 'application/octet-stream')
|
|
@@ -115,6 +115,28 @@ describe('os stdio', () => {
|
|
|
115
115
|
expect(writeSync).toHaveBeenCalledTimes(1)
|
|
116
116
|
})
|
|
117
117
|
|
|
118
|
+
it('writes stderr to console.log in browser-like hosts', () => {
|
|
119
|
+
const consoleLog = vi.spyOn(console, 'log').mockImplementation(() => {})
|
|
120
|
+
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
121
|
+
|
|
122
|
+
delete (globalThis as any).Deno
|
|
123
|
+
delete (globalThis as any).process
|
|
124
|
+
resetHostRuntimeForTests()
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const stderr = NewFile(2, 'stderr')!
|
|
128
|
+
const [writeN, writeErr] = stderr.Write(new TextEncoder().encode('err\n'))
|
|
129
|
+
|
|
130
|
+
expect(writeN).toBe(4)
|
|
131
|
+
expect(writeErr).toBeNull()
|
|
132
|
+
expect(consoleLog).toHaveBeenCalledWith('err')
|
|
133
|
+
expect(consoleError).not.toHaveBeenCalled()
|
|
134
|
+
} finally {
|
|
135
|
+
consoleLog.mockRestore()
|
|
136
|
+
consoleError.mockRestore()
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
|
|
118
140
|
it('falls back to process builtin fs when Deno lacks sync stdio', () => {
|
|
119
141
|
const readSync = vi.fn(
|
|
120
142
|
(
|
package/gs/reflect/iter.ts
CHANGED
|
@@ -11,7 +11,9 @@ export function rangeNum<T extends number | uintptr, N extends number | number>(
|
|
|
11
11
|
|
|
12
12
|
// if the iteration value type is define by
|
|
13
13
|
// type T built-in type.
|
|
14
|
-
return async (
|
|
14
|
+
return async (
|
|
15
|
+
_yield: ((v: Value) => iter.YieldResult) | null,
|
|
16
|
+
): Promise<void> => {
|
|
15
17
|
let convert = t!.PkgPath!() != ''
|
|
16
18
|
// cannot use range T(v) because no core type.
|
|
17
19
|
|
|
@@ -24,7 +26,7 @@ export function rangeNum<T extends number | uintptr, N extends number | number>(
|
|
|
24
26
|
if (convert) {
|
|
25
27
|
tmp = tmp.Convert(t).clone()
|
|
26
28
|
}
|
|
27
|
-
if (!await _yield!(tmp)) {
|
|
29
|
+
if (!(await _yield!(tmp))) {
|
|
28
30
|
return
|
|
29
31
|
}
|
|
30
32
|
}
|
package/gs/reflect/map.test.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AppendSlice,
|
|
4
|
+
MakeMapWithSize,
|
|
5
|
+
MapIter,
|
|
6
|
+
MapOf,
|
|
7
|
+
TypeOf,
|
|
8
|
+
Value,
|
|
9
|
+
ValueOf,
|
|
10
|
+
} from './index.js'
|
|
3
11
|
|
|
4
12
|
describe('MapIter', () => {
|
|
5
13
|
it('should iterate over map entries with proper typing', () => {
|
|
@@ -31,6 +39,53 @@ describe('MapIter', () => {
|
|
|
31
39
|
})
|
|
32
40
|
|
|
33
41
|
describe('Value.MapKeys', () => {
|
|
42
|
+
it('reports map length', () => {
|
|
43
|
+
const map = new Map<string, number>()
|
|
44
|
+
map.set('alpha', 1)
|
|
45
|
+
map.set('beta', 2)
|
|
46
|
+
|
|
47
|
+
expect(ValueOf(map).Len()).toBe(2)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('sets and mutates map fields through the same addressable value', () => {
|
|
51
|
+
const typ = MapOf(TypeOf(''), TypeOf(0))
|
|
52
|
+
const holder: { Items: Map<string, number> | null } = { Items: null }
|
|
53
|
+
const field = new Value(holder.Items, typ, undefined, holder, 'Items')
|
|
54
|
+
|
|
55
|
+
field.Set(MakeMapWithSize(typ, 0))
|
|
56
|
+
field.SetMapIndex(ValueOf('alpha'), ValueOf(1))
|
|
57
|
+
|
|
58
|
+
expect(holder.Items?.get('alpha')).toBe(1)
|
|
59
|
+
expect(field.Len()).toBe(1)
|
|
60
|
+
expect(field.MapIndex(ValueOf('alpha')).Interface()).toBe(1)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('deletes map entries when SetMapIndex receives a zero value', () => {
|
|
64
|
+
const typ = MapOf(TypeOf(''), TypeOf(0))
|
|
65
|
+
const mapValue = MakeMapWithSize(typ, 0)
|
|
66
|
+
|
|
67
|
+
mapValue.SetMapIndex(ValueOf('alpha'), ValueOf(1))
|
|
68
|
+
mapValue.SetMapIndex(ValueOf('alpha'), new Value())
|
|
69
|
+
|
|
70
|
+
const raw = mapValue.Interface()
|
|
71
|
+
expect(raw).toBeInstanceOf(Map)
|
|
72
|
+
expect(mapValue.Len()).toBe(0)
|
|
73
|
+
expect(raw.has('alpha')).toBe(false)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('rejects nil map insertion and invalid map backing values', () => {
|
|
77
|
+
const typ = MapOf(TypeOf(''), TypeOf(0))
|
|
78
|
+
const nilMap = new Value(null, typ)
|
|
79
|
+
const badMap = new Value({ bad: true }, typ)
|
|
80
|
+
|
|
81
|
+
expect(() => nilMap.SetMapIndex(ValueOf('alpha'), ValueOf(1))).toThrow(
|
|
82
|
+
'reflect: assignment to entry in nil map',
|
|
83
|
+
)
|
|
84
|
+
expect(() => badMap.Len()).toThrow(
|
|
85
|
+
'reflect: call of reflect.Value.Len on map Value',
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
|
|
34
89
|
it('returns map keys as reflect values', () => {
|
|
35
90
|
const map = new Map<string, number>()
|
|
36
91
|
map.set('alpha', 1)
|
package/gs/reflect/type.ts
CHANGED
|
@@ -565,6 +565,27 @@ export class Value {
|
|
|
565
565
|
return cloned
|
|
566
566
|
}
|
|
567
567
|
|
|
568
|
+
private currentValue(): ReflectValue {
|
|
569
|
+
if (this._parentVarRef) {
|
|
570
|
+
return this._parentVarRef.value
|
|
571
|
+
}
|
|
572
|
+
if (this._parentStruct && this._fieldName !== undefined) {
|
|
573
|
+
const value = this._parentStruct[this._fieldName]
|
|
574
|
+
return value === undefined ? null : (value as ReflectValue)
|
|
575
|
+
}
|
|
576
|
+
return this._value
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
private storeValue(value: ReflectValue): void {
|
|
580
|
+
this._value = value
|
|
581
|
+
if (this._parentVarRef) {
|
|
582
|
+
this._parentVarRef.value = value
|
|
583
|
+
}
|
|
584
|
+
if (this._parentStruct && this._fieldName !== undefined) {
|
|
585
|
+
this._parentStruct[this._fieldName] = value
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
568
589
|
// Methods required by godoc.txt and used throughout the codebase
|
|
569
590
|
public Int(): number {
|
|
570
591
|
const value = this.numericValue()
|
|
@@ -645,6 +666,16 @@ export class Value {
|
|
|
645
666
|
if (this.Kind() === Slice || this.Kind() === Array) {
|
|
646
667
|
return $.len(this._value as any)
|
|
647
668
|
}
|
|
669
|
+
if (this.Kind() === Map) {
|
|
670
|
+
const value = this.currentValue()
|
|
671
|
+
if (value instanceof globalThis.Map) {
|
|
672
|
+
return value.size
|
|
673
|
+
}
|
|
674
|
+
if (value !== null && value !== undefined) {
|
|
675
|
+
throw new ValueError({ Kind: this.Kind(), Method: 'Len' })
|
|
676
|
+
}
|
|
677
|
+
return 0
|
|
678
|
+
}
|
|
648
679
|
|
|
649
680
|
// Check for slice objects created by $.arrayToSlice
|
|
650
681
|
if (
|
|
@@ -705,7 +736,8 @@ export class Value {
|
|
|
705
736
|
}
|
|
706
737
|
|
|
707
738
|
public IsNil(): boolean {
|
|
708
|
-
|
|
739
|
+
const value = this.currentValue()
|
|
740
|
+
return value === null || value === undefined
|
|
709
741
|
}
|
|
710
742
|
|
|
711
743
|
public Index(i: number): Value {
|
|
@@ -945,15 +977,7 @@ export class Value {
|
|
|
945
977
|
if (!xType.AssignableTo(thisType)) {
|
|
946
978
|
throw new Error('reflect: assign to wrong type')
|
|
947
979
|
}
|
|
948
|
-
this.
|
|
949
|
-
// Also update the parent VarRef if we were dereferenced from one
|
|
950
|
-
if (this._parentVarRef) {
|
|
951
|
-
this._parentVarRef.value = x.value
|
|
952
|
-
}
|
|
953
|
-
// Also update the parent struct field if this is a struct field
|
|
954
|
-
if (this._parentStruct && this._fieldName) {
|
|
955
|
-
this._parentStruct[this._fieldName] = x.value
|
|
956
|
-
}
|
|
980
|
+
this.storeValue(x.value)
|
|
957
981
|
}
|
|
958
982
|
|
|
959
983
|
// Additional methods from deleted reflect.gs.ts
|
|
@@ -1026,28 +1050,30 @@ export class Value {
|
|
|
1026
1050
|
if (this.Kind() !== Map) {
|
|
1027
1051
|
throw new ValueError({ Kind: this.Kind(), Method: 'MapRange' })
|
|
1028
1052
|
}
|
|
1029
|
-
|
|
1053
|
+
const value = this.currentValue()
|
|
1054
|
+
if (value === null || value === undefined) {
|
|
1030
1055
|
return new MapIter(new globalThis.Map())
|
|
1031
1056
|
}
|
|
1032
|
-
if (!(
|
|
1057
|
+
if (!(value instanceof globalThis.Map)) {
|
|
1033
1058
|
throw new ValueError({ Kind: this.Kind(), Method: 'MapRange' })
|
|
1034
1059
|
}
|
|
1035
|
-
return new MapIter(
|
|
1060
|
+
return new MapIter(value)
|
|
1036
1061
|
}
|
|
1037
1062
|
|
|
1038
1063
|
public MapIndex(key: Value): Value {
|
|
1039
1064
|
if (this.Kind() !== Map) {
|
|
1040
1065
|
throw new ValueError({ Kind: this.Kind(), Method: 'MapIndex' })
|
|
1041
1066
|
}
|
|
1042
|
-
|
|
1067
|
+
const value = this.currentValue()
|
|
1068
|
+
if (!(value instanceof globalThis.Map)) {
|
|
1043
1069
|
return new Value(null, new BasicType(Invalid, 'invalid'))
|
|
1044
1070
|
}
|
|
1045
1071
|
const rawKey = key.Interface()
|
|
1046
|
-
if (!
|
|
1072
|
+
if (!value.has(rawKey)) {
|
|
1047
1073
|
return new Value(null, new BasicType(Invalid, 'invalid'))
|
|
1048
1074
|
}
|
|
1049
1075
|
return new Value(
|
|
1050
|
-
|
|
1076
|
+
value.get(rawKey) as ReflectValue,
|
|
1051
1077
|
this.Type().Elem(),
|
|
1052
1078
|
)
|
|
1053
1079
|
}
|
|
@@ -1056,15 +1082,16 @@ export class Value {
|
|
|
1056
1082
|
if (this.Kind() !== Map) {
|
|
1057
1083
|
throw new ValueError({ Kind: this.Kind(), Method: 'MapKeys' })
|
|
1058
1084
|
}
|
|
1059
|
-
|
|
1085
|
+
const value = this.currentValue()
|
|
1086
|
+
if (value === null || value === undefined) {
|
|
1060
1087
|
return $.makeSlice<Value>(0)
|
|
1061
1088
|
}
|
|
1062
|
-
if (!(
|
|
1089
|
+
if (!(value instanceof globalThis.Map)) {
|
|
1063
1090
|
throw new ValueError({ Kind: this.Kind(), Method: 'MapKeys' })
|
|
1064
1091
|
}
|
|
1065
1092
|
const keyType = this.Type().Key()
|
|
1066
1093
|
const keys: Value[] = []
|
|
1067
|
-
for (const key of
|
|
1094
|
+
for (const key of value.keys()) {
|
|
1068
1095
|
keys.push(new Value(key as ReflectValue, keyType))
|
|
1069
1096
|
}
|
|
1070
1097
|
return $.arrayToSlice(keys)
|
|
@@ -1278,7 +1305,7 @@ export class Value {
|
|
|
1278
1305
|
)
|
|
1279
1306
|
}
|
|
1280
1307
|
const zeroVal = Zero(this.Type())
|
|
1281
|
-
this.
|
|
1308
|
+
this.storeValue((zeroVal as unknown as { value: ReflectValue }).value)
|
|
1282
1309
|
}
|
|
1283
1310
|
|
|
1284
1311
|
// SetLen sets v's length to n
|
|
@@ -1312,9 +1339,16 @@ export class Value {
|
|
|
1312
1339
|
' Value',
|
|
1313
1340
|
)
|
|
1314
1341
|
}
|
|
1315
|
-
const mapObj = this.
|
|
1342
|
+
const mapObj = this.currentValue()
|
|
1343
|
+
if (!(mapObj instanceof globalThis.Map)) {
|
|
1344
|
+
throw new Error('reflect: assignment to entry in nil map')
|
|
1345
|
+
}
|
|
1316
1346
|
const keyVal = (key as unknown as { value: ReflectValue }).value
|
|
1317
1347
|
const elemVal = (elem as unknown as { value: ReflectValue }).value
|
|
1348
|
+
if (!elem.IsValid()) {
|
|
1349
|
+
mapObj.delete(keyVal)
|
|
1350
|
+
return
|
|
1351
|
+
}
|
|
1318
1352
|
mapObj.set(keyVal, elemVal)
|
|
1319
1353
|
}
|
|
1320
1354
|
|
|
@@ -2719,15 +2753,14 @@ function typeInfoIdentityKey(
|
|
|
2719
2753
|
return `named:${info.name}`
|
|
2720
2754
|
}
|
|
2721
2755
|
return `struct:${(info.fields ?? [])
|
|
2722
|
-
.map(
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
].join('\u0000'),
|
|
2756
|
+
.map((field) =>
|
|
2757
|
+
[
|
|
2758
|
+
field.name,
|
|
2759
|
+
field.pkgPath ?? '',
|
|
2760
|
+
field.tag ?? '',
|
|
2761
|
+
field.anonymous === true ? 'anonymous' : 'named',
|
|
2762
|
+
typeInfoIdentityKey(field.type, seen),
|
|
2763
|
+
].join('\u0000'),
|
|
2731
2764
|
)
|
|
2732
2765
|
.join('\u0001')}`
|
|
2733
2766
|
case $.TypeKind.Pointer:
|
|
@@ -2904,10 +2937,7 @@ function typeMethods(t: Type): $.MethodSignature[] {
|
|
|
2904
2937
|
return t.methodSignatures()
|
|
2905
2938
|
}
|
|
2906
2939
|
if (!typeInfo && t instanceof PointerType) {
|
|
2907
|
-
return mergeMethodSignatureList(
|
|
2908
|
-
typeMethods(t.Elem()),
|
|
2909
|
-
t.methodSignatures(),
|
|
2910
|
-
)
|
|
2940
|
+
return mergeMethodSignatureList(typeMethods(t.Elem()), t.methodSignatures())
|
|
2911
2941
|
}
|
|
2912
2942
|
if (!typeInfo && t instanceof BasicType) {
|
|
2913
2943
|
return t.methodSignatures()
|
|
@@ -3331,13 +3361,22 @@ function typeFromGoTypeName(typeName: string): Type | null {
|
|
|
3331
3361
|
if (trimmed === '') return null
|
|
3332
3362
|
|
|
3333
3363
|
if (trimmed.startsWith('<-chan ')) {
|
|
3334
|
-
return new ChannelType(
|
|
3364
|
+
return new ChannelType(
|
|
3365
|
+
typeFromGoTypeName(trimmed.slice(7)) ?? anyType(),
|
|
3366
|
+
RecvDir,
|
|
3367
|
+
)
|
|
3335
3368
|
}
|
|
3336
3369
|
if (trimmed.startsWith('chan<- ')) {
|
|
3337
|
-
return new ChannelType(
|
|
3370
|
+
return new ChannelType(
|
|
3371
|
+
typeFromGoTypeName(trimmed.slice(7)) ?? anyType(),
|
|
3372
|
+
SendDir,
|
|
3373
|
+
)
|
|
3338
3374
|
}
|
|
3339
3375
|
if (trimmed.startsWith('chan ')) {
|
|
3340
|
-
return new ChannelType(
|
|
3376
|
+
return new ChannelType(
|
|
3377
|
+
typeFromGoTypeName(trimmed.slice(5)) ?? anyType(),
|
|
3378
|
+
BothDir,
|
|
3379
|
+
)
|
|
3341
3380
|
}
|
|
3342
3381
|
if (trimmed.startsWith('[]')) {
|
|
3343
3382
|
return new SliceType(typeFromGoTypeName(trimmed.slice(2)) ?? anyType())
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { resetHostRuntimeForTests } from '@goscript/builtin/hostio.js'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
BuildInfo,
|
|
7
|
+
BuildSetting,
|
|
8
|
+
Module,
|
|
9
|
+
PrintStack,
|
|
10
|
+
ReadBuildInfo,
|
|
11
|
+
Stack,
|
|
12
|
+
} from './index.js'
|
|
4
13
|
|
|
5
14
|
describe('runtime/debug override', () => {
|
|
6
15
|
it('returns a stack trace as bytes', () => {
|
|
@@ -10,14 +19,33 @@ describe('runtime/debug override', () => {
|
|
|
10
19
|
expect(new TextDecoder().decode(stack)).toContain('Error')
|
|
11
20
|
})
|
|
12
21
|
|
|
13
|
-
it('prints the current stack trace', () => {
|
|
22
|
+
it('prints the current stack trace through the browser-like stderr console fallback', () => {
|
|
23
|
+
const consoleLog = vi.spyOn(console, 'log').mockImplementation(() => {})
|
|
14
24
|
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
25
|
+
const originalDeno = (globalThis as any).Deno
|
|
26
|
+
const originalProcess = (globalThis as any).process
|
|
27
|
+
delete (globalThis as any).Deno
|
|
28
|
+
delete (globalThis as any).process
|
|
29
|
+
resetHostRuntimeForTests()
|
|
15
30
|
|
|
16
31
|
try {
|
|
17
32
|
PrintStack()
|
|
18
|
-
expect(
|
|
19
|
-
expect(
|
|
33
|
+
expect(consoleLog).toHaveBeenCalledTimes(1)
|
|
34
|
+
expect(consoleLog.mock.calls[0][0]).toContain('Error')
|
|
35
|
+
expect(consoleError).not.toHaveBeenCalled()
|
|
20
36
|
} finally {
|
|
37
|
+
if (originalDeno === undefined) {
|
|
38
|
+
delete (globalThis as any).Deno
|
|
39
|
+
} else {
|
|
40
|
+
;(globalThis as any).Deno = originalDeno
|
|
41
|
+
}
|
|
42
|
+
if (originalProcess === undefined) {
|
|
43
|
+
delete (globalThis as any).process
|
|
44
|
+
} else {
|
|
45
|
+
;(globalThis as any).process = originalProcess
|
|
46
|
+
}
|
|
47
|
+
resetHostRuntimeForTests()
|
|
48
|
+
consoleLog.mockRestore()
|
|
21
49
|
consoleError.mockRestore()
|
|
22
50
|
}
|
|
23
51
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
import { writeHostStderrText } from '@goscript/builtin/hostio.js'
|
|
2
3
|
|
|
3
4
|
export class BuildSetting {
|
|
4
5
|
public Key: string
|
|
@@ -10,7 +11,9 @@ export class BuildSetting {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
public clone(): BuildSetting {
|
|
13
|
-
return $.markAsStructValue(
|
|
14
|
+
return $.markAsStructValue(
|
|
15
|
+
new BuildSetting({ Key: this.Key, Value: this.Value }),
|
|
16
|
+
)
|
|
14
17
|
}
|
|
15
18
|
}
|
|
16
19
|
|
|
@@ -88,7 +91,7 @@ export function Stack(): Uint8Array {
|
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
export function PrintStack(): void {
|
|
91
|
-
|
|
94
|
+
writeHostStderrText(new TextDecoder().decode(Stack()))
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
export function ReadBuildInfo(): [BuildInfo | null, boolean] {
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Lookup,
|
|
5
|
+
NewProfile,
|
|
6
|
+
StartCPUProfile,
|
|
7
|
+
StopCPUProfile,
|
|
8
|
+
WriteHeapProfile,
|
|
9
|
+
} from './index.js'
|
|
4
10
|
|
|
5
11
|
describe('runtime/pprof override', () => {
|
|
6
12
|
it('reports CPU profiles as unsupported', () => {
|
|
@@ -105,7 +105,11 @@ export function WriteHeapProfile(w: WriterArg): $.GoError {
|
|
|
105
105
|
|
|
106
106
|
export function SetGoroutineLabels(_ctx: unknown): void {}
|
|
107
107
|
|
|
108
|
-
export function Do(
|
|
108
|
+
export function Do(
|
|
109
|
+
_ctx: unknown,
|
|
110
|
+
_labels: unknown,
|
|
111
|
+
fn: (() => void) | null,
|
|
112
|
+
): void {
|
|
109
113
|
fn?.()
|
|
110
114
|
}
|
|
111
115
|
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Compiler,
|
|
5
5
|
FuncForPC,
|
|
6
6
|
ReadTrace,
|
|
7
|
+
SetFinalizer,
|
|
7
8
|
StartTrace,
|
|
8
9
|
StopTrace,
|
|
9
10
|
} from './runtime.js'
|
|
@@ -18,4 +19,10 @@ describe('runtime override', () => {
|
|
|
18
19
|
expect(ReadTrace()).toBeNull()
|
|
19
20
|
expect(() => StopTrace()).not.toThrow()
|
|
20
21
|
})
|
|
22
|
+
|
|
23
|
+
it('ignores finalizer registration and clearing', () => {
|
|
24
|
+
const obj = {}
|
|
25
|
+
expect(() => SetFinalizer(obj, () => {})).not.toThrow()
|
|
26
|
+
expect(() => SetFinalizer(obj, null)).not.toThrow()
|
|
27
|
+
})
|
|
21
28
|
})
|
package/gs/runtime/runtime.ts
CHANGED
|
@@ -234,14 +234,12 @@ export class PanicError implements Error {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
// SetFinalizer sets the finalizer associated with obj to the provided finalizer function.
|
|
237
|
-
// In goscript/TypeScript environment, finalizers are not supported, so this throws an error.
|
|
238
237
|
export function SetFinalizer(
|
|
239
238
|
_obj: object,
|
|
240
239
|
_finalizer: ((obj: object) => void) | null,
|
|
241
240
|
): void {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
)
|
|
241
|
+
// JavaScript runtimes do not expose Go's finalizer scheduling contract. Treat
|
|
242
|
+
// registration and clearing as no-ops so cleanup backstops don't become fatal.
|
|
245
243
|
}
|
|
246
244
|
|
|
247
245
|
// Cleanup is a handle to a cleanup call for a specific object.
|
|
@@ -2,7 +2,15 @@ import { describe, expect, it } from 'vitest'
|
|
|
2
2
|
|
|
3
3
|
import * as context from '@goscript/context/index.js'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
IsEnabled,
|
|
7
|
+
Log,
|
|
8
|
+
NewTask,
|
|
9
|
+
Start,
|
|
10
|
+
StartRegion,
|
|
11
|
+
Stop,
|
|
12
|
+
WithRegion,
|
|
13
|
+
} from './index.js'
|
|
6
14
|
|
|
7
15
|
describe('runtime/trace override', () => {
|
|
8
16
|
it('creates no-op tasks from nil context', () => {
|
|
@@ -43,7 +43,11 @@ export function NewTask(
|
|
|
43
43
|
]
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
export function Log(
|
|
46
|
+
export function Log(
|
|
47
|
+
_ctx: context.Context | null,
|
|
48
|
+
category: string,
|
|
49
|
+
message: string,
|
|
50
|
+
): void {
|
|
47
51
|
void category
|
|
48
52
|
void message
|
|
49
53
|
}
|