mini_racer_rs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/AI-DISCLOSURE.md +13 -0
  3. data/CHANGELOG.md +45 -0
  4. data/COMPATIBILITY.md +235 -0
  5. data/Cargo.lock +1263 -0
  6. data/Cargo.toml +62 -0
  7. data/LICENSE +21 -0
  8. data/README.md +254 -0
  9. data/THIRD_PARTY_NOTICES.md +4501 -0
  10. data/crates/mini_racer_engine/Cargo.toml +25 -0
  11. data/crates/mini_racer_engine/build.rs +13 -0
  12. data/crates/mini_racer_engine/src/context.rs +802 -0
  13. data/crates/mini_racer_engine/src/control.rs +239 -0
  14. data/crates/mini_racer_engine/src/error.rs +88 -0
  15. data/crates/mini_racer_engine/src/fast_calls.rs +681 -0
  16. data/crates/mini_racer_engine/src/lib.rs +20 -0
  17. data/crates/mini_racer_engine/src/notify.rs +107 -0
  18. data/crates/mini_racer_engine/src/process/code_cache.rs +412 -0
  19. data/crates/mini_racer_engine/src/process/fork.rs +261 -0
  20. data/crates/mini_racer_engine/src/process/platform.rs +194 -0
  21. data/crates/mini_racer_engine/src/process/tasks.rs +96 -0
  22. data/crates/mini_racer_engine/src/process/watchdog.rs +185 -0
  23. data/crates/mini_racer_engine/src/process/workers.rs +165 -0
  24. data/crates/mini_racer_engine/src/process.rs +69 -0
  25. data/crates/mini_racer_engine/src/runner.rs +1560 -0
  26. data/crates/mini_racer_engine/src/serialize.rs +253 -0
  27. data/crates/mini_racer_engine/src/snapshot.rs +221 -0
  28. data/crates/mini_racer_engine/src/spin.rs +23 -0
  29. data/crates/mini_racer_engine/src/sys.rs +566 -0
  30. data/crates/mini_racer_sync/Cargo.toml +18 -0
  31. data/crates/mini_racer_sync/src/channel.rs +621 -0
  32. data/crates/mini_racer_sync/src/fork.rs +116 -0
  33. data/crates/mini_racer_sync/src/lib.rs +20 -0
  34. data/crates/mini_racer_sync/src/lock.rs +49 -0
  35. data/crates/mini_racer_sync/src/parker.rs +44 -0
  36. data/crates/mini_racer_sync/src/primitives.rs +10 -0
  37. data/crates/mini_racer_sync/src/tasks.rs +345 -0
  38. data/crates/mini_racer_sync/src/termination.rs +1234 -0
  39. data/crates/mini_racer_sync/src/workers.rs +283 -0
  40. data/crates/mini_racer_wire/Cargo.toml +18 -0
  41. data/crates/mini_racer_wire/src/decode.rs +926 -0
  42. data/crates/mini_racer_wire/src/lib.rs +67 -0
  43. data/crates/mini_racer_wire/src/marker.rs +43 -0
  44. data/crates/mini_racer_wire/src/text.rs +106 -0
  45. data/crates/mini_racer_wire/src/write.rs +187 -0
  46. data/ext/mini_racer_rs/Cargo.toml +26 -0
  47. data/ext/mini_racer_rs/build.rs +16 -0
  48. data/ext/mini_racer_rs/extconf.rb +78 -0
  49. data/ext/mini_racer_rs/src/context.rs +485 -0
  50. data/ext/mini_racer_rs/src/decode.rs +450 -0
  51. data/ext/mini_racer_rs/src/encode.rs +333 -0
  52. data/ext/mini_racer_rs/src/errors.rs +156 -0
  53. data/ext/mini_racer_rs/src/fork.rs +31 -0
  54. data/ext/mini_racer_rs/src/gc_root.rs +117 -0
  55. data/ext/mini_racer_rs/src/guard.rs +7 -0
  56. data/ext/mini_racer_rs/src/host.rs +339 -0
  57. data/ext/mini_racer_rs/src/lib.rs +44 -0
  58. data/ext/mini_racer_rs/src/options.rs +269 -0
  59. data/ext/mini_racer_rs/src/platform.rs +42 -0
  60. data/ext/mini_racer_rs/src/rb_raw.rs +368 -0
  61. data/ext/mini_racer_rs/src/snapshot.rs +149 -0
  62. data/ext/mini_racer_rs/v8-archives.sha256 +8 -0
  63. data/lib/mini_racer/shared.rb +420 -0
  64. data/lib/mini_racer/truffleruby.rb +439 -0
  65. data/lib/mini_racer/version.rb +6 -0
  66. data/lib/mini_racer.rb +3 -0
  67. data/lib/mini_racer_rs/internal_error.rb +7 -0
  68. data/lib/mini_racer_rs/version.rb +5 -0
  69. data/lib/mini_racer_rs/vocabulary.rb +105 -0
  70. data/lib/mini_racer_rs.rb +33 -0
  71. data/licenses/mini_racer.txt +21 -0
  72. data/licenses/rust/SOURCES.tsv +6 -0
  73. data/licenses/rust/std/COPYRIGHT +34 -0
  74. data/licenses/rust/std/COPYRIGHT-library.html +29357 -0
  75. data/licenses/rust/std/LICENSE-APACHE +176 -0
  76. data/licenses/rust/std/LICENSE-MIT +25 -0
  77. data/licenses/v8/SOURCES.tsv +20 -0
  78. data/licenses/v8/abseil-cpp/LICENSE +203 -0
  79. data/licenses/v8/chromium-build/LICENSE +27 -0
  80. data/licenses/v8/components.tsv +29 -0
  81. data/licenses/v8/dragonbox/LICENSE-Boost +23 -0
  82. data/licenses/v8/fast_float/LICENSE-MIT +27 -0
  83. data/licenses/v8/highway/LICENSE +371 -0
  84. data/licenses/v8/icu/LICENSE +568 -0
  85. data/licenses/v8/inspector_protocol/LICENSE +27 -0
  86. data/licenses/v8/libc++/LICENSE.TXT +311 -0
  87. data/licenses/v8/libc++abi/LICENSE.TXT +311 -0
  88. data/licenses/v8/llvm-libc/LICENSE.TXT +278 -0
  89. data/licenses/v8/rapidhash/LICENSE +34 -0
  90. data/licenses/v8/simdutf/LICENSE +18 -0
  91. data/licenses/v8/siphash/LICENSE +116 -0
  92. data/licenses/v8/utf8-decoder/LICENSE +19 -0
  93. data/licenses/v8/v8/LICENSE +61 -0
  94. data/licenses/v8/v8/LICENSE.fdlibm +6 -0
  95. data/licenses/v8/v8/LICENSE.strongtalk +29 -0
  96. data/licenses/v8/v8/LICENSE.v8 +26 -0
  97. metadata +156 -0
@@ -0,0 +1,926 @@
1
+ use crate::READ_VERSIONS;
2
+ use crate::tag;
3
+
4
+ /// Text as V8 wrote it; the visitor transcodes.
5
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
6
+ pub enum Text<'a> {
7
+ Utf8(&'a [u8]),
8
+ Latin1(&'a [u8]),
9
+ Utf16Le(&'a [u8]),
10
+ }
11
+
12
+ #[derive(Debug, Clone, Copy, PartialEq)]
13
+ pub enum Scalar<'a> {
14
+ Undefined,
15
+ Null,
16
+ /// An absent element of a dense array.
17
+ Hole,
18
+ Bool(bool),
19
+ Int32(i32),
20
+ Uint32(u32),
21
+ Number(f64),
22
+ /// Magnitude as little-endian 64-bit words.
23
+ BigInt {
24
+ negative: bool,
25
+ digits: &'a [u8],
26
+ },
27
+ Text(Text<'a>),
28
+ /// Milliseconds since the Unix epoch.
29
+ Date(f64),
30
+ RegExp {
31
+ pattern: Text<'a>,
32
+ flags: u32,
33
+ },
34
+ /// The whole buffer; a typed array view over it decodes to the same value.
35
+ ArrayBuffer(&'a [u8]),
36
+ }
37
+
38
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
39
+ pub enum Container {
40
+ /// Every value of a multi-value frame, in order.
41
+ Values,
42
+ /// `length` is at most the bytes left in the input.
43
+ DenseArray {
44
+ length: u32,
45
+ },
46
+ /// `length` can be far larger than the entries that follow; do not
47
+ /// reserve by it.
48
+ SparseArray {
49
+ length: u32,
50
+ },
51
+ Object,
52
+ Map,
53
+ Set,
54
+ Error,
55
+ }
56
+
57
+ /// Receives decoded values. Containers get elements through `push` and keyed
58
+ /// entries (object properties, map entries, an array's named properties,
59
+ /// an error's fields) through `insert`.
60
+ ///
61
+ /// Runs of numbers in an array can come all at once instead, through the
62
+ /// methods whose defaults make those calls.
63
+ pub trait Visitor {
64
+ type Value: Copy;
65
+ type Frame;
66
+ type Error;
67
+
68
+ fn scalar(&mut self, scalar: Scalar<'_>) -> Result<Self::Value, Self::Error>;
69
+
70
+ /// Starts a container. A `value` returned here is the container itself;
71
+ /// it is registered at once so children can refer back to it.
72
+ fn begin(
73
+ &mut self,
74
+ container: Container,
75
+ ) -> Result<Begun<Self::Frame, Self::Value>, Self::Error>;
76
+
77
+ fn push(&mut self, frame: &mut Self::Frame, value: Self::Value) -> Result<(), Self::Error>;
78
+
79
+ fn insert(
80
+ &mut self,
81
+ frame: &mut Self::Frame,
82
+ key: Self::Value,
83
+ value: Self::Value,
84
+ ) -> Result<(), Self::Error>;
85
+
86
+ fn end(&mut self, frame: Self::Frame) -> Result<Self::Value, Self::Error>;
87
+
88
+ /// Remembers `value` as V8's object `id` for later back references. Ids
89
+ /// arrive in increasing order, except that a container whose `begin`
90
+ /// returned no value is registered when it ends.
91
+ fn register(&mut self, id: u32, value: Self::Value) -> Result<(), Self::Error>;
92
+
93
+ fn back_ref(&mut self, id: u32) -> Result<Self::Value, Self::Error>;
94
+
95
+ /// Consecutive int32 elements of a dense array, each of which would
96
+ /// otherwise reach `scalar` and then `push`.
97
+ fn push_int32s(&mut self, frame: &mut Self::Frame, values: &[i32]) -> Result<(), Self::Error> {
98
+ for &n in values {
99
+ let value = self.scalar(Scalar::Int32(n))?;
100
+ self.push(frame, value)?;
101
+ }
102
+ Ok(())
103
+ }
104
+
105
+ /// Consecutive double elements of a dense array, each of which would
106
+ /// otherwise reach `scalar` and then `push`.
107
+ fn push_numbers(&mut self, frame: &mut Self::Frame, values: &[f64]) -> Result<(), Self::Error> {
108
+ for &n in values {
109
+ let value = self.scalar(Scalar::Number(n))?;
110
+ self.push(frame, value)?;
111
+ }
112
+ Ok(())
113
+ }
114
+
115
+ /// Consecutive entries of a sparse array with an int32 key and an int32
116
+ /// value, each of which would otherwise reach `scalar` for its key, then
117
+ /// for its value, and then `insert`.
118
+ fn insert_int32s(
119
+ &mut self,
120
+ frame: &mut Self::Frame,
121
+ entries: &[(i32, i32)],
122
+ ) -> Result<(), Self::Error> {
123
+ for &(key, n) in entries {
124
+ let key = self.scalar(Scalar::Int32(key))?;
125
+ let value = self.scalar(Scalar::Int32(n))?;
126
+ self.insert(frame, key, value)?;
127
+ }
128
+ Ok(())
129
+ }
130
+
131
+ /// Consecutive entries of a sparse array with an int32 key and a double
132
+ /// value, each of which would otherwise reach `scalar` for its key, then
133
+ /// for its value, and then `insert`.
134
+ fn insert_numbers(
135
+ &mut self,
136
+ frame: &mut Self::Frame,
137
+ entries: &[(i32, f64)],
138
+ ) -> Result<(), Self::Error> {
139
+ for &(key, n) in entries {
140
+ let key = self.scalar(Scalar::Int32(key))?;
141
+ let value = self.scalar(Scalar::Number(n))?;
142
+ self.insert(frame, key, value)?;
143
+ }
144
+ Ok(())
145
+ }
146
+ }
147
+
148
+ pub struct Begun<F, V> {
149
+ pub frame: F,
150
+ pub value: Option<V>,
151
+ }
152
+
153
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
154
+ pub struct Limits {
155
+ /// Nesting below the outermost value; `mini_racer` stops at 96.
156
+ pub max_depth: u32,
157
+ pub max_bigint_bytes: u64,
158
+ }
159
+
160
+ impl Default for Limits {
161
+ fn default() -> Self {
162
+ Self {
163
+ max_depth: 96,
164
+ max_bigint_bytes: 16 << 20,
165
+ }
166
+ }
167
+ }
168
+
169
+ // Messages follow mini_racer's where its decoder reports the same condition.
170
+ #[derive(Debug, thiserror::Error)]
171
+ pub enum DecodeError<E> {
172
+ #[error("bad header")]
173
+ Header,
174
+ #[error("unsupported wire format version {0}")]
175
+ Version(u32),
176
+ #[error("input too short")]
177
+ Truncated,
178
+ #[error("bad varint")]
179
+ Varint,
180
+ #[error("bad tag: {}", printable(*tag))]
181
+ Unsupported { tag: u8 },
182
+ #[error("too much recursion")]
183
+ TooDeep,
184
+ #[error("bad bigint")]
185
+ BigInt,
186
+ #[error("negative zero bigint")]
187
+ NegativeZero,
188
+ #[error("bigint too big")]
189
+ BigIntTooBig,
190
+ #[error("bad utf16 string size")]
191
+ Utf16Length,
192
+ #[error("{0} count mismatch")]
193
+ Count(&'static str),
194
+ #[error("bad typed array")]
195
+ View,
196
+ #[error("bad regexp")]
197
+ RegExp,
198
+ #[error("bad string object")]
199
+ StringObject,
200
+ #[error("error .{0} is not a string")]
201
+ ErrorField(&'static str),
202
+ #[error("bad error object")]
203
+ ErrorObject,
204
+ #[error("too many objects")]
205
+ TooManyObjects,
206
+ #[error("bad object reference {0}")]
207
+ Reference(u32),
208
+ #[error("bad arraybuffer")]
209
+ ArrayBuffer,
210
+ #[error("{0}")]
211
+ Visitor(E),
212
+ }
213
+
214
+ fn printable(tag: u8) -> String {
215
+ if tag > 32 && tag < 127 {
216
+ char::from(tag).to_string()
217
+ } else {
218
+ format!("{tag:02x}")
219
+ }
220
+ }
221
+
222
+ // A view's offset and length must be multiples of its element size.
223
+ const fn element_size(subtag: u8) -> Option<u64> {
224
+ match subtag {
225
+ b'?' | b'B' | b'C' | b'b' => Some(1),
226
+ b'W' | b'w' | b'h' => Some(2),
227
+ b'D' | b'd' | b'f' => Some(4),
228
+ b'F' | b'Q' | b'q' => Some(8),
229
+ _ => None,
230
+ }
231
+ }
232
+
233
+ const REGEXP_FLAG_BITS: u32 = 9;
234
+ const REGEXP_UNICODE: u32 = 1 << 4;
235
+ // V8 rejects it unless its experimental regexp engine is on, which it is not.
236
+ const REGEXP_LINEAR: u32 = 1 << 6;
237
+ const REGEXP_UNICODE_SETS: u32 = 1 << 8;
238
+
239
+ const VIEW_LENGTH_TRACKING: u64 = 1;
240
+ const VIEW_BACKED_BY_RESIZABLE: u64 = 1 << 1;
241
+
242
+ #[derive(Clone, Copy)]
243
+ struct Reader<'a> {
244
+ rest: &'a [u8],
245
+ }
246
+
247
+ impl<'a> Reader<'a> {
248
+ fn byte<E>(&mut self) -> Result<u8, DecodeError<E>> {
249
+ let (&first, rest) = self.rest.split_first().ok_or(DecodeError::Truncated)?;
250
+ self.rest = rest;
251
+ Ok(first)
252
+ }
253
+
254
+ fn peek<E>(&self) -> Result<u8, DecodeError<E>> {
255
+ self.rest.first().copied().ok_or(DecodeError::Truncated)
256
+ }
257
+
258
+ fn varint<E>(&mut self) -> Result<u64, DecodeError<E>> {
259
+ let mut result = 0u64;
260
+ for shift in (0..64).step_by(7) {
261
+ let byte = self.byte()?;
262
+ // The tenth byte carries only bit 63; anything more overflows a u64.
263
+ if shift == 63 && byte > 1 {
264
+ return Err(DecodeError::Varint);
265
+ }
266
+ result |= u64::from(byte & 0x7f) << shift;
267
+ if byte & 0x80 == 0 {
268
+ return Ok(result);
269
+ }
270
+ }
271
+ Err(DecodeError::Varint)
272
+ }
273
+
274
+ fn varint_u32<E>(&mut self) -> Result<u32, DecodeError<E>> {
275
+ u32::try_from(self.varint()?).map_err(|_| DecodeError::Varint)
276
+ }
277
+
278
+ fn take<E>(&mut self, len: u64) -> Result<&'a [u8], DecodeError<E>> {
279
+ let len = usize::try_from(len).map_err(|_| DecodeError::Truncated)?;
280
+ let (head, rest) = self
281
+ .rest
282
+ .split_at_checked(len)
283
+ .ok_or(DecodeError::Truncated)?;
284
+ self.rest = rest;
285
+ Ok(head)
286
+ }
287
+
288
+ // Every NaN reads as the one quiet NaN, as in V8 and mini_racer.
289
+ fn double<E>(&mut self) -> Result<f64, DecodeError<E>> {
290
+ let bytes: [u8; 8] = self
291
+ .take(8)?
292
+ .try_into()
293
+ .map_err(|_| DecodeError::Truncated)?;
294
+ let value = f64::from_le_bytes(bytes);
295
+ Ok(if value.is_nan() { f64::NAN } else { value })
296
+ }
297
+
298
+ // V8 pads before a two-byte string to align its characters.
299
+ const fn skip_padding(&mut self) {
300
+ while let Some((&tag::PADDING, rest)) = self.rest.split_first() {
301
+ self.rest = rest;
302
+ }
303
+ }
304
+
305
+ // The readers a run takes elements with. Each consumes nothing unless
306
+ // the whole element reads cleanly, so whatever stops a run is read again,
307
+ // and reported, by the general path. They are marked inline because the
308
+ // generic decoder is compiled in the visitor's crate, which cannot inline
309
+ // them otherwise.
310
+ #[inline]
311
+ fn int32_element(&mut self) -> Option<i32> {
312
+ let mut ahead = *self;
313
+ if ahead.byte::<()>().ok()? != tag::INT32 {
314
+ return None;
315
+ }
316
+ let n = zigzag(ahead.varint_u32::<()>().ok()?);
317
+ *self = ahead;
318
+ Some(n)
319
+ }
320
+
321
+ #[inline]
322
+ fn number_element(&mut self) -> Option<f64> {
323
+ let mut ahead = *self;
324
+ if ahead.byte::<()>().ok()? != tag::DOUBLE {
325
+ return None;
326
+ }
327
+ let n = ahead.double::<()>().ok()?;
328
+ *self = ahead;
329
+ Some(n)
330
+ }
331
+
332
+ #[inline]
333
+ fn int32_entry(&mut self) -> Option<(i32, i32)> {
334
+ let mut ahead = *self;
335
+ let entry = (ahead.int32_element()?, ahead.int32_element()?);
336
+ *self = ahead;
337
+ Some(entry)
338
+ }
339
+
340
+ #[inline]
341
+ fn number_entry(&mut self) -> Option<(i32, f64)> {
342
+ let mut ahead = *self;
343
+ let entry = (ahead.int32_element()?, ahead.number_element()?);
344
+ *self = ahead;
345
+ Some(entry)
346
+ }
347
+ }
348
+
349
+ const RUN: usize = 64;
350
+
351
+ const fn zigzag(raw: u32) -> i32 {
352
+ let magnitude = raw >> 1;
353
+ if raw & 1 == 0 {
354
+ magnitude.cast_signed()
355
+ } else {
356
+ !magnitude.cast_signed()
357
+ }
358
+ }
359
+
360
+ #[derive(Clone, Copy)]
361
+ struct Buffer {
362
+ id: u32,
363
+ len: u64,
364
+ resizable: bool,
365
+ }
366
+
367
+ struct Decoder<'a, 'v, V> {
368
+ reader: Reader<'a>,
369
+ visitor: &'v mut V,
370
+ version: u32,
371
+ limits: Limits,
372
+ next_id: u32,
373
+ // One bit per id, set once registered, so a reference to an id not yet
374
+ // registered fails here as in V8, whatever the visitor stores.
375
+ registered: Vec<u64>,
376
+ // In increasing id order, so a view after a back reference can be
377
+ // checked against its buffer.
378
+ buffers: Vec<Buffer>,
379
+ }
380
+
381
+ type Decoded<V> = Result<<V as Visitor>::Value, DecodeError<<V as Visitor>::Error>>;
382
+
383
+ impl<'a, 'v, V: Visitor> Decoder<'a, 'v, V> {
384
+ fn visit<T>(result: Result<T, V::Error>) -> Result<T, DecodeError<V::Error>> {
385
+ result.map_err(DecodeError::Visitor)
386
+ }
387
+
388
+ fn new(
389
+ bytes: &'a [u8],
390
+ limits: Limits,
391
+ visitor: &'v mut V,
392
+ ) -> Result<Self, DecodeError<V::Error>> {
393
+ let mut reader = Reader { rest: bytes };
394
+ if reader.byte()? != tag::HEADER {
395
+ return Err(DecodeError::Header);
396
+ }
397
+ let version = reader.varint_u32()?;
398
+ if !READ_VERSIONS.contains(&version) {
399
+ return Err(DecodeError::Version(version));
400
+ }
401
+ Ok(Self {
402
+ reader,
403
+ visitor,
404
+ version,
405
+ limits,
406
+ next_id: 0,
407
+ registered: Vec::new(),
408
+ buffers: Vec::new(),
409
+ })
410
+ }
411
+
412
+ fn id(&mut self) -> Result<u32, DecodeError<V::Error>> {
413
+ let id = self.next_id;
414
+ self.next_id = id.checked_add(1).ok_or(DecodeError::TooManyObjects)?;
415
+ Ok(id)
416
+ }
417
+
418
+ const fn bit(id: u32) -> (usize, u64) {
419
+ ((id / 64) as usize, 1 << (id % 64))
420
+ }
421
+
422
+ fn is_registered(&self, id: u32) -> bool {
423
+ let (word, mask) = Self::bit(id);
424
+ self.registered
425
+ .get(word)
426
+ .is_some_and(|bits| bits & mask != 0)
427
+ }
428
+
429
+ fn register(&mut self, id: u32, value: V::Value) -> Result<(), DecodeError<V::Error>> {
430
+ let (word, mask) = Self::bit(id);
431
+ if self.registered.len() <= word {
432
+ self.registered.resize(word.saturating_add(1), 0);
433
+ }
434
+ if let Some(bits) = self.registered.get_mut(word) {
435
+ *bits |= mask;
436
+ }
437
+ Self::visit(self.visitor.register(id, value))
438
+ }
439
+
440
+ fn scalar_with_id(&mut self, scalar: Scalar<'_>) -> Decoded<V> {
441
+ let id = self.id()?;
442
+ let value = Self::visit(self.visitor.scalar(scalar))?;
443
+ self.register(id, value)?;
444
+ Ok(value)
445
+ }
446
+
447
+ fn child(depth: u32) -> Result<u32, DecodeError<V::Error>> {
448
+ depth.checked_sub(1).ok_or(DecodeError::TooDeep)
449
+ }
450
+
451
+ fn text(&mut self, tag: u8) -> Result<Option<Text<'a>>, DecodeError<V::Error>> {
452
+ let text = match tag {
453
+ tag::UTF8_STRING => {
454
+ let len = self.reader.varint()?;
455
+ Text::Utf8(self.reader.take(len)?)
456
+ }
457
+ tag::ONE_BYTE_STRING => {
458
+ let len = self.reader.varint()?;
459
+ Text::Latin1(self.reader.take(len)?)
460
+ }
461
+ tag::TWO_BYTE_STRING => {
462
+ let len = self.reader.varint()?;
463
+ let bytes = self.reader.take(len)?;
464
+ if !len.is_multiple_of(2) {
465
+ return Err(DecodeError::Utf16Length);
466
+ }
467
+ Text::Utf16Le(bytes)
468
+ }
469
+ _ => return Ok(None),
470
+ };
471
+ Ok(Some(text))
472
+ }
473
+
474
+ fn bigint(&mut self) -> Result<Scalar<'a>, DecodeError<V::Error>> {
475
+ let bitfield = self.reader.varint()?;
476
+ let negative = bitfield & 1 == 1;
477
+ let len = bitfield >> 1;
478
+ if !len.is_multiple_of(8) {
479
+ return Err(DecodeError::BigInt);
480
+ }
481
+ if negative && len == 0 {
482
+ return Err(DecodeError::NegativeZero);
483
+ }
484
+ let digits = self.reader.take(len)?;
485
+ if len > self.limits.max_bigint_bytes {
486
+ return Err(DecodeError::BigIntTooBig);
487
+ }
488
+ Ok(Scalar::BigInt { negative, digits })
489
+ }
490
+
491
+ fn tag(&mut self) -> Result<u8, DecodeError<V::Error>> {
492
+ loop {
493
+ match self.reader.byte()? {
494
+ tag::PADDING => {}
495
+ tag::VERIFY_OBJECT_COUNT => {
496
+ self.reader.varint_u32()?;
497
+ }
498
+ tag => return Ok(tag),
499
+ }
500
+ }
501
+ }
502
+
503
+ // Where V8 reads a string by itself: any value, which must be a string.
504
+ fn string(&mut self) -> Result<Option<Text<'a>>, DecodeError<V::Error>> {
505
+ let tag = self.tag()?;
506
+ self.text(tag)
507
+ }
508
+
509
+ fn value(&mut self, depth: u32) -> Decoded<V> {
510
+ let tag = self.tag()?;
511
+ if let Some(text) = self.text(tag)? {
512
+ return Self::visit(self.visitor.scalar(Scalar::Text(text)));
513
+ }
514
+ let scalar = match tag {
515
+ tag::UNDEFINED => Scalar::Undefined,
516
+ tag::NULL => Scalar::Null,
517
+ tag::TRUE => Scalar::Bool(true),
518
+ tag::FALSE => Scalar::Bool(false),
519
+ tag::INT32 => Scalar::Int32(zigzag(self.reader.varint_u32()?)),
520
+ tag::UINT32 => Scalar::Uint32(self.reader.varint_u32()?),
521
+ tag::DOUBLE => Scalar::Number(self.reader.double()?),
522
+ tag::BIGINT => self.bigint()?,
523
+ tag::TRUE_OBJECT => return self.scalar_with_id(Scalar::Bool(true)),
524
+ tag::FALSE_OBJECT => return self.scalar_with_id(Scalar::Bool(false)),
525
+ tag::NUMBER_OBJECT => {
526
+ let number = self.reader.double()?;
527
+ return self.scalar_with_id(Scalar::Number(number));
528
+ }
529
+ tag::BIGINT_OBJECT => {
530
+ let bigint = self.bigint()?;
531
+ return self.scalar_with_id(bigint);
532
+ }
533
+ tag::STRING_OBJECT => {
534
+ let text = self.string()?.ok_or(DecodeError::StringObject)?;
535
+ return self.scalar_with_id(Scalar::Text(text));
536
+ }
537
+ tag::DATE => {
538
+ let time = self.reader.double()?;
539
+ return self.scalar_with_id(Scalar::Date(time));
540
+ }
541
+ tag::REGEXP => {
542
+ // mini_racer counts the pattern as a level of nesting.
543
+ Self::child(depth)?;
544
+ let pattern = self.string()?.ok_or(DecodeError::RegExp)?;
545
+ let flags = self.reader.varint_u32()?;
546
+ let unicode_both = REGEXP_UNICODE | REGEXP_UNICODE_SETS;
547
+ if flags >> REGEXP_FLAG_BITS != 0
548
+ || flags & REGEXP_LINEAR != 0
549
+ || flags & unicode_both == unicode_both
550
+ {
551
+ return Err(DecodeError::RegExp);
552
+ }
553
+ return self.scalar_with_id(Scalar::RegExp { pattern, flags });
554
+ }
555
+ tag::ARRAY_BUFFER | tag::IMMUTABLE_ARRAY_BUFFER | tag::RESIZABLE_ARRAY_BUFFER => {
556
+ return self.array_buffer(tag);
557
+ }
558
+ tag::OBJECT_REFERENCE => return self.back_ref(),
559
+ tag::BEGIN_OBJECT => return self.object(depth),
560
+ tag::BEGIN_DENSE_ARRAY => return self.dense_array(depth),
561
+ tag::BEGIN_SPARSE_ARRAY => return self.sparse_array(depth),
562
+ tag::BEGIN_MAP => return self.map(depth),
563
+ tag::BEGIN_SET => return self.set(depth),
564
+ tag::ERROR => return self.error(depth),
565
+ tag => return Err(DecodeError::Unsupported { tag }),
566
+ };
567
+ Self::visit(self.visitor.scalar(scalar))
568
+ }
569
+
570
+ fn array_buffer(&mut self, tag: u8) -> Decoded<V> {
571
+ let len = self.reader.varint()?;
572
+ let resizable = tag == tag::RESIZABLE_ARRAY_BUFFER;
573
+ if resizable && self.reader.varint()? < len {
574
+ return Err(DecodeError::ArrayBuffer);
575
+ }
576
+ let id = self.id()?;
577
+ let bytes = self.reader.take(len)?;
578
+ let value = Self::visit(self.visitor.scalar(Scalar::ArrayBuffer(bytes)))?;
579
+ self.register(id, value)?;
580
+ let buffer = Buffer { id, len, resizable };
581
+ self.buffers.push(buffer);
582
+ self.view(value, buffer)
583
+ }
584
+
585
+ fn back_ref(&mut self) -> Decoded<V> {
586
+ let id = self.reader.varint_u32()?;
587
+ if !self.is_registered(id) {
588
+ return Err(DecodeError::Reference(id));
589
+ }
590
+ let value = Self::visit(self.visitor.back_ref(id))?;
591
+ let buffer = self
592
+ .buffers
593
+ .binary_search_by_key(&id, |buffer| buffer.id)
594
+ .ok()
595
+ .and_then(|index| self.buffers.get(index).copied());
596
+ buffer.map_or(Ok(value), |buffer| self.view(value, buffer))
597
+ }
598
+
599
+ // A view over a buffer decodes to the buffer itself but still takes an
600
+ // object id of its own.
601
+ fn view(&mut self, buffer: V::Value, of: Buffer) -> Decoded<V> {
602
+ if self.reader.peek::<V::Error>().ok() != Some(tag::ARRAY_BUFFER_VIEW) {
603
+ return Ok(buffer);
604
+ }
605
+ self.reader.byte()?;
606
+ let size = u8::try_from(self.reader.varint()?)
607
+ .ok()
608
+ .and_then(element_size)
609
+ .ok_or(DecodeError::View)?;
610
+ let offset = self.reader.varint()?;
611
+ let len = self.reader.varint()?;
612
+ if offset > of.len
613
+ || len > of.len.saturating_sub(offset)
614
+ || !offset.is_multiple_of(size)
615
+ || !len.is_multiple_of(size)
616
+ {
617
+ return Err(DecodeError::View);
618
+ }
619
+ if self.version >= 14 {
620
+ let flags = self.reader.varint()?;
621
+ let tracking = flags & VIEW_LENGTH_TRACKING != 0;
622
+ let backed = flags & VIEW_BACKED_BY_RESIZABLE != 0;
623
+ if (tracking || backed) != of.resizable || (of.resizable && !backed) {
624
+ return Err(DecodeError::View);
625
+ }
626
+ }
627
+ let id = self.id()?;
628
+ self.register(id, buffer)?;
629
+ Ok(buffer)
630
+ }
631
+
632
+ fn begin(
633
+ &mut self,
634
+ container: Container,
635
+ ) -> Result<(V::Frame, u32, bool), DecodeError<V::Error>> {
636
+ let id = self.id()?;
637
+ let begun = Self::visit(self.visitor.begin(container))?;
638
+ if let Some(value) = begun.value {
639
+ self.register(id, value)?;
640
+ }
641
+ Ok((begun.frame, id, begun.value.is_some()))
642
+ }
643
+
644
+ fn end(&mut self, frame: V::Frame, id: u32, registered: bool) -> Decoded<V> {
645
+ let value = Self::visit(self.visitor.end(frame))?;
646
+ if !registered {
647
+ self.register(id, value)?;
648
+ }
649
+ Ok(value)
650
+ }
651
+
652
+ fn insert(&mut self, frame: &mut V::Frame, depth: u32) -> Result<(), DecodeError<V::Error>> {
653
+ let key = self.value(Self::child(depth)?)?;
654
+ let value = self.value(Self::child(depth)?)?;
655
+ Self::visit(self.visitor.insert(frame, key, value))
656
+ }
657
+
658
+ // Reads keyed entries up to `end`, which may follow padding only if a key does.
659
+ fn entries(
660
+ &mut self,
661
+ frame: &mut V::Frame,
662
+ depth: u32,
663
+ end: u8,
664
+ ) -> Result<u32, DecodeError<V::Error>> {
665
+ let mut count = 0u32;
666
+ while self.reader.peek()? != end {
667
+ self.insert(frame, depth)?;
668
+ count = count.checked_add(1).ok_or(DecodeError::TooManyObjects)?;
669
+ }
670
+ self.reader.byte()?;
671
+ Ok(count)
672
+ }
673
+
674
+ fn expect_count(
675
+ &mut self,
676
+ actual: u64,
677
+ what: &'static str,
678
+ ) -> Result<(), DecodeError<V::Error>> {
679
+ if self.reader.varint()? == actual {
680
+ Ok(())
681
+ } else {
682
+ Err(DecodeError::Count(what))
683
+ }
684
+ }
685
+
686
+ fn object(&mut self, depth: u32) -> Decoded<V> {
687
+ let (mut frame, id, registered) = self.begin(Container::Object)?;
688
+ let count = self.entries(&mut frame, depth, tag::END_OBJECT)?;
689
+ self.expect_count(count.into(), "object properties")?;
690
+ self.end(frame, id, registered)
691
+ }
692
+
693
+ fn dense_array(&mut self, depth: u32) -> Decoded<V> {
694
+ let length = self.reader.varint_u32()?;
695
+ // Every element takes at least a byte.
696
+ let Some(mut left) = usize::try_from(length)
697
+ .ok()
698
+ .filter(|&length| length <= self.reader.rest.len())
699
+ else {
700
+ return Err(DecodeError::Truncated);
701
+ };
702
+ let (mut frame, id, registered) = self.begin(Container::DenseArray { length })?;
703
+ while left > 0 {
704
+ let taken = match self.element_run(&mut frame, depth, left)? {
705
+ 0 => {
706
+ self.element(&mut frame, depth)?;
707
+ 1
708
+ }
709
+ run => run,
710
+ };
711
+ left = left.saturating_sub(taken);
712
+ }
713
+ let properties = self.entries(&mut frame, depth, tag::END_DENSE_ARRAY)?;
714
+ self.expect_count(properties.into(), "array property")?;
715
+ self.expect_count(length.into(), "array element")?;
716
+ self.end(frame, id, registered)
717
+ }
718
+
719
+ fn element(&mut self, frame: &mut V::Frame, depth: u32) -> Result<(), DecodeError<V::Error>> {
720
+ let element = if self.reader.peek()? == tag::THE_HOLE {
721
+ self.reader.byte()?;
722
+ Self::visit(self.visitor.scalar(Scalar::Hole))?
723
+ } else {
724
+ self.value(Self::child(depth)?)?
725
+ };
726
+ Self::visit(self.visitor.push(frame, element))
727
+ }
728
+
729
+ fn element_run(
730
+ &mut self,
731
+ frame: &mut V::Frame,
732
+ depth: u32,
733
+ limit: usize,
734
+ ) -> Result<usize, DecodeError<V::Error>> {
735
+ match self.reader.rest.first() {
736
+ Some(&tag::INT32) => {
737
+ self.run(frame, depth, limit, Reader::int32_element, V::push_int32s)
738
+ }
739
+ Some(&tag::DOUBLE) => {
740
+ self.run(frame, depth, limit, Reader::number_element, V::push_numbers)
741
+ }
742
+ _ => Ok(0),
743
+ }
744
+ }
745
+
746
+ // Hands the visitor up to `limit` elements that `read` takes, at once,
747
+ // and returns how many it read; 0 leaves the next element to the general
748
+ // path, which reads it again and reports what stopped `read`. A run
749
+ // checks the depth as its first element would. A lone element skips the
750
+ // buffer, which costs more to fill than a run of one saves. Never inlined,
751
+ // so the buffer is not on the stack in every frame of a deeply nested value.
752
+ #[inline(never)]
753
+ fn run<T: Copy>(
754
+ &mut self,
755
+ frame: &mut V::Frame,
756
+ depth: u32,
757
+ limit: usize,
758
+ read: impl Fn(&mut Reader<'a>) -> Option<T>,
759
+ hand: impl FnOnce(&mut V, &mut V::Frame, &[T]) -> Result<(), V::Error>,
760
+ ) -> Result<usize, DecodeError<V::Error>> {
761
+ let Some(first) = read(&mut self.reader) else {
762
+ return Ok(0);
763
+ };
764
+ Self::child(depth)?;
765
+ let mut ahead = self.reader;
766
+ if limit < 2 || read(&mut ahead).is_none() {
767
+ Self::visit(hand(self.visitor, frame, &[first]))?;
768
+ return Ok(1);
769
+ }
770
+ let mut buffer = [first; RUN];
771
+ let mut filled = 1usize;
772
+ for slot in buffer.iter_mut().take(limit).skip(1) {
773
+ let Some(value) = read(&mut self.reader) else {
774
+ break;
775
+ };
776
+ *slot = value;
777
+ filled = filled.saturating_add(1);
778
+ }
779
+ let run = buffer.get(..filled).unwrap_or_default();
780
+ Self::visit(hand(self.visitor, frame, run))?;
781
+ Ok(run.len())
782
+ }
783
+
784
+ fn sparse_array(&mut self, depth: u32) -> Decoded<V> {
785
+ let length = self.reader.varint_u32()?;
786
+ let (mut frame, id, registered) = self.begin(Container::SparseArray { length })?;
787
+ let mut properties = 0u32;
788
+ while self.reader.peek()? != tag::END_SPARSE_ARRAY {
789
+ // A run stops short of the entry that overflows the count, so the
790
+ // general path inserts it and then fails.
791
+ let room = usize::try_from(u32::MAX.saturating_sub(properties)).unwrap_or(usize::MAX);
792
+ let taken = match self.int32_keyed(&mut frame, depth, room)? {
793
+ 0 => {
794
+ self.insert(&mut frame, depth)?;
795
+ 1
796
+ }
797
+ run => u32::try_from(run).map_err(|_| DecodeError::TooManyObjects)?,
798
+ };
799
+ properties = properties
800
+ .checked_add(taken)
801
+ .ok_or(DecodeError::TooManyObjects)?;
802
+ }
803
+ self.reader.byte()?;
804
+ self.expect_count(properties.into(), "element")?;
805
+ self.expect_count(length.into(), "element")?;
806
+ self.end(frame, id, registered)
807
+ }
808
+
809
+ // Reads entries whose key is an int32, the shape V8 writes for a holey
810
+ // array's elements, and returns how many: a run while their values are
811
+ // int32s or doubles, and otherwise the one entry, as `insert` reads it but
812
+ // without reading its key twice. 0 leaves the next entry to `insert`.
813
+ fn int32_keyed(
814
+ &mut self,
815
+ frame: &mut V::Frame,
816
+ depth: u32,
817
+ limit: usize,
818
+ ) -> Result<usize, DecodeError<V::Error>> {
819
+ if limit == 0 {
820
+ return Ok(0);
821
+ }
822
+ let mut ahead = self.reader;
823
+ let Some(key) = ahead.int32_element() else {
824
+ return Ok(0);
825
+ };
826
+ match ahead.rest.first() {
827
+ Some(&tag::INT32) => {
828
+ self.run(frame, depth, limit, Reader::int32_entry, V::insert_int32s)
829
+ }
830
+ Some(&tag::DOUBLE) => {
831
+ self.run(frame, depth, limit, Reader::number_entry, V::insert_numbers)
832
+ }
833
+ _ => {
834
+ self.reader = ahead;
835
+ Self::child(depth)?;
836
+ let key = Self::visit(self.visitor.scalar(Scalar::Int32(key)))?;
837
+ let value = self.value(Self::child(depth)?)?;
838
+ Self::visit(self.visitor.insert(frame, key, value))?;
839
+ Ok(1)
840
+ }
841
+ }
842
+ }
843
+
844
+ fn map(&mut self, depth: u32) -> Decoded<V> {
845
+ let (mut frame, id, registered) = self.begin(Container::Map)?;
846
+ let entries = self.entries(&mut frame, depth, tag::END_MAP)?;
847
+ self.expect_count(u64::from(entries).saturating_mul(2), "map element")?;
848
+ self.end(frame, id, registered)
849
+ }
850
+
851
+ fn set(&mut self, depth: u32) -> Decoded<V> {
852
+ let (mut frame, id, registered) = self.begin(Container::Set)?;
853
+ let mut count = 0u32;
854
+ while self.reader.peek()? != tag::END_SET {
855
+ let element = self.value(Self::child(depth)?)?;
856
+ Self::visit(self.visitor.push(&mut frame, element))?;
857
+ count = count.checked_add(1).ok_or(DecodeError::TooManyObjects)?;
858
+ }
859
+ self.reader.byte()?;
860
+ self.expect_count(count.into(), "set element")?;
861
+ self.end(frame, id, registered)
862
+ }
863
+
864
+ // V8 reads an optional prototype, message and stack in that order, then
865
+ // registers the error, so a cause after them can refer back to it.
866
+ fn error(&mut self, depth: u32) -> Decoded<V> {
867
+ let id = self.id()?;
868
+ let begun = Self::visit(self.visitor.begin(Container::Error))?;
869
+ let mut frame = begun.frame;
870
+ let mut field = self.reader.byte()?;
871
+ if matches!(field, b'E' | b'F' | b'R' | b'S' | b'T' | b'U') {
872
+ field = self.reader.byte()?;
873
+ }
874
+ for (tag, name) in [(tag::ERROR_MESSAGE, "message"), (tag::ERROR_STACK, "stack")] {
875
+ if field == tag {
876
+ Self::child(depth)?;
877
+ let text = self.string()?.ok_or(DecodeError::ErrorField(name))?;
878
+ let key = self.key(name)?;
879
+ let value = Self::visit(self.visitor.scalar(Scalar::Text(text)))?;
880
+ Self::visit(self.visitor.insert(&mut frame, key, value))?;
881
+ field = self.reader.byte()?;
882
+ }
883
+ }
884
+ if let Some(value) = begun.value {
885
+ self.register(id, value)?;
886
+ }
887
+ if field == tag::ERROR_CAUSE {
888
+ let key = self.key("cause")?;
889
+ let value = self.value(Self::child(depth)?)?;
890
+ Self::visit(self.visitor.insert(&mut frame, key, value))?;
891
+ field = self.reader.byte()?;
892
+ }
893
+ if field != tag::ERROR_END {
894
+ return Err(DecodeError::ErrorObject);
895
+ }
896
+ self.end(frame, id, begun.value.is_some())
897
+ }
898
+
899
+ fn key(&mut self, name: &'static str) -> Decoded<V> {
900
+ Self::visit(
901
+ self.visitor
902
+ .scalar(Scalar::Text(Text::Utf8(name.as_bytes()))),
903
+ )
904
+ }
905
+ }
906
+
907
+ /// Decodes the one value of a V8 `ValueSerializer` buffer.
908
+ pub fn decode_value<V: Visitor>(bytes: &[u8], limits: Limits, visitor: &mut V) -> Decoded<V> {
909
+ Decoder::new(bytes, limits, visitor)?.value(limits.max_depth)
910
+ }
911
+
912
+ /// Decodes every value of a buffer written as several values after one
913
+ /// header, which share object ids. They arrive as a `Container::Values`.
914
+ pub fn decode_values<V: Visitor>(bytes: &[u8], limits: Limits, visitor: &mut V) -> Decoded<V> {
915
+ let mut decoder = Decoder::new(bytes, limits, visitor)?;
916
+ let mut frame = Decoder::<V>::visit(decoder.visitor.begin(Container::Values))?.frame;
917
+ loop {
918
+ decoder.reader.skip_padding();
919
+ if decoder.reader.rest.is_empty() {
920
+ break;
921
+ }
922
+ let value = decoder.value(limits.max_depth)?;
923
+ Decoder::<V>::visit(decoder.visitor.push(&mut frame, value))?;
924
+ }
925
+ Decoder::<V>::visit(decoder.visitor.end(frame))
926
+ }