@@ -141,7 +141,10 @@ namespace MIR { namespace eval {
141
141
virtual void read_mask (uint8_t * dst, size_t dst_ofs, size_t ofs, size_t len) const = 0;
142
142
143
143
virtual bool is_writable () const = 0;
144
- virtual void write_bytes (size_t ofs, const void * data, size_t len) = 0;
144
+ virtual uint8_t * ext_write_bytes (size_t ofs, size_t len) = 0;
145
+ void write_bytes (size_t ofs, const void * data, size_t len) {
146
+ memcpy (ext_write_bytes (ofs, len), data, len);
147
+ }
145
148
virtual void write_mask_from (size_t ofs, const IValue& src, size_t src_ofs, size_t len) = 0;
146
149
147
150
virtual RelocPtr get_reloc (size_t ofs) const = 0;
@@ -257,7 +260,7 @@ namespace MIR { namespace eval {
257
260
}
258
261
259
262
bool is_writable () const override { return false ; }
260
- void write_bytes (size_t ofs, const void * data , size_t len) override { abort (); }
263
+ uint8_t * ext_write_bytes (size_t ofs, size_t len) override { abort (); }
261
264
void write_mask_from (size_t ofs, const IValue& src, size_t src_ofs, size_t len) override { abort (); }
262
265
263
266
RelocPtr get_reloc (size_t ofs) const override { return RelocPtr (); }
@@ -374,7 +377,7 @@ namespace MIR { namespace eval {
374
377
bool is_writable () const override {
375
378
return !is_readonly;
376
379
}
377
- void write_bytes (size_t ofs, const void * data , size_t len) override
380
+ uint8_t * ext_write_bytes (size_t ofs, size_t len) override
378
381
{
379
382
assert (ofs <= length);
380
383
assert (len <= length);
@@ -390,11 +393,10 @@ namespace MIR { namespace eval {
390
393
for ( ; ml % 8 != 0 && ml > 0 ; mo ++, ml --)
391
394
m[mo/8 ] |= (1 << (mo % 8 ));
392
395
}
393
- // Write data
394
- memcpy (this ->data + ofs, data, len);
395
396
// Clear impacted relocations
396
397
auto it = std::remove_if (this ->relocations .begin (), this ->relocations .end (), [&](const Reloc& r){ return (ofs <= r.offset && r.offset < ofs+len); });
397
398
this ->relocations .resize ( it - this ->relocations .begin () );
399
+ return this ->data + ofs;
398
400
}
399
401
void write_mask_from (size_t ofs, const IValue& src, size_t src_ofs, size_t len) override {
400
402
assert (ofs <= length);
@@ -499,7 +501,7 @@ namespace MIR { namespace eval {
499
501
bool is_writable () const override {
500
502
return false ;
501
503
}
502
- void write_bytes (size_t ofs, const void * data , size_t len) override {
504
+ uint8_t * ext_write_bytes (size_t ofs, size_t len) override {
503
505
abort ();
504
506
}
505
507
void write_mask_from (size_t ofs, const IValue& src, size_t src_ofs, size_t len) override {
@@ -611,6 +613,17 @@ namespace MIR { namespace eval {
611
613
storage.as_value ().write_bytes (ofs, data, len);
612
614
}
613
615
}
616
+ uint8_t * ext_write_bytes (const MIR::TypeResolve& state, size_t len) {
617
+ MIR_ASSERT (state, storage, " Writing to invalid slot" );
618
+ MIR_ASSERT (state, storage.as_value ().is_writable (), " Writing to read-only slot" );
619
+ if (len > 0 ) {
620
+ return storage.as_value ().ext_write_bytes (ofs, len);
621
+ }
622
+ else {
623
+ static uint8_t empty_buf;
624
+ return &empty_buf;
625
+ }
626
+ }
614
627
615
628
void write_byte (const MIR::TypeResolve& state, uint8_t v) {
616
629
write_bytes (state, &v, 1 );
@@ -629,12 +642,22 @@ namespace MIR { namespace eval {
629
642
write_uint (state, bits, U128 (v));
630
643
}
631
644
void write_uint (const MIR::TypeResolve& state, unsigned bits, U128 v) {
632
- if (Target_GetCurSpec ().m_arch .m_big_endian ) MIR_TODO (state, " Handle big endian in constant evaluate" );
633
- write_bytes (state, &v, (bits+7 )/8 );
645
+ auto n_bytes = (bits+7 )/8 ;
646
+ if (Target_GetCurSpec ().m_arch .m_big_endian ) {
647
+ v.to_be_bytes (ext_write_bytes (state, n_bytes), n_bytes);
648
+ }
649
+ else {
650
+ v.to_le_bytes (ext_write_bytes (state, n_bytes), n_bytes);
651
+ }
634
652
}
635
653
void write_sint (const MIR::TypeResolve& state, unsigned bits, S128 v) {
636
- if (Target_GetCurSpec ().m_arch .m_big_endian ) MIR_TODO (state, " Handle big endian in constant evaluate" );
637
- write_bytes (state, &v, (bits+7 )/8 );
654
+ auto n_bytes = (bits+7 )/8 ;
655
+ if (Target_GetCurSpec ().m_arch .m_big_endian ) {
656
+ v.get_inner ().to_be_bytes (ext_write_bytes (state, n_bytes), n_bytes);
657
+ }
658
+ else {
659
+ v.get_inner ().to_le_bytes (ext_write_bytes (state, n_bytes), n_bytes);
660
+ }
638
661
}
639
662
void write_ptr (const MIR::TypeResolve& state, uint64_t val, RelocPtr reloc) {
640
663
write_uint (state, Target_GetPointerBits (), U128 (val));
@@ -644,11 +667,16 @@ namespace MIR { namespace eval {
644
667
storage.as_value ().set_reloc (ofs, std::move (reloc));
645
668
}
646
669
647
- void read_bytes (const MIR::TypeResolve& state, void * data , size_t len) const {
670
+ const uint8_t * ext_read_bytes (const MIR::TypeResolve& state, size_t len) const {
648
671
MIR_ASSERT (state, storage, " " );
649
672
MIR_ASSERT (state, len >= 1 , " " );
650
673
const auto * src = storage.as_value ().get_bytes (ofs, len, /* check_mask*/ true );
651
674
MIR_ASSERT (state, src, " Invalid read: " << ofs << " +" << len << " (in " << *this << " )" );
675
+ return src;
676
+ }
677
+ void read_bytes (const MIR::TypeResolve& state, void * data, size_t len) const {
678
+ const auto * src = ext_read_bytes (state, len);
679
+ assert (src);
652
680
memcpy (data, src, len);
653
681
}
654
682
double read_float (const ::MIR::TypeResolve& state, unsigned bits) const {
@@ -661,33 +689,27 @@ namespace MIR { namespace eval {
661
689
}
662
690
}
663
691
U128 read_uint (const ::MIR::TypeResolve& state, unsigned bits) const {
664
- if (Target_GetCurSpec ().m_arch .m_big_endian ) MIR_TODO (state, " Handle big endian in constant evaluate" );
665
692
assert (bits <= 128 );
666
- if (bits > 64 ) {
667
- uint64_t v[ 2 ] = { 0 , 0 } ;
668
- read_bytes (state, v, (bits+ 7 )/ 8 );
669
- return U128 (v[ 0 ], v[ 1 ] );
693
+ auto n_bytes = (bits+ 7 )/ 8 ;
694
+ U128 rv ;
695
+ if ( Target_GetCurSpec (). m_arch . m_big_endian ) {
696
+ rv. from_be_bytes ( ext_read_bytes (state, n_bytes), n_bytes );
670
697
}
671
698
else {
672
- uint64_t rv = 0 ;
673
- read_bytes (state, &rv, (bits+7 )/8 );
674
- return U128 (rv);
699
+ rv.from_le_bytes (ext_read_bytes (state, n_bytes), n_bytes);
675
700
}
701
+ return rv;
676
702
}
677
703
S128 read_sint (const ::MIR::TypeResolve& state, unsigned bits) const {
678
- auto v = read_uint (state, bits);
679
- if ( v.bit (bits-1 ) ) {
680
- // Apply sign extension
681
- if ( bits <= 64 ) {
682
- auto v64 = v.truncate_u64 ();
683
- v64 |= UINT64_MAX << bits;
684
- v = U128 (v64, UINT64_MAX);
685
- }
686
- else {
687
- assert (bits == 128 );
688
- }
704
+ auto n_bytes = (bits+7 )/8 ;
705
+ S128 rv;
706
+ if (Target_GetCurSpec ().m_arch .m_big_endian ) {
707
+ rv.from_be_bytes (ext_read_bytes (state, n_bytes), n_bytes);
689
708
}
690
- return S128 (v);
709
+ else {
710
+ rv.from_le_bytes (ext_read_bytes (state, n_bytes), n_bytes);
711
+ }
712
+ return rv;
691
713
}
692
714
uint64_t read_usize (const ::MIR::TypeResolve& state) const {
693
715
return read_uint (state, Target_GetPointerBits ()).truncate_u64 ();
0 commit comments