goscript 0.2.6 → 0.2.7

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 (264) hide show
  1. package/cmd/goscript/cmd-compile.go +7 -0
  2. package/cmd/goscript/cmd_compile_test.go +83 -0
  3. package/compiler/compile-request.go +3 -0
  4. package/compiler/compiler-cache.go +828 -0
  5. package/compiler/compiler-cache_test.go +705 -0
  6. package/compiler/config.go +2 -0
  7. package/compiler/index.test.ts +26 -1
  8. package/compiler/index.ts +5 -0
  9. package/compiler/lowered-program.go +31 -20
  10. package/compiler/lowering.go +349 -93
  11. package/compiler/lowering_bench_test.go +1 -0
  12. package/compiler/override-facts.go +309 -8
  13. package/compiler/override-parity-verifier.go +45 -1
  14. package/compiler/override-parity-verifier_test.go +100 -0
  15. package/compiler/override-registry_test.go +1 -0
  16. package/compiler/package-graph.go +40 -12
  17. package/compiler/package-graph_test.go +29 -0
  18. package/compiler/runtime-contract.go +8 -0
  19. package/compiler/service.go +98 -11
  20. package/compiler/skeleton_test.go +110 -14
  21. package/compiler/typescript-emitter.go +120 -23
  22. package/dist/compiler/index.d.ts +2 -0
  23. package/dist/compiler/index.js +3 -0
  24. package/dist/compiler/index.js.map +1 -1
  25. package/dist/gs/builtin/builtin.d.ts +24 -33
  26. package/dist/gs/builtin/builtin.js +54 -61
  27. package/dist/gs/builtin/builtin.js.map +1 -1
  28. package/dist/gs/builtin/hostio.d.ts +1 -0
  29. package/dist/gs/builtin/hostio.js +1 -1
  30. package/dist/gs/builtin/hostio.js.map +1 -1
  31. package/dist/gs/builtin/index.d.ts +1 -0
  32. package/dist/gs/builtin/index.js +1 -0
  33. package/dist/gs/builtin/index.js.map +1 -1
  34. package/dist/gs/builtin/panic.d.ts +18 -0
  35. package/dist/gs/builtin/panic.js +98 -0
  36. package/dist/gs/builtin/panic.js.map +1 -0
  37. package/dist/gs/builtin/slice.d.ts +10 -0
  38. package/dist/gs/builtin/slice.js +110 -53
  39. package/dist/gs/builtin/slice.js.map +1 -1
  40. package/dist/gs/builtin/type.js +15 -3
  41. package/dist/gs/builtin/type.js.map +1 -1
  42. package/dist/gs/builtin/varRef.d.ts +1 -1
  43. package/dist/gs/builtin/varRef.js +3 -2
  44. package/dist/gs/builtin/varRef.js.map +1 -1
  45. package/dist/gs/bytes/bytes.gs.js +51 -38
  46. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  47. package/dist/gs/bytes/reader.gs.d.ts +1 -1
  48. package/dist/gs/bytes/reader.gs.js +6 -7
  49. package/dist/gs/bytes/reader.gs.js.map +1 -1
  50. package/dist/gs/cmp/index.d.ts +1 -1
  51. package/dist/gs/cmp/index.js +43 -10
  52. package/dist/gs/cmp/index.js.map +1 -1
  53. package/dist/gs/context/context.d.ts +2 -2
  54. package/dist/gs/context/context.js +1 -1
  55. package/dist/gs/context/context.js.map +1 -1
  56. package/dist/gs/embed/index.js +1 -1
  57. package/dist/gs/embed/index.js.map +1 -1
  58. package/dist/gs/encoding/binary/index.js +201 -8
  59. package/dist/gs/encoding/binary/index.js.map +1 -1
  60. package/dist/gs/encoding/json/index.d.ts +5 -0
  61. package/dist/gs/encoding/json/index.js +388 -25
  62. package/dist/gs/encoding/json/index.js.map +1 -1
  63. package/dist/gs/errors/errors.js +17 -24
  64. package/dist/gs/errors/errors.js.map +1 -1
  65. package/dist/gs/fmt/fmt.js +129 -35
  66. package/dist/gs/fmt/fmt.js.map +1 -1
  67. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1 -1
  68. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -1
  69. package/dist/gs/internal/bytealg/index.js +43 -8
  70. package/dist/gs/internal/bytealg/index.js.map +1 -1
  71. package/dist/gs/internal/byteorder/index.d.ts +2 -2
  72. package/dist/gs/internal/byteorder/index.js +2 -2
  73. package/dist/gs/internal/byteorder/index.js.map +1 -1
  74. package/dist/gs/io/fs/format.js +2 -2
  75. package/dist/gs/io/fs/format.js.map +1 -1
  76. package/dist/gs/io/fs/fs.d.ts +1 -1
  77. package/dist/gs/io/fs/fs.js +1 -1
  78. package/dist/gs/io/fs/fs.js.map +1 -1
  79. package/dist/gs/io/io.d.ts +21 -21
  80. package/dist/gs/io/io.js +49 -50
  81. package/dist/gs/io/io.js.map +1 -1
  82. package/dist/gs/math/bits/index.js +26 -8
  83. package/dist/gs/math/bits/index.js.map +1 -1
  84. package/dist/gs/math/copysign.gs.js +10 -17
  85. package/dist/gs/math/copysign.gs.js.map +1 -1
  86. package/dist/gs/math/pow.gs.js +5 -0
  87. package/dist/gs/math/pow.gs.js.map +1 -1
  88. package/dist/gs/math/signbit.gs.js +6 -2
  89. package/dist/gs/math/signbit.gs.js.map +1 -1
  90. package/dist/gs/mime/index.js +1 -0
  91. package/dist/gs/mime/index.js.map +1 -1
  92. package/dist/gs/net/http/index.d.ts +6 -6
  93. package/dist/gs/net/http/index.js +507 -43
  94. package/dist/gs/net/http/index.js.map +1 -1
  95. package/dist/gs/os/stat.gs.d.ts +2 -2
  96. package/dist/gs/os/types.gs.d.ts +1 -1
  97. package/dist/gs/os/types.gs.js +1 -1
  98. package/dist/gs/os/types.gs.js.map +1 -1
  99. package/dist/gs/os/types_js.gs.d.ts +1 -1
  100. package/dist/gs/os/types_js.gs.js +7 -7
  101. package/dist/gs/os/types_js.gs.js.map +1 -1
  102. package/dist/gs/os/types_unix.gs.d.ts +1 -1
  103. package/dist/gs/os/types_unix.gs.js +1 -1
  104. package/dist/gs/os/types_unix.gs.js.map +1 -1
  105. package/dist/gs/os/zero_copy_posix.gs.d.ts +1 -1
  106. package/dist/gs/os/zero_copy_posix.gs.js +1 -1
  107. package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
  108. package/dist/gs/path/filepath/match.js +8 -4
  109. package/dist/gs/path/filepath/match.js.map +1 -1
  110. package/dist/gs/path/filepath/path.js +216 -42
  111. package/dist/gs/path/filepath/path.js.map +1 -1
  112. package/dist/gs/path/match.js +6 -3
  113. package/dist/gs/path/match.js.map +1 -1
  114. package/dist/gs/reflect/type.d.ts +5 -4
  115. package/dist/gs/reflect/type.js +29 -11
  116. package/dist/gs/reflect/type.js.map +1 -1
  117. package/dist/gs/slices/slices.js +11 -11
  118. package/dist/gs/slices/slices.js.map +1 -1
  119. package/dist/gs/strconv/atof.gs.js +156 -43
  120. package/dist/gs/strconv/atof.gs.js.map +1 -1
  121. package/dist/gs/strconv/atoi.gs.d.ts +3 -2
  122. package/dist/gs/strconv/atoi.gs.js +86 -67
  123. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  124. package/dist/gs/strconv/ftoa.gs.js +73 -3
  125. package/dist/gs/strconv/ftoa.gs.js.map +1 -1
  126. package/dist/gs/strconv/itoa.gs.d.ts +4 -4
  127. package/dist/gs/strconv/itoa.gs.js +5 -4
  128. package/dist/gs/strconv/itoa.gs.js.map +1 -1
  129. package/dist/gs/strconv/quote.gs.d.ts +1 -1
  130. package/dist/gs/strconv/quote.gs.js +311 -103
  131. package/dist/gs/strconv/quote.gs.js.map +1 -1
  132. package/dist/gs/strings/reader.d.ts +1 -1
  133. package/dist/gs/strings/reader.js +8 -8
  134. package/dist/gs/strings/reader.js.map +1 -1
  135. package/dist/gs/strings/strings.js +87 -61
  136. package/dist/gs/strings/strings.js.map +1 -1
  137. package/dist/gs/sync/atomic/doc_64.gs.d.ts +14 -14
  138. package/dist/gs/sync/atomic/doc_64.gs.js +10 -10
  139. package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
  140. package/dist/gs/sync/atomic/type.gs.d.ts +22 -22
  141. package/dist/gs/sync/atomic/type.gs.js +4 -4
  142. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  143. package/dist/gs/sync/sync.js +50 -12
  144. package/dist/gs/sync/sync.js.map +1 -1
  145. package/dist/gs/syscall/fs.d.ts +6 -6
  146. package/dist/gs/syscall/fs.js +1 -1
  147. package/dist/gs/syscall/fs.js.map +1 -1
  148. package/dist/gs/time/time.d.ts +18 -18
  149. package/dist/gs/time/time.js +58 -55
  150. package/dist/gs/time/time.js.map +1 -1
  151. package/dist/gs/unicode/tables.d.ts +11 -0
  152. package/dist/gs/unicode/tables.js +635 -0
  153. package/dist/gs/unicode/tables.js.map +1 -0
  154. package/dist/gs/unicode/unicode.d.ts +58 -38
  155. package/dist/gs/unicode/unicode.js +362 -278
  156. package/dist/gs/unicode/unicode.js.map +1 -1
  157. package/go.sum +13 -0
  158. package/gs/builtin/builtin.ts +83 -93
  159. package/gs/builtin/hostio.ts +1 -1
  160. package/gs/builtin/index.ts +1 -0
  161. package/gs/builtin/panic.test.ts +189 -0
  162. package/gs/builtin/panic.ts +107 -0
  163. package/gs/builtin/runtime-contract.test.ts +5 -5
  164. package/gs/builtin/slice.test.ts +23 -0
  165. package/gs/builtin/slice.ts +133 -95
  166. package/gs/builtin/type.ts +16 -3
  167. package/gs/builtin/varRef.ts +4 -2
  168. package/gs/builtin/wide-int.test.ts +41 -0
  169. package/gs/bytes/bytes.gs.ts +54 -41
  170. package/gs/bytes/bytes.test.ts +18 -1
  171. package/gs/bytes/reader.gs.ts +7 -8
  172. package/gs/cmp/index.test.ts +55 -0
  173. package/gs/cmp/index.ts +45 -9
  174. package/gs/context/context.ts +3 -3
  175. package/gs/embed/index.ts +2 -2
  176. package/gs/encoding/binary/index.test.ts +104 -0
  177. package/gs/encoding/binary/index.ts +259 -11
  178. package/gs/encoding/json/index.test.ts +107 -0
  179. package/gs/encoding/json/index.ts +400 -29
  180. package/gs/errors/errors.test.ts +44 -1
  181. package/gs/errors/errors.ts +15 -31
  182. package/gs/fmt/fmt.test.ts +70 -2
  183. package/gs/fmt/fmt.ts +128 -34
  184. package/gs/golang.org/x/crypto/cryptobyte/index.ts +1 -1
  185. package/gs/internal/bytealg/index.test.ts +26 -1
  186. package/gs/internal/bytealg/index.ts +44 -8
  187. package/gs/internal/byteorder/index.ts +6 -4
  188. package/gs/io/fs/format.ts +2 -2
  189. package/gs/io/fs/fs.ts +2 -2
  190. package/gs/io/fs/stat.test.ts +2 -2
  191. package/gs/io/fs/sub.test.ts +2 -2
  192. package/gs/io/fs/walk.test.ts +2 -2
  193. package/gs/io/io.test.ts +47 -5
  194. package/gs/io/io.ts +73 -73
  195. package/gs/io/limit.test.ts +103 -0
  196. package/gs/math/bits/index.test.ts +128 -0
  197. package/gs/math/bits/index.ts +26 -8
  198. package/gs/math/copysign.gs.test.ts +3 -1
  199. package/gs/math/copysign.gs.ts +10 -22
  200. package/gs/math/pow.gs.test.ts +4 -5
  201. package/gs/math/pow.gs.ts +5 -0
  202. package/gs/math/signbit.gs.test.ts +2 -1
  203. package/gs/math/signbit.gs.ts +6 -3
  204. package/gs/mime/index.ts +1 -0
  205. package/gs/net/http/index.test.ts +683 -2
  206. package/gs/net/http/index.ts +598 -57
  207. package/gs/net/http/meta.json +3 -0
  208. package/gs/os/stat.gs.ts +2 -2
  209. package/gs/os/types.gs.ts +2 -2
  210. package/gs/os/types_js.gs.ts +9 -9
  211. package/gs/os/types_unix.gs.ts +2 -2
  212. package/gs/os/zero_copy_posix.gs.ts +2 -2
  213. package/gs/path/filepath/match.test.ts +16 -0
  214. package/gs/path/filepath/match.ts +8 -4
  215. package/gs/path/filepath/path.test.ts +91 -9
  216. package/gs/path/filepath/path.ts +223 -49
  217. package/gs/path/match.test.ts +32 -0
  218. package/gs/path/match.ts +6 -3
  219. package/gs/reflect/deepequal.test.ts +1 -1
  220. package/gs/reflect/field.test.ts +1 -1
  221. package/gs/reflect/function-types.test.ts +6 -6
  222. package/gs/reflect/sliceat.test.ts +13 -13
  223. package/gs/reflect/structof.test.ts +4 -4
  224. package/gs/reflect/type.ts +34 -14
  225. package/gs/reflect/typefor.test.ts +5 -5
  226. package/gs/runtime/pprof/index.test.ts +20 -0
  227. package/gs/runtime/trace/index.test.ts +3 -0
  228. package/gs/slices/slices.test.ts +31 -0
  229. package/gs/slices/slices.ts +11 -11
  230. package/gs/strconv/append.test.ts +99 -0
  231. package/gs/strconv/atof.gs.ts +156 -42
  232. package/gs/strconv/atof.test.ts +45 -0
  233. package/gs/strconv/atoi.gs.ts +87 -69
  234. package/gs/strconv/atoi.test.ts +49 -0
  235. package/gs/strconv/ftoa.gs.ts +85 -10
  236. package/gs/strconv/ftoa.test.ts +43 -0
  237. package/gs/strconv/itoa.gs.ts +10 -9
  238. package/gs/strconv/quote.gs.ts +335 -108
  239. package/gs/strconv/quote.test.ts +111 -0
  240. package/gs/strings/reader.test.ts +10 -10
  241. package/gs/strings/reader.ts +9 -9
  242. package/gs/strings/strings.test.ts +18 -5
  243. package/gs/strings/strings.ts +81 -68
  244. package/gs/sync/atomic/doc_64.gs.ts +24 -24
  245. package/gs/sync/atomic/doc_64.test.ts +5 -5
  246. package/gs/sync/atomic/type.gs.ts +28 -28
  247. package/gs/sync/sync.test.ts +109 -1
  248. package/gs/sync/sync.ts +46 -12
  249. package/gs/syscall/fs.ts +8 -8
  250. package/gs/syscall/net.test.ts +1 -1
  251. package/gs/time/parse.test.ts +45 -0
  252. package/gs/time/time.test.ts +46 -23
  253. package/gs/time/time.ts +69 -66
  254. package/gs/unicode/gen.go +198 -0
  255. package/gs/unicode/tables.ts +646 -0
  256. package/gs/unicode/unicode.test.ts +69 -0
  257. package/gs/unicode/unicode.ts +396 -312
  258. package/package.json +1 -1
  259. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +0 -20
  260. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +0 -134
  261. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +0 -1
  262. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +0 -30
  263. package/gs/github.com/aperturerobotics/util/conc/index.ts +0 -172
  264. package/gs/github.com/aperturerobotics/util/conc/meta.json +0 -9
@@ -118,6 +118,15 @@ export declare function copy<T>(dst: Slice<T>, src: string): number;
118
118
  * @throws Error if index is out of bounds or type is unsupported.
119
119
  */
120
120
  export declare function index<T>(collection: GoStringValue | Slice<T> | T[], index: number): T | number;
121
+ /**
122
+ * arrayIndex reads collection[index] with Go bounds-check semantics, panicking
123
+ * with the Go runtime message when index is out of range. Strings and maps are
124
+ * lowered through their own helpers, so this covers Go arrays and slices. The
125
+ * overloads reproduce the element type of a direct collection[index]: a byte
126
+ * collection yields number, an element slice yields its element type.
127
+ */
128
+ export declare function arrayIndex(collection: Uint8Array, index: number): number;
129
+ export declare function arrayIndex<T>(collection: Slice<T> | T[], index: number): T;
121
130
  /**
122
131
  * indexRef returns an addressable reference to a slice or array element.
123
132
  */
@@ -169,6 +178,7 @@ export declare const stringToRune: (str: string) => number;
169
178
  * @returns The resulting string.
170
179
  */
171
180
  export declare const runesToString: (runes: Slice<number>) => string;
181
+ export declare function runeToString(r: number): string;
172
182
  /**
173
183
  * Converts a number to a byte (uint8) by truncating to the range 0-255.
174
184
  * Equivalent to Go's byte() conversion.
@@ -1,3 +1,4 @@
1
+ import { runtimePanic } from './panic.js';
1
2
  import { isOwnedPointerHandle, isVarRef, varRef, } from './varRef.js';
2
3
  export class GoBinaryString extends String {
3
4
  bytes;
@@ -63,6 +64,15 @@ function sliceIndexProperty(prop) {
63
64
  }
64
65
  return index;
65
66
  }
67
+ // outOfRangeIndex panics with Go's index-out-of-range runtime message. Go omits
68
+ // the "with length" suffix for negative indices and includes it otherwise, so
69
+ // callers route every element bounds failure through here to stay byte-faithful.
70
+ function outOfRangeIndex(index, length) {
71
+ if (index < 0) {
72
+ runtimePanic(`runtime error: index out of range [${index}]`);
73
+ }
74
+ runtimePanic(`runtime error: index out of range [${index}] with length ${length}`);
75
+ }
66
76
  /**
67
77
  * wrapSliceProxy wraps a SliceProxy in a Proxy to intercept index access
68
78
  * and route it through the backing array.
@@ -77,7 +87,7 @@ function wrapSliceProxy(proxy) {
77
87
  if (index < meta.length) {
78
88
  return meta.backing[meta.offset + index];
79
89
  }
80
- throw new Error(`Slice index out of range: ${index} >= ${meta.length}`);
90
+ outOfRangeIndex(index, meta.length);
81
91
  }
82
92
  if (prop === 'length') {
83
93
  return meta.length;
@@ -95,7 +105,7 @@ function wrapSliceProxy(proxy) {
95
105
  target[index] = value; // Also update the proxy target for consistency
96
106
  return true;
97
107
  }
98
- throw new Error(`Slice index out of range: ${index} >= ${meta.length}`);
108
+ outOfRangeIndex(index, meta.length);
99
109
  }
100
110
  if (prop === 'length' || prop === '__meta__') {
101
111
  return false;
@@ -138,7 +148,7 @@ export function asArray(slice) {
138
148
  }
139
149
  export function sliceToArray(slice, length, typeHint) {
140
150
  if (len(slice) < length) {
141
- throw new Error(`runtime error: cannot convert slice with length ${len(slice)} to array with length ${length}`);
151
+ runtimePanic(`runtime error: cannot convert slice with length ${len(slice)} to array or pointer to array with length ${length}`);
142
152
  }
143
153
  if (typeHint === 'byte') {
144
154
  return new Uint8Array(asArray(slice).slice(0, length));
@@ -147,7 +157,7 @@ export function sliceToArray(slice, length, typeHint) {
147
157
  }
148
158
  export function sliceToArrayPointer(slice, length, typeHint) {
149
159
  if (len(slice) < length) {
150
- throw new Error(`runtime error: cannot convert slice with length ${len(slice)} to array pointer with length ${length}`);
160
+ runtimePanic(`runtime error: cannot convert slice with length ${len(slice)} to array or pointer to array with length ${length}`);
151
161
  }
152
162
  if (typeHint === 'byte') {
153
163
  if (slice instanceof Uint8Array) {
@@ -208,7 +218,9 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
208
218
  if (typeHint === 'byte') {
209
219
  const actualCapacity = capacity === undefined ? length : capacity;
210
220
  if (length < 0 || actualCapacity < 0 || length > actualCapacity) {
211
- throw new Error(`Invalid slice length (${length}) or capacity (${actualCapacity})`);
221
+ runtimePanic(actualCapacity < 0 ?
222
+ 'runtime error: makeslice: cap out of range'
223
+ : 'runtime error: makeslice: len out of range');
212
224
  }
213
225
  // If capacity equals length, use Uint8Array directly for efficiency
214
226
  if (actualCapacity === length) {
@@ -218,7 +230,9 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
218
230
  }
219
231
  const actualCapacity = capacity === undefined ? length : capacity;
220
232
  if (length < 0 || actualCapacity < 0 || length > actualCapacity) {
221
- throw new Error(`Invalid slice length (${length}) or capacity (${actualCapacity})`);
233
+ runtimePanic(actualCapacity < 0 ?
234
+ 'runtime error: makeslice: cap out of range'
235
+ : 'runtime error: makeslice: len out of range');
222
236
  }
223
237
  const zeroValue = () => {
224
238
  if (zeroFactory !== undefined) {
@@ -266,7 +280,7 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
266
280
  if (index < target.__meta__.length) {
267
281
  return target.__meta__.backing[target.__meta__.offset + index];
268
282
  }
269
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
283
+ runtimePanic(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
270
284
  }
271
285
  if (prop === 'length') {
272
286
  return target.__meta__.length;
@@ -284,7 +298,7 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
284
298
  target[index] = value; // Also update the proxy target for consistency
285
299
  return true;
286
300
  }
287
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
301
+ runtimePanic(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
288
302
  }
289
303
  if (prop === 'length' || prop === '__meta__') {
290
304
  return false;
@@ -307,7 +321,7 @@ s, low, high, max) {
307
321
  if (index < target.__meta__.length) {
308
322
  return target.__meta__.backing[target.__meta__.offset + index];
309
323
  }
310
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
324
+ runtimePanic(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
311
325
  }
312
326
  if (prop === 'length') {
313
327
  return target.__meta__.length;
@@ -341,7 +355,7 @@ s, low, high, max) {
341
355
  target.__meta__.length++;
342
356
  return true;
343
357
  }
344
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
358
+ runtimePanic(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
345
359
  }
346
360
  if (prop === 'length' || prop === '__meta__') {
347
361
  return false;
@@ -361,13 +375,13 @@ s, low, high, max) {
361
375
  actualHigh < actualLow ||
362
376
  actualLow > baseCapacity ||
363
377
  actualHigh > baseCapacity) {
364
- throw new Error(`Invalid slice indices: low ${actualLow}, high ${actualHigh} for Uint8Array with capacity ${baseCapacity}`);
378
+ runtimePanic(`runtime error: slice bounds out of range [${actualLow}:${actualHigh}] with capacity ${baseCapacity}`);
365
379
  }
366
380
  const newLength = actualHigh - actualLow;
367
381
  if (max !== undefined) {
368
382
  if (max < actualHigh || max > baseCapacity) {
369
383
  // max is relative to the original s.length (capacity)
370
- throw new Error(`Invalid max index: ${max}. Constraints: low ${actualLow} <= high ${actualHigh} <= max <= capacity ${baseCapacity}`);
384
+ runtimePanic(`runtime error: slice bounds out of range [:${actualHigh}:${max}] with capacity ${baseCapacity}`);
371
385
  }
372
386
  const newCap = max - actualLow; // Capacity of the new slice view
373
387
  return byteSliceView(backing, baseOffset + actualLow, newLength, newCap);
@@ -379,13 +393,13 @@ s, low, high, max) {
379
393
  low = low ?? 0;
380
394
  high = high ?? 0;
381
395
  if (low < 0 || high < low) {
382
- throw new Error(`Invalid slice indices: ${low}:${high}`);
396
+ runtimePanic(`runtime error: slice bounds out of range [${low}:${high}]`);
383
397
  }
384
398
  if (low !== 0 || high !== 0) {
385
- throw new Error(`runtime error: slice bounds out of range [:${high}] with capacity 0`);
399
+ runtimePanic(`runtime error: slice bounds out of range [:${high}] with capacity 0`);
386
400
  }
387
401
  if (max !== undefined && max !== 0) {
388
- throw new Error(`runtime error: slice bounds out of range [::${max}] with capacity 0`);
402
+ runtimePanic(`runtime error: slice bounds out of range [::${max}] with capacity 0`);
389
403
  }
390
404
  return null;
391
405
  }
@@ -393,12 +407,12 @@ s, low, high, max) {
393
407
  low = low ?? 0;
394
408
  high = high ?? slen;
395
409
  if (low < 0 || high < low) {
396
- throw new Error(`Invalid slice indices: ${low}:${high}`);
410
+ runtimePanic(`runtime error: slice bounds out of range [${low}:${high}]`);
397
411
  }
398
412
  // In Go, high can be up to capacity, not just length
399
413
  const scap = cap(s);
400
414
  if (high > scap) {
401
- throw new Error(`Slice index out of range: ${high} > ${scap}`);
415
+ runtimePanic(`Slice index out of range: ${high} > ${scap}`);
402
416
  }
403
417
  if (Array.isArray(s) &&
404
418
  !isComplexSlice(s) &&
@@ -422,13 +436,13 @@ s, low, high, max) {
422
436
  let newCap;
423
437
  if (max !== undefined) {
424
438
  if (max < high) {
425
- throw new Error(`Invalid slice indices: ${low}:${high}:${max}`);
439
+ runtimePanic(`runtime error: slice bounds out of range [:${high}:${max}]`);
426
440
  }
427
441
  if (isComplexSlice(s) && max > oldOffset + oldCap) {
428
- throw new Error(`Slice index out of range: ${max} > ${oldOffset + oldCap}`);
442
+ runtimePanic(`Slice index out of range: ${max} > ${oldOffset + oldCap}`);
429
443
  }
430
444
  if (!isComplexSlice(s) && max > s.length) {
431
- throw new Error(`Slice index out of range: ${max} > ${s.length}`);
445
+ runtimePanic(`Slice index out of range: ${max} > ${s.length}`);
432
446
  }
433
447
  newCap = max - low;
434
448
  }
@@ -493,7 +507,7 @@ export const arrayToSlice = (arr, depth = 1) => {
493
507
  if (index < target.__meta__.length) {
494
508
  return target.__meta__.backing[target.__meta__.offset + index];
495
509
  }
496
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
510
+ runtimePanic(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
497
511
  }
498
512
  if (prop === 'length') {
499
513
  return target.__meta__.length;
@@ -525,7 +539,7 @@ export const arrayToSlice = (arr, depth = 1) => {
525
539
  target.__meta__.length++;
526
540
  return true;
527
541
  }
528
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
542
+ runtimePanic(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
529
543
  }
530
544
  if (prop === 'length' || prop === '__meta__') {
531
545
  return false;
@@ -931,41 +945,66 @@ function copySliceValues(src, count) {
931
945
  */
932
946
  export function index(collection, index) {
933
947
  if (collection === null || collection === undefined) {
934
- throw new Error('runtime error: index on nil or undefined collection');
948
+ runtimePanic('runtime error: index on nil or undefined collection');
935
949
  }
936
950
  if (isGoStringValue(collection)) {
937
951
  return indexString(collection, index); // Use the existing indexString for byte access
938
952
  }
939
953
  else if (collection instanceof Uint8Array) {
940
954
  if (index < 0 || index >= collection.length) {
941
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
955
+ outOfRangeIndex(index, collection.length);
942
956
  }
943
957
  return collection[index];
944
958
  }
945
959
  else if (isComplexSlice(collection)) {
946
960
  if (index < 0 || index >= collection.__meta__.length) {
947
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`);
961
+ outOfRangeIndex(index, collection.__meta__.length);
948
962
  }
949
963
  return collection.__meta__.backing[collection.__meta__.offset + index];
950
964
  }
951
965
  else if (Array.isArray(collection)) {
952
966
  if (index < 0 || index >= collection.length) {
953
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
967
+ outOfRangeIndex(index, collection.length);
954
968
  }
955
969
  return collection[index];
956
970
  }
957
- throw new Error('runtime error: index on unsupported type');
971
+ runtimePanic('runtime error: index on unsupported type');
972
+ }
973
+ export function arrayIndex(collection, index) {
974
+ if (collection === null || collection === undefined) {
975
+ outOfRangeIndex(index, 0);
976
+ }
977
+ if (collection instanceof Uint8Array) {
978
+ if (index < 0 || index >= collection.length) {
979
+ outOfRangeIndex(index, collection.length);
980
+ }
981
+ return collection[index];
982
+ }
983
+ if (isComplexSlice(collection)) {
984
+ const length = collection.__meta__.length;
985
+ if (index < 0 || index >= length) {
986
+ outOfRangeIndex(index, length);
987
+ }
988
+ return collection.__meta__.backing[collection.__meta__.offset + index];
989
+ }
990
+ if (Array.isArray(collection)) {
991
+ if (index < 0 || index >= collection.length) {
992
+ outOfRangeIndex(index, collection.length);
993
+ }
994
+ return collection[index];
995
+ }
996
+ runtimePanic('runtime error: index on unsupported type');
958
997
  }
959
998
  /**
960
999
  * indexRef returns an addressable reference to a slice or array element.
961
1000
  */
962
1001
  export function indexRef(collection, index) {
963
1002
  if (collection === null || collection === undefined) {
964
- throw new Error('runtime error: index on nil or undefined collection');
1003
+ runtimePanic('runtime error: index on nil or undefined collection');
965
1004
  }
966
1005
  if (collection instanceof Uint8Array) {
967
1006
  if (index < 0 || index >= collection.length) {
968
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
1007
+ outOfRangeIndex(index, collection.length);
969
1008
  }
970
1009
  const ref = {
971
1010
  get value() {
@@ -984,7 +1023,7 @@ export function indexRef(collection, index) {
984
1023
  }
985
1024
  if (isComplexSlice(collection)) {
986
1025
  if (index < 0 || index >= collection.__meta__.length) {
987
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`);
1026
+ outOfRangeIndex(index, collection.__meta__.length);
988
1027
  }
989
1028
  const backingIndex = collection.__meta__.offset + index;
990
1029
  const ref = {
@@ -1004,7 +1043,7 @@ export function indexRef(collection, index) {
1004
1043
  }
1005
1044
  if (Array.isArray(collection)) {
1006
1045
  if (index < 0 || index >= collection.length) {
1007
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
1046
+ outOfRangeIndex(index, collection.length);
1008
1047
  }
1009
1048
  const ref = {
1010
1049
  get value() {
@@ -1021,7 +1060,7 @@ export function indexRef(collection, index) {
1021
1060
  ref.__goPointer = collectionPointer(ref, collection, index);
1022
1061
  return ref;
1023
1062
  }
1024
- throw new Error('runtime error: index on unsupported type');
1063
+ runtimePanic('runtime error: index on unsupported type');
1025
1064
  }
1026
1065
  function collectionPointer(ref, collection, index) {
1027
1066
  return {
@@ -1030,7 +1069,7 @@ function collectionPointer(ref, collection, index) {
1030
1069
  __goRef: () => ref,
1031
1070
  __goSlice: (length) => {
1032
1071
  if (length < 0) {
1033
- throw new Error('runtime error: unsafe slice length out of range');
1072
+ runtimePanic('runtime error: unsafe slice length out of range');
1034
1073
  }
1035
1074
  return goSlice(collection, index, index + length, index + length);
1036
1075
  },
@@ -1072,7 +1111,7 @@ export function arrayPointerFromIndexRef(ref, length, sourceElementByteSize = 1,
1072
1111
  */
1073
1112
  export function indexAddress(collection, index) {
1074
1113
  if (collection === null || collection === undefined) {
1075
- throw new Error('runtime error: index on nil or undefined collection');
1114
+ runtimePanic('runtime error: index on nil or undefined collection');
1076
1115
  }
1077
1116
  let backing;
1078
1117
  let backingIndex;
@@ -1093,10 +1132,10 @@ export function indexAddress(collection, index) {
1093
1132
  length = collection.length;
1094
1133
  }
1095
1134
  else {
1096
- throw new Error('runtime error: index on unsupported type');
1135
+ runtimePanic('runtime error: index on unsupported type');
1097
1136
  }
1098
1137
  if (index < 0 || index >= length) {
1099
- throw new Error(`runtime error: index out of range [${index}] with length ${length}`);
1138
+ outOfRangeIndex(index, length);
1100
1139
  }
1101
1140
  let base = addressBases.get(backing);
1102
1141
  if (base === undefined) {
@@ -1160,11 +1199,11 @@ function numericByteSource(backing, elementByteSize) {
1160
1199
  */
1161
1200
  export function indexByteAddress(collection, index, elementByteSize) {
1162
1201
  if (collection === null || collection === undefined) {
1163
- throw new Error('runtime error: index on nil or undefined collection');
1202
+ runtimePanic('runtime error: index on nil or undefined collection');
1164
1203
  }
1165
1204
  if (collection instanceof Uint8Array) {
1166
1205
  if (index < 0 || index >= collection.length) {
1167
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
1206
+ outOfRangeIndex(index, collection.length);
1168
1207
  }
1169
1208
  const view = new Uint8Array(collection.buffer);
1170
1209
  const base = byteAddressBase(collection.buffer, {
@@ -1180,7 +1219,7 @@ export function indexByteAddress(collection, index, elementByteSize) {
1180
1219
  }
1181
1220
  if (isComplexSlice(collection)) {
1182
1221
  if (index < 0 || index >= collection.__meta__.length) {
1183
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`);
1222
+ outOfRangeIndex(index, collection.__meta__.length);
1184
1223
  }
1185
1224
  const backing = collection.__meta__.backing;
1186
1225
  const byteSize = Math.max(1, Math.trunc(elementByteSize));
@@ -1189,13 +1228,13 @@ export function indexByteAddress(collection, index, elementByteSize) {
1189
1228
  }
1190
1229
  if (Array.isArray(collection)) {
1191
1230
  if (index < 0 || index >= collection.length) {
1192
- throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
1231
+ outOfRangeIndex(index, collection.length);
1193
1232
  }
1194
1233
  const byteSize = Math.max(1, Math.trunc(elementByteSize));
1195
1234
  const base = byteAddressBase(collection, numericByteSource(collection, byteSize));
1196
1235
  return base + index * byteSize;
1197
1236
  }
1198
- throw new Error('runtime error: index on unsupported type');
1237
+ runtimePanic('runtime error: index on unsupported type');
1199
1238
  }
1200
1239
  /**
1201
1240
  * unsafePointerRef resolves a byte-addressed synthetic unsafe pointer created
@@ -1210,7 +1249,7 @@ export function unsafePointerRef(address) {
1210
1249
  }
1211
1250
  const offset = numericAddress - base;
1212
1251
  if (offset < 0 || offset >= source.byteLength) {
1213
- throw new Error('runtime error: unsafe pointer address out of range');
1252
+ runtimePanic('runtime error: unsafe pointer address out of range');
1214
1253
  }
1215
1254
  return {
1216
1255
  get value() {
@@ -1230,7 +1269,7 @@ function byteArrayFromAddress(address, length) {
1230
1269
  const index = sliceIndexProperty(prop);
1231
1270
  if (index >= 0) {
1232
1271
  if (index >= length) {
1233
- throw new Error(`Slice index out of range: ${index} >= ${length}`);
1272
+ runtimePanic(`Slice index out of range: ${index} >= ${length}`);
1234
1273
  }
1235
1274
  return unsafePointerRef(start + index).value;
1236
1275
  }
@@ -1240,7 +1279,7 @@ function byteArrayFromAddress(address, length) {
1240
1279
  const index = sliceIndexProperty(prop);
1241
1280
  if (index >= 0) {
1242
1281
  if (index >= length) {
1243
- throw new Error(`Slice index out of range: ${index} >= ${length}`);
1282
+ runtimePanic(`Slice index out of range: ${index} >= ${length}`);
1244
1283
  }
1245
1284
  unsafePointerRef(start + index).value = value;
1246
1285
  return true;
@@ -1290,8 +1329,26 @@ export const stringToRune = (str) => {
1290
1329
  * @returns The resulting string.
1291
1330
  */
1292
1331
  export const runesToString = (runes) => {
1293
- return runes?.length ? String.fromCharCode(...runes) : '';
1332
+ if (!runes?.length) {
1333
+ return '';
1334
+ }
1335
+ let out = '';
1336
+ for (const r of runes) {
1337
+ out += runeToString(r);
1338
+ }
1339
+ return out;
1294
1340
  };
1341
+ // runeToString encodes one rune as Go's string(rune) does: a valid Unicode
1342
+ // scalar value becomes its character including code points above U+FFFF (astral
1343
+ // planes), and a negative, out-of-range, or surrogate rune becomes U+FFFD
1344
+ // (utf8.RuneError), never a throw. String.fromCharCode truncated astral runes to
1345
+ // a single broken UTF-16 unit; String.fromCodePoint preserves the full rune.
1346
+ export function runeToString(r) {
1347
+ if (r < 0 || r > 0x10ffff || (r >= 0xd800 && r <= 0xdfff)) {
1348
+ return '�';
1349
+ }
1350
+ return String.fromCodePoint(r);
1351
+ }
1295
1352
  /**
1296
1353
  * Converts a number to a byte (uint8) by truncating to the range 0-255.
1297
1354
  * Equivalent to Go's byte() conversion.
@@ -1314,22 +1371,22 @@ export const indexString = (str, index) => {
1314
1371
  // Bytes - access directly
1315
1372
  if (str instanceof Uint8Array) {
1316
1373
  if (index < 0 || index >= str.length) {
1317
- throw new Error(`runtime error: index out of range [${index}] with length ${str.length}`);
1374
+ outOfRangeIndex(index, str.length);
1318
1375
  }
1319
1376
  return str[index];
1320
1377
  }
1321
1378
  // Array or null
1322
1379
  if (str === null || str === undefined) {
1323
- throw new Error(`runtime error: index out of range [${index}] with length 0`);
1380
+ outOfRangeIndex(index, 0);
1324
1381
  }
1325
1382
  if (index < 0 || index >= str.length) {
1326
- throw new Error(`runtime error: index out of range [${index}] with length ${str.length}`);
1383
+ outOfRangeIndex(index, str.length);
1327
1384
  }
1328
1385
  return str[index];
1329
1386
  }
1330
1387
  const bytes = goStringBytes(str);
1331
1388
  if (index < 0 || index >= bytes.length) {
1332
- throw new Error(`runtime error: index out of range [${index}] with length ${bytes.length}`);
1389
+ outOfRangeIndex(index, bytes.length);
1333
1390
  }
1334
1391
  return bytes[index];
1335
1392
  };
@@ -1366,7 +1423,7 @@ export const sliceString = (str, low, high) => {
1366
1423
  actualLow <= bytes.length) {
1367
1424
  return '';
1368
1425
  }
1369
- throw new Error(`runtime error: slice bounds out of range [${actualLow}:${actualHigh}] with length ${bytes.length}`);
1426
+ runtimePanic(`runtime error: slice bounds out of range [${actualLow}:${actualHigh}] with length ${bytes.length}`);
1370
1427
  }
1371
1428
  return goStringFromBytes(bytes.subarray(actualLow, actualHigh));
1372
1429
  };
@@ -1586,18 +1643,18 @@ export function indexStringOrBytes(value, index) {
1586
1643
  else if (value instanceof Uint8Array) {
1587
1644
  // For Uint8Array, direct access returns the byte value
1588
1645
  if (index < 0 || index >= value.length) {
1589
- throw new Error(`runtime error: index out of range [${index}] with length ${value.length}`);
1646
+ outOfRangeIndex(index, value.length);
1590
1647
  }
1591
1648
  return value[index];
1592
1649
  }
1593
1650
  else if (value === null) {
1594
- throw new Error(`runtime error: index out of range [${index}] with length 0`);
1651
+ outOfRangeIndex(index, 0);
1595
1652
  }
1596
1653
  else {
1597
1654
  // For Slice<number> (including SliceProxy)
1598
1655
  const length = len(value);
1599
1656
  if (index < 0 || index >= length) {
1600
- throw new Error(`runtime error: index out of range [${index}] with length ${length}`);
1657
+ outOfRangeIndex(index, length);
1601
1658
  }
1602
1659
  return value[index];
1603
1660
  }