goscript 0.1.3 → 0.2.0

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.
Files changed (330) hide show
  1. package/README.md +5 -2
  2. package/cmd/go_js_wasm_exec/main.go +201 -0
  3. package/cmd/go_js_wasm_exec/main_test.go +83 -0
  4. package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/cmd/goscript/cmd_compile_test.go +105 -6
  8. package/compiler/build-flags.go +9 -10
  9. package/compiler/compile-request.go +12 -9
  10. package/compiler/compliance_test.go +0 -1
  11. package/compiler/config.go +2 -0
  12. package/compiler/gotest/request.go +28 -0
  13. package/compiler/gotest/runner.go +353 -27
  14. package/compiler/gotest/runner_test.go +400 -1
  15. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  16. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  17. package/compiler/lowered-program.go +24 -17
  18. package/compiler/lowering.go +988 -263
  19. package/compiler/lowering_bench_test.go +364 -0
  20. package/compiler/override-facts.go +15 -0
  21. package/compiler/override-parity-verifier.go +450 -0
  22. package/compiler/override-parity.go +122 -0
  23. package/compiler/override-registry_test.go +559 -0
  24. package/compiler/package-graph.go +61 -4
  25. package/compiler/package-graph_test.go +30 -0
  26. package/compiler/protobuf-ts-binding.go +514 -0
  27. package/compiler/protobuf-ts-binding_test.go +172 -0
  28. package/compiler/semantic-model-types.go +17 -4
  29. package/compiler/semantic-model.go +709 -72
  30. package/compiler/semantic-model_test.go +219 -0
  31. package/compiler/service.go +20 -1
  32. package/compiler/skeleton_test.go +1008 -20
  33. package/compiler/typescript-emitter.go +147 -15
  34. package/dist/gs/builtin/builtin.d.ts +2 -2
  35. package/dist/gs/builtin/builtin.js +20 -0
  36. package/dist/gs/builtin/builtin.js.map +1 -1
  37. package/dist/gs/builtin/slice.d.ts +2 -1
  38. package/dist/gs/builtin/slice.js +34 -4
  39. package/dist/gs/builtin/slice.js.map +1 -1
  40. package/dist/gs/builtin/type.d.ts +14 -6
  41. package/dist/gs/builtin/type.js +224 -64
  42. package/dist/gs/builtin/type.js.map +1 -1
  43. package/dist/gs/builtin/varRef.d.ts +11 -0
  44. package/dist/gs/builtin/varRef.js +57 -2
  45. package/dist/gs/builtin/varRef.js.map +1 -1
  46. package/dist/gs/bytes/buffer.gs.js +1 -1
  47. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  48. package/dist/gs/bytes/reader.gs.js +1 -1
  49. package/dist/gs/bytes/reader.gs.js.map +1 -1
  50. package/dist/gs/compress/zlib/index.d.ts +13 -6
  51. package/dist/gs/compress/zlib/index.js +131 -35
  52. package/dist/gs/compress/zlib/index.js.map +1 -1
  53. package/dist/gs/crypto/sha1/index.js +2 -5
  54. package/dist/gs/crypto/sha1/index.js.map +1 -1
  55. package/dist/gs/crypto/sha256/index.js +2 -5
  56. package/dist/gs/crypto/sha256/index.js.map +1 -1
  57. package/dist/gs/crypto/sha512/index.js +2 -5
  58. package/dist/gs/crypto/sha512/index.js.map +1 -1
  59. package/dist/gs/embed/index.d.ts +6 -0
  60. package/dist/gs/embed/index.js +210 -5
  61. package/dist/gs/embed/index.js.map +1 -1
  62. package/dist/gs/encoding/json/index.d.ts +114 -0
  63. package/dist/gs/encoding/json/index.js +544 -36
  64. package/dist/gs/encoding/json/index.js.map +1 -1
  65. package/dist/gs/fmt/fmt.d.ts +3 -3
  66. package/dist/gs/fmt/fmt.js +29 -16
  67. package/dist/gs/fmt/fmt.js.map +1 -1
  68. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
  69. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
  70. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  71. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
  72. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
  73. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
  74. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  75. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  76. package/dist/gs/go/scanner/index.d.ts +2 -0
  77. package/dist/gs/go/scanner/index.js +29 -5
  78. package/dist/gs/go/scanner/index.js.map +1 -1
  79. package/dist/gs/go/token/index.js +22 -6
  80. package/dist/gs/go/token/index.js.map +1 -1
  81. package/dist/gs/hash/index.d.ts +6 -0
  82. package/dist/gs/hash/index.js +20 -0
  83. package/dist/gs/hash/index.js.map +1 -1
  84. package/dist/gs/internal/goarch/index.d.ts +43 -3
  85. package/dist/gs/internal/goarch/index.js +42 -10
  86. package/dist/gs/internal/goarch/index.js.map +1 -1
  87. package/dist/gs/io/fs/fs.js +26 -14
  88. package/dist/gs/io/fs/fs.js.map +1 -1
  89. package/dist/gs/io/fs/readdir.js +8 -4
  90. package/dist/gs/io/fs/readdir.js.map +1 -1
  91. package/dist/gs/io/fs/sub.js +8 -1
  92. package/dist/gs/io/fs/sub.js.map +1 -1
  93. package/dist/gs/io/io.d.ts +12 -6
  94. package/dist/gs/io/io.js +87 -42
  95. package/dist/gs/io/io.js.map +1 -1
  96. package/dist/gs/math/bits/index.d.ts +31 -5
  97. package/dist/gs/math/bits/index.js +29 -28
  98. package/dist/gs/math/bits/index.js.map +1 -1
  99. package/dist/gs/mime/index.d.ts +16 -0
  100. package/dist/gs/mime/index.js +315 -6
  101. package/dist/gs/mime/index.js.map +1 -1
  102. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  103. package/dist/gs/net/http/httptest/index.js +85 -6
  104. package/dist/gs/net/http/httptest/index.js.map +1 -1
  105. package/dist/gs/net/http/index.d.ts +303 -6
  106. package/dist/gs/net/http/index.js +1615 -58
  107. package/dist/gs/net/http/index.js.map +1 -1
  108. package/dist/gs/os/dir_unix.gs.js +1 -1
  109. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  110. package/dist/gs/os/error.gs.js +1 -1
  111. package/dist/gs/os/error.gs.js.map +1 -1
  112. package/dist/gs/os/exec.gs.d.ts +1 -0
  113. package/dist/gs/os/exec.gs.js +4 -8
  114. package/dist/gs/os/exec.gs.js.map +1 -1
  115. package/dist/gs/os/exec_posix.gs.js +1 -1
  116. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  117. package/dist/gs/os/index.d.ts +1 -1
  118. package/dist/gs/os/index.js +1 -1
  119. package/dist/gs/os/index.js.map +1 -1
  120. package/dist/gs/os/proc.gs.d.ts +4 -0
  121. package/dist/gs/os/proc.gs.js +12 -6
  122. package/dist/gs/os/proc.gs.js.map +1 -1
  123. package/dist/gs/os/root_js.gs.js +1 -1
  124. package/dist/gs/os/root_js.gs.js.map +1 -1
  125. package/dist/gs/os/types.gs.js +1 -1
  126. package/dist/gs/os/types.gs.js.map +1 -1
  127. package/dist/gs/os/types_js.gs.d.ts +6 -2
  128. package/dist/gs/os/types_js.gs.js +170 -9
  129. package/dist/gs/os/types_js.gs.js.map +1 -1
  130. package/dist/gs/os/types_unix.gs.js +1 -1
  131. package/dist/gs/os/types_unix.gs.js.map +1 -1
  132. package/dist/gs/path/path.js +11 -7
  133. package/dist/gs/path/path.js.map +1 -1
  134. package/dist/gs/reflect/index.d.ts +5 -4
  135. package/dist/gs/reflect/index.js +4 -3
  136. package/dist/gs/reflect/index.js.map +1 -1
  137. package/dist/gs/reflect/map.js +15 -0
  138. package/dist/gs/reflect/map.js.map +1 -1
  139. package/dist/gs/reflect/type.d.ts +26 -6
  140. package/dist/gs/reflect/type.js +1498 -279
  141. package/dist/gs/reflect/type.js.map +1 -1
  142. package/dist/gs/reflect/types.d.ts +14 -6
  143. package/dist/gs/reflect/types.js +35 -1
  144. package/dist/gs/reflect/types.js.map +1 -1
  145. package/dist/gs/reflect/value.d.ts +1 -0
  146. package/dist/gs/reflect/value.js +83 -41
  147. package/dist/gs/reflect/value.js.map +1 -1
  148. package/dist/gs/reflect/visiblefields.js +4 -140
  149. package/dist/gs/reflect/visiblefields.js.map +1 -1
  150. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  151. package/dist/gs/runtime/pprof/index.js +50 -30
  152. package/dist/gs/runtime/pprof/index.js.map +1 -1
  153. package/dist/gs/runtime/runtime.js +5 -4
  154. package/dist/gs/runtime/runtime.js.map +1 -1
  155. package/dist/gs/runtime/trace/index.js +5 -19
  156. package/dist/gs/runtime/trace/index.js.map +1 -1
  157. package/dist/gs/strconv/atoi.gs.js +1 -1
  158. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  159. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  160. package/dist/gs/strconv/complex.gs.js +148 -0
  161. package/dist/gs/strconv/complex.gs.js.map +1 -0
  162. package/dist/gs/strconv/index.d.ts +1 -0
  163. package/dist/gs/strconv/index.js +1 -0
  164. package/dist/gs/strconv/index.js.map +1 -1
  165. package/dist/gs/strings/builder.js +1 -1
  166. package/dist/gs/strings/reader.d.ts +1 -1
  167. package/dist/gs/strings/reader.js +11 -7
  168. package/dist/gs/strings/reader.js.map +1 -1
  169. package/dist/gs/strings/replace.js +15 -7
  170. package/dist/gs/strings/replace.js.map +1 -1
  171. package/dist/gs/strings/strings.d.ts +5 -0
  172. package/dist/gs/strings/strings.js +57 -5
  173. package/dist/gs/strings/strings.js.map +1 -1
  174. package/dist/gs/sync/atomic/type.gs.js +9 -9
  175. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  176. package/dist/gs/sync/atomic/value.gs.js +2 -2
  177. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  178. package/dist/gs/sync/sync.d.ts +2 -1
  179. package/dist/gs/sync/sync.js +37 -16
  180. package/dist/gs/sync/sync.js.map +1 -1
  181. package/dist/gs/syscall/env.js +22 -14
  182. package/dist/gs/syscall/env.js.map +1 -1
  183. package/dist/gs/syscall/js/index.js +9 -0
  184. package/dist/gs/syscall/js/index.js.map +1 -1
  185. package/dist/gs/testing/testing.js +59 -15
  186. package/dist/gs/testing/testing.js.map +1 -1
  187. package/dist/gs/time/time.d.ts +24 -1
  188. package/dist/gs/time/time.js +43 -3
  189. package/dist/gs/time/time.js.map +1 -1
  190. package/dist/gs/unique/index.js +7 -1
  191. package/dist/gs/unique/index.js.map +1 -1
  192. package/go.mod +3 -3
  193. package/go.sum +16 -0
  194. package/gs/builtin/builtin.ts +25 -2
  195. package/gs/builtin/runtime-contract.test.ts +260 -18
  196. package/gs/builtin/slice.ts +51 -4
  197. package/gs/builtin/type.ts +310 -63
  198. package/gs/builtin/varRef.ts +85 -2
  199. package/gs/bytes/buffer.gs.ts +1 -1
  200. package/gs/bytes/reader.gs.ts +1 -1
  201. package/gs/compress/zlib/index.test.ts +159 -1
  202. package/gs/compress/zlib/index.ts +164 -37
  203. package/gs/compress/zlib/meta.json +4 -1
  204. package/gs/compress/zlib/parity.json +51 -0
  205. package/gs/crypto/sha1/index.test.ts +19 -2
  206. package/gs/crypto/sha1/index.ts +3 -6
  207. package/gs/crypto/sha256/index.test.ts +14 -2
  208. package/gs/crypto/sha256/index.ts +3 -6
  209. package/gs/crypto/sha512/index.test.ts +17 -2
  210. package/gs/crypto/sha512/index.ts +3 -6
  211. package/gs/embed/index.test.ts +87 -0
  212. package/gs/embed/index.ts +229 -5
  213. package/gs/encoding/json/index.test.ts +360 -6
  214. package/gs/encoding/json/index.ts +679 -38
  215. package/gs/encoding/json/parity.json +81 -0
  216. package/gs/fmt/fmt.test.ts +41 -3
  217. package/gs/fmt/fmt.ts +40 -17
  218. package/gs/fmt/meta.json +6 -1
  219. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
  220. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
  221. package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
  222. package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
  223. package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
  224. package/gs/github.com/pkg/errors/errors.ts +54 -30
  225. package/gs/go/scanner/index.test.ts +39 -56
  226. package/gs/go/scanner/index.ts +33 -5
  227. package/gs/go/scanner/parity.json +27 -0
  228. package/gs/go/token/index.ts +22 -6
  229. package/gs/hash/index.test.ts +20 -33
  230. package/gs/hash/index.ts +28 -0
  231. package/gs/hash/parity.json +21 -0
  232. package/gs/internal/goarch/index.test.ts +32 -0
  233. package/gs/internal/goarch/index.ts +45 -13
  234. package/gs/internal/goarch/parity.json +144 -0
  235. package/gs/io/fs/fs.ts +26 -14
  236. package/gs/io/fs/readdir.test.ts +38 -0
  237. package/gs/io/fs/readdir.ts +8 -4
  238. package/gs/io/fs/sub.ts +8 -1
  239. package/gs/io/io.test.ts +77 -6
  240. package/gs/io/io.ts +115 -52
  241. package/gs/io/meta.json +7 -1
  242. package/gs/io/parity.json +162 -0
  243. package/gs/math/bits/index.test.ts +14 -1
  244. package/gs/math/bits/index.ts +75 -32
  245. package/gs/math/bits/parity.json +156 -0
  246. package/gs/mime/index.test.ts +90 -0
  247. package/gs/mime/index.ts +369 -6
  248. package/gs/mime/parity.json +36 -0
  249. package/gs/net/http/httptest/index.test.ts +98 -2
  250. package/gs/net/http/httptest/index.ts +101 -6
  251. package/gs/net/http/httptest/parity.json +15 -0
  252. package/gs/net/http/index.test.ts +797 -12
  253. package/gs/net/http/index.ts +1874 -136
  254. package/gs/net/http/meta.json +16 -1
  255. package/gs/net/http/parity.json +193 -0
  256. package/gs/os/dir_unix.gs.ts +1 -1
  257. package/gs/os/error.gs.ts +1 -1
  258. package/gs/os/exec.gs.ts +4 -8
  259. package/gs/os/exec_posix.gs.ts +1 -1
  260. package/gs/os/file_unix_js.test.ts +52 -0
  261. package/gs/os/index.test.ts +9 -0
  262. package/gs/os/index.ts +1 -0
  263. package/gs/os/meta.json +4 -0
  264. package/gs/os/parity.json +9 -0
  265. package/gs/os/proc.gs.ts +18 -5
  266. package/gs/os/proc.test.ts +26 -0
  267. package/gs/os/readdir.test.ts +56 -0
  268. package/gs/os/root_js.gs.ts +1 -1
  269. package/gs/os/types.gs.ts +1 -1
  270. package/gs/os/types_js.gs.ts +170 -9
  271. package/gs/os/types_unix.gs.ts +1 -1
  272. package/gs/path/path.ts +11 -7
  273. package/gs/reflect/deepequal.test.ts +10 -1
  274. package/gs/reflect/field.test.ts +37 -15
  275. package/gs/reflect/function-types.test.ts +518 -22
  276. package/gs/reflect/index.ts +8 -6
  277. package/gs/reflect/map.ts +20 -0
  278. package/gs/reflect/meta.json +6 -4
  279. package/gs/reflect/parity.json +234 -0
  280. package/gs/reflect/sliceat.test.ts +156 -0
  281. package/gs/reflect/structof.test.ts +401 -0
  282. package/gs/reflect/type.ts +1980 -365
  283. package/gs/reflect/typefor.test.ts +540 -10
  284. package/gs/reflect/types.ts +43 -18
  285. package/gs/reflect/value.ts +105 -45
  286. package/gs/reflect/visiblefields.ts +5 -168
  287. package/gs/runtime/parity.json +24 -0
  288. package/gs/runtime/pprof/index.test.ts +29 -7
  289. package/gs/runtime/pprof/index.ts +56 -30
  290. package/gs/runtime/pprof/parity.json +27 -0
  291. package/gs/runtime/runtime.test.ts +3 -1
  292. package/gs/runtime/runtime.ts +4 -3
  293. package/gs/runtime/trace/index.test.ts +5 -3
  294. package/gs/runtime/trace/index.ts +8 -20
  295. package/gs/runtime/trace/parity.json +36 -0
  296. package/gs/strconv/atoi.gs.ts +1 -1
  297. package/gs/strconv/complex.gs.ts +174 -0
  298. package/gs/strconv/complex.test.ts +65 -0
  299. package/gs/strconv/index.ts +1 -0
  300. package/gs/strconv/parity.json +120 -0
  301. package/gs/strings/builder.ts +1 -1
  302. package/gs/strings/meta.json +5 -2
  303. package/gs/strings/parity.json +186 -0
  304. package/gs/strings/reader.test.ts +2 -2
  305. package/gs/strings/reader.ts +11 -7
  306. package/gs/strings/replace.ts +15 -7
  307. package/gs/strings/strings.test.ts +22 -2
  308. package/gs/strings/strings.ts +64 -6
  309. package/gs/sync/atomic/type.gs.ts +9 -9
  310. package/gs/sync/atomic/value.gs.ts +2 -2
  311. package/gs/sync/meta.json +1 -0
  312. package/gs/sync/sync.test.ts +41 -1
  313. package/gs/sync/sync.ts +41 -16
  314. package/gs/syscall/env.ts +29 -14
  315. package/gs/syscall/js/index.test.ts +18 -0
  316. package/gs/syscall/js/index.ts +12 -0
  317. package/gs/testing/testing.test.ts +99 -3
  318. package/gs/testing/testing.ts +95 -24
  319. package/gs/time/parity.json +225 -0
  320. package/gs/time/time.test.ts +20 -2
  321. package/gs/time/time.ts +49 -7
  322. package/gs/unique/index.ts +7 -1
  323. package/package.json +4 -2
  324. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  325. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
  326. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  327. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
  328. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
  329. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
  330. /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
@@ -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
- let zeroValue: ReflectValue
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
- zeroValue = false
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
- zeroValue = 0
67
- break
71
+ return 0
68
72
  case String:
69
- zeroValue = ''
70
- break
73
+ return ''
71
74
  case Slice:
72
75
  case Array:
73
- zeroValue = []
74
- break
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
- zeroValue = null
77
- break
85
+ return null
78
86
  }
87
+ }
79
88
 
80
- return new Value(zeroValue, typ)
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
- // Check if this is a pointer type
124
- const type = v.Type()
125
- if (type.Kind() === Ptr) {
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
- // For the pointer value, we'll use the zero value but with pointer type
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
- if (
158
- p &&
159
- typeof p === 'object' &&
160
- 'value' in p &&
161
- (p as { value?: unknown }).value instanceof Value
162
- ) {
163
- const target = (p as { value: Value }).value
164
- const ref: $.VarRef<ReflectValue> = {
165
- get value(): ReflectValue {
166
- return target.Interface() as ReflectValue
167
- },
168
- set value(value: ReflectValue) {
169
- target.Set(new Value(value, typ))
170
- },
171
- __isVarRef: true,
172
- }
173
- return new Value(ref, ptrType)
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 new Value($.unsupportedPointerRef<ReflectValue>(p), ptrType)
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 { Type, Ptr, Struct } from './type.js'
2
+ import { Struct, Type, visibleStructFields } from './type.js'
3
3
  import { StructField } from './types.js'
4
4
 
5
- // VisibleFields returns all the visible fields in t, which must be a
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!.Kind() != 25) {
19
- $.panic('reflect.VisibleFields of non-struct type ' + t!.String())
10
+ if (t.Kind() !== Struct) {
11
+ $.panic('reflect.VisibleFields of non-struct type ' + t.String())
20
12
  }
21
- let w = new visibleFieldsWalker({
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('writes deterministic CPU profile bytes', () => {
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)).toBeNull()
15
+ expect(StartCPUProfile(writer)?.Error()).toBe(
16
+ 'runtime/pprof: profiles are unsupported in GoScript',
17
+ )
16
18
  StopCPUProfile()
17
19
 
18
- expect(chunks.reduce((total, chunk) => total + chunk.length, 0)).toBeGreaterThan(0)
20
+ expect(chunks).toHaveLength(0)
19
21
  })
20
22
 
21
- it('writes deterministic memory profile bytes', () => {
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)).toBeNull()
34
- expect(chunks.reduce((total, chunk) => total + chunk.length, 0)).toBeGreaterThan(0)
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
- let activeCPUWriter: io.Writer | null = null
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 === '' ? 0 : 1
26
+ return this.builtIn && this.name !== '' ? 1 : this.values.size
22
27
  }
23
28
 
24
- public WriteTo(w: WriterArg, debug: number): $.GoError {
25
- return writeProfile(w, `goscript pprof ${this.name} debug=${debug}\n`)
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
- if (activeCPUWriter != null) {
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
- if (activeCPUWriter != null) {
68
- writeProfile(activeCPUWriter, 'goscript cpu profile stop\n')
69
- activeCPUWriter = null
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
- function writeProfile(w: WriterArg, text: string): $.GoError {
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()).toBeNull()
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
  })
@@ -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
- if (typeof globalThis.gc === 'function') {
40
- ;(globalThis as any).gc()
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 null
108
+ return $.newError('runtime: execution tracing is unsupported in GoScript')
108
109
  }
109
110
 
110
111
  // StopTrace stops execution tracing.