2016-01-28 14:52:40 +01:00
|
|
|
/** @file
|
|
|
|
|
*
|
|
|
|
|
* @par History
|
|
|
|
|
*/
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2026-07-25 23:01:18 +02:00
|
|
|
#include "bscript/eprog.h"
|
2016-02-11 22:54:43 +01:00
|
|
|
|
|
|
|
|
#include <cstdio>
|
2026-07-21 08:50:32 +02:00
|
|
|
#include <fmt/format.h>
|
|
|
|
|
#include <fmt/ostream.h>
|
|
|
|
|
#include <iomanip>
|
2018-01-29 21:55:48 +01:00
|
|
|
|
2026-07-25 23:01:18 +02:00
|
|
|
#include "clib/refptr.h"
|
|
|
|
|
#include "clib/stlutil.h"
|
|
|
|
|
#include "bscript/escriptv.h"
|
|
|
|
|
#include "bscript/fmodule.h"
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2026-01-17 10:30:21 +01:00
|
|
|
|
|
|
|
|
namespace Pol::Bscript
|
2016-02-19 19:26:35 +01:00
|
|
|
{
|
|
|
|
|
EScriptProgram::EScriptProgram()
|
|
|
|
|
: ref_counted(),
|
2016-02-11 22:54:43 +01:00
|
|
|
nglobals( 0 ),
|
|
|
|
|
expectedArgs( 0 ),
|
|
|
|
|
haveProgram( false ),
|
2016-02-19 19:26:35 +01:00
|
|
|
name( "" ),
|
|
|
|
|
modules(),
|
|
|
|
|
tokens(),
|
|
|
|
|
symbols(),
|
2016-02-11 22:54:43 +01:00
|
|
|
exported_functions(),
|
2016-02-19 19:26:35 +01:00
|
|
|
version( 0 ),
|
2016-02-11 22:54:43 +01:00
|
|
|
invocations( 0 ),
|
|
|
|
|
instr_cycles( 0 ),
|
2018-10-09 16:36:35 +02:00
|
|
|
pkg( nullptr ),
|
2016-02-19 19:26:35 +01:00
|
|
|
instr(),
|
|
|
|
|
debug_loaded( false ),
|
|
|
|
|
globalvarnames(),
|
|
|
|
|
blocks(),
|
|
|
|
|
dbg_functions(),
|
|
|
|
|
dbg_filenames(),
|
|
|
|
|
dbg_filenum(),
|
|
|
|
|
dbg_linenum(),
|
|
|
|
|
dbg_ins_blocks(),
|
|
|
|
|
dbg_ins_statementbegin()
|
|
|
|
|
{
|
|
|
|
|
++escript_program_count;
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
// compiler only:
|
|
|
|
|
EPDbgBlock block;
|
|
|
|
|
block.parentblockidx = 0;
|
|
|
|
|
block.parentvariables = 0;
|
|
|
|
|
blocks.push_back( block );
|
|
|
|
|
}
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
EScriptProgram::~EScriptProgram()
|
|
|
|
|
{
|
|
|
|
|
Clib::delete_all( modules );
|
|
|
|
|
--escript_program_count;
|
|
|
|
|
}
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2025-01-24 20:20:21 +01:00
|
|
|
std::string EScriptProgram::dbg_get_instruction( size_t atPC ) const
|
|
|
|
|
{
|
2026-07-21 08:50:32 +02:00
|
|
|
return fmt::to_string( instr[atPC].token );
|
2025-01-24 20:20:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t EScriptProgram::sizeEstimate() const
|
|
|
|
|
{
|
|
|
|
|
using namespace Clib;
|
|
|
|
|
size_t size = sizeof( EScriptProgram );
|
|
|
|
|
size += memsize( globalvarnames );
|
|
|
|
|
for ( const auto& l : globalvarnames )
|
|
|
|
|
size += l.capacity();
|
|
|
|
|
size += memsize( dbg_filenames );
|
|
|
|
|
for ( const auto& l : dbg_filenames )
|
|
|
|
|
size += l.capacity();
|
|
|
|
|
size += memsize( dbg_filenum ) + memsize( dbg_linenum ) + memsize( dbg_ins_blocks ) +
|
|
|
|
|
memsize( dbg_ins_statementbegin ) + memsize( modules ) + memsize( exported_functions ) +
|
|
|
|
|
memsize( instr ) + memsize( blocks ) + memsize( dbg_functions );
|
|
|
|
|
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EScriptProgram::dump( std::ostream& os )
|
|
|
|
|
{
|
|
|
|
|
Token token;
|
|
|
|
|
unsigned PC;
|
|
|
|
|
if ( !exported_functions.empty() )
|
|
|
|
|
{
|
|
|
|
|
os << "Exported Functions:" << std::endl;
|
|
|
|
|
os << " PC Args Name" << std::endl;
|
|
|
|
|
for ( auto& elem : exported_functions )
|
|
|
|
|
{
|
|
|
|
|
os << std::setw( 5 ) << elem.PC << std::setw( 6 ) << elem.nargs << " " << elem.name
|
|
|
|
|
<< std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unsigned nLines = tokens.length() / sizeof( StoredToken );
|
|
|
|
|
for ( PC = 0; PC < nLines; PC++ )
|
|
|
|
|
{
|
|
|
|
|
if ( _readToken( token, PC ) )
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-01-18 09:35:52 +01:00
|
|
|
|
2026-07-21 08:50:32 +02:00
|
|
|
fmt::println( os, "{}: {}", PC, token );
|
2026-01-18 09:35:52 +01:00
|
|
|
if ( token.id == INS_CASEJMP )
|
2025-01-24 20:20:21 +01:00
|
|
|
{
|
2026-01-18 09:35:52 +01:00
|
|
|
dump_casejmp( os, token );
|
2025-01-24 20:20:21 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EScriptProgram::dump_casejmp( std::ostream& os, const Token& token )
|
|
|
|
|
{
|
|
|
|
|
const unsigned char* dataptr = token.dataptr;
|
|
|
|
|
for ( ;; )
|
|
|
|
|
{
|
|
|
|
|
unsigned short offset;
|
|
|
|
|
std::memcpy( &offset, dataptr, sizeof( unsigned short ) );
|
|
|
|
|
dataptr += 2;
|
|
|
|
|
unsigned char type = *dataptr;
|
|
|
|
|
dataptr += 1;
|
|
|
|
|
if ( type == CASE_TYPE_LONG )
|
|
|
|
|
{
|
|
|
|
|
int lval;
|
|
|
|
|
std::memcpy( &lval, dataptr, sizeof( int ) );
|
|
|
|
|
dataptr += 4;
|
|
|
|
|
os << "\t" << lval << ": @" << offset << std::endl;
|
|
|
|
|
}
|
|
|
|
|
else if ( type == CASE_TYPE_DEFAULT )
|
|
|
|
|
{
|
|
|
|
|
os << "\tdefault: @" << offset << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{ // type is the length of the string, otherwise
|
|
|
|
|
os << "\t\"" << std::string( (const char*)dataptr, type ) << "\": @" << offset << std::endl;
|
|
|
|
|
dataptr += type;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-17 10:30:21 +01:00
|
|
|
} // namespace Pol::Bscript
|