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
@@ -10,6 +10,7 @@ import {
10
10
  cloneStructValue,
11
11
  callGenericMethod,
12
12
  chanRecvWithOk,
13
+ fieldRef,
13
14
  functionValue,
14
15
  genericZero,
15
16
  goSlice,
@@ -28,6 +29,9 @@ import {
28
29
  namedFunction,
29
30
  namedValueInterfaceValue,
30
31
  newError,
32
+ ownedPointerAddress,
33
+ ownedPointerFromRef,
34
+ ownedPointerRef,
31
35
  pointerValue,
32
36
  print,
33
37
  println,
@@ -36,6 +40,7 @@ import {
36
40
  registerStructType,
37
41
  resetHostRuntimeForTests,
38
42
  selectStatement,
43
+ sliceFromOwnedPointer,
39
44
  sliceToArray,
40
45
  sliceHeaderRef,
41
46
  stringHeaderRef,
@@ -139,6 +144,12 @@ describe('builtin runtime contract helpers', () => {
139
144
  expect(uint(uint64And(0xf0n, 0x3cn), 32)).toBe(0x30)
140
145
  expect(uint(uint64Or(0xf0n, 0x0fn), 32)).toBe(0xff)
141
146
  expect(uint(uint64Xor(0xf0n, 0xffn), 32)).toBe(0x0f)
147
+ expect(
148
+ uint64And(
149
+ uint('18446744073709551615', 64),
150
+ uint('18014398509481983', 64),
151
+ ),
152
+ ).toBe(18014398509481983n)
142
153
  expect(uintShr(0x80000000, 31, 32)).toBe(1)
143
154
  expect(uintShr(0x80000000, 32, 32)).toBe(0)
144
155
  expect(uintShr(0xff, 4, 8)).toBe(15)
@@ -164,6 +175,9 @@ describe('builtin runtime contract helpers', () => {
164
175
  }),
165
176
  ).toEqual({ value: nilNamedSlice, ok: true })
166
177
  expect(pointerValue({ ok: true })).toEqual({ ok: true })
178
+ const nilSliceIface = interfaceValue(null, '[]*main.StatusEntry')
179
+ expect(len(nilSliceIface as any)).toBe(0)
180
+ expect(cap(nilSliceIface as any)).toBe(0)
167
181
  const namedPointerBox = namedValueInterfaceValue(
168
182
  varRef(new Uint8Array([1, 2])),
169
183
  '*main.Bytes',
@@ -181,9 +195,9 @@ describe('builtin runtime contract helpers', () => {
181
195
  expect(bytesToUint8Array(pointerValue(namedPointerMethodBox))).toEqual(
182
196
  new Uint8Array([1, 2, 3]),
183
197
  )
184
- expect(bytesToUint8Array(goSlice(pointerValue(namedPointerMethodBox), 1))).toEqual(
185
- new Uint8Array([2, 3]),
186
- )
198
+ expect(
199
+ bytesToUint8Array(goSlice(pointerValue(namedPointerMethodBox), 1)),
200
+ ).toEqual(new Uint8Array([2, 3]))
187
201
  const namedStringBox = namedValueInterfaceValue('id', 'main.Name', {
188
202
  String: (receiver: string) => `name:${receiver}`,
189
203
  })
@@ -227,6 +241,31 @@ describe('builtin runtime contract helpers', () => {
227
241
  ])
228
242
  })
229
243
 
244
+ it('attaches owned pointer handles to variable and field refs', () => {
245
+ const local = varRef(1)
246
+ const localPointer = ownedPointerFromRef(local)
247
+ expect(localPointer).toBeDefined()
248
+ expect(ownedPointerRef(localPointer!)).toBe(local)
249
+ expect(ownedPointerAddress(localPointer!)).toBe(local.__goAddress!())
250
+ ownedPointerRef(localPointer!).value = 3
251
+ expect(local.value).toBe(3)
252
+ expect(() => sliceFromOwnedPointer(localPointer!, 1)).toThrow(
253
+ 'reflect.SliceAt requires a GoScript-owned pointer',
254
+ )
255
+
256
+ const target = { count: 2 }
257
+ const count = fieldRef(target, 'count')
258
+ const countPointer = ownedPointerFromRef(count)
259
+ expect(countPointer).toBeDefined()
260
+ ownedPointerRef(countPointer!).value = 4
261
+ expect(target.count).toBe(4)
262
+
263
+ const sameField = fieldRef(target, 'count')
264
+ expect(ownedPointerAddress(ownedPointerFromRef(sameField)!)).toBe(
265
+ ownedPointerAddress(countPointer!),
266
+ )
267
+ })
268
+
230
269
  it('matches struct map keys by Go comparable value', () => {
231
270
  class Key {
232
271
  public _fields: {
@@ -301,19 +340,16 @@ describe('builtin runtime contract helpers', () => {
301
340
  returns: [],
302
341
  },
303
342
  ])
304
- registerStructType(
305
- 'collision.Hash',
306
- new HashMessage(),
307
- [],
308
- HashMessage,
309
- {},
310
- )
343
+ registerStructType('collision.Hash', new HashMessage(), [], HashMessage, [])
311
344
 
312
345
  expect(typeAssertTuple(new HashInterfaceImpl(), 'collision.Hash')[1]).toBe(
313
346
  true,
314
347
  )
315
348
  expect(
316
- typeAssertTuple(markAsStructValue(new HashMessage()), 'collision.Hash')[1],
349
+ typeAssertTuple(
350
+ markAsStructValue(new HashMessage()),
351
+ 'collision.Hash',
352
+ )[1],
317
353
  ).toBe(true)
318
354
  })
319
355
 
@@ -331,6 +367,30 @@ describe('builtin runtime contract helpers', () => {
331
367
  ).toEqual([13, true])
332
368
  })
333
369
 
370
+ it('asserts fixed-width numeric values by runtime type name', () => {
371
+ expect(
372
+ typeAssertTuple<number>(13, { kind: TypeKind.Basic, name: 'uint64' }),
373
+ ).toEqual([13, true])
374
+ expect(
375
+ typeAssertTuple<number>(13, { kind: TypeKind.Basic, name: 'int32' }),
376
+ ).toEqual([13, true])
377
+ })
378
+
379
+ it('asserts typed byte-slice pointers through uint8 descriptors', () => {
380
+ const bytes = varRef(makeSlice<number>(4, undefined, 'byte'))
381
+ const boxed = interfaceValue(bytes, '*[]byte')
382
+
383
+ expect(
384
+ typeAssertTuple<typeof bytes>(boxed, {
385
+ kind: TypeKind.Pointer,
386
+ elemType: {
387
+ kind: TypeKind.Slice,
388
+ elemType: { kind: TypeKind.Basic, name: 'uint8' },
389
+ },
390
+ }),
391
+ ).toEqual([bytes, true])
392
+ })
393
+
334
394
  it('exposes addressable slice and array index references', () => {
335
395
  const values = [1, 2, 3]
336
396
  const second = indexRef(values, 1)
@@ -396,7 +456,9 @@ describe('builtin runtime contract helpers', () => {
396
456
  sh.Data = strh.Data
397
457
  sh.Len = strh.Len
398
458
  sh.Cap = strh.Len
399
- expect(bytesToUint8Array(headerBytes.value)).toEqual(new Uint8Array([97, 98, 99]))
459
+ expect(bytesToUint8Array(headerBytes.value)).toEqual(
460
+ new Uint8Array([97, 98, 99]),
461
+ )
400
462
  })
401
463
 
402
464
  it('exposes stable synthetic slice index addresses', () => {
@@ -411,6 +473,27 @@ describe('builtin runtime contract helpers', () => {
411
473
  expect(indexAddress(other, 0)).not.toBe(indexAddress(left, 0))
412
474
  })
413
475
 
476
+ it('exposes owned pointer handles for addressable collection elements', () => {
477
+ const values = [1, 2, 3, 4]
478
+ const second = indexRef(values, 1)
479
+ const pointer = ownedPointerFromRef(second)
480
+
481
+ expect(pointer).toBeDefined()
482
+ expect(ownedPointerAddress(pointer!)).toBe(indexAddress(values, 1))
483
+ ownedPointerRef(pointer!).value = 8
484
+ expect(values).toEqual([1, 8, 3, 4])
485
+
486
+ const view = sliceFromOwnedPointer(pointer!, 2) as number[]
487
+ view[1] = 12
488
+ expect(values).toEqual([1, 8, 12, 4])
489
+
490
+ const bytes = new Uint8Array([5, 6, 7])
491
+ const bytePointer = ownedPointerFromRef(indexRef<number>(bytes, 1))
492
+ const byteView = sliceFromOwnedPointer(bytePointer!, 2) as Uint8Array
493
+ byteView[0] = 9
494
+ expect(Array.from(bytes)).toEqual([5, 9, 7])
495
+ })
496
+
414
497
  it('copies slices into fixed arrays with Go length checks', () => {
415
498
  const source = goSlice([1, 2, 3], 1, 3)
416
499
  const array = sliceToArray<number>(source, 2)
@@ -455,7 +538,11 @@ describe('builtin runtime contract helpers', () => {
455
538
  expect(typeAssert<Runner>(new Runner(), runnerInterface).ok).toBe(true)
456
539
  expect(typeAssert<Runner>(null, runnerInterface).ok).toBe(false)
457
540
 
458
- const emptyInterface = registerInterfaceType('phase5.EmptyInterface', null, [])
541
+ const emptyInterface = registerInterfaceType(
542
+ 'phase5.EmptyInterface',
543
+ null,
544
+ [],
545
+ )
459
546
  const fn = functionValue(() => 'ok', {
460
547
  kind: TypeKind.Function,
461
548
  params: [],
@@ -519,28 +606,55 @@ describe('builtin runtime contract helpers', () => {
519
606
  )
520
607
  expect(typeAssert<{ Name(): string }>(dogRef, dogInterface).ok).toBe(true)
521
608
 
609
+ const bytesRef = varRef<Bytes>(new Uint8Array([1, 2, 3]))
610
+ const boxedBytesRef = interfaceValue<any>(bytesRef, '*[]byte')
611
+ const [assertedBytesRef, bytesOk] = typeAssertTuple<typeof bytesRef>(
612
+ boxedBytesRef,
613
+ {
614
+ kind: TypeKind.Pointer,
615
+ elemType: {
616
+ kind: TypeKind.Slice,
617
+ elemType: { kind: TypeKind.Basic, name: 'int' },
618
+ },
619
+ },
620
+ )
621
+ expect(bytesOk).toBe(true)
622
+ expect(pointerValue(assertedBytesRef)).toBe(bytesRef.value)
623
+
624
+ const greetInfo = {
625
+ kind: TypeKind.Function,
626
+ name: 'phase5.Greet',
627
+ params: [{ kind: TypeKind.Basic, name: 'string' }],
628
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
629
+ }
522
630
  const greet = namedFunction(
523
631
  (name: string) => `hello ${name}`,
524
632
  'phase5.Greet',
633
+ greetInfo,
525
634
  )
635
+ expect(typeAssert<typeof greet>(greet, greetInfo).ok).toBe(true)
526
636
  expect(
527
637
  typeAssert<typeof greet>(greet, {
528
638
  kind: TypeKind.Function,
529
639
  name: 'phase5.Greet',
640
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
641
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
530
642
  }).ok,
531
- ).toBe(true)
643
+ ).toBe(false)
532
644
  expect(
533
645
  typeAssert<{ Name: string }>(
534
646
  { Name: 'Alice' },
535
647
  {
536
648
  kind: TypeKind.Struct,
537
649
  methods: [],
538
- fields: {
539
- Name: {
650
+ fields: [
651
+ {
652
+ name: 'Name',
653
+ key: 'Name',
540
654
  type: { kind: TypeKind.Basic, name: 'string' },
541
655
  tag: 'json:"name"',
542
656
  },
543
- },
657
+ ],
544
658
  },
545
659
  ).ok,
546
660
  ).toBe(true)
@@ -551,6 +665,20 @@ describe('builtin runtime contract helpers', () => {
551
665
  })
552
666
  expect(literal(7)).toBe('7')
553
667
  expect(literal).toHaveProperty('__typeInfo')
668
+ expect(
669
+ typeAssert<typeof literal>(literal, {
670
+ kind: TypeKind.Function,
671
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
672
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
673
+ }).ok,
674
+ ).toBe(true)
675
+ expect(
676
+ typeAssert<(...args: unknown[]) => unknown>(() => undefined, {
677
+ kind: TypeKind.Function,
678
+ params: [],
679
+ results: [],
680
+ }).ok,
681
+ ).toBe(false)
554
682
 
555
683
  const genericArgs = {
556
684
  T: {
@@ -564,6 +692,118 @@ describe('builtin runtime contract helpers', () => {
564
692
  expect(callGenericMethod(genericArgs, 'T', 'String', 12)).toBe('12')
565
693
  })
566
694
 
695
+ it('compares anonymous descriptors inside function assertions', () => {
696
+ const acceptsAny = functionValue((value: unknown) => String(value), {
697
+ kind: TypeKind.Function,
698
+ name: 'main.AcceptsAny',
699
+ params: [{ kind: TypeKind.Interface, methods: [] }],
700
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
701
+ })
702
+
703
+ expect(
704
+ typeAssert<typeof acceptsAny>(acceptsAny, {
705
+ kind: TypeKind.Function,
706
+ name: 'main.AcceptsAny',
707
+ params: [{ kind: TypeKind.Interface, methods: [] }],
708
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
709
+ }).ok,
710
+ ).toBe(true)
711
+
712
+ const acceptsStruct = functionValue(
713
+ (value: { Name: string }) => value.Name,
714
+ {
715
+ kind: TypeKind.Function,
716
+ name: 'main.AcceptsStruct',
717
+ params: [
718
+ {
719
+ kind: TypeKind.Struct,
720
+ methods: [],
721
+ fields: [
722
+ {
723
+ name: 'Name',
724
+ type: { kind: TypeKind.Basic, name: 'string' },
725
+ tag: 'json:"name"',
726
+ },
727
+ ],
728
+ },
729
+ ],
730
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
731
+ },
732
+ )
733
+
734
+ expect(
735
+ typeAssert<typeof acceptsStruct>(acceptsStruct, {
736
+ kind: TypeKind.Function,
737
+ name: 'main.AcceptsStruct',
738
+ params: [
739
+ {
740
+ kind: TypeKind.Struct,
741
+ methods: [],
742
+ fields: [
743
+ {
744
+ name: 'Name',
745
+ type: { kind: TypeKind.Basic, name: 'string' },
746
+ tag: 'json:"name"',
747
+ },
748
+ ],
749
+ },
750
+ ],
751
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
752
+ }).ok,
753
+ ).toBe(true)
754
+ expect(
755
+ typeAssert<typeof acceptsStruct>(acceptsStruct, {
756
+ kind: TypeKind.Function,
757
+ name: 'main.AcceptsStruct',
758
+ params: [
759
+ {
760
+ kind: TypeKind.Struct,
761
+ methods: [],
762
+ fields: [
763
+ {
764
+ name: 'Name',
765
+ type: { kind: TypeKind.Basic, name: 'string' },
766
+ tag: 'json:"other"',
767
+ },
768
+ ],
769
+ },
770
+ ],
771
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
772
+ }).ok,
773
+ ).toBe(false)
774
+
775
+ const acceptsAlias = functionValue((value: number) => value, {
776
+ kind: TypeKind.Function,
777
+ name: 'main.AcceptsAlias',
778
+ params: [{ kind: TypeKind.Basic, name: 'int', typeName: 'main.A' }],
779
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
780
+ })
781
+ expect(
782
+ typeAssert<typeof acceptsAlias>(acceptsAlias, {
783
+ kind: TypeKind.Function,
784
+ name: 'main.AcceptsAlias',
785
+ params: [{ kind: TypeKind.Basic, name: 'int', typeName: 'main.A' }],
786
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
787
+ }).ok,
788
+ ).toBe(true)
789
+ expect(
790
+ typeAssert<typeof acceptsAlias>(acceptsAlias, {
791
+ kind: TypeKind.Function,
792
+ name: 'main.AcceptsAlias',
793
+ params: [{ kind: TypeKind.Basic, name: 'int', typeName: 'main.B' }],
794
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
795
+ }).ok,
796
+ ).toBe(false)
797
+ expect(
798
+ typeAssert<typeof acceptsAlias>(acceptsAlias, {
799
+ kind: TypeKind.Function,
800
+ name: 'main.AcceptsAlias',
801
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
802
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
803
+ }).ok,
804
+ ).toBe(false)
805
+ })
806
+
567
807
  it('exposes channel helpers used by future lowering', async () => {
568
808
  const channel = makeChannel<number>(1, 0, 'both')
569
809
  expect(cap(channel)).toBe(1)
@@ -629,7 +869,9 @@ describe('builtin runtime contract helpers', () => {
629
869
  await signal.send('value')
630
870
  const received = await Promise.race([
631
871
  signal.receive(),
632
- new Promise<string>((resolve) => setTimeout(() => resolve('timeout'), 20)),
872
+ new Promise<string>((resolve) =>
873
+ setTimeout(() => resolve('timeout'), 20),
874
+ ),
633
875
  ])
634
876
  expect(received).toBe('value')
635
877
  })
@@ -1,4 +1,10 @@
1
- import { isVarRef, varRef, type VarRef } from './varRef.js'
1
+ import {
2
+ isOwnedPointerHandle,
3
+ isVarRef,
4
+ varRef,
5
+ type OwnedPointerHandle,
6
+ type VarRef,
7
+ } from './varRef.js'
2
8
 
3
9
  export class GoBinaryString extends String {
4
10
  readonly bytes: Uint8Array
@@ -1291,7 +1297,7 @@ export function indexRef<T>(
1291
1297
  `runtime error: index out of range [${index}] with length ${collection.length}`,
1292
1298
  )
1293
1299
  }
1294
- return {
1300
+ const ref: VarRef<T> = {
1295
1301
  get value() {
1296
1302
  return collection[index] as T
1297
1303
  },
@@ -1303,6 +1309,8 @@ export function indexRef<T>(
1303
1309
  __goCollection: collection,
1304
1310
  __goIndex: index,
1305
1311
  }
1312
+ ref.__goPointer = collectionPointer(ref, collection, index)
1313
+ return ref
1306
1314
  }
1307
1315
  if (isComplexSlice(collection)) {
1308
1316
  if (index < 0 || index >= collection.__meta__.length) {
@@ -1311,7 +1319,7 @@ export function indexRef<T>(
1311
1319
  )
1312
1320
  }
1313
1321
  const backingIndex = collection.__meta__.offset + index
1314
- return {
1322
+ const ref: VarRef<T> = {
1315
1323
  get value() {
1316
1324
  return collection.__meta__.backing[backingIndex]
1317
1325
  },
@@ -1323,6 +1331,8 @@ export function indexRef<T>(
1323
1331
  __goCollection: collection,
1324
1332
  __goIndex: index,
1325
1333
  }
1334
+ ref.__goPointer = collectionPointer(ref, collection, index)
1335
+ return ref
1326
1336
  }
1327
1337
  if (Array.isArray(collection)) {
1328
1338
  if (index < 0 || index >= collection.length) {
@@ -1330,7 +1340,7 @@ export function indexRef<T>(
1330
1340
  `runtime error: index out of range [${index}] with length ${collection.length}`,
1331
1341
  )
1332
1342
  }
1333
- return {
1343
+ const ref: VarRef<T> = {
1334
1344
  get value() {
1335
1345
  return collection[index]
1336
1346
  },
@@ -1342,10 +1352,40 @@ export function indexRef<T>(
1342
1352
  __goCollection: collection,
1343
1353
  __goIndex: index,
1344
1354
  }
1355
+ ref.__goPointer = collectionPointer(ref, collection, index)
1356
+ return ref
1345
1357
  }
1346
1358
  throw new Error('runtime error: index on unsupported type')
1347
1359
  }
1348
1360
 
1361
+ function collectionPointer<T>(
1362
+ ref: VarRef<T>,
1363
+ collection: Slice<T> | T[] | Uint8Array,
1364
+ index: number,
1365
+ ): OwnedPointerHandle<T> {
1366
+ return {
1367
+ __goOwnedPointer: true,
1368
+ __goAddress: () => indexAddress(collection, index),
1369
+ __goRef: () => ref,
1370
+ __goSlice: (length: number) => {
1371
+ if (length < 0) {
1372
+ throw new Error('runtime error: unsafe slice length out of range')
1373
+ }
1374
+ return goSlice(collection as any, index, index + length, index + length)
1375
+ },
1376
+ }
1377
+ }
1378
+
1379
+ export function sliceFromOwnedPointer<T>(
1380
+ pointer: OwnedPointerHandle<T>,
1381
+ length: number,
1382
+ ): Slice<T> | Uint8Array {
1383
+ if (!isOwnedPointerHandle(pointer) || pointer.__goSlice === undefined) {
1384
+ throw new Error('reflect.SliceAt requires a GoScript-owned pointer')
1385
+ }
1386
+ return pointer.__goSlice(length) as Slice<T> | Uint8Array
1387
+ }
1388
+
1349
1389
  /**
1350
1390
  * arrayPointerFromIndexRef turns &slice[i] into a pointer to an N-element array
1351
1391
  * view. This models unsafe conversions such as (*[64]byte)(unsafe.Pointer(&b[0]))
@@ -1684,6 +1724,13 @@ function collectionValue(value: unknown): unknown {
1684
1724
  if (isVarRef(value)) {
1685
1725
  return collectionValue(value.value)
1686
1726
  }
1727
+ if (
1728
+ typeof value === 'object' &&
1729
+ value !== null &&
1730
+ (value as { __isTypedNil?: unknown }).__isTypedNil === true
1731
+ ) {
1732
+ return null
1733
+ }
1687
1734
  if (
1688
1735
  typeof value === 'object' &&
1689
1736
  value !== null &&