@@ -40,9 +40,6 @@ struct ControlFrame
40
40
// / The target instruction code offset.
41
41
const size_t code_offset{0 };
42
42
43
- // / The immediates offset for block instructions.
44
- const size_t immediates_offset{0 };
45
-
46
43
// / The frame stack height of the parent frame.
47
44
const int parent_stack_height{0 };
48
45
@@ -54,11 +51,10 @@ struct ControlFrame
54
51
std::vector<size_t > br_immediate_offsets{};
55
52
56
53
ControlFrame (Instr _instruction, std::optional<ValType> _type, int _parent_stack_height,
57
- size_t _code_offset = 0 , size_t _immediates_offset = 0 ) noexcept
54
+ size_t _code_offset = 0 ) noexcept
58
55
: instruction{_instruction},
59
56
type{_type},
60
57
code_offset{_code_offset},
61
- immediates_offset{_immediates_offset},
62
58
parent_stack_height{_parent_stack_height}
63
59
{}
64
60
};
@@ -210,7 +206,6 @@ void push_branch_immediates(const ControlFrame& branch_frame, int stack_height,
210
206
// Push frame start location as br immediates - these are final if frame is loop,
211
207
// but for block/if/else these are just placeholders, to be filled at end instruction.
212
208
push (immediates, static_cast <uint32_t >(branch_frame.code_offset ));
213
- push (immediates, static_cast <uint32_t >(branch_frame.immediates_offset ));
214
209
push (immediates, static_cast <uint32_t >(stack_drop));
215
210
}
216
211
@@ -465,7 +460,7 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
465
460
466
461
// Push label with immediates offset after arity.
467
462
control_stack.emplace (Instr::block, block_type, static_cast <int >(operand_stack.size ()),
468
- code.instructions .size (), code. immediates . size () );
463
+ code.instructions .size ());
469
464
break ;
470
465
}
471
466
@@ -475,7 +470,7 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
475
470
std::tie (loop_type, pos) = parse_blocktype (pos, end);
476
471
477
472
control_stack.emplace (Instr::loop, loop_type, static_cast <int >(operand_stack.size ()),
478
- code.instructions .size (), code. immediates . size () );
473
+ code.instructions .size ());
479
474
break ;
480
475
}
481
476
@@ -485,12 +480,12 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
485
480
std::tie (if_type, pos) = parse_blocktype (pos, end);
486
481
487
482
control_stack.emplace (Instr::if_, if_type, static_cast <int >(operand_stack.size ()),
488
- code.instructions .size (), code. immediates . size () );
483
+ code.instructions .size ());
489
484
490
485
// Placeholders for immediate values, filled at the matching end or else instructions.
491
- push ( code.immediates , uint32_t { 0 }); // Diff to the else instruction
492
- push (code.immediates , uint32_t {0 }); // Diff for the immediates.
493
- break ;
486
+ code.instructions . push_back (opcode);
487
+ push (code.instructions , uint32_t {0 }); // Diff to the else instruction
488
+ continue ;
494
489
}
495
490
496
491
case Instr::else_:
@@ -500,30 +495,27 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
500
495
501
496
update_result_stack (frame, operand_stack); // else is the end of if.
502
497
503
- const auto if_imm_offset = frame.immediates_offset ;
498
+ const auto if_imm_offset = frame.code_offset + 1 ;
504
499
const auto frame_type = frame.type ;
505
500
auto frame_br_immediate_offsets = std::move (frame.br_immediate_offsets );
506
501
507
502
control_stack.pop ();
508
503
control_stack.emplace (Instr::else_, frame_type, static_cast <int >(operand_stack.size ()),
509
- code.instructions .size (), code. immediates . size () );
504
+ code.instructions .size ());
510
505
// br immediates from `then` branch will need to be filled at the end of `else`
511
506
control_stack.top ().br_immediate_offsets = std::move (frame_br_immediate_offsets);
512
507
513
508
// Placeholders for immediate values, filled at the matching end instructions.
514
- push ( code.immediates , uint32_t { 0 }); // Diff to the end instruction.
515
- push (code.immediates , uint32_t {0 }); // Diff for the immediates
509
+ code.instructions . push_back (opcode);
510
+ push (code.instructions , uint32_t {0 }); // Diff to the end instruction.
516
511
517
512
// Fill in if's immediates with offsets of first instruction in else block.
518
- const auto target_pc = static_cast <uint32_t >(code.instructions .size () + 1 );
519
- const auto target_imm = static_cast <uint32_t >(code.immediates .size ());
513
+ const auto target_pc = static_cast <uint32_t >(code.instructions .size ());
520
514
521
- // Set the imm values for else instruction.
522
- auto * if_imm = code.immediates .data () + if_imm_offset;
515
+ // Set the imm values for if instruction.
516
+ auto * if_imm = code.instructions .data () + if_imm_offset;
523
517
store (if_imm, target_pc);
524
- if_imm += sizeof (target_pc);
525
- store (if_imm, target_imm);
526
- break ;
518
+ continue ;
527
519
}
528
520
529
521
case Instr::end:
@@ -541,26 +533,21 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
541
533
const auto target_pc = control_stack.size () == 1 ?
542
534
static_cast <uint32_t >(code.instructions .size ()) :
543
535
static_cast <uint32_t >(code.instructions .size () + 1 );
544
- const auto target_imm = static_cast <uint32_t >(code.immediates .size ());
545
536
546
537
if (frame.instruction == Instr::if_ || frame.instruction == Instr::else_)
547
538
{
548
539
// We're at the end instruction of the if block without else or at the end of
549
540
// else block. Fill in if/else's immediates with offsets of first instruction
550
541
// after if/else block.
551
- auto * if_imm = code.immediates .data () + frame.immediates_offset ;
542
+ auto * if_imm = code.instructions .data () + frame.code_offset + 1 ;
552
543
store (if_imm, target_pc);
553
- if_imm += sizeof (target_pc);
554
- store (if_imm, target_imm);
555
544
}
556
545
557
546
// Fill in immediates all br/br_table instructions jumping out of this block.
558
547
for (const auto br_imm_offset : frame.br_immediate_offsets )
559
548
{
560
- auto * br_imm = code.immediates .data () + br_imm_offset;
549
+ auto * br_imm = code.instructions .data () + br_imm_offset;
561
550
store (br_imm, static_cast <uint32_t >(target_pc));
562
- br_imm += sizeof (uint32_t );
563
- store (br_imm, static_cast <uint32_t >(target_imm));
564
551
// stack drop and arity were already stored in br handler
565
552
}
566
553
}
@@ -588,13 +575,14 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
588
575
589
576
update_branch_stack (frame, branch_frame, operand_stack);
590
577
591
- push (code.immediates , get_branch_arity (branch_frame));
578
+ code.instructions .push_back (opcode);
579
+ push (code.instructions , get_branch_arity (branch_frame));
592
580
593
581
// Remember this br immediates offset to fill it at end instruction.
594
- branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
582
+ branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
595
583
596
584
push_branch_immediates (
597
- branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
585
+ branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
598
586
599
587
if (instr == Instr::br)
600
588
mark_frame_unreachable (frame, operand_stack);
@@ -607,7 +595,7 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
607
595
push_operand (operand_stack, *branch_frame.type );
608
596
}
609
597
610
- break ;
598
+ continue ;
611
599
}
612
600
613
601
case Instr::br_table:
@@ -626,15 +614,16 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
626
614
if (default_label_idx >= control_stack.size ())
627
615
throw validation_error{" invalid label index" };
628
616
629
- push (code.immediates , static_cast <uint32_t >(label_indices.size ()));
617
+ code.instructions .push_back (opcode);
618
+ push (code.instructions , static_cast <uint32_t >(label_indices.size ()));
630
619
631
620
auto & default_branch_frame = control_stack[default_label_idx];
632
621
const auto default_branch_type = get_branch_frame_type (default_branch_frame);
633
622
634
623
update_branch_stack (frame, default_branch_frame, operand_stack);
635
624
636
625
// arity is the same for all indices, so we push it once
637
- push (code.immediates , get_branch_arity (default_branch_frame));
626
+ push (code.instructions , get_branch_arity (default_branch_frame));
638
627
639
628
// Remember immediates offset for all br items to fill them at end instruction.
640
629
for (const auto idx : label_indices)
@@ -644,17 +633,17 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
644
633
if (get_branch_frame_type (branch_frame) != default_branch_type)
645
634
throw validation_error{" br_table labels have inconsistent types" };
646
635
647
- branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
636
+ branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
648
637
push_branch_immediates (
649
- branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
638
+ branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
650
639
}
651
- default_branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
640
+ default_branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
652
641
push_branch_immediates (
653
- default_branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
642
+ default_branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
654
643
655
644
mark_frame_unreachable (frame, operand_stack);
656
645
657
- break ;
646
+ continue ;
658
647
}
659
648
660
649
case Instr::return_:
@@ -667,15 +656,16 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
667
656
668
657
update_branch_stack (frame, branch_frame, operand_stack);
669
658
670
- push (code.immediates , get_branch_arity (branch_frame));
659
+ code.instructions .push_back (opcode);
660
+ push (code.instructions , get_branch_arity (branch_frame));
671
661
672
- branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
662
+ branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
673
663
674
664
push_branch_immediates (
675
- branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
665
+ branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
676
666
677
667
mark_frame_unreachable (frame, operand_stack);
678
- break ;
668
+ continue ;
679
669
}
680
670
681
671
case Instr::call:
0 commit comments