mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 13:37:58 -05:00
144 lines
3.2 KiB
C++
144 lines
3.2 KiB
C++
|
|
#include "Processor/Program.h"
|
|
#include "Processor/Data_Files.h"
|
|
#include "Processor/Processor.h"
|
|
|
|
#include "Processor/Instruction.hpp"
|
|
|
|
void Program::compute_constants()
|
|
{
|
|
bool debug = OnlineOptions::singleton.has_option("debug_alloc");
|
|
|
|
for (int reg_type = 0; reg_type < MAX_REG_TYPE; reg_type++)
|
|
{
|
|
max_reg[reg_type] = 0;
|
|
max_mem[reg_type] = 0;
|
|
}
|
|
for (unsigned int i=0; i<p.size(); i++)
|
|
{
|
|
if (!p[i].get_offline_data_usage(offline_data_used))
|
|
unknown_usage = true;
|
|
for (int reg_type = 0; reg_type < MAX_REG_TYPE; reg_type++)
|
|
{
|
|
auto reg = p[i].get_max_reg(reg_type);
|
|
if (debug and reg)
|
|
cerr << i << ": " << reg << endl;
|
|
max_reg[reg_type] = max(max_reg[reg_type], reg);
|
|
max_mem[reg_type] = max(max_mem[reg_type],
|
|
p[i].get_mem(RegType(reg_type)));
|
|
}
|
|
writes_persistence |= (p[i].opcode & 0xFF) == WRITEFILESHARE;
|
|
}
|
|
}
|
|
|
|
void Program::parse(string filename)
|
|
{
|
|
if (OnlineOptions::singleton.has_option("throw_exceptions"))
|
|
parse_with_error(filename);
|
|
else
|
|
{
|
|
try
|
|
{
|
|
parse_with_error(filename);
|
|
}
|
|
catch(exception& e)
|
|
{
|
|
cerr << "Error in bytecode: " << e.what() << endl;
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Program::parse_with_error(string filename)
|
|
{
|
|
name = boost::filesystem::path(filename).stem().string();
|
|
ifstream pinp(filename);
|
|
if (pinp.fail())
|
|
throw file_error(filename);
|
|
|
|
try
|
|
{
|
|
parse(pinp);
|
|
}
|
|
catch (bytecode_error& e)
|
|
{
|
|
stringstream os;
|
|
os << "Cannot parse " << filename << " (" << e.what() << ")" << endl;
|
|
os << "Does the compiler version match the virtual machine? "
|
|
<< "If in doubt, recompile the VM";
|
|
if (not OnlineOptions::singleton.executable.empty())
|
|
os << " using 'make " << OnlineOptions::singleton.executable << "'";
|
|
os << ".";
|
|
throw bytecode_error(os.str());
|
|
}
|
|
|
|
// compute hash
|
|
pinp.clear();
|
|
pinp.seekg(0);
|
|
Hash hasher;
|
|
while (pinp.peek(), !pinp.eof())
|
|
{
|
|
char buf[1024];
|
|
size_t n = pinp.readsome(buf, 1024);
|
|
hasher.update(buf, n);
|
|
}
|
|
hash = hasher.final().str();
|
|
}
|
|
|
|
void Program::parse(istream& s)
|
|
{
|
|
p.resize(0);
|
|
Instruction instr;
|
|
s.peek();
|
|
while (!s.eof())
|
|
{
|
|
bool fail = false;
|
|
try
|
|
{
|
|
instr.parse(s, p.size());
|
|
}
|
|
catch (bytecode_error&)
|
|
{
|
|
throw;
|
|
}
|
|
catch (exception&)
|
|
{
|
|
fail = true;
|
|
}
|
|
fail |= s.fail();
|
|
|
|
if (fail)
|
|
{
|
|
stringstream os;
|
|
os << "error while parsing " << hex << showbase << instr.opcode
|
|
<< " at " << dec << p.size();
|
|
throw bytecode_error(os.str());
|
|
}
|
|
|
|
p.push_back(instr);
|
|
//cerr << "\t" << instr << endl;
|
|
s.peek();
|
|
}
|
|
compute_constants();
|
|
}
|
|
|
|
void Program::print_offline_cost() const
|
|
{
|
|
if (unknown_usage)
|
|
{
|
|
cerr << "Tape has unknown usage" << endl;
|
|
return;
|
|
}
|
|
|
|
cerr << "Cost of first tape:" << endl;
|
|
offline_data_used.print_cost();
|
|
}
|
|
|
|
|
|
ostream& operator<<(ostream& s,const Program& P)
|
|
{
|
|
for (unsigned int i=0; i<P.p.size(); i++)
|
|
{ s << i << " :: " << P.p[i] << endl; }
|
|
return s;
|
|
}
|