Hi,
I'm trying to bring an old C++ mini-game I made to the web. It heavily
relies on Sleep, so I've been trying to get it to work through Asyncify.
When I try to compile it with that flag on, it generates the following
error in 1.25:
-----------------------
LLVM ERROR: InvokeState == 1 || InvokeState == 2
Stack dump:
0. Program arguments: C:/Program
Files/Emscripten/clang/e1.25.0_64bit\llc
c:\users\jens\appdata\local\temp\tmpncthh0\a.out.bc -march=js -filetype=asm
-o c:\users\jens\appdata\local\temp\tmpmqkl4z.4.js -emscripten-assertions=1
-emscripten-no-aliasing-function-pointers -O0 -emscripten-max-setjmps=20
1. Running pass 'JavaScript backend' on module
'c:\users\jens\appdata\local\temp\tmpncthh0\a.out.bc'.
Traceback (most recent call last):
File "C:\Program Files\Emscripten\emscripten\1.25.0\emscripten.py", line
1578, in <module>
_main(environ=os.environ)
File "C:\Program Files\Emscripten\emscripten\1.25.0\emscripten.py", line
1566, in _main
temp_files.run_and_clean(lambda: main(
File "C:\Program Files\Emscripten\emscripten\1.25.0\tools\tempfiles.py",
line 39, in run_and_clean
return func()
File "C:\Program Files\Emscripten\emscripten\1.25.0\emscripten.py", line
1574, in <lambda>
DEBUG_CACHE=DEBUG_CACHE,
File "C:\Program Files\Emscripten\emscripten\1.25.0\emscripten.py", line
1461, in main
jcache=jcache, temp_files=temp_files, DEBUG=DEBUG,
DEBUG_CACHE=DEBUG_CACHE)
File "C:\Program Files\Emscripten\emscripten\1.25.0\emscripten.py", line
804, in emscript_fast
end_funcs = backend_output.rindex(end_funcs_marker)
ValueError: substring not found
Traceback (most recent call last):
File "C:\Program Files\Emscripten\emscripten\1.25.0\\emcc", line 1259, in
<module>
final = shared.Building.emscripten(final, append_ext=False,
extra_args=extra_args)
File "C:\Program Files\Emscripten\emscripten\1.25.0\tools\shared.py",
line 1464, in emscripten
assert os.path.exists(filename + '.o.js'), 'Emscripten failed to
generate .js'
AssertionError: Emscripten failed to generate .js
-----------------------
I've attached the source that generates this error. It's a single .cpp
file, so maybe it'll be helpful tracking this down.
Cheers,
Jens
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
#include <time.h>
#include <math.h>
#include <string>
#include <list>
#include <vector>
#include <sstream>
#include <emscripten.h>
#include <emscripten/html5.h>
using namespace std;
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
int _kbhit() { return 0; }
int _getch() { return 0; }
void _putch(char _ch)
{
char buf[2];
buf[0] = _ch;
buf[1] = 0;
printf("%s", buf);
}
#define localtime_s(a, b) localtime_r(b, a)
void fopen_s(
FILE** pFile,
const char *filename,
const char *mode
)
{
*pFile = fopen(filename, mode);
}
EM_BOOL keypress_callback(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
{
printf("keypress\r\n");
return 0;
}
class COsmosis
{
public:
enum
{
RES_CONTINUE = -1,
RES_CONTINUE_NOLINEFEED = -2,
RES_CLOSECONNECTION = -3,
CHAR_LOCALCONTROLKEY = 1,
};
int m_iProgram;
int m_Delay[3];
vector<string> m_lProgram;
vector<string> m_lVariableKeys;
vector<string> m_lVariableValues;
vector<string> m_lOptions;
int m_iStandaloneResponse;
int m_ServerSocket;
int m_ClientSocket;
int m_MasterSocket;
COsmosis()
{
m_iProgram = 0;
m_ServerSocket = -1;
m_ClientSocket = -1;
m_MasterSocket = -1;
m_Delay[0] = m_Delay[1] = m_Delay[2] = 0;
m_iStandaloneResponse = -1;
}
~COsmosis()
{
}
void SendCharLocal(char _Ch)
{
_putch(_Ch);
}
char GetCharLocal()
{
while (true)
{
if (_kbhit())
{
char ch = _getch();
_putch(ch);
return ch;
}
}
}
void SendLocal(const char *_pSt)
{
int i = 0;
while (_pSt[i] != 0)
SendCharLocal(_pSt[i++]);
}
int GetChar(bool _bBlock = true)
{
char ch = 0;
while (ch == 0)
{
if (_kbhit())
{
ch = _getch();
if (ch == '!')
ch = CHAR_LOCALCONTROLKEY;
}
else
{
if (!_bBlock)
return 0;
}
}
SendCharLocal(ch);
return ch;
}
bool SendChar(char _Ch)
{
SendCharLocal(_Ch);
return true;
}
int FindLineFromLabel(const string &_Label)
{
if (_Label.empty())
return -1;
size_t nProg = m_lProgram.size();
for (size_t i = 0; i < nProg; i++)
{
const string &Line = m_lProgram[i];
if (Line.at(0) == '[' && Line.at(1) == '@')
{
string Label = Line.substr(1, Line.length() - 2);
if (Label == _Label)
return int(i);
}
}
SendLocal("Label not found: ");
SendLocal(_Label.c_str());
SendLocal("\r\n");
return -1;
}
void SetVariable(const string &_Var, const string &_Val)
{
const string *pVal = &_Val;
string Val2 = _Val;
Val2 = _Val;
pVal = &Val2;
char EOL[] = "\r\n";
while (true)
{
size_t iPos = pVal->find('|');
if (iPos == -1)
break;
if (pVal == &_Val)
{
Val2 = _Val;
pVal = &Val2;
}
Val2.replace(iPos, 1, EOL);
}
size_t nVar = m_lVariableKeys.size();
for (size_t i = 0; i < nVar; i++)
{
if (m_lVariableKeys[i] == _Var)
{
m_lVariableValues[i] = *pVal;
return;
}
}
m_lVariableKeys.push_back(_Var);
m_lVariableValues.push_back(*pVal);
}
void SetVariable_i(const string &_Var, int _Val)
{
char Buf[1024];
sprintf(Buf, "%i", _Val);
SetVariable(_Var, Buf);
}
void SetVariable_f(const string &_Var, float _Val)
{
char Buf[1024];
sprintf(Buf, "%.2f", _Val);
SetVariable(_Var, Buf);
}
string GetVariable(const string &_Var)
{
size_t nVar = m_lVariableKeys.size();
for (size_t i = 0; i < nVar; i++)
{
if (m_lVariableKeys[i] == _Var)
return m_lVariableValues[i];
}
return string();
}
string GetCurTimeString(const char *_pFormat = NULL)
{
time_t ltime;
time(<ime);
char Buf[512];
tm today;
localtime_s(&today, <ime);
if (_pFormat)
strftime(Buf, 512, _pFormat, &today);
else
strftime(Buf, 512, "%d %B %Y, %H:%M", &today);
return Buf;
}
string GetStrSep(string &_St, char _Separator)
{
size_t iFind = _St.find(_Separator);
if (iFind == -1)
{
string Res = _St;
_St.clear();
return Res;
}
string Res = _St.substr(0, iFind);
_St = _St.substr(iFind + 1, _St.length());
return Res;
}
char InputLine(const string &_Param)
{
SendChar('>');
SendChar(' ');
while (true)
{
char ch = GetChar();
if (ch == RES_CLOSECONNECTION)
return RES_CLOSECONNECTION;
if (ch == '\n' || ch == '\r')
{
SendChar('\r');
SendChar('\n');
return RES_CONTINUE;
}
if (ch == CHAR_LOCALCONTROLKEY)
{
return FindLineFromLabel(_Param);
}
}
}
void EndResponse(string &_StRes)
{
if (m_lOptions.size() < 3)
return;
for (int i = 0; i < 3; i++)
{
emscripten_sleep(3000);
SendLocal("\r\n");
SendLocal(m_lOptions[i].c_str());
SendLocal("\r\n");
InputLine("");
SendLocal("Processing input. Please wait.");
}
emscripten_sleep(1500);
}
int CalibratePanel(string _Param)
{
//[calibratepanel,@panels,$panel_x,$panel_y,$panel3_power,-40,10]
char ch = GetChar();
if (ch == '5')
return RES_CONTINUE;
if (ch == RES_CLOSECONNECTION)
return RES_CLOSECONNECTION;
string Loop = GetStrSep(_Param, ',');
string VarX = GetStrSep(_Param, ',');
string VarY = GetStrSep(_Param, ',');
string VarPow = GetStrSep(_Param, ',');
int OptX = atoi(GetStrSep(_Param, ',').c_str());
int OptY = atoi(GetStrSep(_Param, ',').c_str());
int Step = atoi(GetStrSep(_Param, ',').c_str());
int CurX = atoi(GetVariable(VarX).c_str());
int CurY = atoi(GetVariable(VarY).c_str());
switch (ch)
{
case '1': CurX = min(CurX + Step, 180); break;
case '2': CurX = max(CurX - Step, -180); break;
case '3': CurY = min(CurY + Step, 180); break;
case '4': CurY = max(CurY - Step, -180); break;
}
float Pow = float(max(200 - abs(OptX - CurX) - abs(OptY - CurY), 0)) * 0.20f / 200 + 0.04f;
SetVariable_f(VarPow, Pow);
SetVariable_i(VarX, CurX);
SetVariable_i(VarY, CurY);
return FindLineFromLabel(Loop);
}
int Takeoff(string _Param)
{
string Loop = GetStrSep(_Param, ',');
string VarAltitude = GetStrSep(_Param, ',');
string VarSpeed = GetStrSep(_Param, ',');
string VarFuel = GetStrSep(_Param, ',');
int OptimalAlt1 = atoi(GetStrSep(_Param, ',').c_str());
int OptimalAlt2 = atoi(GetStrSep(_Param, ',').c_str());
int Altitude = atoi(GetVariable(VarAltitude).c_str());
int Speed = atoi(GetVariable(VarSpeed).c_str());
int Fuel = atoi(GetVariable(VarFuel).c_str());
if (OptimalAlt2 > 0)
{
clock_t ltime = clock();
while (true)
{
char ch = GetChar(false);
if (ch == RES_CLOSECONNECTION)
return RES_CLOSECONNECTION;
if (ch == ' ')
{
if (Altitude > OptimalAlt2 * 0.5)
return RES_CONTINUE;
}
emscripten_sleep(1);
clock_t ctime = clock();
if (ctime - ltime > 500)
break;
}
int BaseAccel = 214;
int AltitudeBonus = 0;
Speed += BaseAccel;
if (Altitude > OptimalAlt1 && Altitude < OptimalAlt2)
Speed += int(20 * Altitude);
else
Speed += int(10 * Altitude);
Altitude += int(float(Speed) / 1000 + 0.5f);
if (Altitude > OptimalAlt2 * 3.0)
return RES_CONTINUE;
Fuel -= 7;
}
else
{
clock_t ltime = clock();
while (true)
{
char ch = GetChar(false);
if (ch == RES_CLOSECONNECTION)
return RES_CLOSECONNECTION;
emscripten_sleep(1);
clock_t ctime = clock();
if (ctime - ltime > 500)
break;
}
int Left = OptimalAlt1 - Altitude;
Speed -= 8000;
Speed = (4 * Speed + Left * 100) / 5;
if (abs(Altitude - OptimalAlt1) < 100)
return RES_CONTINUE;
Altitude += int(float(Speed) / 1000 + 0.5f);
Fuel -= 3;
}
SetVariable_i(VarSpeed, Speed);
SetVariable_i(VarAltitude, Altitude);
SetVariable_i(VarFuel, Fuel);
return FindLineFromLabel(Loop);
}
int Entry(string _Param)
{
string Loop = GetStrSep(_Param, ',');
string VarAltitude = GetStrSep(_Param, ',');
string VarSpeed = GetStrSep(_Param, ',');
string VarShield = GetStrSep(_Param, ',');
string VarAngle = GetStrSep(_Param, ',');
int OptimalAngle = atoi(GetStrSep(_Param, ',').c_str());
int EndAltitude = atoi(GetStrSep(_Param, ',').c_str());
int Altitude = atoi(GetVariable(VarAltitude).c_str());
int Speed = atoi(GetVariable(VarSpeed).c_str());
int Angle = atoi(GetVariable(VarAngle).c_str());
int Shield = atoi(GetVariable(VarShield).c_str());
clock_t ltime = clock();
while (true)
{
char ch = GetChar(false);
if (ch == RES_CLOSECONNECTION)
return RES_CLOSECONNECTION;
if (ch == '1')
Angle += 2;
else if (ch == '2')
Angle -= 2;
emscripten_sleep(1);
clock_t ctime = clock();
if (ctime - ltime > 500)
break;
}
bool bReduceShield = false;
if (GetVariable("$shield_trigger").empty())
{
SetVariable("$shield_trigger", "1");
bReduceShield = true;
}
else
SetVariable("$shield_trigger", "");
if ((OptimalAngle - Angle) > 4)
{
SetVariable("$shield_status", "Failing");
if (bReduceShield)
Shield -= 2;
else
Shield -= 1;
}
else
{
SetVariable("$shield_status", "Holding");
if (bReduceShield)
Shield -= 1;
}
if (Shield <= 0)
{
Shield = 0;
SetVariable("$shield_status", "Failed");
}
Speed = int(Speed * 0.97f);
Speed -= 219;
Altitude -= int(0.5f + float(Speed) / 2809.0f);
if (Altitude <= EndAltitude)
return RES_CONTINUE;
SetVariable_i(VarSpeed, Speed);
SetVariable_i(VarAltitude, Altitude);
SetVariable_i(VarAngle, Angle);
SetVariable_i(VarShield, Shield);
return FindLineFromLabel(Loop);
}
int WaitForClient(const char *_pDev)
{
SetVariable("$clientip", "127.0.0.1");
return -1;
}
void KillInput()
{
while (_kbhit())
_getch();
}
bool LoadMenu(const char *_pPath)
{
FILE *pFile;
string Path = "menus/";
Path += _pPath;
fopen_s(&pFile, Path.c_str(), "rb");
if (!pFile)
{
printf("Could not open %s", _pPath);
return false;
}
fseek(pFile, 0, SEEK_END);
int Len = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
char *pBuf = new char[Len + 1];
if (!pBuf)
return false;
fread(pBuf, 1, Len, pFile);
fclose(pFile);
pBuf[Len] = 0;
int iStartLine = 0;
int iPos = 0;
while (pBuf[iPos] != 0)
{
if (pBuf[iPos] == '\n')
{
string St;
St.insert(0, pBuf + iStartLine, iPos - iStartLine - 1);
if (St.length() == 0)
St = " ";
if (St.find("#include") == 0)
{
string Path = St.substr(9, 1024);
if (!LoadMenu(Path.c_str()))
return false;
}
m_lProgram.push_back(St);
iPos++;
iStartLine = iPos;
}
else
iPos++;
}
delete[] pBuf;
return true;
}
int ResolveString(string &_In)
{
int Res = RES_CONTINUE;
while (true)
{
size_t iCmdStart = _In.find('[');
if (iCmdStart == -1)
break;
size_t iCmdEnd = _In.find(']', iCmdStart + 1);
while (true)
{
size_t iCmdStart2 = _In.find('[', iCmdStart + 1);
if (iCmdStart2 == -1 || iCmdStart2 > iCmdEnd)
break;
iCmdStart = iCmdStart2;
}
string Param = _In.substr(iCmdStart + 1, iCmdEnd - iCmdStart - 1);
string Msg = GetStrSep(Param, ':');
string StRes;
if (Msg.at(0) == '$')
StRes = GetVariable(Msg);
else if (Msg == "set")
{
string Key = GetStrSep(Param, ',');
SetVariable(Key, Param);
}
else if (Msg == "\\")
Res = RES_CONTINUE_NOLINEFEED;
else if (Msg == "|")
StRes = "\r";
else if (Msg == "option")
{
string Desc = GetStrSep(Param, ',');
bool bOk = true;
if (Param.find(',') != -1)
{
string Var = Param;
Param = GetStrSep(Var, ',');
if (GetVariable(Var).empty())
bOk = false;
}
if (bOk)
{
m_lOptions.push_back(Param);
size_t nOption = m_lOptions.size();
ostringstream strm;
strm << nOption << ". " << Desc;
StRes = strm.str();
}
}
else if (Msg == "endoptions")
{
while (true)
{
char ch = GetChar();
if (ch == RES_CLOSECONNECTION)
{
_In = "";
return RES_CLOSECONNECTION;
}
ch -= '1';
if (size_t(ch) < m_lOptions.size())
{
string Label = m_lOptions.at(ch);
if (Label.empty())
break;
Res = FindLineFromLabel(Label);
if (Res != -1)
break;
}
}
m_lOptions.clear();
StRes = "\r\n\r\n";
}
else if (Msg == "goto")
Res = FindLineFromLabel(Param);
else if (Msg == "appendline")
{
string Key = GetStrSep(Param, ',');
string Val = GetVariable(Key);
Val += "\r\n" + Param;
SetVariable(Key, Val);
}
else if (Msg == "getlastline")
{
string Key = GetStrSep(Param, ',');
string Val = GetVariable(Key);
size_t iPos = Val.rfind('\n', Val.length() - 1);
StRes = Val.substr(iPos + 1, 1024);
}
else if (Msg == "curdatetime")
StRes = GetCurTimeString();
else if (Msg == "quit")
{
_In = "";
return RES_CLOSECONNECTION;
}
else if (Msg == "killinput")
{
KillInput();
}
else if (Msg == "branch")
{
string Var = GetVariable(GetStrSep(Param, ','));
string Operator = GetStrSep(Param, ',');
string Condition = GetStrSep(Param, ',');
bool bBranch = false;
if (Operator == "==")
bBranch = (Var == Condition);
else if (Operator == "!=")
bBranch = (Var != Condition);
else if (Operator == "<")
bBranch = (float(atof(Var.c_str())) < float(atof(Condition.c_str())));
else if (Operator == ">")
bBranch = (float(atof(Var.c_str())) > float(atof(Condition.c_str())));
string Branch1 = GetStrSep(Param, ',');
string Branch2 = GetStrSep(Param, ',');
if (bBranch)
Res = FindLineFromLabel(Branch1);
else
Res = FindLineFromLabel(Branch2);
}
else if (Msg == "key")
{
vector<char> lKeys;
vector<string> lBranch;
while (true)
{
string St = GetStrSep(Param, ',');
if (St.empty())
break;
char ch = St.at(0);
if (ch == '!')
ch = 1;
lKeys.push_back(ch);
lBranch.push_back(GetStrSep(Param, ','));
}
size_t nSize = lKeys.size();
if (nSize == 2 && lKeys[0] == 1)
{
emscripten_sleep(4000);
Res = FindLineFromLabel(lBranch[1]);
}
SendChar('\r');
SendChar('\n');
}
else if (Msg == "setdelay")
{
m_Delay[0] = atoi(GetStrSep(Param, ',').c_str());
m_Delay[1] = atoi(GetStrSep(Param, ',').c_str());
m_Delay[2] = atoi(GetStrSep(Param, ',').c_str());
}
else if (Msg == "disconnect")
{
_In = "";
return RES_CLOSECONNECTION;
}
else if (Msg == "m_add")
{
float f = 0;
while (!Param.empty())
{
string Var = GetStrSep(Param, ',');
if (Var.size() > 0 && Var.at(0) == '$')
Var = GetVariable(Var);
f += (float)atof(Var.c_str());
}
char Res2[1024];
sprintf(Res2, "%.2f", f);
StRes = Res2;
}
else if (Msg == "m_inc")
{
int Val = atoi(GetVariable(Param).c_str());
SetVariable_i(Param, Val + 1);
}
else if (Msg == "calibratepanel")
Res = CalibratePanel(Param);
else if (Msg == "takeoff")
Res = Takeoff(Param);
else if (Msg == "entry")
Res = Entry(Param);
else if (Msg == "inputline")
Res = InputLine(Param);
else if (Msg == "response")
{
m_lOptions.push_back(Param);
}
else if (Msg == "endresponse")
{
EndResponse(StRes);
if (StRes == "")
Res = FindLineFromLabel(Param);
m_lOptions.clear();
}
else if (Msg == "waitforclient")
{
Res = WaitForClient(Param.c_str());
SendLocal("\n");
}
_In.replace(iCmdStart, iCmdEnd - iCmdStart + 1, StRes);
}
return Res;
}
int Run()
{
if (!LoadMenu("root.txt"))
return 1;
SetVariable("$datetime", GetCurTimeString());
int Res = 0;
while (Res > RES_CLOSECONNECTION)
{
Res = 0;
m_iProgram = 0;
m_lOptions.clear();
while (Res >= RES_CONTINUE_NOLINEFEED)
{
if (m_iProgram >= int(m_lProgram.size()))
m_iProgram = 0;
string St = m_lProgram.at(m_iProgram);
Res = ResolveString(St);
size_t Len = St.length();
if (Len > 0)
{
for (size_t i = 0; i < Len; i++)
{
char ch = St[i];
if (ch == '_')
{
emscripten_sleep(m_Delay[1]);
}
else
{
if (Res != RES_CONTINUE_NOLINEFEED)
emscripten_sleep(m_Delay[0]);
SendChar(ch);
}
}
if (Res == RES_CONTINUE)
{
SendChar('\r');
if (!SendChar('\n'))
break;
}
emscripten_sleep(m_Delay[2]);
}
if (Res >= 0)
m_iProgram = Res;
else
m_iProgram++;
}
}
return 0;
}
};
int main(int argc, char* argv[])
{
emscripten_set_keypress_callback(0, 0, 1, keypress_callback);
COsmosis Game;
Game.Run();
return 0;
}