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/reflect/value.ts
CHANGED
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
PointerTo,
|
|
14
14
|
Ptr,
|
|
15
15
|
Slice,
|
|
16
|
+
SliceOf,
|
|
17
|
+
Struct,
|
|
16
18
|
String,
|
|
17
19
|
Type,
|
|
18
20
|
Uint,
|
|
@@ -25,6 +27,8 @@ import {
|
|
|
25
27
|
Chan,
|
|
26
28
|
BasicType,
|
|
27
29
|
Invalid,
|
|
30
|
+
structFieldStorageKey,
|
|
31
|
+
typeInfoFromReflectType,
|
|
28
32
|
} from './type.js'
|
|
29
33
|
import {
|
|
30
34
|
Pointer,
|
|
@@ -44,12 +48,13 @@ export function Zero(typ: Type | null): Value {
|
|
|
44
48
|
if (typ === null) {
|
|
45
49
|
return new Value() // Return invalid value for null type
|
|
46
50
|
}
|
|
47
|
-
|
|
51
|
+
return new Value(zeroReflectValue(typ), typ)
|
|
52
|
+
}
|
|
48
53
|
|
|
54
|
+
function zeroReflectValue(typ: Type): ReflectValue {
|
|
49
55
|
switch (typ.Kind()) {
|
|
50
56
|
case Bool:
|
|
51
|
-
|
|
52
|
-
break
|
|
57
|
+
return false
|
|
53
58
|
case Int:
|
|
54
59
|
case Int8:
|
|
55
60
|
case Int16:
|
|
@@ -63,21 +68,61 @@ export function Zero(typ: Type | null): Value {
|
|
|
63
68
|
case Uintptr:
|
|
64
69
|
case Float32:
|
|
65
70
|
case Float64:
|
|
66
|
-
|
|
67
|
-
break
|
|
71
|
+
return 0
|
|
68
72
|
case String:
|
|
69
|
-
|
|
70
|
-
break
|
|
73
|
+
return ''
|
|
71
74
|
case Slice:
|
|
72
75
|
case Array:
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
return []
|
|
77
|
+
case Struct: {
|
|
78
|
+
const typeInfo = $.getTypeByName(typ.String())
|
|
79
|
+
if (typeInfo && $.isStructTypeInfo(typeInfo) && typeInfo.ctor) {
|
|
80
|
+
return $.markAsStructValue(new typeInfo.ctor()) as ReflectValue
|
|
81
|
+
}
|
|
82
|
+
return newStructValue(typ)
|
|
83
|
+
}
|
|
75
84
|
default:
|
|
76
|
-
|
|
77
|
-
break
|
|
85
|
+
return null
|
|
78
86
|
}
|
|
87
|
+
}
|
|
79
88
|
|
|
80
|
-
|
|
89
|
+
function newStructValue(typ: Type): ReflectValue {
|
|
90
|
+
const StructValue = class {
|
|
91
|
+
public _fields: Record<string, $.VarRef<unknown>> = {}
|
|
92
|
+
|
|
93
|
+
public clone(): unknown {
|
|
94
|
+
const cloned = newStructValue(typ) as {
|
|
95
|
+
_fields: Record<string, $.VarRef<unknown>>
|
|
96
|
+
}
|
|
97
|
+
for (const key of Object.keys(this._fields)) {
|
|
98
|
+
cloned._fields[key].value = this._fields[key].value
|
|
99
|
+
}
|
|
100
|
+
return cloned
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
Object.defineProperty(StructValue, '__reflectType', { value: typ })
|
|
104
|
+
Object.defineProperty(StructValue, '__typeInfo', {
|
|
105
|
+
value: typeInfoFromReflectType(typ),
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
const value = new StructValue() as unknown as {
|
|
109
|
+
_fields: Record<string, $.VarRef<ReflectValue>>
|
|
110
|
+
} & Record<string, unknown>
|
|
111
|
+
for (let i = 0; i < typ.NumField(); i++) {
|
|
112
|
+
const field = typ.Field(i)
|
|
113
|
+
const key = structFieldStorageKey(typ, i)
|
|
114
|
+
const ref = $.varRef<ReflectValue>(zeroReflectValue(field.Type))
|
|
115
|
+
value._fields[key] = ref
|
|
116
|
+
Object.defineProperty(value, key, {
|
|
117
|
+
enumerable: true,
|
|
118
|
+
configurable: true,
|
|
119
|
+
get: () => ref.value,
|
|
120
|
+
set: (next: unknown) => {
|
|
121
|
+
ref.value = next as ReflectValue
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
return value
|
|
81
126
|
}
|
|
82
127
|
|
|
83
128
|
// Copy copies the contents of src to dst until either dst has been filled
|
|
@@ -120,20 +165,12 @@ function getArrayFromValue(value: Value): unknown[] | null {
|
|
|
120
165
|
|
|
121
166
|
// Indirect returns the value that v points to.
|
|
122
167
|
export function Indirect(v: Value): Value {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// Ptr kind
|
|
127
|
-
const elemType = type.Elem()
|
|
128
|
-
if (elemType) {
|
|
129
|
-
// Return a new Value with the same underlying value but the element type
|
|
130
|
-
return new Value(
|
|
131
|
-
(v as unknown as { value: ReflectValue }).value,
|
|
132
|
-
elemType,
|
|
133
|
-
)
|
|
168
|
+
if (v.Kind() === Ptr) {
|
|
169
|
+
if (v.IsNil()) {
|
|
170
|
+
return new Value()
|
|
134
171
|
}
|
|
172
|
+
return v.Elem()
|
|
135
173
|
}
|
|
136
|
-
// For non-pointer types, just return the value as-is
|
|
137
174
|
return v
|
|
138
175
|
}
|
|
139
176
|
|
|
@@ -143,9 +180,7 @@ export function New(typ: Type | null): Value {
|
|
|
143
180
|
return new Value() // Return invalid value for null type
|
|
144
181
|
}
|
|
145
182
|
const ptrType = PointerTo(typ)
|
|
146
|
-
|
|
147
|
-
// In a real implementation, this would be a pointer to the zero value
|
|
148
|
-
return new Value(null, ptrType) // null represents the pointer value
|
|
183
|
+
return new Value($.varRef(zeroReflectValue(typ)), ptrType)
|
|
149
184
|
}
|
|
150
185
|
|
|
151
186
|
// NewAt returns a Value representing a pointer to the value at p.
|
|
@@ -154,25 +189,50 @@ export function NewAt(typ: Type | null, p: Pointer | unknown): Value {
|
|
|
154
189
|
return new Value()
|
|
155
190
|
}
|
|
156
191
|
const ptrType = PointerTo(typ)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return new Value(
|
|
192
|
+
const pointer = ownedPointerHandleFromPointerArg(p)
|
|
193
|
+
if (pointer !== undefined) {
|
|
194
|
+
return new Value(
|
|
195
|
+
$.ownedPointerRef(pointer) as $.VarRef<ReflectValue>,
|
|
196
|
+
ptrType,
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
throw new Error('reflect.NewAt requires a GoScript-owned pointer')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function SliceAt(
|
|
203
|
+
typ: Type | null,
|
|
204
|
+
p: Pointer | unknown,
|
|
205
|
+
n: number,
|
|
206
|
+
): Value {
|
|
207
|
+
if (typ === null) {
|
|
208
|
+
return new Value()
|
|
209
|
+
}
|
|
210
|
+
if (n < 0) {
|
|
211
|
+
throw new Error('reflect.SliceAt: negative length')
|
|
212
|
+
}
|
|
213
|
+
if (p === null && n === 0) {
|
|
214
|
+
return new Value(null, SliceOf(typ))
|
|
215
|
+
}
|
|
216
|
+
const pointer = ownedPointerHandleFromPointerArg(p)
|
|
217
|
+
if (pointer === undefined) {
|
|
218
|
+
throw new Error('reflect.SliceAt requires a GoScript-owned pointer')
|
|
219
|
+
}
|
|
220
|
+
const slice = $.sliceFromOwnedPointer(pointer, n)
|
|
221
|
+
return new Value(slice as ReflectValue, SliceOf(typ))
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function ownedPointerHandleFromPointerArg(
|
|
225
|
+
p: unknown,
|
|
226
|
+
): $.OwnedPointerHandle<ReflectValue> | undefined {
|
|
227
|
+
if ($.isOwnedPointerHandle(p)) {
|
|
228
|
+
return p as $.OwnedPointerHandle<ReflectValue>
|
|
229
|
+
}
|
|
230
|
+
if ($.isVarRef(p)) {
|
|
231
|
+
return $.ownedPointerFromRef(p as $.VarRef<ReflectValue>) as
|
|
232
|
+
| $.OwnedPointerHandle<ReflectValue>
|
|
233
|
+
| undefined
|
|
174
234
|
}
|
|
175
|
-
return
|
|
235
|
+
return undefined
|
|
176
236
|
}
|
|
177
237
|
|
|
178
238
|
// MakeSlice returns a Value representing a new slice with the specified type, length, and capacity.
|
|
@@ -1,177 +1,14 @@
|
|
|
1
1
|
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
-
import {
|
|
2
|
+
import { Struct, Type, visibleStructFields } from './type.js'
|
|
3
3
|
import { StructField } from './types.js'
|
|
4
4
|
|
|
5
|
-
// VisibleFields returns all
|
|
6
|
-
// struct type. A field is defined as visible if it's accessible
|
|
7
|
-
// directly with a FieldByName call. The returned fields include fields
|
|
8
|
-
// inside anonymous struct members and unexported fields. They follow
|
|
9
|
-
// the same order found in the struct, with anonymous fields followed
|
|
10
|
-
// immediately by their promoted fields.
|
|
11
|
-
//
|
|
12
|
-
// For each element e of the returned slice, the corresponding field
|
|
13
|
-
// can be retrieved from a value v of type t by calling v.FieldByIndex(e.Index).
|
|
5
|
+
// VisibleFields returns all fields visible through ordinary struct field lookup.
|
|
14
6
|
export function VisibleFields(t: Type): $.Slice<StructField> {
|
|
15
7
|
if (t == null) {
|
|
16
8
|
$.panic('reflect: VisibleFields(nil)')
|
|
17
9
|
}
|
|
18
|
-
if (t
|
|
19
|
-
$.panic('reflect.VisibleFields of non-struct type ' + t
|
|
10
|
+
if (t.Kind() !== Struct) {
|
|
11
|
+
$.panic('reflect.VisibleFields of non-struct type ' + t.String())
|
|
20
12
|
}
|
|
21
|
-
|
|
22
|
-
byName: $.makeMap<string, number>(),
|
|
23
|
-
fields: $.makeSlice<StructField>(0, t!.NumField!()),
|
|
24
|
-
index: $.makeSlice<number>(0, 2, 'number'),
|
|
25
|
-
visiting: $.makeMap<Type, boolean>(),
|
|
26
|
-
})
|
|
27
|
-
w.walk(t)
|
|
28
|
-
// Remove all the fields that have been hidden.
|
|
29
|
-
// Use an in-place removal that avoids copying in
|
|
30
|
-
// the common case that there are no hidden fields.
|
|
31
|
-
let j = 0
|
|
32
|
-
|
|
33
|
-
// A field has been removed. We need to shuffle
|
|
34
|
-
// all the subsequent elements up.
|
|
35
|
-
for (let i = 0; i < $.len(w.fields); i++) {
|
|
36
|
-
{
|
|
37
|
-
let f = w.fields![i]
|
|
38
|
-
if (f!.Name == '') {
|
|
39
|
-
continue
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// A field has been removed. We need to shuffle
|
|
43
|
-
// all the subsequent elements up.
|
|
44
|
-
if (i != j) {
|
|
45
|
-
// A field has been removed. We need to shuffle
|
|
46
|
-
// all the subsequent elements up.
|
|
47
|
-
w.fields![j] = f!.clone()
|
|
48
|
-
}
|
|
49
|
-
j++
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return $.goSlice(w.fields, undefined, j)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
class visibleFieldsWalker {
|
|
56
|
-
public get byName(): Map<string, number> {
|
|
57
|
-
return this._fields.byName.value
|
|
58
|
-
}
|
|
59
|
-
public set byName(value: Map<string, number>) {
|
|
60
|
-
this._fields.byName.value = value
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public get visiting(): Map<Type, boolean> {
|
|
64
|
-
return this._fields.visiting.value
|
|
65
|
-
}
|
|
66
|
-
public set visiting(value: Map<Type, boolean>) {
|
|
67
|
-
this._fields.visiting.value = value
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public get fields(): $.Slice<StructField> {
|
|
71
|
-
return this._fields.fields.value
|
|
72
|
-
}
|
|
73
|
-
public set fields(value: $.Slice<StructField>) {
|
|
74
|
-
this._fields.fields.value = value
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
public get index(): $.Slice<number> {
|
|
78
|
-
return this._fields.index.value
|
|
79
|
-
}
|
|
80
|
-
public set index(value: $.Slice<number>) {
|
|
81
|
-
this._fields.index.value = value
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
public _fields: {
|
|
85
|
-
byName: $.VarRef<Map<string, number>>
|
|
86
|
-
visiting: $.VarRef<Map<Type, boolean>>
|
|
87
|
-
fields: $.VarRef<$.Slice<StructField>>
|
|
88
|
-
index: $.VarRef<$.Slice<number>>
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
constructor(
|
|
92
|
-
init?: Partial<{
|
|
93
|
-
byName?: Map<string, number>
|
|
94
|
-
fields?: $.Slice<StructField>
|
|
95
|
-
index?: $.Slice<number>
|
|
96
|
-
visiting?: Map<Type, boolean>
|
|
97
|
-
}>,
|
|
98
|
-
) {
|
|
99
|
-
this._fields = {
|
|
100
|
-
byName: $.varRef(init?.byName ?? $.makeMap<string, number>()),
|
|
101
|
-
visiting: $.varRef(init?.visiting ?? $.makeMap<Type, boolean>()),
|
|
102
|
-
fields: $.varRef(init?.fields ?? $.makeSlice<StructField>(0, 0)),
|
|
103
|
-
index: $.varRef(init?.index ?? $.makeSlice<number>(0, 2, 'number')),
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
public clone(): visibleFieldsWalker {
|
|
108
|
-
const cloned = new visibleFieldsWalker()
|
|
109
|
-
cloned._fields = {
|
|
110
|
-
byName: $.varRef(this._fields.byName.value),
|
|
111
|
-
visiting: $.varRef(this._fields.visiting.value),
|
|
112
|
-
fields: $.varRef(this._fields.fields.value),
|
|
113
|
-
index: $.varRef(this._fields.index.value),
|
|
114
|
-
}
|
|
115
|
-
return cloned
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// walk walks all the fields in the struct type t, visiting
|
|
119
|
-
// fields in index preorder and appending them to w.fields
|
|
120
|
-
// (this maintains the required ordering).
|
|
121
|
-
// Fields that have been overridden have their
|
|
122
|
-
// Name field cleared.
|
|
123
|
-
public walk(t: Type): void {
|
|
124
|
-
const w = this
|
|
125
|
-
if ($.mapGet(w.visiting, t, false)[0]) {
|
|
126
|
-
return
|
|
127
|
-
}
|
|
128
|
-
$.mapSet(w.visiting, t, true)
|
|
129
|
-
for (let i = 0; i < t!.NumField!(); i++) {
|
|
130
|
-
if (!t!.Field) continue
|
|
131
|
-
const field = t!.Field(i)
|
|
132
|
-
if (field) {
|
|
133
|
-
const f = field.clone()
|
|
134
|
-
f.Index = $.append(null, ...(w.index ?? [])) as number[]
|
|
135
|
-
if (f.Anonymous) {
|
|
136
|
-
if (f.Type && f.Type.Kind() === Ptr) {
|
|
137
|
-
const elemType = f.Type.Elem!()
|
|
138
|
-
if (elemType) {
|
|
139
|
-
f.Type = elemType
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (f.Type && f.Type.Kind() === Struct) {
|
|
143
|
-
w.walk(f.Type)
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
w.fields = $.append(w.fields, f)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
$.deleteMapEntry(w.visiting, t)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Register this type with the runtime type system
|
|
154
|
-
static __typeInfo = $.registerStructType(
|
|
155
|
-
'visibleFieldsWalker',
|
|
156
|
-
new visibleFieldsWalker(),
|
|
157
|
-
[{ name: 'walk', args: [{ name: 't', type: 'Type' }], returns: [] }],
|
|
158
|
-
visibleFieldsWalker,
|
|
159
|
-
{
|
|
160
|
-
byName: {
|
|
161
|
-
kind: $.TypeKind.Map,
|
|
162
|
-
keyType: { kind: $.TypeKind.Basic, name: 'string' },
|
|
163
|
-
elemType: { kind: $.TypeKind.Basic, name: 'number' },
|
|
164
|
-
},
|
|
165
|
-
visiting: {
|
|
166
|
-
kind: $.TypeKind.Map,
|
|
167
|
-
keyType: 'Type',
|
|
168
|
-
elemType: { kind: $.TypeKind.Basic, name: 'boolean' },
|
|
169
|
-
},
|
|
170
|
-
fields: { kind: $.TypeKind.Slice, elemType: 'StructField' },
|
|
171
|
-
index: {
|
|
172
|
-
kind: $.TypeKind.Slice,
|
|
173
|
-
elemType: { kind: $.TypeKind.Basic, name: 'number' },
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
)
|
|
13
|
+
return $.arrayToSlice(visibleStructFields(t).map((field) => field.clone()))
|
|
177
14
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"strict": false,
|
|
4
|
+
"symbols": {
|
|
5
|
+
"Compiler": {
|
|
6
|
+
"status": "real"
|
|
7
|
+
},
|
|
8
|
+
"GOARCH": {
|
|
9
|
+
"status": "real"
|
|
10
|
+
},
|
|
11
|
+
"GOOS": {
|
|
12
|
+
"status": "real"
|
|
13
|
+
},
|
|
14
|
+
"ReadTrace": {
|
|
15
|
+
"status": "real"
|
|
16
|
+
},
|
|
17
|
+
"StartTrace": {
|
|
18
|
+
"status": "real"
|
|
19
|
+
},
|
|
20
|
+
"StopTrace": {
|
|
21
|
+
"status": "real"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { Lookup, StartCPUProfile, StopCPUProfile } from './index.js'
|
|
3
|
+
import { Lookup, NewProfile, StartCPUProfile, StopCPUProfile, WriteHeapProfile } from './index.js'
|
|
4
4
|
|
|
5
5
|
describe('runtime/pprof override', () => {
|
|
6
|
-
it('
|
|
6
|
+
it('reports CPU profiles as unsupported', () => {
|
|
7
7
|
const chunks: Uint8Array[] = []
|
|
8
8
|
const writer = {
|
|
9
9
|
Write(p: Uint8Array): [number, null] {
|
|
@@ -12,13 +12,15 @@ describe('runtime/pprof override', () => {
|
|
|
12
12
|
},
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
expect(StartCPUProfile(writer)).
|
|
15
|
+
expect(StartCPUProfile(writer)?.Error()).toBe(
|
|
16
|
+
'runtime/pprof: profiles are unsupported in GoScript',
|
|
17
|
+
)
|
|
16
18
|
StopCPUProfile()
|
|
17
19
|
|
|
18
|
-
expect(chunks
|
|
20
|
+
expect(chunks).toHaveLength(0)
|
|
19
21
|
})
|
|
20
22
|
|
|
21
|
-
it('
|
|
23
|
+
it('reports memory profiles as unsupported', () => {
|
|
22
24
|
const chunks: Uint8Array[] = []
|
|
23
25
|
const writer = {
|
|
24
26
|
Write(p: Uint8Array): [number, null] {
|
|
@@ -30,7 +32,27 @@ describe('runtime/pprof override', () => {
|
|
|
30
32
|
const profile = Lookup('allocs')
|
|
31
33
|
|
|
32
34
|
expect(profile).not.toBeNull()
|
|
33
|
-
expect(profile!.WriteTo(writer, 0)).
|
|
34
|
-
|
|
35
|
+
expect(profile!.WriteTo(writer, 0)?.Error()).toBe(
|
|
36
|
+
'runtime/pprof: profiles are unsupported in GoScript',
|
|
37
|
+
)
|
|
38
|
+
expect(WriteHeapProfile(writer)?.Error()).toBe(
|
|
39
|
+
'runtime/pprof: profiles are unsupported in GoScript',
|
|
40
|
+
)
|
|
41
|
+
expect(chunks).toHaveLength(0)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('tracks custom profile values', () => {
|
|
45
|
+
const profile = NewProfile('goscript.test')
|
|
46
|
+
const value = { key: 'value' }
|
|
47
|
+
|
|
48
|
+
expect(Lookup('goscript.test')).toBe(profile)
|
|
49
|
+
expect(profile.Count()).toBe(0)
|
|
50
|
+
profile.Add(value, 0)
|
|
51
|
+
expect(profile.Count()).toBe(1)
|
|
52
|
+
profile.Remove(value)
|
|
53
|
+
expect(profile.Count()).toBe(0)
|
|
54
|
+
expect(() => NewProfile('goscript.test')).toThrow(
|
|
55
|
+
'pprof: NewProfile name already in use: goscript.test',
|
|
56
|
+
)
|
|
35
57
|
})
|
|
36
58
|
})
|
|
@@ -4,13 +4,18 @@ import * as io from '@goscript/io/index.js'
|
|
|
4
4
|
|
|
5
5
|
type WriterArg = io.Writer | $.VarRef<io.Writer> | null | undefined
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const unsupportedProfileError = errors.New(
|
|
8
|
+
'runtime/pprof: profiles are unsupported in GoScript',
|
|
9
|
+
)
|
|
8
10
|
|
|
9
11
|
export class Profile {
|
|
10
12
|
public name: string
|
|
13
|
+
private values = new Map<unknown, true>()
|
|
14
|
+
private builtIn: boolean
|
|
11
15
|
|
|
12
|
-
constructor(name = '') {
|
|
16
|
+
constructor(name = '', builtIn = false) {
|
|
13
17
|
this.name = name
|
|
18
|
+
this.builtIn = builtIn
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
public Name(): string {
|
|
@@ -18,11 +23,28 @@ export class Profile {
|
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
public Count(): number {
|
|
21
|
-
return this.name
|
|
26
|
+
return this.builtIn && this.name !== '' ? 1 : this.values.size
|
|
22
27
|
}
|
|
23
28
|
|
|
24
|
-
public
|
|
25
|
-
|
|
29
|
+
public Add(value: unknown, _skip: number): void {
|
|
30
|
+
if (this.name === '') {
|
|
31
|
+
throw new Error('pprof: use of uninitialized Profile')
|
|
32
|
+
}
|
|
33
|
+
if (this.builtIn) {
|
|
34
|
+
throw new Error(`pprof: Add called on built-in Profile ${this.name}`)
|
|
35
|
+
}
|
|
36
|
+
if (this.values.has(value)) {
|
|
37
|
+
throw new Error('pprof: Profile.Add of duplicate value')
|
|
38
|
+
}
|
|
39
|
+
this.values.set(value, true)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public Remove(value: unknown): void {
|
|
43
|
+
this.values.delete(value)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public WriteTo(_w: WriterArg, _debug: number): $.GoError {
|
|
47
|
+
return unsupportedProfileError
|
|
26
48
|
}
|
|
27
49
|
}
|
|
28
50
|
|
|
@@ -34,40 +56,51 @@ export function Lookup(name: string): Profile | null {
|
|
|
34
56
|
case 'threadcreate':
|
|
35
57
|
case 'block':
|
|
36
58
|
case 'mutex':
|
|
37
|
-
return new Profile(name)
|
|
59
|
+
return new Profile(name, true)
|
|
38
60
|
default:
|
|
39
|
-
return null
|
|
61
|
+
return customProfiles.get(name) ?? null
|
|
40
62
|
}
|
|
41
63
|
}
|
|
42
64
|
|
|
43
65
|
export function Profiles(): $.Slice<Profile | null> {
|
|
44
66
|
return $.arrayToSlice([
|
|
45
|
-
new Profile('allocs'),
|
|
46
|
-
new Profile('block'),
|
|
47
|
-
new Profile('goroutine'),
|
|
48
|
-
new Profile('heap'),
|
|
49
|
-
new Profile('mutex'),
|
|
50
|
-
new Profile('threadcreate'),
|
|
67
|
+
new Profile('allocs', true),
|
|
68
|
+
new Profile('block', true),
|
|
69
|
+
new Profile('goroutine', true),
|
|
70
|
+
new Profile('heap', true),
|
|
71
|
+
new Profile('mutex', true),
|
|
72
|
+
new Profile('threadcreate', true),
|
|
73
|
+
...Array.from(customProfiles.values()),
|
|
51
74
|
])
|
|
52
75
|
}
|
|
53
76
|
|
|
77
|
+
export function NewProfile(name: string): Profile {
|
|
78
|
+
if (name === '') {
|
|
79
|
+
throw new Error('pprof: NewProfile with empty name')
|
|
80
|
+
}
|
|
81
|
+
if (Lookup(name) != null) {
|
|
82
|
+
throw new Error(`pprof: NewProfile name already in use: ${name}`)
|
|
83
|
+
}
|
|
84
|
+
const profile = new Profile(name)
|
|
85
|
+
customProfiles.set(name, profile)
|
|
86
|
+
return profile
|
|
87
|
+
}
|
|
88
|
+
|
|
54
89
|
export function StartCPUProfile(w: WriterArg): $.GoError {
|
|
55
90
|
const writer = writerFromArg(w)
|
|
56
91
|
if (writer == null) {
|
|
57
92
|
return errors.New('runtime/pprof: nil profile writer')
|
|
58
93
|
}
|
|
59
|
-
|
|
60
|
-
return errors.New('runtime/pprof: CPU profiling already active')
|
|
61
|
-
}
|
|
62
|
-
activeCPUWriter = writer
|
|
63
|
-
return writeProfile(writer, 'goscript cpu profile start\n')
|
|
94
|
+
return unsupportedProfileError
|
|
64
95
|
}
|
|
65
96
|
|
|
66
|
-
export function StopCPUProfile(): void {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
97
|
+
export function StopCPUProfile(): void {}
|
|
98
|
+
|
|
99
|
+
export function WriteHeapProfile(w: WriterArg): $.GoError {
|
|
100
|
+
if (writerFromArg(w) == null) {
|
|
101
|
+
return errors.New('runtime/pprof: nil profile writer')
|
|
70
102
|
}
|
|
103
|
+
return unsupportedProfileError
|
|
71
104
|
}
|
|
72
105
|
|
|
73
106
|
export function SetGoroutineLabels(_ctx: unknown): void {}
|
|
@@ -94,11 +127,4 @@ function writerFromArg(w: WriterArg): io.Writer | null {
|
|
|
94
127
|
return $.pointerValueOrNil(w)
|
|
95
128
|
}
|
|
96
129
|
|
|
97
|
-
|
|
98
|
-
const writer = writerFromArg(w)
|
|
99
|
-
if (writer == null) {
|
|
100
|
-
return errors.New('runtime/pprof: nil profile writer')
|
|
101
|
-
}
|
|
102
|
-
const [, err] = writer.Write($.stringToBytes(text))
|
|
103
|
-
return err
|
|
104
|
-
}
|
|
130
|
+
const customProfiles = new Map<string, Profile>()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"strict": false,
|
|
4
|
+
"symbols": {
|
|
5
|
+
"Lookup": {
|
|
6
|
+
"status": "real"
|
|
7
|
+
},
|
|
8
|
+
"NewProfile": {
|
|
9
|
+
"status": "real"
|
|
10
|
+
},
|
|
11
|
+
"Profile": {
|
|
12
|
+
"status": "real"
|
|
13
|
+
},
|
|
14
|
+
"Profiles": {
|
|
15
|
+
"status": "real"
|
|
16
|
+
},
|
|
17
|
+
"StartCPUProfile": {
|
|
18
|
+
"status": "real"
|
|
19
|
+
},
|
|
20
|
+
"StopCPUProfile": {
|
|
21
|
+
"status": "real"
|
|
22
|
+
},
|
|
23
|
+
"WriteHeapProfile": {
|
|
24
|
+
"status": "real"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -12,7 +12,9 @@ describe('runtime override', () => {
|
|
|
12
12
|
it('exposes stack and trace compatibility helpers', () => {
|
|
13
13
|
expect(Compiler).toBe('gc')
|
|
14
14
|
expect(FuncForPC(0)).toBeNull()
|
|
15
|
-
expect(StartTrace()).
|
|
15
|
+
expect(StartTrace()?.Error()).toBe(
|
|
16
|
+
'runtime: execution tracing is unsupported in GoScript',
|
|
17
|
+
)
|
|
16
18
|
expect(ReadTrace()).toBeNull()
|
|
17
19
|
expect(() => StopTrace()).not.toThrow()
|
|
18
20
|
})
|
package/gs/runtime/runtime.ts
CHANGED
|
@@ -36,8 +36,9 @@ export function NumCPU(): number {
|
|
|
36
36
|
export function GC(): void {
|
|
37
37
|
// In JavaScript, we can't force garbage collection
|
|
38
38
|
// Some engines have gc() function in development, but it's not standard
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const gc = (globalThis as { gc?: () => void }).gc
|
|
40
|
+
if (typeof gc === 'function') {
|
|
41
|
+
gc()
|
|
41
42
|
}
|
|
42
43
|
// Otherwise, this is a no-op
|
|
43
44
|
}
|
|
@@ -104,7 +105,7 @@ export function FuncForPC(_pc: number): Func | null {
|
|
|
104
105
|
|
|
105
106
|
// StartTrace enables execution tracing.
|
|
106
107
|
export function StartTrace(): $.GoError {
|
|
107
|
-
return
|
|
108
|
+
return $.newError('runtime: execution tracing is unsupported in GoScript')
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
// StopTrace stops execution tracing.
|