2026-07-25 23:01:18 +02:00
|
|
|
#include "bscript/compiler/codegen/DataEmitter.h"
|
2020-08-11 11:50:16 -07:00
|
|
|
|
|
|
|
|
#include <algorithm>
|
2021-05-19 20:45:38 +02:00
|
|
|
#include <limits>
|
2026-01-18 09:35:52 +01:00
|
|
|
#include <stdexcept>
|
2020-08-11 11:50:16 -07:00
|
|
|
|
|
|
|
|
namespace Pol::Bscript::Compiler
|
|
|
|
|
{
|
|
|
|
|
DataEmitter::DataEmitter( DataSection& data_section ) : data_section( data_section ) {}
|
|
|
|
|
|
|
|
|
|
unsigned DataEmitter::append( double value )
|
|
|
|
|
{
|
|
|
|
|
// The old compiler always appends doubles. For parity,
|
|
|
|
|
// we'll do the same here.
|
|
|
|
|
return append( reinterpret_cast<const std::byte*>( &value ), sizeof value );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned DataEmitter::append( int value )
|
|
|
|
|
{
|
|
|
|
|
// The old compiler always appends integers. For parity,
|
|
|
|
|
// we'll do the same here.
|
|
|
|
|
return append( reinterpret_cast<const std::byte*>( &value ), sizeof value );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned DataEmitter::store( const std::string& s )
|
|
|
|
|
{
|
2020-12-01 02:23:03 -08:00
|
|
|
return store( reinterpret_cast<const std::byte*>( s.c_str() ),
|
|
|
|
|
static_cast<unsigned>( s.length() + 1 ) );
|
2020-08-11 11:50:16 -07:00
|
|
|
}
|
|
|
|
|
|
2020-12-01 02:23:03 -08:00
|
|
|
unsigned DataEmitter::store( const std::byte* data, size_t len )
|
2020-08-11 11:50:16 -07:00
|
|
|
{
|
|
|
|
|
if ( auto existing = find( data, len ) )
|
|
|
|
|
return existing;
|
2026-01-18 09:35:52 +01:00
|
|
|
return append( data, len );
|
2020-08-11 11:50:16 -07:00
|
|
|
}
|
|
|
|
|
|
2020-12-01 02:23:03 -08:00
|
|
|
unsigned DataEmitter::append( const std::byte* data, size_t len )
|
2020-08-11 11:50:16 -07:00
|
|
|
{
|
2020-12-01 02:23:03 -08:00
|
|
|
size_t position = data_section.size();
|
2026-01-18 09:35:52 +01:00
|
|
|
if ( position + len > std::numeric_limits<unsigned>::max() )
|
|
|
|
|
{
|
2020-12-01 02:23:03 -08:00
|
|
|
throw std::runtime_error( "Data offset overflow" );
|
|
|
|
|
}
|
2020-08-11 11:50:16 -07:00
|
|
|
data_section.insert( data_section.end(), data, data + len );
|
|
|
|
|
|
2020-12-01 02:23:03 -08:00
|
|
|
return static_cast<unsigned>( position );
|
2020-08-11 11:50:16 -07:00
|
|
|
}
|
|
|
|
|
|
2020-12-01 02:23:03 -08:00
|
|
|
unsigned DataEmitter::find( const std::byte* data, size_t len )
|
2020-08-11 11:50:16 -07:00
|
|
|
{
|
|
|
|
|
if ( data_section.empty() )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
auto start = data_section.begin();
|
|
|
|
|
++start; // offset=0 means no data, not data at offset 0
|
|
|
|
|
auto itr = std::search( start, data_section.end(), data, data + len );
|
|
|
|
|
if ( itr != data_section.end() )
|
2021-08-28 22:26:15 +02:00
|
|
|
return static_cast<unsigned>( itr - data_section.begin() );
|
2020-08-11 11:50:16 -07:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Pol::Bscript::Compiler
|