1use crate::runtime::host::{abi_arg, abi_result};
7use wasmtime::{FuncType, HeapType, Linker, RefType, StructType, Val, ValType};
8
9use crate::runtime::StoreData;
10use crate::runtime::fuel;
11use crate::runtime::host::{
12 intrinsic_array_type, intrinsic_string_type, intrinsic_uint8_array_type, register_host_fn,
13 register_host_fn_async, write_submilli_string_struct, write_submilli_string_struct_units,
14};
15use crate::runtime::intrinsic_types::{IntrinsicTypes, build_intrinsic_types, intrinsic_types};
16use crate::runtime::prelude::vtable::read_string_units;
17use crate::runtime::prelude::{MODULE_NAME, closure, declare_method};
18use crate::{MangledName, PackageDeclaration, Param, Type};
19
20const BYTES_PER_ELEMENT: f64 = 1.0;
23
24pub(crate) fn install_constants(
27 linker: &mut Linker<StoreData>,
28 store: &mut wasmtime::Store<StoreData>,
29) -> wasmtime::Result<()> {
30 let gty = wasmtime::GlobalType::new(ValType::F64, wasmtime::Mutability::Var);
31 let global = wasmtime::Global::new(&mut *store, gty, Val::F64(BYTES_PER_ELEMENT.to_bits()))?;
32 let mangled = ctor_key("BYTES_PER_ELEMENT");
33 linker.define(&mut *store, MODULE_NAME, mangled.as_str(), global)?;
34 Ok(())
35}
36
37fn method_key(method: &str) -> MangledName {
38 crate::mangle::extend(&crate::mangle::prelude("Uint8Array"), method)
39}
40
41fn ctor_key(method: &str) -> MangledName {
43 crate::mangle::extend(&crate::mangle::prelude("Uint8ArrayConstructor"), method)
44}
45
46fn ref_to(struct_ty: StructType) -> ValType {
47 ValType::Ref(RefType::new(false, HeapType::ConcreteStruct(struct_ty)))
48}
49
50fn object_ref(intr: &IntrinsicTypes) -> ValType {
53 ValType::Ref(RefType::new(
54 true,
55 HeapType::ConcreteStruct(intr.object.clone()),
56 ))
57}
58
59fn f64v(v: &Val) -> f64 {
60 match v {
61 Val::F64(bits) => f64::from_bits(*bits),
62 _ => f64::NAN,
63 }
64}
65
66fn string_val(caller: &mut wasmtime::Caller<'_, StoreData>, s: &str) -> wasmtime::Result<Val> {
67 let st = write_submilli_string_struct(caller, s)?;
68 Ok(Val::AnyRef(Some(st.to_anyref())))
69}
70
71#[allow(clippy::too_many_lines)]
72pub fn install(linker: &mut Linker<StoreData>) -> wasmtime::Result<()> {
73 let engine = linker.engine().clone();
74 let intr = build_intrinsic_types(&engine)?;
75 let uint8 = ref_to(intrinsic_uint8_array_type(&engine)?);
76 let string = ref_to(intrinsic_string_type(&engine)?);
77 let array = ref_to(intrinsic_array_type(&engine)?);
78 let obj = object_ref(&intr);
79 let num = ValType::F64;
80 let boolean = ValType::I32;
81 let callback = obj.clone();
83
84 let ft = |params: Vec<ValType>, results: Vec<ValType>| FuncType::new(&engine, params, results);
85
86 register_host_fn(
88 linker,
89 MODULE_NAME,
90 method_key("length"),
91 ft(vec![uint8.clone()], vec![num.clone()]),
92 |caller, params, results| {
93 *abi_result(results, 0)? = Val::F64(
94 super::length(caller, abi_arg(params, 0)?, "Uint8Array#length")?.to_bits(),
95 );
96 Ok(())
97 },
98 )?;
99 register_host_fn(
100 linker,
101 MODULE_NAME,
102 method_key("BYTES_PER_ELEMENT"),
103 ft(vec![uint8.clone()], vec![num.clone()]),
104 |_caller, _params, results| {
105 *abi_result(results, 0)? = Val::F64(BYTES_PER_ELEMENT.to_bits());
106 Ok(())
107 },
108 )?;
109 register_host_fn(
110 linker,
111 MODULE_NAME,
112 method_key("byteLength"),
113 ft(vec![uint8.clone()], vec![num.clone()]),
114 |caller, params, results| {
115 *abi_result(results, 0)? = Val::F64(
116 super::length(caller, abi_arg(params, 0)?, "Uint8Array#byteLength")?.to_bits(),
117 );
118 Ok(())
119 },
120 )?;
121 register_host_fn(
122 linker,
123 MODULE_NAME,
124 method_key("at"),
125 ft(vec![uint8.clone(), num.clone()], vec![obj.clone()]),
126 |caller, params, results| {
127 *abi_result(results, 0)? = super::at(
128 caller,
129 abi_arg(params, 0)?,
130 f64v(abi_arg(params, 1)?),
131 "Uint8Array#at",
132 )?;
133 Ok(())
134 },
135 )?;
136 for (name, kind) in [
137 ("keys", super::IterKind::Keys),
138 ("values", super::IterKind::Values),
139 ("iterator", super::IterKind::Values),
140 ("entries", super::IterKind::Entries),
141 ] {
142 register_host_fn(
143 linker,
144 MODULE_NAME,
145 method_key(name),
146 ft(vec![uint8.clone()], vec![obj.clone()]),
147 move |caller, params, results| {
148 *abi_result(results, 0)? = super::iterate(caller, abi_arg(params, 0)?, kind)?;
149 Ok(())
150 },
151 )?;
152 }
153 for name in ["slice", "subarray"] {
154 register_host_fn(
155 linker,
156 MODULE_NAME,
157 method_key(name),
158 ft(
159 vec![uint8.clone(), num.clone(), num.clone()],
160 vec![uint8.clone()],
161 ),
162 |caller, params, results| {
163 let out = super::slice(
164 caller,
165 abi_arg(params, 0)?,
166 f64v(abi_arg(params, 1)?),
167 f64v(abi_arg(params, 2)?),
168 "Uint8Array#slice",
169 )?;
170 *abi_result(results, 0)? = super::build(caller, &out)?;
171 Ok(())
172 },
173 )?;
174 }
175 register_host_fn(
176 linker,
177 MODULE_NAME,
178 method_key("with"),
179 ft(
180 vec![uint8.clone(), num.clone(), num.clone()],
181 vec![uint8.clone()],
182 ),
183 |caller, params, results| {
184 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#with")?;
185 match super::with(&bytes, f64v(abi_arg(params, 1)?), f64v(abi_arg(params, 2)?)) {
186 Some(out) => {
187 *abi_result(results, 0)? = super::build(caller, &out)?;
188 Ok(())
189 }
190 None => Err(crate::runtime::host::range_error("index out of range")),
191 }
192 },
193 )?;
194 for name in ["indexOf", "lastIndexOf"] {
195 let last = name == "lastIndexOf";
196 register_host_fn(
197 linker,
198 MODULE_NAME,
199 method_key(name),
200 ft(
201 vec![uint8.clone(), num.clone(), num.clone()],
202 vec![num.clone()],
203 ),
204 move |caller, params, results| {
205 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#indexOf")?;
206 let r = if last {
207 super::last_index_of(
208 &bytes,
209 f64v(abi_arg(params, 1)?),
210 f64v(abi_arg(params, 2)?),
211 )
212 } else {
213 super::index_of(&bytes, f64v(abi_arg(params, 1)?), f64v(abi_arg(params, 2)?))
214 };
215 *abi_result(results, 0)? = Val::F64(r.to_bits());
216 Ok(())
217 },
218 )?;
219 }
220 register_host_fn(
221 linker,
222 MODULE_NAME,
223 method_key("includes"),
224 ft(
225 vec![uint8.clone(), num.clone(), num.clone()],
226 vec![boolean.clone()],
227 ),
228 |caller, params, results| {
229 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#includes")?;
230 let r = super::includes(&bytes, f64v(abi_arg(params, 1)?), f64v(abi_arg(params, 2)?));
231 *abi_result(results, 0)? = Val::I32(i32::from(r));
232 Ok(())
233 },
234 )?;
235 register_host_fn(
236 linker,
237 MODULE_NAME,
238 method_key("join"),
239 ft(vec![uint8.clone(), string.clone()], vec![string.clone()]),
240 |caller, params, results| {
241 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#join")?;
242 let sep = read_string_units(caller, abi_arg(params, 1)?, "Uint8Array#join separator")?;
243 let out = super::join(&bytes, &sep);
244 *abi_result(results, 0)? = {
245 let st = write_submilli_string_struct_units(caller, &out)?;
246 Val::AnyRef(Some(st.to_anyref()))
247 };
248 Ok(())
249 },
250 )?;
251 register_host_fn(
252 linker,
253 MODULE_NAME,
254 method_key("toString"),
255 ft(vec![uint8.clone()], vec![string.clone()]),
256 |caller, params, results| {
257 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toString")?;
258 let out = super::join(&bytes, &[u16::from(b',')]);
259 *abi_result(results, 0)? = {
260 let st = write_submilli_string_struct_units(caller, &out)?;
261 Val::AnyRef(Some(st.to_anyref()))
262 };
263 Ok(())
264 },
265 )?;
266 register_host_fn(
267 linker,
268 MODULE_NAME,
269 method_key("toJson"),
270 ft(vec![uint8.clone()], vec![string.clone()]),
271 |caller, params, results| {
272 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toJson")?;
273 let json = format!("\"{}\"", super::to_base64_standard(&bytes));
274 *abi_result(results, 0)? = string_val(caller, &json)?;
275 Ok(())
276 },
277 )?;
278 register_host_fn(
279 linker,
280 MODULE_NAME,
281 method_key("toHex"),
282 ft(vec![uint8.clone()], vec![string.clone()]),
283 |caller, params, results| {
284 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toHex")?;
285 *abi_result(results, 0)? = string_val(caller, &super::to_hex(&bytes))?;
286 Ok(())
287 },
288 )?;
289 register_host_fn(
290 linker,
291 MODULE_NAME,
292 method_key("toBase64"),
293 ft(vec![uint8.clone(), obj.clone()], vec![string.clone()]),
294 |caller, params, results| {
295 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toBase64")?;
296 let (url_safe, omit) = super::read_base64_options(caller, abi_arg(params, 1)?)?;
297 fuel::charge(&mut *caller, fuel::SCAN, bytes.len() as u64)?;
298 *abi_result(results, 0)? =
299 string_val(caller, &super::encode_base64(&bytes, url_safe, omit))?;
300 Ok(())
301 },
302 )?;
303 register_host_fn(
304 linker,
305 MODULE_NAME,
306 method_key("equals"),
307 ft(vec![uint8.clone(), uint8.clone()], vec![boolean.clone()]),
308 |caller, params, results| {
309 let a = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#equals")?;
310 let b = super::read_bytes(caller, abi_arg(params, 1)?, "Uint8Array#equals")?;
311 *abi_result(results, 0)? = Val::I32(i32::from(super::equals(&a, &b)));
312 Ok(())
313 },
314 )?;
315
316 register_host_fn(
318 linker,
319 MODULE_NAME,
320 method_key("reverse"),
321 ft(vec![uint8.clone()], vec![uint8.clone()]),
322 |caller, params, results| {
323 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#reverse")?;
324 *abi_result(results, 0)? = super::reverse(caller, abi_arg(params, 0)?, bytes)?;
325 Ok(())
326 },
327 )?;
328 register_host_fn(
329 linker,
330 MODULE_NAME,
331 method_key("fill"),
332 ft(
333 vec![uint8.clone(), num.clone(), num.clone(), num.clone()],
334 vec![uint8.clone()],
335 ),
336 |caller, params, results| {
337 *abi_result(results, 0)? = super::fill(
338 caller,
339 abi_arg(params, 0)?,
340 f64v(abi_arg(params, 1)?),
341 f64v(abi_arg(params, 2)?),
342 f64v(abi_arg(params, 3)?),
343 )?;
344 Ok(())
345 },
346 )?;
347 register_host_fn(
348 linker,
349 MODULE_NAME,
350 method_key("copyWithin"),
351 ft(
352 vec![uint8.clone(), num.clone(), num.clone(), num.clone()],
353 vec![uint8.clone()],
354 ),
355 |caller, params, results| {
356 *abi_result(results, 0)? = super::copy_within(
357 caller,
358 abi_arg(params, 0)?,
359 f64v(abi_arg(params, 1)?),
360 f64v(abi_arg(params, 2)?),
361 f64v(abi_arg(params, 3)?),
362 )?;
363 Ok(())
364 },
365 )?;
366 register_host_fn(
367 linker,
368 MODULE_NAME,
369 method_key("set"),
370 ft(vec![uint8.clone(), uint8.clone(), num.clone()], vec![]),
371 |caller, params, _results| {
372 super::set(
373 caller,
374 abi_arg(params, 0)?,
375 abi_arg(params, 1)?,
376 f64v(abi_arg(params, 2)?),
377 )
378 },
379 )?;
380 register_host_fn_async(
381 linker,
382 MODULE_NAME,
383 method_key("sort"),
384 ft(vec![uint8.clone(), obj.clone()], vec![uint8.clone()]),
385 |caller, params, results| {
386 Box::pin(async move {
387 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#sort")?;
388 let cmp =
389 read_comparator(caller, abi_arg(params, 1)?, "Uint8Array#sort comparator")?;
390 *abi_result(results, 0)? =
391 super::sort(caller, abi_arg(params, 0)?, bytes, cmp).await?;
392 Ok(())
393 })
394 },
395 )?;
396
397 register_host_fn(
399 linker,
400 MODULE_NAME,
401 method_key("toReversed"),
402 ft(vec![uint8.clone()], vec![uint8.clone()]),
403 |caller, params, results| {
404 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toReversed")?;
405 let out = super::to_reversed(bytes);
406 *abi_result(results, 0)? = super::build(caller, &out)?;
407 Ok(())
408 },
409 )?;
410 register_host_fn_async(
411 linker,
412 MODULE_NAME,
413 method_key("toSorted"),
414 ft(vec![uint8.clone(), obj.clone()], vec![uint8.clone()]),
415 |caller, params, results| {
416 Box::pin(async move {
417 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toSorted")?;
418 let cmp = read_comparator(
419 caller,
420 abi_arg(params, 1)?,
421 "Uint8Array#toSorted comparator",
422 )?;
423 let out = super::to_sorted(caller, bytes, cmp).await?;
424 *abi_result(results, 0)? = super::build(caller, &out)?;
425 Ok(())
426 })
427 },
428 )?;
429
430 register_host_fn_async(
432 linker,
433 MODULE_NAME,
434 method_key("forEach"),
435 ft(vec![uint8.clone(), callback.clone()], vec![]),
436 |caller, params, _results| {
437 Box::pin(async move {
438 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#forEach")?;
439 let f = closure::read_callback(
440 caller,
441 abi_arg(params, 1)?,
442 "Uint8Array#forEach callback",
443 )?;
444 super::for_each(caller, *abi_arg(params, 0)?, bytes, &f).await
445 })
446 },
447 )?;
448 register_host_fn_async(
449 linker,
450 MODULE_NAME,
451 method_key("map"),
452 ft(vec![uint8.clone(), callback.clone()], vec![uint8.clone()]),
453 |caller, params, results| {
454 Box::pin(async move {
455 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#map")?;
456 let f =
457 closure::read_callback(caller, abi_arg(params, 1)?, "Uint8Array#map callback")?;
458 let out = super::map(caller, *abi_arg(params, 0)?, bytes, &f).await?;
459 *abi_result(results, 0)? = super::build(caller, &out)?;
460 Ok(())
461 })
462 },
463 )?;
464 register_host_fn_async(
465 linker,
466 MODULE_NAME,
467 method_key("filter"),
468 ft(vec![uint8.clone(), callback.clone()], vec![uint8.clone()]),
469 |caller, params, results| {
470 Box::pin(async move {
471 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#filter")?;
472 let pred = closure::read_callback(
473 caller,
474 abi_arg(params, 1)?,
475 "Uint8Array#filter predicate",
476 )?;
477 let out = super::filter(caller, *abi_arg(params, 0)?, bytes, &pred).await?;
478 *abi_result(results, 0)? = super::build(caller, &out)?;
479 Ok(())
480 })
481 },
482 )?;
483 for (name, reverse) in [("reduce", false), ("reduceRight", true)] {
484 register_host_fn_async(
485 linker,
486 MODULE_NAME,
487 method_key(name),
488 ft(
489 vec![uint8.clone(), callback.clone(), obj.clone()],
490 vec![obj.clone()],
491 ),
492 move |caller, params, results| {
493 Box::pin(async move {
494 let bytes =
495 super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#reduce")?;
496 let f = closure::read_callback(
497 caller,
498 abi_arg(params, 1)?,
499 "Uint8Array#reduce callback",
500 )?;
501 *abi_result(results, 0)? = super::reduce(
502 caller,
503 *abi_arg(params, 0)?,
504 bytes,
505 &f,
506 *abi_arg(params, 2)?,
507 reverse,
508 )
509 .await?;
510 Ok(())
511 })
512 },
513 )?;
514 }
515 for (name, reverse) in [("find", false), ("findLast", true)] {
516 register_host_fn_async(
517 linker,
518 MODULE_NAME,
519 method_key(name),
520 ft(vec![uint8.clone(), callback.clone()], vec![obj.clone()]),
521 move |caller, params, results| {
522 Box::pin(async move {
523 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#find")?;
524 let pred = closure::read_callback(
525 caller,
526 abi_arg(params, 1)?,
527 "Uint8Array#find predicate",
528 )?;
529 *abi_result(results, 0)? = match super::find_match(
530 caller,
531 *abi_arg(params, 0)?,
532 &bytes,
533 &pred,
534 reverse,
535 )
536 .await?
537 {
538 Some(i) => {
539 let byte = *bytes.get(i).ok_or_else(|| {
540 crate::runtime::host::fatal_host_error(
541 "Uint8Array#find: invalid result index",
542 )
543 })?;
544 super::box_byte(caller, byte)?
545 }
546 None => crate::runtime::prelude::undefined::value(caller)?,
547 };
548 Ok(())
549 })
550 },
551 )?;
552 }
553 for (name, reverse) in [("findIndex", false), ("findLastIndex", true)] {
554 register_host_fn_async(
555 linker,
556 MODULE_NAME,
557 method_key(name),
558 ft(vec![uint8.clone(), callback.clone()], vec![num.clone()]),
559 move |caller, params, results| {
560 Box::pin(async move {
561 let bytes =
562 super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#findIndex")?;
563 let pred = closure::read_callback(
564 caller,
565 abi_arg(params, 1)?,
566 "Uint8Array#findIndex predicate",
567 )?;
568 let idx =
569 super::find_match(caller, *abi_arg(params, 0)?, &bytes, &pred, reverse)
570 .await?;
571 let r = idx.map_or(-1.0, |i| i as f64);
572 *abi_result(results, 0)? = Val::F64(r.to_bits());
573 Ok(())
574 })
575 },
576 )?;
577 }
578 register_host_fn_async(
579 linker,
580 MODULE_NAME,
581 method_key("some"),
582 ft(vec![uint8.clone(), callback.clone()], vec![boolean.clone()]),
583 |caller, params, results| {
584 Box::pin(async move {
585 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#some")?;
586 let pred = closure::read_callback(
587 caller,
588 abi_arg(params, 1)?,
589 "Uint8Array#some predicate",
590 )?;
591 let r = super::some(caller, *abi_arg(params, 0)?, bytes, &pred).await?;
592 *abi_result(results, 0)? = Val::I32(i32::from(r));
593 Ok(())
594 })
595 },
596 )?;
597 register_host_fn_async(
598 linker,
599 MODULE_NAME,
600 method_key("every"),
601 ft(vec![uint8.clone(), callback.clone()], vec![boolean.clone()]),
602 |caller, params, results| {
603 Box::pin(async move {
604 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#every")?;
605 let pred = closure::read_callback(
606 caller,
607 abi_arg(params, 1)?,
608 "Uint8Array#every predicate",
609 )?;
610 let r = super::every(caller, *abi_arg(params, 0)?, bytes, &pred).await?;
611 *abi_result(results, 0)? = Val::I32(i32::from(r));
612 Ok(())
613 })
614 },
615 )?;
616
617 for (name, label) in [
619 ("fromArray", "Uint8Array.fromArray"),
620 ("of", "Uint8Array.of"),
621 ] {
622 register_host_fn(
623 linker,
624 MODULE_NAME,
625 ctor_key(name),
626 ft(vec![array.clone()], vec![uint8.clone()]),
627 move |caller, params, results| {
628 let bytes = super::read_number_array(caller, abi_arg(params, 0)?, label)?;
629 *abi_result(results, 0)? = super::build(caller, &bytes)?;
630 Ok(())
631 },
632 )?;
633 }
634 let object_nonnull = ValType::Ref(RefType::new(
639 false,
640 HeapType::ConcreteStruct(intr.object.clone()),
641 ));
642 register_host_fn(
643 linker,
644 MODULE_NAME,
645 ctor_key("new"),
646 ft(vec![object_nonnull], vec![uint8.clone()]),
647 |caller, params, results| {
648 let intr = intrinsic_types(&mut *caller)?;
649 let bytes = if crate::runtime::prelude::collection::is_a(
650 caller,
651 abi_arg(params, 0)?,
652 &intr.array,
653 )? {
654 super::read_number_array(caller, abi_arg(params, 0)?, "Uint8Array.new")?
655 } else {
656 let n = crate::runtime::host::read_boxed_number(
657 caller,
658 abi_arg(params, 0)?,
659 "Uint8Array.new",
660 )?;
661 *abi_result(results, 0)? = super::allocate(caller, super::alloc_len(n)?)?;
662 return Ok(());
663 };
664 *abi_result(results, 0)? = super::build(caller, &bytes)?;
665 Ok(())
666 },
667 )?;
668 register_host_fn(
669 linker,
670 MODULE_NAME,
671 ctor_key("alloc"),
672 ft(vec![num.clone()], vec![uint8.clone()]),
673 |caller, params, results| {
674 let n = super::alloc_len(f64v(abi_arg(params, 0)?))?;
675 *abi_result(results, 0)? = super::allocate(caller, n)?;
676 Ok(())
677 },
678 )?;
679 register_host_fn(
680 linker,
681 MODULE_NAME,
682 ctor_key("fromBytes"),
683 ft(vec![uint8.clone()], vec![uint8.clone()]),
684 |caller, params, results| {
685 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array.fromBytes")?;
686 *abi_result(results, 0)? = super::build(caller, &bytes)?;
687 Ok(())
688 },
689 )?;
690 register_host_fn(
691 linker,
692 MODULE_NAME,
693 ctor_key("fromBase64"),
694 ft(vec![string.clone(), obj.clone()], vec![uint8.clone()]),
695 |caller, params, results| {
696 let units = read_string_units(caller, abi_arg(params, 0)?, "Uint8Array.fromBase64")?;
697 let s = String::from_utf16_lossy(&units);
698 let (url_safe, _) = super::read_base64_options(caller, abi_arg(params, 1)?)?;
699 fuel::charge(&mut *caller, fuel::SCAN, s.len() as u64)?;
700 let bytes = super::decode_base64(&s, url_safe)?;
701 *abi_result(results, 0)? = super::build(caller, &bytes)?;
702 Ok(())
703 },
704 )?;
705 register_host_fn(
706 linker,
707 MODULE_NAME,
708 ctor_key("fromHex"),
709 ft(vec![string.clone()], vec![uint8.clone()]),
710 |caller, params, results| {
711 let units = read_string_units(caller, abi_arg(params, 0)?, "Uint8Array.fromHex")?;
712 let bytes = super::from_hex(&units)?;
713 *abi_result(results, 0)? = super::build(caller, &bytes)?;
714 Ok(())
715 },
716 )?;
717 Ok(())
718}
719
720fn read_comparator(
722 caller: &mut wasmtime::Caller<'_, StoreData>,
723 val: &Val,
724 name: &str,
725) -> wasmtime::Result<Option<closure::Closure>> {
726 if crate::runtime::prelude::undefined::is_undefined(caller, val)? {
727 Ok(None)
728 } else {
729 Ok(Some(closure::read_callback(caller, val, name)?))
730 }
731}
732
733fn byte_callback_params(leading: Vec<Type>) -> Vec<Type> {
737 leading
738 .into_iter()
739 .chain([Type::Number, Type::Number, Type::Uint8Array])
740 .collect()
741}
742
743pub fn declare(defs: &mut PackageDeclaration) {
744 let u8a = || Param::new("a", Type::Uint8Array);
745 let bytes_per_element = ctor_key("BYTES_PER_ELEMENT");
747 defs.values.insert(
748 bytes_per_element.as_str().to_string(),
749 crate::ValueSymbol {
750 name: "BYTES_PER_ELEMENT".to_string(),
751 mangled_name: bytes_per_element,
752 declaration_span: crate::Span::at(crate::FileId::PRELUDE),
753 kind: crate::ValueKind::Const {
754 ty: Type::Number,
755 doc: None,
756 },
757 },
758 );
759 let callback = || Param::new("f", Type::Unknown);
762 let n = |name: &str| Param::new(name, Type::Number);
763 let u8_ret = Type::Uint8Array;
764 let comparator = || {
765 Type::Union(vec![
766 Type::Function {
767 optional: 0,
768 params: vec![Type::Number, Type::Number],
769 ret: Box::new(Type::Number),
770 predicate: None,
771 has_rest: false,
772 },
773 Type::Undefined,
774 ])
775 };
776 let base64_options = || {
777 Type::Union(vec![
778 Type::prelude_interface("Base64Options".to_string(), Vec::new()),
779 Type::Undefined,
780 ])
781 };
782
783 let m = |defs: &mut PackageDeclaration, name: &str, params: Vec<Param>, ret: Type| {
784 declare_method(defs, name, method_key(name), params, ret);
785 };
786
787 m(defs, "length", vec![u8a()], Type::Number);
788 m(defs, "byteLength", vec![u8a()], Type::Number);
789 m(defs, "BYTES_PER_ELEMENT", vec![u8a()], Type::Number);
790 m(
791 defs,
792 "at",
793 vec![u8a(), n("index")],
794 Type::Union(vec![Type::Number, Type::Undefined]),
795 );
796 let iter = |ty: Type| Type::prelude_interface("Iterator".to_string(), vec![ty]);
797 m(defs, "keys", vec![u8a()], iter(Type::Number));
798 m(defs, "values", vec![u8a()], iter(Type::Number));
799 m(defs, "iterator", vec![u8a()], iter(Type::Number));
800 m(
801 defs,
802 "entries",
803 vec![u8a()],
804 iter(Type::Tuple(vec![Type::Number, Type::Number].into())),
805 );
806 for name in ["slice", "subarray"] {
807 m(
808 defs,
809 name,
810 vec![u8a(), n("start"), n("end")],
811 u8_ret.clone(),
812 );
813 }
814 m(
815 defs,
816 "with",
817 vec![u8a(), n("index"), n("value")],
818 u8_ret.clone(),
819 );
820 for name in ["indexOf", "lastIndexOf"] {
821 m(
822 defs,
823 name,
824 vec![u8a(), n("value"), n("fromIndex")],
825 Type::Number,
826 );
827 }
828 m(
829 defs,
830 "includes",
831 vec![u8a(), n("value"), n("fromIndex")],
832 Type::Boolean,
833 );
834 m(
835 defs,
836 "join",
837 vec![u8a(), Param::new("sep", Type::String)],
838 Type::String,
839 );
840 m(defs, "toString", vec![u8a()], Type::String);
841 m(defs, "toJson", vec![u8a()], Type::String);
842 m(defs, "toHex", vec![u8a()], Type::String);
843 m(
844 defs,
845 "toBase64",
846 vec![u8a(), Param::new("options", base64_options())],
847 Type::String,
848 );
849 m(
850 defs,
851 "equals",
852 vec![u8a(), Param::new("other", Type::Uint8Array)],
853 Type::Boolean,
854 );
855
856 m(defs, "reverse", vec![u8a()], u8_ret.clone());
857 m(
858 defs,
859 "fill",
860 vec![u8a(), n("value"), n("start"), n("end")],
861 u8_ret.clone(),
862 );
863 m(
864 defs,
865 "copyWithin",
866 vec![u8a(), n("target"), n("start"), n("end")],
867 u8_ret.clone(),
868 );
869 m(
870 defs,
871 "set",
872 vec![u8a(), Param::new("source", Type::Uint8Array), n("offset")],
873 Type::Void,
874 );
875 m(
876 defs,
877 "sort",
878 vec![u8a(), Param::new("compareFn", comparator())],
879 u8_ret.clone(),
880 );
881 m(defs, "toReversed", vec![u8a()], u8_ret.clone());
882 m(
883 defs,
884 "toSorted",
885 vec![u8a(), Param::new("compareFn", comparator())],
886 u8_ret.clone(),
887 );
888
889 m(defs, "forEach", vec![u8a(), callback()], Type::Void);
890 for name in ["map", "filter"] {
891 m(defs, name, vec![u8a(), callback()], u8_ret.clone());
892 }
893 let u = || Type::TypeVar("U".to_string());
894 for name in ["reduce", "reduceRight"] {
895 m(
896 defs,
897 name,
898 vec![u8a(), callback(), Param::new("initial", u())],
899 u(),
900 );
901 }
902 for name in ["find", "findLast"] {
903 m(
904 defs,
905 name,
906 vec![u8a(), callback()],
907 Type::Union(vec![Type::Number, Type::Undefined]),
908 );
909 }
910 for name in ["findIndex", "findLastIndex"] {
911 m(defs, name, vec![u8a(), callback()], Type::Number);
912 }
913 for name in ["some", "every"] {
914 m(defs, name, vec![u8a(), callback()], Type::Boolean);
915 }
916
917 let items = || Param::new("items", Type::Array(Box::new(Type::Number)));
918 for name in ["fromArray", "of"] {
919 declare_method(defs, name, ctor_key(name), vec![items()], u8_ret.clone());
920 }
921 declare_method(
924 defs,
925 "new",
926 ctor_key("new"),
927 vec![Param::with_default(
928 "values",
929 Type::Union(vec![Type::Array(Box::new(Type::Number)), Type::Number]),
930 crate::DefaultValue::Number(0.0),
931 )],
932 u8_ret.clone(),
933 );
934 declare_method(
935 defs,
936 "alloc",
937 ctor_key("alloc"),
938 vec![Param::new("length", Type::Number)],
939 u8_ret.clone(),
940 );
941 declare_method(
942 defs,
943 "fromBytes",
944 ctor_key("fromBytes"),
945 vec![Param::new("bytes", Type::Uint8Array)],
946 u8_ret.clone(),
947 );
948 declare_method(
949 defs,
950 "fromBase64",
951 ctor_key("fromBase64"),
952 vec![
953 Param::new("encoded", Type::String),
954 Param::new("options", base64_options()),
955 ],
956 u8_ret.clone(),
957 );
958 declare_method(
959 defs,
960 "fromHex",
961 ctor_key("fromHex"),
962 vec![Param::new("encoded", Type::String)],
963 u8_ret,
964 );
965}
966
967#[allow(clippy::too_many_lines)]
970pub(crate) fn declare_types(defs: &mut crate::PackageDeclaration) {
971 use crate::runtime::prelude::declaration::doc;
972 use crate::{
973 Dispatch, MethodSig, Param, PropertySig, Span, Type, TypeKind, TypeSymbol, ValueKind,
974 ValueSymbol,
975 };
976 use std::collections::BTreeMap;
977 defs.types.insert(
978 "Uint8Array".to_string(),
979 TypeSymbol {
980 name: "Uint8Array".to_string(),
981 mangled_name: crate::mangle::prelude("Uint8Array"),
982 declaration_span: Span::at(crate::FileId::PRELUDE),
983 kind: TypeKind::Interface { index: None,
984 generics: Vec::new(),
985 methods: BTreeMap::from([
986 (
987 "toString".to_string(),
988 MethodSig {
989 optional: false,
990 generics: Vec::new(),
991 params: Vec::new(),
992 ret: Type::String,
993 predicate: None,
994 doc: doc(
995 "/** Returns this array's bytes joined as a comma-separated decimal string — e.g. `Uint8Array.new([1, 2, 3]).toString() === \"1,2,3\"`. Matches the JS `Uint8Array.prototype.toString` shape. */",
996 ),
997 },
998 ),
999 (
1000 "toJson".to_string(),
1001 MethodSig {
1002 optional: false,
1003 generics: Vec::new(),
1004 params: Vec::new(),
1005 ret: Type::String,
1006 predicate: None,
1007 doc: doc(
1008 "/** Returns this array's bytes as a standard (padded) base64 string wrapped in `\"…\"` (the JSON string form). */",
1009 ),
1010 },
1011 ),
1012 (
1013 "equals".to_string(),
1014 MethodSig {
1015 optional: false,
1016 generics: Vec::new(),
1017 params: vec![Param::new("other", Type::Uint8Array)],
1018 ret: Type::Boolean,
1019 predicate: None,
1020 doc: doc(
1021 "/**\n * Byte-by-byte equality with `other`. Returns `false` when lengths differ.\n * @param other Bytes to compare against.\n */",
1022 ),
1023 },
1024 ),
1025 (
1026 "join".to_string(),
1027 MethodSig {
1028 optional: false,
1029 generics: Vec::new(),
1030 params: vec![Param::with_default(
1031 "separator",
1032 Type::String,
1033 crate::DefaultValue::String(",".to_string()),
1034 )],
1035 ret: Type::String,
1036 predicate: None,
1037 doc: doc(
1038 "/**\n * Returns this array's bytes formatted in decimal and concatenated with `separator` between adjacent pairs.\n * @param separator String placed between elements. Defaults to `\",\"`.\n */",
1039 ),
1040 },
1041 ),
1042 (
1043 "reverse".to_string(),
1044 MethodSig {
1045 optional: false,
1046 generics: Vec::new(),
1047 params: Vec::new(),
1048 ret: Type::Uint8Array,
1049 predicate: None,
1050 doc: doc(
1051 "/** Reverses this array's bytes in place and returns `this`. */",
1052 ),
1053 },
1054 ),
1055 (
1056 "fill".to_string(),
1057 MethodSig {
1058 optional: false,
1059 generics: Vec::new(),
1060 params: vec![
1061 Param::new("value", Type::Number),
1062 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1063 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1064 ],
1065 ret: Type::Uint8Array,
1066 predicate: None,
1067 doc: doc("/** Converts `value` to a byte and writes it to every position in `[start, end)`. Returns `this`. */"),
1068 },
1069 ),
1070 (
1071 "copyWithin".to_string(),
1072 MethodSig {
1073 optional: false,
1074 generics: Vec::new(),
1075 params: vec![
1076 Param::new("target", Type::Number),
1077 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1078 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1079 ],
1080 ret: Type::Uint8Array,
1081 predicate: None,
1082 doc: doc("/** Copies `bytes[start..end)` to `bytes[target..]` in place. Returns `this`. */"),
1083 },
1084 ),
1085 (
1086 "slice".to_string(),
1087 MethodSig {
1088 optional: false,
1089 generics: Vec::new(),
1090 params: vec![
1091 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1092 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1093 ],
1094 ret: Type::Uint8Array,
1095 predicate: None,
1096 doc: doc("/** Returns a fresh copy of the bytes in `[start, end)`. */"),
1097 },
1098 ),
1099 (
1100 "subarray".to_string(),
1101 MethodSig {
1102 optional: false,
1103 generics: Vec::new(),
1104 params: vec![
1105 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1106 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1107 ],
1108 ret: Type::Uint8Array,
1109 predicate: None,
1110 doc: doc("/** Deep-copy alias for `slice` under v1 (no `ArrayBuffer` view sharing). */"),
1111 },
1112 ),
1113 (
1114 "with".to_string(),
1115 MethodSig {
1116 optional: false,
1117 generics: Vec::new(),
1118 params: vec![
1119 Param::new("index", Type::Number),
1120 Param::new("value", Type::Number),
1121 ],
1122 ret: Type::Uint8Array,
1123 predicate: None,
1124 doc: doc("/** Returns a clone of this array with `value` converted to a byte and written at `index`. */"),
1125 },
1126 ),
1127 (
1128 "set".to_string(),
1129 MethodSig {
1130 optional: false,
1131 generics: Vec::new(),
1132 params: vec![
1133 Param::new("values", Type::Uint8Array),
1134 Param::with_default("offset", Type::Number, crate::DefaultValue::Number(0.0)),
1135 ],
1136 ret: Type::Void,
1137 predicate: None,
1138 doc: doc("/** Copies `values` into this array starting at `offset`. Throws on out-of-bounds. */"),
1139 },
1140 ),
1141 (
1142 "forEach".to_string(),
1143 MethodSig {
1144 optional: false,
1145 generics: Vec::new(),
1146 params: vec![Param::new("callback", Type::Function {
1147 optional: 0,
1148 params: byte_callback_params(Vec::new()),
1149 ret: Box::new(Type::Void),
1150 predicate: None,
1151 has_rest: false,
1152 })],
1153 ret: Type::Void,
1154 predicate: None,
1155 doc: doc("/** Invokes `callback(byte, index, array)` for every byte in order. */"),
1156 },
1157 ),
1158 (
1159 "map".to_string(),
1160 MethodSig {
1161 optional: false,
1162 generics: Vec::new(),
1163 params: vec![Param::new("callback", Type::Function {
1164 optional: 0,
1165 params: byte_callback_params(Vec::new()),
1166 ret: Box::new(Type::Number),
1167 predicate: None,
1168 has_rest: false,
1169 })],
1170 ret: Type::Uint8Array,
1171 predicate: None,
1172 doc: doc("/** Returns a new `Uint8Array` with each `callback(this[i], i, this)` result converted to a byte. */"),
1173 },
1174 ),
1175 (
1176 "filter".to_string(),
1177 MethodSig {
1178 optional: false,
1179 generics: Vec::new(),
1180 params: vec![Param::new("predicate", Type::Function {
1181 optional: 0,
1182 params: byte_callback_params(Vec::new()),
1183 ret: Box::new(Type::Unknown),
1184 predicate: None,
1185 has_rest: false,
1186 })],
1187 ret: Type::Uint8Array,
1188 predicate: None,
1189 doc: doc("/** Returns a new `Uint8Array` containing every byte for which `predicate(byte, index, array)` returns a truthy value. */"),
1190 },
1191 ),
1192 (
1193 "some".to_string(),
1194 MethodSig {
1195 optional: false,
1196 generics: Vec::new(),
1197 params: vec![Param::new("predicate", Type::Function {
1198 optional: 0,
1199 params: byte_callback_params(Vec::new()),
1200 ret: Box::new(Type::Unknown),
1201 predicate: None,
1202 has_rest: false,
1203 })],
1204 ret: Type::Boolean,
1205 predicate: None,
1206 doc: doc("/** Returns `true` if `predicate` returns a truthy value for any byte. */"),
1207 },
1208 ),
1209 (
1210 "every".to_string(),
1211 MethodSig {
1212 optional: false,
1213 generics: Vec::new(),
1214 params: vec![Param::new("predicate", Type::Function {
1215 optional: 0,
1216 params: byte_callback_params(Vec::new()),
1217 ret: Box::new(Type::Unknown),
1218 predicate: None,
1219 has_rest: false,
1220 })],
1221 ret: Type::Boolean,
1222 predicate: None,
1223 doc: doc("/** Returns `true` iff `predicate(byte, index, array)` returns a truthy value for every byte. */"),
1224 },
1225 ),
1226 (
1227 "reduce".to_string(),
1228 MethodSig {
1229 optional: false,
1230 generics: vec!["U".to_string()],
1231 params: vec![
1232 Param::new("callback", Type::Function {
1233 optional: 0,
1234 params: byte_callback_params(vec![Type::TypeVar("U".to_string())]),
1235 ret: Box::new(Type::TypeVar("U".to_string())),
1236 predicate: None,
1237 has_rest: false,
1238 }),
1239 Param::new("initial", Type::TypeVar("U".to_string())),
1240 ],
1241 ret: Type::TypeVar("U".to_string()),
1242 predicate: None,
1243 doc: doc("/** Folds bytes left-to-right with `callback(acc, byte, index, array)`. */"),
1244 },
1245 ),
1246 (
1247 "reduceRight".to_string(),
1248 MethodSig {
1249 optional: false,
1250 generics: vec!["U".to_string()],
1251 params: vec![
1252 Param::new("callback", Type::Function {
1253 optional: 0,
1254 params: byte_callback_params(vec![Type::TypeVar("U".to_string())]),
1255 ret: Box::new(Type::TypeVar("U".to_string())),
1256 predicate: None,
1257 has_rest: false,
1258 }),
1259 Param::new("initial", Type::TypeVar("U".to_string())),
1260 ],
1261 ret: Type::TypeVar("U".to_string()),
1262 predicate: None,
1263 doc: doc("/** Folds bytes right-to-left with `callback(acc, byte, index, array)`. */"),
1264 },
1265 ),
1266 (
1267 "keys".to_string(),
1268 MethodSig {
1269 optional: false,
1270 generics: Vec::new(),
1271 params: Vec::new(),
1272 ret: Type::prelude_interface("Iterator".to_string(), vec![Type::Number]),
1273 predicate: None,
1274 doc: doc("/** Returns a live `Iterator<number>` of the indices. */"),
1275 },
1276 ),
1277 (
1278 "values".to_string(),
1279 MethodSig {
1280 optional: false,
1281 generics: Vec::new(),
1282 params: Vec::new(),
1283 ret: Type::prelude_interface("Iterator".to_string(), vec![Type::Number]),
1284 predicate: None,
1285 doc: doc("/** Returns a live `Iterator<number>` of the bytes; writes during iteration are seen. */"),
1286 },
1287 ),
1288 (
1289 "iterator".to_string(),
1290 MethodSig {
1291 optional: false,
1292 generics: Vec::new(),
1293 params: Vec::new(),
1294 ret: Type::prelude_interface("Iterator".to_string(), vec![Type::Number]),
1295 predicate: None,
1296 doc: doc("/** Returns a live `Iterator<number>` of the bytes, which `for-of` and spread use. */"),
1297 },
1298 ),
1299 (
1300 "entries".to_string(),
1301 MethodSig {
1302 optional: false,
1303 generics: Vec::new(),
1304 params: Vec::new(),
1305 ret: Type::prelude_interface("Iterator".to_string(), vec![Type::Tuple(vec![Type::Number, Type::Number].into())]),
1306 predicate: None,
1307 doc: doc("/** Returns a live `Iterator<[number, number]>` of index/byte pairs. */"),
1308 },
1309 ),
1310 (
1311 "at".to_string(),
1312 MethodSig {
1313 optional: false,
1314 generics: Vec::new(),
1315 params: vec![Param::new("index", Type::Number)],
1316 ret: Type::Union(vec![Type::Number, Type::Undefined]),
1317 predicate: None,
1318 doc: doc("/** Returns the byte at `index`, or `undefined` if out of range. Negative indices count from the end. */"),
1319 },
1320 ),
1321 (
1322 "indexOf".to_string(),
1323 MethodSig {
1324 optional: false,
1325 generics: Vec::new(),
1326 params: vec![
1327 Param::new("target", Type::Number),
1328 Param::with_default("fromIndex", Type::Number, crate::DefaultValue::Number(0.0)),
1329 ],
1330 ret: Type::Number,
1331 predicate: None,
1332 doc: doc("/** Returns the first index of `target`, or `-1`. */"),
1333 },
1334 ),
1335 (
1336 "lastIndexOf".to_string(),
1337 MethodSig {
1338 optional: false,
1339 generics: Vec::new(),
1340 params: vec![
1341 Param::new("target", Type::Number),
1342 Param::with_default("fromIndex", Type::Number, crate::DefaultValue::OmittedNumber { omitted: f64::INFINITY, undefined: 0.0 }),
1343 ],
1344 ret: Type::Number,
1345 predicate: None,
1346 doc: doc("/** Returns the last index of `target`, or `-1`. */"),
1347 },
1348 ),
1349 (
1350 "includes".to_string(),
1351 MethodSig {
1352 optional: false,
1353 generics: Vec::new(),
1354 params: vec![
1355 Param::new("target", Type::Number),
1356 Param::with_default("fromIndex", Type::Number, crate::DefaultValue::Number(0.0)),
1357 ],
1358 ret: Type::Boolean,
1359 predicate: None,
1360 doc: doc("/** Returns `true` if `target` appears at or after `fromIndex`. */"),
1361 },
1362 ),
1363 (
1364 "find".to_string(),
1365 MethodSig {
1366 optional: false,
1367 generics: Vec::new(),
1368 params: vec![Param::new("predicate", Type::Function {
1369 optional: 0,
1370 params: byte_callback_params(Vec::new()),
1371 ret: Box::new(Type::Boolean),
1372 predicate: None,
1373 has_rest: false,
1374 })],
1375 ret: Type::Union(vec![Type::Number, Type::Undefined]),
1376 predicate: None,
1377 doc: doc("/** Returns the first byte for which `predicate(byte, index, array)` returns `true`, or `undefined`. */"),
1378 },
1379 ),
1380 (
1381 "findLast".to_string(),
1382 MethodSig {
1383 optional: false,
1384 generics: Vec::new(),
1385 params: vec![Param::new("predicate", Type::Function {
1386 optional: 0,
1387 params: byte_callback_params(Vec::new()),
1388 ret: Box::new(Type::Unknown),
1389 predicate: None,
1390 has_rest: false,
1391 })],
1392 ret: Type::Union(vec![Type::Number, Type::Undefined]),
1393 predicate: None,
1394 doc: doc("/** Returns the last byte for which `predicate(byte, index, array)` returns a truthy value, or `undefined`. */"),
1395 },
1396 ),
1397 (
1398 "findIndex".to_string(),
1399 MethodSig {
1400 optional: false,
1401 generics: Vec::new(),
1402 params: vec![Param::new("predicate", Type::Function {
1403 optional: 0,
1404 params: byte_callback_params(Vec::new()),
1405 ret: Box::new(Type::Boolean),
1406 predicate: None,
1407 has_rest: false,
1408 })],
1409 ret: Type::Number,
1410 predicate: None,
1411 doc: doc("/** Returns the index of the first matching byte, or `-1`. */"),
1412 },
1413 ),
1414 (
1415 "findLastIndex".to_string(),
1416 MethodSig {
1417 optional: false,
1418 generics: Vec::new(),
1419 params: vec![Param::new("predicate", Type::Function {
1420 optional: 0,
1421 params: byte_callback_params(Vec::new()),
1422 ret: Box::new(Type::Unknown),
1423 predicate: None,
1424 has_rest: false,
1425 })],
1426 ret: Type::Number,
1427 predicate: None,
1428 doc: doc("/** Returns the index of the last matching byte, or `-1`. */"),
1429 },
1430 ),
1431 (
1432 "sort".to_string(),
1433 MethodSig {
1434 optional: false,
1435 generics: Vec::new(),
1436 params: vec![Param::with_default(
1437 "compareFn",
1438 Type::Union(vec![
1439 Type::Function {
1440 optional: 0,
1441 params: vec![Type::Number, Type::Number],
1442 ret: Box::new(Type::Number),
1443 predicate: None,
1444 has_rest: false,
1445 },
1446 Type::Undefined,
1447 ]),
1448 crate::DefaultValue::Undefined,
1449 )],
1450 ret: Type::Uint8Array,
1451 predicate: None,
1452 doc: doc("/** Sorts bytes in place via `compareFn(a, b)`. With no `compareFn`, sorts numerically ascending. Returns `this`. */"),
1453 },
1454 ),
1455 (
1456 "toReversed".to_string(),
1457 MethodSig {
1458 optional: false,
1459 generics: Vec::new(),
1460 params: Vec::new(),
1461 ret: Type::Uint8Array,
1462 predicate: None,
1463 doc: doc("/** Returns a fresh copy with bytes reversed. */"),
1464 },
1465 ),
1466 (
1467 "toSorted".to_string(),
1468 MethodSig {
1469 optional: false,
1470 generics: Vec::new(),
1471 params: vec![Param::with_default(
1472 "compareFn",
1473 Type::Union(vec![
1474 Type::Function {
1475 optional: 0,
1476 params: vec![Type::Number, Type::Number],
1477 ret: Box::new(Type::Number),
1478 predicate: None,
1479 has_rest: false,
1480 },
1481 Type::Undefined,
1482 ]),
1483 crate::DefaultValue::Undefined,
1484 )],
1485 ret: Type::Uint8Array,
1486 predicate: None,
1487 doc: doc("/** Returns a fresh copy sorted via `compareFn`. With no `compareFn`, sorts numerically ascending. */"),
1488 },
1489 ),
1490 (
1491 "toBase64".to_string(),
1492 MethodSig {
1493 optional: false,
1494 generics: Vec::new(),
1495 params: vec![Param::with_default(
1496 "options",
1497 Type::Union(vec![
1498 Type::prelude_interface("Base64Options".to_string(), Vec::new()),
1499 Type::Undefined,
1500 ]),
1501 crate::DefaultValue::Undefined,
1502 )],
1503 ret: Type::String,
1504 predicate: None,
1505 doc: doc("/** Returns the bytes as a base64 string. `options` selects alphabet and padding. */"),
1506 },
1507 ),
1508 (
1509 "toHex".to_string(),
1510 MethodSig {
1511 optional: false,
1512 generics: Vec::new(),
1513 params: Vec::new(),
1514 ret: Type::String,
1515 predicate: None,
1516 doc: doc("/** Returns the bytes as a lowercase hex string. */"),
1517 },
1518 ),
1519 ]),
1520 properties: BTreeMap::from([
1521 (
1522 "length".to_string(),
1523 PropertySig {
1524 ty: Type::Number,
1525 readonly: true,
1526 intrinsic: false,
1527 optional: false,
1528 doc: doc("/** The number of bytes in this array. */"),
1529 },
1530 ),
1531 (
1532 "BYTES_PER_ELEMENT".to_string(),
1533 PropertySig {
1534 ty: Type::Number,
1535 readonly: true,
1536 intrinsic: false,
1537 optional: false,
1538 doc: doc("/** The size in bytes of each element: always `1`. */"),
1539 },
1540 ),
1541 (
1542 "byteLength".to_string(),
1543 PropertySig {
1544 ty: Type::Number,
1545 readonly: true,
1546 intrinsic: false,
1547 optional: false,
1548 doc: doc("/** Equivalent to `length`. Provided for JS `TypedArray` API compatibility. */"),
1549 },
1550 ),
1551 ]),
1552 dispatch: Dispatch::Direct,
1553 doc: doc(
1554 "/** Packed byte array. Constructed via `new Uint8Array([...])` / `Uint8Array.alloc(n)` / `Uint8Array.fromArray(...)` / etc. */",
1555 ),
1556 },
1557 },
1558 );
1559
1560 defs.types.insert(
1561 "Uint8ArrayConstructor".to_string(),
1562 TypeSymbol {
1563 name: "Uint8ArrayConstructor".to_string(),
1564 mangled_name: crate::mangle::prelude("Uint8ArrayConstructor"),
1565 declaration_span: Span::at(crate::FileId::PRELUDE),
1566 kind: TypeKind::Interface { index: None,
1567 generics: Vec::new(),
1568 methods: BTreeMap::from([
1569 (
1570 "new".to_string(),
1571 MethodSig {
1572 optional: false,
1573 generics: Vec::new(),
1574 params: vec![Param::with_default(
1575 "values",
1576 Type::Union(vec![
1577 Type::Array(Box::new(Type::Number)),
1578 Type::Number,
1579 ]),
1580 crate::DefaultValue::Number(0.0),
1581 )],
1582 ret: Type::Uint8Array,
1583 predicate: None,
1584 doc: doc(
1585 "/**\n * Build a new `Uint8Array`. Given an array, truncates each element and reduces it modulo 256, as JavaScript does, so `-1` is 255. Given a number, allocates that many zero bytes (the same as `Uint8Array.alloc`, including its `RangeError` on a negative or too-large length). With no argument, the array is empty.\n * @param values Numeric values to copy into the new array, or the length to allocate. Defaults to `0`.\n */",
1586 ),
1587 },
1588 ),
1589 (
1590 "alloc".to_string(),
1591 MethodSig {
1592 optional: false,
1593 generics: Vec::new(),
1594 params: vec![Param::new("n", Type::Number)],
1595 ret: Type::Uint8Array,
1596 predicate: None,
1597 doc: doc(
1598 "/**\n * Allocate a zero-filled `Uint8Array` of length `n`. Fractional values truncate toward zero and `NaN` gives an empty array; a negative or too-large `n` raises a `RangeError`.\n * @param n Length in bytes.\n */",
1599 ),
1600 },
1601 ),
1602 (
1603 "fromArray".to_string(),
1604 MethodSig {
1605 optional: false,
1606 generics: Vec::new(),
1607 params: vec![Param::new(
1608 "values",
1609 Type::Array(Box::new(Type::Number)),
1610 )],
1611 ret: Type::Uint8Array,
1612 predicate: None,
1613 doc: doc(
1614 "/** Build a new `Uint8Array` from `values` — canonical name for `Uint8Array.new(values)`. */",
1615 ),
1616 },
1617 ),
1618 (
1619 "fromBytes".to_string(),
1620 MethodSig {
1621 optional: false,
1622 generics: Vec::new(),
1623 params: vec![Param::new("other", Type::Uint8Array)],
1624 ret: Type::Uint8Array,
1625 predicate: None,
1626 doc: doc(
1627 "/** Returns a deep copy of `other`. Mutations on the result don't touch `other`. */",
1628 ),
1629 },
1630 ),
1631 (
1632 "of".to_string(),
1633 MethodSig {
1634 optional: false,
1635 generics: Vec::new(),
1636 params: vec![Param::rest(
1637 "values",
1638 Type::Array(Box::new(Type::Number)),
1639 )],
1640 ret: Type::Uint8Array,
1641 predicate: None,
1642 doc: doc(
1643 "/** Build a `Uint8Array` from the supplied byte values — `Uint8Array.of(1, 2, 3)`. */",
1644 ),
1645 },
1646 ),
1647 (
1648 "fromBase64".to_string(),
1649 MethodSig {
1650 optional: false,
1651 generics: Vec::new(),
1652 params: vec![
1653 Param::new("s", Type::String),
1654 Param::with_default(
1655 "options",
1656 Type::Union(vec![
1657 Type::prelude_interface("Base64Options".to_string(), Vec::new()),
1658 Type::Undefined,
1659 ]),
1660 crate::DefaultValue::Undefined,
1661 ),
1662 ],
1663 ret: Type::Uint8Array,
1664 predicate: None,
1665 doc: doc(
1666 "/** Decode `s` as base64; `options.alphabet` picks standard vs URL-safe. Malformed input throws a `SyntaxError`. */",
1667 ),
1668 },
1669 ),
1670 (
1671 "fromHex".to_string(),
1672 MethodSig {
1673 optional: false,
1674 generics: Vec::new(),
1675 params: vec![Param::new("s", Type::String)],
1676 ret: Type::Uint8Array,
1677 predicate: None,
1678 doc: doc(
1679 "/** Decode `s` as a hex string. Mixed case accepted; whitespace or an odd length throws a `SyntaxError`. */",
1680 ),
1681 },
1682 ),
1683 ]),
1684 properties: BTreeMap::from([(
1685 "BYTES_PER_ELEMENT".to_string(),
1686 PropertySig {
1687 ty: Type::Number,
1688 readonly: true,
1689 intrinsic: false,
1690 optional: false,
1691 doc: doc("/** The size in bytes of each element: always `1`. */"),
1692 },
1693 )]),
1694 dispatch: Dispatch::Static,
1695 doc: doc(
1696 "/** Constructor object for `Uint8Array`. Accessed via the global `Uint8Array` binding. */",
1697 ),
1698 },
1699 },
1700 );
1701
1702 defs.types.insert(
1703 "Base64Options".to_string(),
1704 TypeSymbol {
1705 name: "Base64Options".to_string(),
1706 mangled_name: crate::mangle::prelude("Base64Options"),
1707 declaration_span: Span::at(crate::FileId::PRELUDE),
1708 kind: TypeKind::Interface { index: None,
1709 generics: Vec::new(),
1710 methods: BTreeMap::new(),
1711 properties: BTreeMap::from([
1712 (
1713 "alphabet".to_string(),
1714 PropertySig {
1715 ty: Type::Union(vec![
1716 Type::StringLiteral("base64".to_string()),
1717 Type::StringLiteral("base64url".to_string()),
1718 ]),
1719 readonly: false,
1720 intrinsic: false,
1721 optional: true,
1722 doc: doc(
1723 "/** Alphabet selector. `\"base64\"` (default) or `\"base64url\"`. */",
1724 ),
1725 },
1726 ),
1727 (
1728 "omitPadding".to_string(),
1729 PropertySig {
1730 ty: Type::Boolean,
1731 readonly: false,
1732 intrinsic: false,
1733 optional: true,
1734 doc: doc(
1735 "/** When `true`, omit the trailing `=` padding. Encode-only. */",
1736 ),
1737 },
1738 ),
1739 ]),
1740 dispatch: Dispatch::VTable,
1741 doc: doc(
1742 "/** Options bag for `Uint8Array#toBase64` / `Uint8Array.fromBase64`. All fields optional. */",
1743 ),
1744 },
1745 },
1746 );
1747
1748 defs.values.insert(
1749 "Uint8Array".to_string(),
1750 ValueSymbol {
1751 name: "Uint8Array".to_string(),
1752 mangled_name: crate::mangle::prelude("Uint8Array"),
1753 declaration_span: Span::at(crate::FileId::PRELUDE),
1754 kind: ValueKind::Const {
1755 ty: Type::prelude_interface("Uint8ArrayConstructor".to_string(), Vec::new()),
1756 doc: doc(
1757 "/** The `Uint8Array` constructor — call `Uint8Array.new([...])` or `Uint8Array.alloc(n)` to make instances. */",
1758 ),
1759 },
1760 },
1761 );
1762}