mustardscript 0.1.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 (99) hide show
  1. package/Cargo.lock +1579 -0
  2. package/Cargo.toml +40 -0
  3. package/LICENSE +201 -0
  4. package/README.md +828 -0
  5. package/SECURITY.md +34 -0
  6. package/crates/mustard/Cargo.toml +31 -0
  7. package/crates/mustard/src/cancellation.rs +28 -0
  8. package/crates/mustard/src/diagnostic.rs +145 -0
  9. package/crates/mustard/src/ir.rs +435 -0
  10. package/crates/mustard/src/lib.rs +21 -0
  11. package/crates/mustard/src/limits.rs +22 -0
  12. package/crates/mustard/src/parser/expressions.rs +723 -0
  13. package/crates/mustard/src/parser/mod.rs +115 -0
  14. package/crates/mustard/src/parser/operators.rs +105 -0
  15. package/crates/mustard/src/parser/patterns.rs +123 -0
  16. package/crates/mustard/src/parser/scope.rs +107 -0
  17. package/crates/mustard/src/parser/statements.rs +298 -0
  18. package/crates/mustard/src/parser/tests/acceptance.rs +339 -0
  19. package/crates/mustard/src/parser/tests/mod.rs +2 -0
  20. package/crates/mustard/src/parser/tests/rejections.rs +107 -0
  21. package/crates/mustard/src/runtime/accounting.rs +613 -0
  22. package/crates/mustard/src/runtime/api.rs +192 -0
  23. package/crates/mustard/src/runtime/async_runtime/mod.rs +5 -0
  24. package/crates/mustard/src/runtime/async_runtime/promises.rs +246 -0
  25. package/crates/mustard/src/runtime/async_runtime/reactions.rs +400 -0
  26. package/crates/mustard/src/runtime/async_runtime/scheduler.rs +224 -0
  27. package/crates/mustard/src/runtime/builtins/arrays.rs +1205 -0
  28. package/crates/mustard/src/runtime/builtins/collections.rs +573 -0
  29. package/crates/mustard/src/runtime/builtins/install.rs +501 -0
  30. package/crates/mustard/src/runtime/builtins/intl.rs +553 -0
  31. package/crates/mustard/src/runtime/builtins/mod.rs +25 -0
  32. package/crates/mustard/src/runtime/builtins/objects.rs +405 -0
  33. package/crates/mustard/src/runtime/builtins/primitives.rs +859 -0
  34. package/crates/mustard/src/runtime/builtins/promises.rs +335 -0
  35. package/crates/mustard/src/runtime/builtins/regexp.rs +356 -0
  36. package/crates/mustard/src/runtime/builtins/strings.rs +803 -0
  37. package/crates/mustard/src/runtime/builtins/support.rs +561 -0
  38. package/crates/mustard/src/runtime/bytecode.rs +123 -0
  39. package/crates/mustard/src/runtime/compiler/assignments.rs +690 -0
  40. package/crates/mustard/src/runtime/compiler/bindings.rs +92 -0
  41. package/crates/mustard/src/runtime/compiler/context.rs +46 -0
  42. package/crates/mustard/src/runtime/compiler/control.rs +342 -0
  43. package/crates/mustard/src/runtime/compiler/expressions.rs +372 -0
  44. package/crates/mustard/src/runtime/compiler/mod.rs +173 -0
  45. package/crates/mustard/src/runtime/compiler/statements.rs +459 -0
  46. package/crates/mustard/src/runtime/conversions/boundary.rs +293 -0
  47. package/crates/mustard/src/runtime/conversions/coercions.rs +217 -0
  48. package/crates/mustard/src/runtime/conversions/errors.rs +118 -0
  49. package/crates/mustard/src/runtime/conversions/mod.rs +14 -0
  50. package/crates/mustard/src/runtime/conversions/operators.rs +334 -0
  51. package/crates/mustard/src/runtime/env.rs +355 -0
  52. package/crates/mustard/src/runtime/exceptions.rs +377 -0
  53. package/crates/mustard/src/runtime/gc.rs +595 -0
  54. package/crates/mustard/src/runtime/mod.rs +318 -0
  55. package/crates/mustard/src/runtime/properties.rs +1762 -0
  56. package/crates/mustard/src/runtime/serialization.rs +127 -0
  57. package/crates/mustard/src/runtime/shared.rs +108 -0
  58. package/crates/mustard/src/runtime/snapshot_validation_tests.rs +93 -0
  59. package/crates/mustard/src/runtime/state.rs +652 -0
  60. package/crates/mustard/src/runtime/tests/async_host.rs +104 -0
  61. package/crates/mustard/src/runtime/tests/collections.rs +50 -0
  62. package/crates/mustard/src/runtime/tests/diagnostics.rs +36 -0
  63. package/crates/mustard/src/runtime/tests/exceptions.rs +122 -0
  64. package/crates/mustard/src/runtime/tests/execution.rs +553 -0
  65. package/crates/mustard/src/runtime/tests/gc.rs +533 -0
  66. package/crates/mustard/src/runtime/tests/mod.rs +56 -0
  67. package/crates/mustard/src/runtime/tests/serialization.rs +170 -0
  68. package/crates/mustard/src/runtime/validation/bytecode.rs +484 -0
  69. package/crates/mustard/src/runtime/validation/mod.rs +14 -0
  70. package/crates/mustard/src/runtime/validation/policy.rs +94 -0
  71. package/crates/mustard/src/runtime/validation/snapshot.rs +406 -0
  72. package/crates/mustard/src/runtime/validation/walk.rs +206 -0
  73. package/crates/mustard/src/runtime/vm.rs +1016 -0
  74. package/crates/mustard/src/span.rs +22 -0
  75. package/crates/mustard/src/structured.rs +107 -0
  76. package/crates/mustard-bridge/Cargo.toml +17 -0
  77. package/crates/mustard-bridge/src/codec.rs +46 -0
  78. package/crates/mustard-bridge/src/dto.rs +99 -0
  79. package/crates/mustard-bridge/src/lib.rs +12 -0
  80. package/crates/mustard-bridge/src/operations.rs +142 -0
  81. package/crates/mustard-node/Cargo.toml +24 -0
  82. package/crates/mustard-node/build.rs +3 -0
  83. package/crates/mustard-node/src/lib.rs +236 -0
  84. package/crates/mustard-sidecar/Cargo.toml +21 -0
  85. package/crates/mustard-sidecar/src/lib.rs +134 -0
  86. package/crates/mustard-sidecar/src/main.rs +36 -0
  87. package/dist/index.js +20 -0
  88. package/dist/install.js +117 -0
  89. package/dist/lib/cancellation.js +124 -0
  90. package/dist/lib/errors.js +46 -0
  91. package/dist/lib/executor.js +555 -0
  92. package/dist/lib/policy.js +292 -0
  93. package/dist/lib/progress.js +356 -0
  94. package/dist/lib/runtime.js +109 -0
  95. package/dist/lib/structured.js +286 -0
  96. package/dist/native-loader.js +227 -0
  97. package/index.d.ts +23 -0
  98. package/mustard.d.ts +220 -0
  99. package/package.json +97 -0
@@ -0,0 +1,459 @@
1
+ use super::super::bytecode::Instruction;
2
+ use super::{
3
+ Compiler,
4
+ context::{CompileContext, LoopContext},
5
+ pattern_bindings,
6
+ };
7
+ use crate::{
8
+ diagnostic::{MustardError, MustardResult},
9
+ ir::{AssignOp, BinaryOp, BindingKind, Expr, ForInit, ForOfHead, Pattern, Stmt},
10
+ };
11
+
12
+ impl Compiler {
13
+ pub(super) fn compile_stmt(
14
+ &mut self,
15
+ context: &mut CompileContext,
16
+ statement: &Stmt,
17
+ ) -> MustardResult<()> {
18
+ match statement {
19
+ Stmt::Block { body, .. } => {
20
+ context.code.push(Instruction::PushEnv);
21
+ context.scope_depth += 1;
22
+ self.emit_block_prologue(context, body, false)?;
23
+ for statement in body {
24
+ self.compile_stmt(context, statement)?;
25
+ }
26
+ context.scope_depth -= 1;
27
+ context.code.push(Instruction::PopEnv);
28
+ }
29
+ Stmt::VariableDecl { declarators, .. } => {
30
+ for declarator in declarators {
31
+ if let Some(initializer) = &declarator.initializer {
32
+ self.compile_expr(context, initializer)?;
33
+ } else {
34
+ context.code.push(Instruction::PushUndefined);
35
+ }
36
+ self.compile_pattern_binding(context, &declarator.pattern)?;
37
+ }
38
+ }
39
+ Stmt::FunctionDecl { .. } => {}
40
+ Stmt::Expression { expression, .. } => {
41
+ self.compile_expr(context, expression)?;
42
+ context.code.push(Instruction::Pop);
43
+ }
44
+ Stmt::If {
45
+ test,
46
+ consequent,
47
+ alternate,
48
+ ..
49
+ } => {
50
+ self.compile_expr(context, test)?;
51
+ let jump_to_else = self.emit_jump(context, Instruction::JumpIfFalse(usize::MAX));
52
+ context.code.push(Instruction::Pop);
53
+ self.compile_stmt(context, consequent)?;
54
+ let jump_to_end = self.emit_jump(context, Instruction::Jump(usize::MAX));
55
+ let else_ip = context.code.len();
56
+ self.patch_jump(context, jump_to_else, else_ip);
57
+ context.code.push(Instruction::Pop);
58
+ if let Some(alternate) = alternate {
59
+ self.compile_stmt(context, alternate)?;
60
+ }
61
+ let end_ip = context.code.len();
62
+ self.patch_jump(context, jump_to_end, end_ip);
63
+ }
64
+ Stmt::While { test, body, .. } => {
65
+ let loop_start = context.code.len();
66
+ self.compile_expr(context, test)?;
67
+ let exit_jump = self.emit_jump(context, Instruction::JumpIfFalse(usize::MAX));
68
+ context.code.push(Instruction::Pop);
69
+ context.loop_stack.push(LoopContext {
70
+ handler_depth: context.active_handlers.len(),
71
+ scope_depth: context.scope_depth,
72
+ ..LoopContext::default()
73
+ });
74
+ self.compile_stmt(context, body)?;
75
+ let loop_ctx = context.loop_stack.pop().unwrap_or_default();
76
+ let continue_target = loop_ctx.continue_target.unwrap_or(loop_start);
77
+ for jump in loop_ctx.continue_jumps {
78
+ self.patch_control_transfer(context, jump, continue_target);
79
+ }
80
+ context.code.push(Instruction::Jump(loop_start));
81
+ let false_path_ip = context.code.len();
82
+ context.code.push(Instruction::Pop);
83
+ let loop_end = context.code.len();
84
+ self.patch_jump(context, exit_jump, false_path_ip);
85
+ for jump in loop_ctx.break_jumps {
86
+ self.patch_control_transfer(context, jump, loop_end);
87
+ }
88
+ }
89
+ Stmt::DoWhile { body, test, .. } => {
90
+ let loop_start = context.code.len();
91
+ context.loop_stack.push(LoopContext {
92
+ handler_depth: context.active_handlers.len(),
93
+ scope_depth: context.scope_depth,
94
+ ..LoopContext::default()
95
+ });
96
+ self.compile_stmt(context, body)?;
97
+ let continue_target = context.code.len();
98
+ if let Some(loop_ctx) = context.loop_stack.last_mut() {
99
+ loop_ctx.continue_target = Some(continue_target);
100
+ }
101
+ self.compile_expr(context, test)?;
102
+ let exit_jump = self.emit_jump(context, Instruction::JumpIfFalse(usize::MAX));
103
+ context.code.push(Instruction::Pop);
104
+ context.code.push(Instruction::Jump(loop_start));
105
+ let false_path_ip = context.code.len();
106
+ context.code.push(Instruction::Pop);
107
+ let loop_end = context.code.len();
108
+ self.patch_jump(context, exit_jump, false_path_ip);
109
+ let loop_ctx = context.loop_stack.pop().unwrap_or_default();
110
+ for jump in loop_ctx.continue_jumps {
111
+ self.patch_control_transfer(context, jump, continue_target);
112
+ }
113
+ for jump in loop_ctx.break_jumps {
114
+ self.patch_control_transfer(context, jump, loop_end);
115
+ }
116
+ }
117
+ Stmt::For {
118
+ init,
119
+ test,
120
+ update,
121
+ body,
122
+ ..
123
+ } => {
124
+ context.code.push(Instruction::PushEnv);
125
+ context.scope_depth += 1;
126
+ if let Some(init) = init {
127
+ match init {
128
+ ForInit::VariableDecl {
129
+ kind: _,
130
+ declarators,
131
+ } => {
132
+ for declarator in declarators {
133
+ for (name, mutable) in pattern_bindings(&declarator.pattern) {
134
+ context
135
+ .code
136
+ .push(Instruction::DeclareName { name, mutable });
137
+ }
138
+ if let Some(initializer) = &declarator.initializer {
139
+ self.compile_expr(context, initializer)?;
140
+ } else {
141
+ context.code.push(Instruction::PushUndefined);
142
+ }
143
+ self.compile_pattern_binding(context, &declarator.pattern)?;
144
+ }
145
+ }
146
+ ForInit::Expression(expression) => {
147
+ self.compile_expr(context, expression)?;
148
+ context.code.push(Instruction::Pop);
149
+ }
150
+ }
151
+ }
152
+ let loop_start = context.code.len();
153
+ let exit_jump = if let Some(test) = test {
154
+ self.compile_expr(context, test)?;
155
+ let jump = self.emit_jump(context, Instruction::JumpIfFalse(usize::MAX));
156
+ context.code.push(Instruction::Pop);
157
+ Some(jump)
158
+ } else {
159
+ None
160
+ };
161
+ context.loop_stack.push(LoopContext {
162
+ handler_depth: context.active_handlers.len(),
163
+ scope_depth: context.scope_depth,
164
+ ..LoopContext::default()
165
+ });
166
+ self.compile_stmt(context, body)?;
167
+ let update_start = context.code.len();
168
+ if let Some(loop_ctx) = context.loop_stack.last_mut() {
169
+ loop_ctx.continue_target = Some(update_start);
170
+ }
171
+ if let Some(update) = update {
172
+ self.compile_expr(context, update)?;
173
+ context.code.push(Instruction::Pop);
174
+ }
175
+ context.code.push(Instruction::Jump(loop_start));
176
+ let false_path_ip = context.code.len();
177
+ if exit_jump.is_some() {
178
+ context.code.push(Instruction::Pop);
179
+ }
180
+ let loop_end = context.code.len();
181
+ if let Some(exit_jump) = exit_jump {
182
+ self.patch_jump(context, exit_jump, false_path_ip);
183
+ }
184
+ let loop_ctx = context.loop_stack.pop().unwrap_or_default();
185
+ for jump in loop_ctx.continue_jumps {
186
+ self.patch_control_transfer(context, jump, update_start);
187
+ }
188
+ for jump in loop_ctx.break_jumps {
189
+ self.patch_control_transfer(context, jump, loop_end);
190
+ }
191
+ context.scope_depth -= 1;
192
+ context.code.push(Instruction::PopEnv);
193
+ }
194
+ Stmt::ForOf {
195
+ span,
196
+ await_each,
197
+ head,
198
+ iterable,
199
+ body,
200
+ } => {
201
+ context.code.push(Instruction::PushEnv);
202
+ context.scope_depth += 1;
203
+ let loop_scope_depth = context.scope_depth;
204
+ let iterator_binding = self.fresh_internal_name(context, "iter");
205
+ let assignment_value_binding = match head {
206
+ ForOfHead::Binding { .. } => None,
207
+ ForOfHead::Assignment { .. } => {
208
+ Some(self.fresh_internal_name(context, "for_of_value"))
209
+ }
210
+ };
211
+ context.code.push(Instruction::DeclareName {
212
+ name: iterator_binding.clone(),
213
+ mutable: false,
214
+ });
215
+ if let Some(binding) = &assignment_value_binding {
216
+ context.code.push(Instruction::DeclareName {
217
+ name: binding.clone(),
218
+ mutable: true,
219
+ });
220
+ context.code.push(Instruction::PushUndefined);
221
+ context
222
+ .code
223
+ .push(Instruction::InitializePattern(Pattern::Identifier {
224
+ span: *span,
225
+ name: binding.clone(),
226
+ }));
227
+ }
228
+ self.compile_expr(context, iterable)?;
229
+ context.code.push(Instruction::CreateIterator);
230
+ context
231
+ .code
232
+ .push(Instruction::InitializePattern(Pattern::Identifier {
233
+ span: *span,
234
+ name: iterator_binding.clone(),
235
+ }));
236
+
237
+ let loop_start = context.code.len();
238
+ context
239
+ .code
240
+ .push(Instruction::LoadName(iterator_binding.clone()));
241
+ context.code.push(Instruction::IteratorNext);
242
+ let exit_jump = self.emit_jump(context, Instruction::JumpIfTrue(usize::MAX));
243
+ context.code.push(Instruction::Pop);
244
+ if *await_each {
245
+ context.code.push(Instruction::Await);
246
+ }
247
+
248
+ match head {
249
+ ForOfHead::Binding { kind, pattern } => {
250
+ context.code.push(Instruction::PushEnv);
251
+ context.scope_depth += 1;
252
+ for (name, _) in pattern_bindings(pattern) {
253
+ context.code.push(Instruction::DeclareName {
254
+ name,
255
+ mutable: *kind == BindingKind::Let,
256
+ });
257
+ }
258
+ self.compile_pattern_binding(context, pattern)?;
259
+ }
260
+ ForOfHead::Assignment { target } => {
261
+ let binding = assignment_value_binding
262
+ .as_ref()
263
+ .expect("assignment-target for...of should have a temp binding");
264
+ context
265
+ .code
266
+ .push(Instruction::InitializePattern(Pattern::Identifier {
267
+ span: *span,
268
+ name: binding.clone(),
269
+ }));
270
+ self.compile_assignment(
271
+ context,
272
+ target,
273
+ AssignOp::Assign,
274
+ &Expr::Identifier {
275
+ span: *span,
276
+ name: binding.clone(),
277
+ },
278
+ )?;
279
+ context.code.push(Instruction::Pop);
280
+ }
281
+ }
282
+ context.loop_stack.push(LoopContext {
283
+ handler_depth: context.active_handlers.len(),
284
+ scope_depth: loop_scope_depth,
285
+ ..LoopContext::default()
286
+ });
287
+ self.compile_stmt(context, body)?;
288
+ if matches!(head, ForOfHead::Binding { .. }) {
289
+ context.scope_depth -= 1;
290
+ context.code.push(Instruction::PopEnv);
291
+ }
292
+ let continue_target = context.code.len();
293
+ context.code.push(Instruction::Jump(loop_start));
294
+
295
+ let done_path_ip = context.code.len();
296
+ context.code.push(Instruction::Pop);
297
+ context.code.push(Instruction::Pop);
298
+ let loop_end = context.code.len();
299
+ self.patch_jump(context, exit_jump, done_path_ip);
300
+
301
+ let loop_ctx = context.loop_stack.pop().unwrap_or_default();
302
+ for jump in loop_ctx.continue_jumps {
303
+ self.patch_control_transfer(context, jump, continue_target);
304
+ }
305
+ for jump in loop_ctx.break_jumps {
306
+ self.patch_control_transfer(context, jump, loop_end);
307
+ }
308
+
309
+ context.scope_depth -= 1;
310
+ context.code.push(Instruction::PopEnv);
311
+ }
312
+ Stmt::ForIn {
313
+ span,
314
+ head,
315
+ object,
316
+ body,
317
+ } => {
318
+ self.compile_stmt(
319
+ context,
320
+ &Stmt::ForOf {
321
+ span: *span,
322
+ await_each: false,
323
+ head: head.clone(),
324
+ iterable: Expr::Call {
325
+ span: *span,
326
+ callee: Box::new(Expr::Member {
327
+ span: *span,
328
+ object: Box::new(Expr::Identifier {
329
+ span: *span,
330
+ name: "Object".to_string(),
331
+ }),
332
+ property: crate::ir::MemberProperty::Static(
333
+ crate::ir::PropertyName::Identifier("keys".to_string()),
334
+ ),
335
+ optional: false,
336
+ }),
337
+ arguments: vec![crate::ir::CallArgument::Value(object.clone())],
338
+ optional: false,
339
+ },
340
+ body: body.clone(),
341
+ },
342
+ )?;
343
+ }
344
+ Stmt::Break { span } => {
345
+ let Some(loop_ctx) = context.loop_stack.last() else {
346
+ return Err(MustardError::runtime_at(
347
+ "`break` used outside of a loop",
348
+ *span,
349
+ ));
350
+ };
351
+ let patch =
352
+ self.emit_jump_transfer(context, loop_ctx.handler_depth, loop_ctx.scope_depth);
353
+ context
354
+ .loop_stack
355
+ .last_mut()
356
+ .expect("loop context should still exist")
357
+ .break_jumps
358
+ .push(patch);
359
+ }
360
+ Stmt::Continue { span } => {
361
+ let Some(loop_ctx) = context.loop_stack.last() else {
362
+ return Err(MustardError::runtime_at(
363
+ "`continue` used outside of a loop",
364
+ *span,
365
+ ));
366
+ };
367
+ let patch =
368
+ self.emit_jump_transfer(context, loop_ctx.handler_depth, loop_ctx.scope_depth);
369
+ context
370
+ .loop_stack
371
+ .last_mut()
372
+ .expect("loop context should still exist")
373
+ .continue_jumps
374
+ .push(patch);
375
+ }
376
+ Stmt::Return { value, .. } => {
377
+ if let Some(value) = value {
378
+ self.compile_expr(context, value)?;
379
+ } else {
380
+ context.code.push(Instruction::PushUndefined);
381
+ }
382
+ self.emit_return(context);
383
+ }
384
+ Stmt::Throw { span, value } => {
385
+ self.compile_expr(context, value)?;
386
+ if let Some(active_finally) = context.active_finally.last() {
387
+ self.emit_scope_cleanup(context, active_finally.scope_depth);
388
+ context.code.push(Instruction::PushPendingThrow);
389
+ self.emit_jump_to_active_finally_exit(context);
390
+ } else {
391
+ context.code.push(Instruction::Throw { span: *span });
392
+ }
393
+ }
394
+ Stmt::Try {
395
+ body,
396
+ catch,
397
+ finally,
398
+ ..
399
+ } => {
400
+ self.compile_try(context, body, catch.as_ref(), finally.as_deref())?;
401
+ }
402
+ Stmt::Switch {
403
+ discriminant,
404
+ cases,
405
+ ..
406
+ } => {
407
+ self.compile_expr(context, discriminant)?;
408
+ let mut case_jumps = Vec::new();
409
+ let mut default_case_index = None;
410
+ context.loop_stack.push(LoopContext {
411
+ handler_depth: context.active_handlers.len(),
412
+ scope_depth: context.scope_depth,
413
+ ..LoopContext::default()
414
+ });
415
+ for (case_index, case) in cases.iter().enumerate() {
416
+ if let Some(test) = &case.test {
417
+ context.code.push(Instruction::Dup);
418
+ self.compile_expr(context, test)?;
419
+ context.code.push(Instruction::Binary(BinaryOp::StrictEq));
420
+ let miss_jump =
421
+ self.emit_jump(context, Instruction::JumpIfFalse(usize::MAX));
422
+ context.code.push(Instruction::Pop);
423
+ context.code.push(Instruction::Pop);
424
+ case_jumps.push(self.emit_jump(context, Instruction::Jump(usize::MAX)));
425
+ let miss_ip = context.code.len();
426
+ self.patch_jump(context, miss_jump, miss_ip);
427
+ context.code.push(Instruction::Pop);
428
+ } else {
429
+ default_case_index = Some(case_index);
430
+ }
431
+ }
432
+ context.code.push(Instruction::Pop);
433
+ let jump_past_cases = self.emit_jump(context, Instruction::Jump(usize::MAX));
434
+ let mut case_offsets = Vec::new();
435
+ for case in cases {
436
+ let case_start = context.code.len();
437
+ case_offsets.push(case_start);
438
+ for statement in &case.consequent {
439
+ self.compile_stmt(context, statement)?;
440
+ }
441
+ }
442
+ let end_ip = context.code.len();
443
+ let default_target = default_case_index
444
+ .and_then(|index| case_offsets.get(index).copied())
445
+ .unwrap_or(end_ip);
446
+ self.patch_jump(context, jump_past_cases, default_target);
447
+ for (jump, target) in case_jumps.into_iter().zip(case_offsets.iter().copied()) {
448
+ self.patch_jump(context, jump, target);
449
+ }
450
+ let loop_ctx = context.loop_stack.pop().unwrap_or_default();
451
+ for jump in loop_ctx.break_jumps {
452
+ self.patch_control_transfer(context, jump, end_ip);
453
+ }
454
+ }
455
+ Stmt::Empty { .. } => {}
456
+ }
457
+ Ok(())
458
+ }
459
+ }