@@ -19,14 +19,6 @@ inline void store(uint8_t* dst, T value) noexcept
19
19
__builtin_memcpy (dst, &value, sizeof (value));
20
20
}
21
21
22
- template <typename T>
23
- inline void push (bytes& b, T value)
24
- {
25
- uint8_t storage[sizeof (T)];
26
- store (storage, value);
27
- b.append (storage, sizeof (storage));
28
- }
29
-
30
22
template <typename T>
31
23
inline void push (std::vector<uint8_t >& b, T value)
32
24
{
@@ -48,9 +40,6 @@ struct ControlFrame
48
40
// / The target instruction code offset.
49
41
const size_t code_offset{0 };
50
42
51
- // / The immediates offset for block instructions.
52
- const size_t immediates_offset{0 };
53
-
54
43
// / The frame stack height of the parent frame.
55
44
const int parent_stack_height{0 };
56
45
@@ -62,11 +51,10 @@ struct ControlFrame
62
51
std::vector<size_t > br_immediate_offsets{};
63
52
64
53
ControlFrame (Instr _instruction, std::optional<ValType> _type, int _parent_stack_height,
65
- size_t _code_offset = 0 , size_t _immediates_offset = 0 ) noexcept
54
+ size_t _code_offset = 0 ) noexcept
66
55
: instruction{_instruction},
67
56
type{_type},
68
57
code_offset{_code_offset},
69
- immediates_offset{_immediates_offset},
70
58
parent_stack_height{_parent_stack_height}
71
59
{}
72
60
};
@@ -210,16 +198,16 @@ inline void update_branch_stack(const ControlFrame& current_frame, const Control
210
198
drop_operand (current_frame, operand_stack, from_valtype (*branch_frame_type));
211
199
}
212
200
213
- void push_branch_immediates (const ControlFrame& branch_frame, int stack_height, bytes& immediates)
201
+ void push_branch_immediates (
202
+ const ControlFrame& branch_frame, int stack_height, std::vector<uint8_t >& instructions)
214
203
{
215
204
// How many stack items to drop when taking the branch.
216
205
const auto stack_drop = stack_height - branch_frame.parent_stack_height ;
217
206
218
207
// Push frame start location as br immediates - these are final if frame is loop,
219
208
// but for block/if/else these are just placeholders, to be filled at end instruction.
220
- push (immediates, static_cast <uint32_t >(branch_frame.code_offset ));
221
- push (immediates, static_cast <uint32_t >(branch_frame.immediates_offset ));
222
- push (immediates, static_cast <uint32_t >(stack_drop));
209
+ push (instructions, static_cast <uint32_t >(branch_frame.code_offset ));
210
+ push (instructions, static_cast <uint32_t >(stack_drop));
223
211
}
224
212
225
213
inline void mark_frame_unreachable (
@@ -473,7 +461,7 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
473
461
474
462
// Push label with immediates offset after arity.
475
463
control_stack.emplace (Instr::block, block_type, static_cast <int >(operand_stack.size ()),
476
- code.instructions .size (), code. immediates . size () );
464
+ code.instructions .size ());
477
465
break ;
478
466
}
479
467
@@ -483,7 +471,7 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
483
471
std::tie (loop_type, pos) = parse_blocktype (pos, end);
484
472
485
473
control_stack.emplace (Instr::loop, loop_type, static_cast <int >(operand_stack.size ()),
486
- code.instructions .size (), code. immediates . size () );
474
+ code.instructions .size ());
487
475
break ;
488
476
}
489
477
@@ -493,12 +481,12 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
493
481
std::tie (if_type, pos) = parse_blocktype (pos, end);
494
482
495
483
control_stack.emplace (Instr::if_, if_type, static_cast <int >(operand_stack.size ()),
496
- code.instructions .size (), code. immediates . size () );
484
+ code.instructions .size ());
497
485
498
486
// Placeholders for immediate values, filled at the matching end or else instructions.
499
- push ( code.immediates , uint32_t { 0 }); // Diff to the else instruction
500
- push (code.immediates , uint32_t {0 }); // Diff for the immediates.
501
- break ;
487
+ code.instructions . push_back (opcode);
488
+ push (code.instructions , uint32_t {0 }); // Diff to the else instruction
489
+ continue ;
502
490
}
503
491
504
492
case Instr::else_:
@@ -508,30 +496,27 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
508
496
509
497
update_result_stack (frame, operand_stack); // else is the end of if.
510
498
511
- const auto if_imm_offset = frame.immediates_offset ;
499
+ const auto if_imm_offset = frame.code_offset + 1 ;
512
500
const auto frame_type = frame.type ;
513
501
auto frame_br_immediate_offsets = std::move (frame.br_immediate_offsets );
514
502
515
503
control_stack.pop ();
516
504
control_stack.emplace (Instr::else_, frame_type, static_cast <int >(operand_stack.size ()),
517
- code.instructions .size (), code. immediates . size () );
505
+ code.instructions .size ());
518
506
// br immediates from `then` branch will need to be filled at the end of `else`
519
507
control_stack.top ().br_immediate_offsets = std::move (frame_br_immediate_offsets);
520
508
521
509
// Placeholders for immediate values, filled at the matching end instructions.
522
- push ( code.immediates , uint32_t { 0 }); // Diff to the end instruction.
523
- push (code.immediates , uint32_t {0 }); // Diff for the immediates
510
+ code.instructions . push_back (opcode);
511
+ push (code.instructions , uint32_t {0 }); // Diff to the end instruction.
524
512
525
513
// Fill in if's immediates with offsets of first instruction in else block.
526
- const auto target_pc = static_cast <uint32_t >(code.instructions .size () + 1 );
527
- const auto target_imm = static_cast <uint32_t >(code.immediates .size ());
514
+ const auto target_pc = static_cast <uint32_t >(code.instructions .size ());
528
515
529
- // Set the imm values for else instruction.
530
- auto * if_imm = code.immediates .data () + if_imm_offset;
516
+ // Set the imm values for if instruction.
517
+ auto * if_imm = code.instructions .data () + if_imm_offset;
531
518
store (if_imm, target_pc);
532
- if_imm += sizeof (target_pc);
533
- store (if_imm, target_imm);
534
- break ;
519
+ continue ;
535
520
}
536
521
537
522
case Instr::end:
@@ -549,26 +534,21 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
549
534
const auto target_pc = control_stack.size () == 1 ?
550
535
static_cast <uint32_t >(code.instructions .size ()) :
551
536
static_cast <uint32_t >(code.instructions .size () + 1 );
552
- const auto target_imm = static_cast <uint32_t >(code.immediates .size ());
553
537
554
538
if (frame.instruction == Instr::if_ || frame.instruction == Instr::else_)
555
539
{
556
540
// We're at the end instruction of the if block without else or at the end of
557
541
// else block. Fill in if/else's immediates with offsets of first instruction
558
542
// after if/else block.
559
- auto * if_imm = code.immediates .data () + frame.immediates_offset ;
543
+ auto * if_imm = code.instructions .data () + frame.code_offset + 1 ;
560
544
store (if_imm, target_pc);
561
- if_imm += sizeof (target_pc);
562
- store (if_imm, target_imm);
563
545
}
564
546
565
547
// Fill in immediates all br/br_table instructions jumping out of this block.
566
548
for (const auto br_imm_offset : frame.br_immediate_offsets )
567
549
{
568
- auto * br_imm = code.immediates .data () + br_imm_offset;
550
+ auto * br_imm = code.instructions .data () + br_imm_offset;
569
551
store (br_imm, static_cast <uint32_t >(target_pc));
570
- br_imm += sizeof (uint32_t );
571
- store (br_imm, static_cast <uint32_t >(target_imm));
572
552
// stack drop and arity were already stored in br handler
573
553
}
574
554
}
@@ -596,13 +576,14 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
596
576
597
577
update_branch_stack (frame, branch_frame, operand_stack);
598
578
599
- push (code.immediates , get_branch_arity (branch_frame));
579
+ code.instructions .push_back (opcode);
580
+ push (code.instructions , get_branch_arity (branch_frame));
600
581
601
582
// Remember this br immediates offset to fill it at end instruction.
602
- branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
583
+ branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
603
584
604
585
push_branch_immediates (
605
- branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
586
+ branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
606
587
607
588
if (instr == Instr::br)
608
589
mark_frame_unreachable (frame, operand_stack);
@@ -615,7 +596,7 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
615
596
push_operand (operand_stack, *branch_frame.type );
616
597
}
617
598
618
- break ;
599
+ continue ;
619
600
}
620
601
621
602
case Instr::br_table:
@@ -653,13 +634,13 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
653
634
if (get_branch_frame_type (branch_frame) != default_branch_type)
654
635
throw validation_error{" br_table labels have inconsistent types" };
655
636
656
- branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
637
+ branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
657
638
push_branch_immediates (
658
- branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
639
+ branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
659
640
}
660
- default_branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
641
+ default_branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
661
642
push_branch_immediates (
662
- default_branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
643
+ default_branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
663
644
664
645
mark_frame_unreachable (frame, operand_stack);
665
646
@@ -676,15 +657,16 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
676
657
677
658
update_branch_stack (frame, branch_frame, operand_stack);
678
659
679
- push (code.immediates , get_branch_arity (branch_frame));
660
+ code.instructions .push_back (opcode);
661
+ push (code.instructions , get_branch_arity (branch_frame));
680
662
681
- branch_frame.br_immediate_offsets .push_back (code.immediates .size ());
663
+ branch_frame.br_immediate_offsets .push_back (code.instructions .size ());
682
664
683
665
push_branch_immediates (
684
- branch_frame, static_cast <int >(operand_stack.size ()), code.immediates );
666
+ branch_frame, static_cast <int >(operand_stack.size ()), code.instructions );
685
667
686
668
mark_frame_unreachable (frame, operand_stack);
687
- break ;
669
+ continue ;
688
670
}
689
671
690
672
case Instr::call:
0 commit comments