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.
Files changed (295) 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} +7 -0
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/cmd/goscript-wasm/main.go +38 -6
  8. package/compiler/compile-request.go +12 -9
  9. package/compiler/compliance_test.go +0 -1
  10. package/compiler/config.go +2 -0
  11. package/compiler/diagnostic.go +104 -12
  12. package/compiler/diagnostic_test.go +106 -0
  13. package/compiler/gotest/request.go +28 -0
  14. package/compiler/gotest/runner.go +354 -44
  15. package/compiler/gotest/runner_test.go +293 -1
  16. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  17. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  18. package/compiler/index.test.ts +23 -0
  19. package/compiler/lowered-program.go +33 -24
  20. package/compiler/lowering.go +746 -194
  21. package/compiler/lowering_bench_test.go +42 -27
  22. package/compiler/lowering_internal_test.go +18 -0
  23. package/compiler/override-facts.go +15 -0
  24. package/compiler/override-parity-verifier.go +450 -0
  25. package/compiler/override-parity.go +122 -0
  26. package/compiler/override-registry_test.go +559 -0
  27. package/compiler/protobuf-ts-binding.go +567 -0
  28. package/compiler/protobuf-ts-binding_test.go +402 -0
  29. package/compiler/runtime-contract.go +4 -0
  30. package/compiler/runtime-contract_test.go +2 -0
  31. package/compiler/semantic-model-types.go +9 -4
  32. package/compiler/semantic-model.go +282 -70
  33. package/compiler/semantic-model_test.go +82 -1
  34. package/compiler/service.go +21 -1
  35. package/compiler/skeleton_test.go +118 -10
  36. package/compiler/typescript-emitter.go +128 -13
  37. package/compiler/wasm/compile_test.go +37 -4
  38. package/compiler/{wasm_api.go → wasm-api.go} +57 -7
  39. package/dist/gs/builtin/hostio.js +5 -0
  40. package/dist/gs/builtin/hostio.js.map +1 -1
  41. package/dist/gs/builtin/slice.d.ts +13 -2
  42. package/dist/gs/builtin/slice.js +187 -6
  43. package/dist/gs/builtin/slice.js.map +1 -1
  44. package/dist/gs/builtin/type.d.ts +13 -5
  45. package/dist/gs/builtin/type.js +153 -60
  46. package/dist/gs/builtin/type.js.map +1 -1
  47. package/dist/gs/builtin/varRef.d.ts +11 -0
  48. package/dist/gs/builtin/varRef.js +57 -2
  49. package/dist/gs/builtin/varRef.js.map +1 -1
  50. package/dist/gs/bytes/buffer.gs.js +1 -1
  51. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  52. package/dist/gs/bytes/reader.gs.js +1 -1
  53. package/dist/gs/bytes/reader.gs.js.map +1 -1
  54. package/dist/gs/compress/zlib/index.d.ts +10 -3
  55. package/dist/gs/compress/zlib/index.js +50 -16
  56. package/dist/gs/compress/zlib/index.js.map +1 -1
  57. package/dist/gs/encoding/json/index.d.ts +114 -0
  58. package/dist/gs/encoding/json/index.js +544 -36
  59. package/dist/gs/encoding/json/index.js.map +1 -1
  60. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +101 -0
  61. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +589 -0
  62. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  63. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +1 -0
  64. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +17 -11
  65. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
  66. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  67. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  68. package/dist/gs/go/scanner/index.d.ts +2 -0
  69. package/dist/gs/go/scanner/index.js +29 -5
  70. package/dist/gs/go/scanner/index.js.map +1 -1
  71. package/dist/gs/go/token/index.js +22 -6
  72. package/dist/gs/go/token/index.js.map +1 -1
  73. package/dist/gs/hash/index.d.ts +6 -0
  74. package/dist/gs/hash/index.js +20 -0
  75. package/dist/gs/hash/index.js.map +1 -1
  76. package/dist/gs/internal/byteorder/index.js +2 -2
  77. package/dist/gs/internal/byteorder/index.js.map +1 -1
  78. package/dist/gs/internal/goarch/index.d.ts +43 -3
  79. package/dist/gs/internal/goarch/index.js +42 -10
  80. package/dist/gs/internal/goarch/index.js.map +1 -1
  81. package/dist/gs/io/fs/fs.js +26 -14
  82. package/dist/gs/io/fs/fs.js.map +1 -1
  83. package/dist/gs/io/fs/readdir.js +4 -2
  84. package/dist/gs/io/fs/readdir.js.map +1 -1
  85. package/dist/gs/io/fs/sub.js +8 -1
  86. package/dist/gs/io/fs/sub.js.map +1 -1
  87. package/dist/gs/io/io.d.ts +2 -0
  88. package/dist/gs/io/io.js.map +1 -1
  89. package/dist/gs/math/bits/index.d.ts +5 -0
  90. package/dist/gs/math/bits/index.js +16 -4
  91. package/dist/gs/math/bits/index.js.map +1 -1
  92. package/dist/gs/mime/index.d.ts +16 -0
  93. package/dist/gs/mime/index.js +315 -6
  94. package/dist/gs/mime/index.js.map +1 -1
  95. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  96. package/dist/gs/net/http/httptest/index.js +85 -6
  97. package/dist/gs/net/http/httptest/index.js.map +1 -1
  98. package/dist/gs/net/http/index.d.ts +300 -5
  99. package/dist/gs/net/http/index.js +1598 -58
  100. package/dist/gs/net/http/index.js.map +1 -1
  101. package/dist/gs/os/dir_unix.gs.js +1 -1
  102. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  103. package/dist/gs/os/error.gs.js +1 -1
  104. package/dist/gs/os/error.gs.js.map +1 -1
  105. package/dist/gs/os/exec.gs.d.ts +1 -0
  106. package/dist/gs/os/exec.gs.js +4 -8
  107. package/dist/gs/os/exec.gs.js.map +1 -1
  108. package/dist/gs/os/exec_posix.gs.js +1 -1
  109. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  110. package/dist/gs/os/index.d.ts +1 -1
  111. package/dist/gs/os/index.js +1 -1
  112. package/dist/gs/os/index.js.map +1 -1
  113. package/dist/gs/os/proc.gs.d.ts +4 -0
  114. package/dist/gs/os/proc.gs.js +12 -6
  115. package/dist/gs/os/proc.gs.js.map +1 -1
  116. package/dist/gs/os/root_js.gs.js +1 -1
  117. package/dist/gs/os/root_js.gs.js.map +1 -1
  118. package/dist/gs/os/types.gs.js +1 -1
  119. package/dist/gs/os/types.gs.js.map +1 -1
  120. package/dist/gs/os/types_js.gs.js +1 -1
  121. package/dist/gs/os/types_js.gs.js.map +1 -1
  122. package/dist/gs/os/types_unix.gs.js +1 -1
  123. package/dist/gs/os/types_unix.gs.js.map +1 -1
  124. package/dist/gs/path/path.js +11 -7
  125. package/dist/gs/path/path.js.map +1 -1
  126. package/dist/gs/reflect/index.d.ts +5 -4
  127. package/dist/gs/reflect/index.js +4 -3
  128. package/dist/gs/reflect/index.js.map +1 -1
  129. package/dist/gs/reflect/map.js +15 -0
  130. package/dist/gs/reflect/map.js.map +1 -1
  131. package/dist/gs/reflect/type.d.ts +25 -6
  132. package/dist/gs/reflect/type.js +1475 -228
  133. package/dist/gs/reflect/type.js.map +1 -1
  134. package/dist/gs/reflect/types.d.ts +14 -6
  135. package/dist/gs/reflect/types.js +35 -1
  136. package/dist/gs/reflect/types.js.map +1 -1
  137. package/dist/gs/reflect/value.d.ts +1 -0
  138. package/dist/gs/reflect/value.js +83 -41
  139. package/dist/gs/reflect/value.js.map +1 -1
  140. package/dist/gs/reflect/visiblefields.js +4 -140
  141. package/dist/gs/reflect/visiblefields.js.map +1 -1
  142. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  143. package/dist/gs/runtime/pprof/index.js +50 -30
  144. package/dist/gs/runtime/pprof/index.js.map +1 -1
  145. package/dist/gs/runtime/runtime.js +5 -4
  146. package/dist/gs/runtime/runtime.js.map +1 -1
  147. package/dist/gs/runtime/trace/index.js +5 -19
  148. package/dist/gs/runtime/trace/index.js.map +1 -1
  149. package/dist/gs/strconv/atoi.gs.js +1 -1
  150. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  151. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  152. package/dist/gs/strconv/complex.gs.js +148 -0
  153. package/dist/gs/strconv/complex.gs.js.map +1 -0
  154. package/dist/gs/strconv/index.d.ts +1 -0
  155. package/dist/gs/strconv/index.js +1 -0
  156. package/dist/gs/strconv/index.js.map +1 -1
  157. package/dist/gs/strings/builder.js +1 -1
  158. package/dist/gs/strings/reader.js +9 -5
  159. package/dist/gs/strings/reader.js.map +1 -1
  160. package/dist/gs/strings/replace.js +15 -7
  161. package/dist/gs/strings/replace.js.map +1 -1
  162. package/dist/gs/strings/strings.d.ts +5 -0
  163. package/dist/gs/strings/strings.js +57 -5
  164. package/dist/gs/strings/strings.js.map +1 -1
  165. package/dist/gs/sync/atomic/doc_64.gs.js +7 -6
  166. package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
  167. package/dist/gs/sync/atomic/type.gs.js +9 -9
  168. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  169. package/dist/gs/sync/atomic/value.gs.js +2 -2
  170. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  171. package/dist/gs/syscall/env.js +22 -14
  172. package/dist/gs/syscall/env.js.map +1 -1
  173. package/dist/gs/testing/testing.js +55 -13
  174. package/dist/gs/testing/testing.js.map +1 -1
  175. package/dist/gs/time/time.d.ts +24 -1
  176. package/dist/gs/time/time.js +43 -3
  177. package/dist/gs/time/time.js.map +1 -1
  178. package/dist/gs/unique/index.js +7 -1
  179. package/dist/gs/unique/index.js.map +1 -1
  180. package/go.mod +3 -3
  181. package/go.sum +16 -0
  182. package/gs/builtin/hostio.test.ts +16 -0
  183. package/gs/builtin/hostio.ts +7 -0
  184. package/gs/builtin/runtime-contract.test.ts +246 -21
  185. package/gs/builtin/slice.ts +269 -24
  186. package/gs/builtin/type.ts +226 -59
  187. package/gs/builtin/varRef.ts +85 -2
  188. package/gs/bytes/buffer.gs.ts +1 -1
  189. package/gs/bytes/reader.gs.ts +1 -1
  190. package/gs/compress/zlib/index.test.ts +62 -1
  191. package/gs/compress/zlib/index.ts +53 -16
  192. package/gs/compress/zlib/parity.json +51 -0
  193. package/gs/encoding/json/index.test.ts +360 -6
  194. package/gs/encoding/json/index.ts +679 -38
  195. package/gs/encoding/json/parity.json +81 -0
  196. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +373 -3
  197. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +893 -1
  198. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +18 -0
  199. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +17 -11
  200. package/gs/github.com/pkg/errors/errors.ts +54 -30
  201. package/gs/go/scanner/index.test.ts +39 -56
  202. package/gs/go/scanner/index.ts +33 -5
  203. package/gs/go/scanner/parity.json +27 -0
  204. package/gs/go/token/index.ts +22 -6
  205. package/gs/hash/index.test.ts +20 -33
  206. package/gs/hash/index.ts +28 -0
  207. package/gs/hash/parity.json +21 -0
  208. package/gs/internal/byteorder/index.test.ts +2 -2
  209. package/gs/internal/byteorder/index.ts +2 -2
  210. package/gs/internal/goarch/index.test.ts +32 -0
  211. package/gs/internal/goarch/index.ts +45 -13
  212. package/gs/internal/goarch/parity.json +144 -0
  213. package/gs/io/fs/fs.ts +26 -14
  214. package/gs/io/fs/readdir.ts +4 -4
  215. package/gs/io/fs/sub.ts +8 -1
  216. package/gs/io/io.ts +1 -0
  217. package/gs/io/parity.json +162 -0
  218. package/gs/math/bits/index.test.ts +14 -1
  219. package/gs/math/bits/index.ts +23 -4
  220. package/gs/math/bits/parity.json +156 -0
  221. package/gs/mime/index.test.ts +90 -0
  222. package/gs/mime/index.ts +369 -6
  223. package/gs/mime/parity.json +36 -0
  224. package/gs/net/http/httptest/index.test.ts +98 -2
  225. package/gs/net/http/httptest/index.ts +101 -6
  226. package/gs/net/http/httptest/parity.json +15 -0
  227. package/gs/net/http/index.test.ts +781 -12
  228. package/gs/net/http/index.ts +1860 -139
  229. package/gs/net/http/meta.json +16 -1
  230. package/gs/net/http/parity.json +193 -0
  231. package/gs/os/dir_unix.gs.ts +1 -1
  232. package/gs/os/error.gs.ts +1 -1
  233. package/gs/os/exec.gs.ts +4 -8
  234. package/gs/os/exec_posix.gs.ts +1 -1
  235. package/gs/os/index.test.ts +9 -0
  236. package/gs/os/index.ts +1 -0
  237. package/gs/os/parity.json +9 -0
  238. package/gs/os/proc.gs.ts +18 -5
  239. package/gs/os/proc.test.ts +26 -0
  240. package/gs/os/root_js.gs.ts +1 -1
  241. package/gs/os/types.gs.ts +1 -1
  242. package/gs/os/types_js.gs.ts +1 -1
  243. package/gs/os/types_unix.gs.ts +1 -1
  244. package/gs/path/path.ts +11 -7
  245. package/gs/reflect/field.test.ts +37 -15
  246. package/gs/reflect/function-types.test.ts +518 -22
  247. package/gs/reflect/index.ts +8 -6
  248. package/gs/reflect/map.ts +20 -0
  249. package/gs/reflect/meta.json +6 -4
  250. package/gs/reflect/parity.json +234 -0
  251. package/gs/reflect/sliceat.test.ts +156 -0
  252. package/gs/reflect/structof.test.ts +401 -0
  253. package/gs/reflect/type.ts +1961 -317
  254. package/gs/reflect/typefor.test.ts +530 -10
  255. package/gs/reflect/types.ts +43 -18
  256. package/gs/reflect/value.ts +105 -45
  257. package/gs/reflect/visiblefields.ts +5 -168
  258. package/gs/runtime/parity.json +24 -0
  259. package/gs/runtime/pprof/index.test.ts +29 -7
  260. package/gs/runtime/pprof/index.ts +56 -30
  261. package/gs/runtime/pprof/parity.json +27 -0
  262. package/gs/runtime/runtime.test.ts +3 -1
  263. package/gs/runtime/runtime.ts +4 -3
  264. package/gs/runtime/trace/index.test.ts +5 -3
  265. package/gs/runtime/trace/index.ts +8 -20
  266. package/gs/runtime/trace/parity.json +36 -0
  267. package/gs/strconv/atoi.gs.ts +1 -1
  268. package/gs/strconv/complex.gs.ts +174 -0
  269. package/gs/strconv/complex.test.ts +65 -0
  270. package/gs/strconv/index.ts +1 -0
  271. package/gs/strconv/parity.json +120 -0
  272. package/gs/strings/builder.ts +1 -1
  273. package/gs/strings/parity.json +186 -0
  274. package/gs/strings/reader.ts +9 -5
  275. package/gs/strings/replace.ts +15 -7
  276. package/gs/strings/strings.test.ts +22 -2
  277. package/gs/strings/strings.ts +64 -6
  278. package/gs/sync/atomic/doc_64.gs.ts +6 -7
  279. package/gs/sync/atomic/doc_64.test.ts +43 -0
  280. package/gs/sync/atomic/type.gs.ts +9 -9
  281. package/gs/sync/atomic/value.gs.ts +2 -2
  282. package/gs/syscall/env.ts +29 -14
  283. package/gs/testing/testing.test.ts +67 -0
  284. package/gs/testing/testing.ts +87 -19
  285. package/gs/time/parity.json +225 -0
  286. package/gs/time/time.test.ts +20 -2
  287. package/gs/time/time.ts +49 -7
  288. package/gs/unique/index.ts +7 -1
  289. package/package.json +4 -2
  290. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  291. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
  292. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  293. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
  294. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
  295. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
@@ -104,6 +104,7 @@ export type MainScriptMeta = {
104
104
  }
105
105
 
106
106
  const encoder = new TextEncoder()
107
+ const decoder = new TextDecoder()
107
108
 
108
109
  function getDynamicRequire(): ((specifier: string) => unknown) | null {
109
110
  try {
@@ -342,6 +343,12 @@ function detectHostRuntime(): HostRuntime {
342
343
  buffer,
343
344
  )
344
345
  }
346
+ if (fd === 1 || fd === 2) {
347
+ fallbackConsoleWriter(fd === 2 ? 'error' : 'log')(
348
+ decoder.decode(buffer),
349
+ )
350
+ return buffer.length
351
+ }
345
352
  throw new HostUnsupportedError()
346
353
  }
347
354
  const writeStdoutText: HostTextWrite = (data: string) => {
@@ -10,12 +10,14 @@ import {
10
10
  cloneStructValue,
11
11
  callGenericMethod,
12
12
  chanRecvWithOk,
13
+ fieldRef,
13
14
  functionValue,
14
15
  genericZero,
15
16
  goSlice,
16
17
  int,
17
18
  arrayPointerFromIndexRef,
18
19
  indexAddress,
20
+ indexByteAddress,
19
21
  indexRef,
20
22
  interfaceValue,
21
23
  len,
@@ -28,6 +30,9 @@ import {
28
30
  namedFunction,
29
31
  namedValueInterfaceValue,
30
32
  newError,
33
+ ownedPointerAddress,
34
+ ownedPointerFromRef,
35
+ ownedPointerRef,
31
36
  pointerValue,
32
37
  print,
33
38
  println,
@@ -36,6 +41,7 @@ import {
36
41
  registerStructType,
37
42
  resetHostRuntimeForTests,
38
43
  selectStatement,
44
+ sliceFromOwnedPointer,
39
45
  sliceToArray,
40
46
  sliceHeaderRef,
41
47
  stringHeaderRef,
@@ -57,6 +63,7 @@ import {
57
63
  uintShr,
58
64
  unref,
59
65
  unsupportedPointerRef,
66
+ unsafePointerRef,
60
67
  varRef,
61
68
  } from './index.js'
62
69
 
@@ -139,9 +146,12 @@ describe('builtin runtime contract helpers', () => {
139
146
  expect(uint(uint64And(0xf0n, 0x3cn), 32)).toBe(0x30)
140
147
  expect(uint(uint64Or(0xf0n, 0x0fn), 32)).toBe(0xff)
141
148
  expect(uint(uint64Xor(0xf0n, 0xffn), 32)).toBe(0x0f)
142
- expect(uint64And(uint('18446744073709551615', 64), uint('18014398509481983', 64))).toBe(
143
- 18014398509481983n,
144
- )
149
+ expect(
150
+ uint64And(
151
+ uint('18446744073709551615', 64),
152
+ uint('18014398509481983', 64),
153
+ ),
154
+ ).toBe(18014398509481983n)
145
155
  expect(uintShr(0x80000000, 31, 32)).toBe(1)
146
156
  expect(uintShr(0x80000000, 32, 32)).toBe(0)
147
157
  expect(uintShr(0xff, 4, 8)).toBe(15)
@@ -187,9 +197,9 @@ describe('builtin runtime contract helpers', () => {
187
197
  expect(bytesToUint8Array(pointerValue(namedPointerMethodBox))).toEqual(
188
198
  new Uint8Array([1, 2, 3]),
189
199
  )
190
- expect(bytesToUint8Array(goSlice(pointerValue(namedPointerMethodBox), 1))).toEqual(
191
- new Uint8Array([2, 3]),
192
- )
200
+ expect(
201
+ bytesToUint8Array(goSlice(pointerValue(namedPointerMethodBox), 1)),
202
+ ).toEqual(new Uint8Array([2, 3]))
193
203
  const namedStringBox = namedValueInterfaceValue('id', 'main.Name', {
194
204
  String: (receiver: string) => `name:${receiver}`,
195
205
  })
@@ -233,6 +243,31 @@ describe('builtin runtime contract helpers', () => {
233
243
  ])
234
244
  })
235
245
 
246
+ it('attaches owned pointer handles to variable and field refs', () => {
247
+ const local = varRef(1)
248
+ const localPointer = ownedPointerFromRef(local)
249
+ expect(localPointer).toBeDefined()
250
+ expect(ownedPointerRef(localPointer!)).toBe(local)
251
+ expect(ownedPointerAddress(localPointer!)).toBe(local.__goAddress!())
252
+ ownedPointerRef(localPointer!).value = 3
253
+ expect(local.value).toBe(3)
254
+ expect(() => sliceFromOwnedPointer(localPointer!, 1)).toThrow(
255
+ 'reflect.SliceAt requires a GoScript-owned pointer',
256
+ )
257
+
258
+ const target = { count: 2 }
259
+ const count = fieldRef(target, 'count')
260
+ const countPointer = ownedPointerFromRef(count)
261
+ expect(countPointer).toBeDefined()
262
+ ownedPointerRef(countPointer!).value = 4
263
+ expect(target.count).toBe(4)
264
+
265
+ const sameField = fieldRef(target, 'count')
266
+ expect(ownedPointerAddress(ownedPointerFromRef(sameField)!)).toBe(
267
+ ownedPointerAddress(countPointer!),
268
+ )
269
+ })
270
+
236
271
  it('matches struct map keys by Go comparable value', () => {
237
272
  class Key {
238
273
  public _fields: {
@@ -307,19 +342,16 @@ describe('builtin runtime contract helpers', () => {
307
342
  returns: [],
308
343
  },
309
344
  ])
310
- registerStructType(
311
- 'collision.Hash',
312
- new HashMessage(),
313
- [],
314
- HashMessage,
315
- {},
316
- )
345
+ registerStructType('collision.Hash', new HashMessage(), [], HashMessage, [])
317
346
 
318
347
  expect(typeAssertTuple(new HashInterfaceImpl(), 'collision.Hash')[1]).toBe(
319
348
  true,
320
349
  )
321
350
  expect(
322
- typeAssertTuple(markAsStructValue(new HashMessage()), 'collision.Hash')[1],
351
+ typeAssertTuple(
352
+ markAsStructValue(new HashMessage()),
353
+ 'collision.Hash',
354
+ )[1],
323
355
  ).toBe(true)
324
356
  })
325
357
 
@@ -393,6 +425,16 @@ describe('builtin runtime contract helpers', () => {
393
425
  arrayView[2] = 19
394
426
  expect((byteBacking as Uint8Array)[3]).toBe(19)
395
427
 
428
+ const words = [0x11223344, 0]
429
+ const wordBytes = arrayPointerFromIndexRef(indexRef(words, 0), 8, 4, 1)
430
+ const byteView = pointerValue(wordBytes) as number[]
431
+ expect(byteView[0]).toBe(0x44)
432
+ expect(byteView[3]).toBe(0x11)
433
+ byteView[4] = 0xaa
434
+ expect(words[1]).toBe(0xaa)
435
+ wordBytes.value = [1, 2, 3, 4]
436
+ expect(words[0]).toBe(0x04030201)
437
+
396
438
  shortBytes![0] = 14
397
439
  expect(bytesToUint8Array(shortBytes)).toEqual(new Uint8Array([14, 0]))
398
440
 
@@ -426,7 +468,9 @@ describe('builtin runtime contract helpers', () => {
426
468
  sh.Data = strh.Data
427
469
  sh.Len = strh.Len
428
470
  sh.Cap = strh.Len
429
- expect(bytesToUint8Array(headerBytes.value)).toEqual(new Uint8Array([97, 98, 99]))
471
+ expect(bytesToUint8Array(headerBytes.value)).toEqual(
472
+ new Uint8Array([97, 98, 99]),
473
+ )
430
474
  })
431
475
 
432
476
  it('exposes stable synthetic slice index addresses', () => {
@@ -441,6 +485,43 @@ describe('builtin runtime contract helpers', () => {
441
485
  expect(indexAddress(other, 0)).not.toBe(indexAddress(left, 0))
442
486
  })
443
487
 
488
+ it('resolves unsafe byte addresses within numeric slice elements', () => {
489
+ const words = makeSlice<number>(2, undefined, 'number')
490
+ const first = indexByteAddress(words, 0, 8)
491
+ const second = indexByteAddress(words, 1, 8)
492
+
493
+ expect(second - first).toBe(8)
494
+ unsafePointerRef<number>(first + 1).value = 0x12
495
+ unsafePointerRef<number>(first + 7).value = 0x80
496
+ expect(unsafePointerRef<number>(first + 1).value).toBe(0x12)
497
+ expect(unsafePointerRef<number>(first + 7).value).toBe(0x80)
498
+ expect(words![0]).toBe(0x8000000000001200n as unknown as number)
499
+
500
+ unsafePointerRef<number>(second).value = 0x34
501
+ expect(words![1]).toBe(0x34)
502
+ })
503
+
504
+ it('exposes owned pointer handles for addressable collection elements', () => {
505
+ const values = [1, 2, 3, 4]
506
+ const second = indexRef(values, 1)
507
+ const pointer = ownedPointerFromRef(second)
508
+
509
+ expect(pointer).toBeDefined()
510
+ expect(ownedPointerAddress(pointer!)).toBe(indexAddress(values, 1))
511
+ ownedPointerRef(pointer!).value = 8
512
+ expect(values).toEqual([1, 8, 3, 4])
513
+
514
+ const view = sliceFromOwnedPointer(pointer!, 2) as number[]
515
+ view[1] = 12
516
+ expect(values).toEqual([1, 8, 12, 4])
517
+
518
+ const bytes = new Uint8Array([5, 6, 7])
519
+ const bytePointer = ownedPointerFromRef(indexRef<number>(bytes, 1))
520
+ const byteView = sliceFromOwnedPointer(bytePointer!, 2) as Uint8Array
521
+ byteView[0] = 9
522
+ expect(Array.from(bytes)).toEqual([5, 9, 7])
523
+ })
524
+
444
525
  it('copies slices into fixed arrays with Go length checks', () => {
445
526
  const source = goSlice([1, 2, 3], 1, 3)
446
527
  const array = sliceToArray<number>(source, 2)
@@ -485,7 +566,11 @@ describe('builtin runtime contract helpers', () => {
485
566
  expect(typeAssert<Runner>(new Runner(), runnerInterface).ok).toBe(true)
486
567
  expect(typeAssert<Runner>(null, runnerInterface).ok).toBe(false)
487
568
 
488
- const emptyInterface = registerInterfaceType('phase5.EmptyInterface', null, [])
569
+ const emptyInterface = registerInterfaceType(
570
+ 'phase5.EmptyInterface',
571
+ null,
572
+ [],
573
+ )
489
574
  const fn = functionValue(() => 'ok', {
490
575
  kind: TypeKind.Function,
491
576
  params: [],
@@ -564,28 +649,40 @@ describe('builtin runtime contract helpers', () => {
564
649
  expect(bytesOk).toBe(true)
565
650
  expect(pointerValue(assertedBytesRef)).toBe(bytesRef.value)
566
651
 
652
+ const greetInfo = {
653
+ kind: TypeKind.Function,
654
+ name: 'phase5.Greet',
655
+ params: [{ kind: TypeKind.Basic, name: 'string' }],
656
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
657
+ }
567
658
  const greet = namedFunction(
568
659
  (name: string) => `hello ${name}`,
569
660
  'phase5.Greet',
661
+ greetInfo,
570
662
  )
663
+ expect(typeAssert<typeof greet>(greet, greetInfo).ok).toBe(true)
571
664
  expect(
572
665
  typeAssert<typeof greet>(greet, {
573
666
  kind: TypeKind.Function,
574
667
  name: 'phase5.Greet',
668
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
669
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
575
670
  }).ok,
576
- ).toBe(true)
671
+ ).toBe(false)
577
672
  expect(
578
673
  typeAssert<{ Name: string }>(
579
674
  { Name: 'Alice' },
580
675
  {
581
676
  kind: TypeKind.Struct,
582
677
  methods: [],
583
- fields: {
584
- Name: {
678
+ fields: [
679
+ {
680
+ name: 'Name',
681
+ key: 'Name',
585
682
  type: { kind: TypeKind.Basic, name: 'string' },
586
683
  tag: 'json:"name"',
587
684
  },
588
- },
685
+ ],
589
686
  },
590
687
  ).ok,
591
688
  ).toBe(true)
@@ -596,6 +693,20 @@ describe('builtin runtime contract helpers', () => {
596
693
  })
597
694
  expect(literal(7)).toBe('7')
598
695
  expect(literal).toHaveProperty('__typeInfo')
696
+ expect(
697
+ typeAssert<typeof literal>(literal, {
698
+ kind: TypeKind.Function,
699
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
700
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
701
+ }).ok,
702
+ ).toBe(true)
703
+ expect(
704
+ typeAssert<(...args: unknown[]) => unknown>(() => undefined, {
705
+ kind: TypeKind.Function,
706
+ params: [],
707
+ results: [],
708
+ }).ok,
709
+ ).toBe(false)
599
710
 
600
711
  const genericArgs = {
601
712
  T: {
@@ -609,6 +720,118 @@ describe('builtin runtime contract helpers', () => {
609
720
  expect(callGenericMethod(genericArgs, 'T', 'String', 12)).toBe('12')
610
721
  })
611
722
 
723
+ it('compares anonymous descriptors inside function assertions', () => {
724
+ const acceptsAny = functionValue((value: unknown) => String(value), {
725
+ kind: TypeKind.Function,
726
+ name: 'main.AcceptsAny',
727
+ params: [{ kind: TypeKind.Interface, methods: [] }],
728
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
729
+ })
730
+
731
+ expect(
732
+ typeAssert<typeof acceptsAny>(acceptsAny, {
733
+ kind: TypeKind.Function,
734
+ name: 'main.AcceptsAny',
735
+ params: [{ kind: TypeKind.Interface, methods: [] }],
736
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
737
+ }).ok,
738
+ ).toBe(true)
739
+
740
+ const acceptsStruct = functionValue(
741
+ (value: { Name: string }) => value.Name,
742
+ {
743
+ kind: TypeKind.Function,
744
+ name: 'main.AcceptsStruct',
745
+ params: [
746
+ {
747
+ kind: TypeKind.Struct,
748
+ methods: [],
749
+ fields: [
750
+ {
751
+ name: 'Name',
752
+ type: { kind: TypeKind.Basic, name: 'string' },
753
+ tag: 'json:"name"',
754
+ },
755
+ ],
756
+ },
757
+ ],
758
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
759
+ },
760
+ )
761
+
762
+ expect(
763
+ typeAssert<typeof acceptsStruct>(acceptsStruct, {
764
+ kind: TypeKind.Function,
765
+ name: 'main.AcceptsStruct',
766
+ params: [
767
+ {
768
+ kind: TypeKind.Struct,
769
+ methods: [],
770
+ fields: [
771
+ {
772
+ name: 'Name',
773
+ type: { kind: TypeKind.Basic, name: 'string' },
774
+ tag: 'json:"name"',
775
+ },
776
+ ],
777
+ },
778
+ ],
779
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
780
+ }).ok,
781
+ ).toBe(true)
782
+ expect(
783
+ typeAssert<typeof acceptsStruct>(acceptsStruct, {
784
+ kind: TypeKind.Function,
785
+ name: 'main.AcceptsStruct',
786
+ params: [
787
+ {
788
+ kind: TypeKind.Struct,
789
+ methods: [],
790
+ fields: [
791
+ {
792
+ name: 'Name',
793
+ type: { kind: TypeKind.Basic, name: 'string' },
794
+ tag: 'json:"other"',
795
+ },
796
+ ],
797
+ },
798
+ ],
799
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
800
+ }).ok,
801
+ ).toBe(false)
802
+
803
+ const acceptsAlias = functionValue((value: number) => value, {
804
+ kind: TypeKind.Function,
805
+ name: 'main.AcceptsAlias',
806
+ params: [{ kind: TypeKind.Basic, name: 'int', typeName: 'main.A' }],
807
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
808
+ })
809
+ expect(
810
+ typeAssert<typeof acceptsAlias>(acceptsAlias, {
811
+ kind: TypeKind.Function,
812
+ name: 'main.AcceptsAlias',
813
+ params: [{ kind: TypeKind.Basic, name: 'int', typeName: 'main.A' }],
814
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
815
+ }).ok,
816
+ ).toBe(true)
817
+ expect(
818
+ typeAssert<typeof acceptsAlias>(acceptsAlias, {
819
+ kind: TypeKind.Function,
820
+ name: 'main.AcceptsAlias',
821
+ params: [{ kind: TypeKind.Basic, name: 'int', typeName: 'main.B' }],
822
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
823
+ }).ok,
824
+ ).toBe(false)
825
+ expect(
826
+ typeAssert<typeof acceptsAlias>(acceptsAlias, {
827
+ kind: TypeKind.Function,
828
+ name: 'main.AcceptsAlias',
829
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
830
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
831
+ }).ok,
832
+ ).toBe(false)
833
+ })
834
+
612
835
  it('exposes channel helpers used by future lowering', async () => {
613
836
  const channel = makeChannel<number>(1, 0, 'both')
614
837
  expect(cap(channel)).toBe(1)
@@ -674,7 +897,9 @@ describe('builtin runtime contract helpers', () => {
674
897
  await signal.send('value')
675
898
  const received = await Promise.race([
676
899
  signal.receive(),
677
- new Promise<string>((resolve) => setTimeout(() => resolve('timeout'), 20)),
900
+ new Promise<string>((resolve) =>
901
+ setTimeout(() => resolve('timeout'), 20),
902
+ ),
678
903
  ])
679
904
  expect(received).toBe('value')
680
905
  })