/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include "attacks.h"
#include "misc.h"
#include "position.h"
#include "tune.h"
#include "uci.h"
using namespace Stockfish;
#ifdef __EMSCRIPTEN__
UCIEngine* uciP; // Create a global pointer to the UCI object
#ifndef __EMSCRIPTEN_SINGLE_THREADED__
bool ready = false;
#endif
#endif
#ifdef UNIVERSAL_BINARY
namespace Stockfish {
int main(int argc, char* argv[]); // silence 'no previous declaration'
__attribute__((used)) // keep main alive
#endif
int main(int argc, char* argv[]) {
std::cout << engine_info() << std::endl;
Attacks::init();
Position::init();
#ifdef __EMSCRIPTEN__
uciP = new UCIEngine(argc, argv); // initialize the UCI object
Tune::init(uciP->engine_options());
#ifndef __EMSCRIPTEN_SINGLE_THREADED__
ready = true;
// Multithreaded: the UCI loop runs on the (proxy) main thread and pulls
// commands from a thread-safe queue that the JS host pushes onto (see glue.cpp).
// main() blocks here, but that is fine because it runs on W1, a separate pthread.
uciP->loop();
#endif
// Single-threaded: return from main(). There is no separate (proxy) main
// thread, so blocking in loop() would stall the only thread (and the JS
// event loop / readline). Commands are processed on demand via the
// command() ccall (process_command), which ASYNCIFY can suspend/resume.
#else
auto cli = CommandLine(argc, argv);
auto uci = std::make_unique(std::move(cli));
Tune::init(uci->engine_options());
uci->loop();
#endif
return 0;
}
#ifdef UNIVERSAL_BINARY
} // namespace Stockfish
#ifdef UNIVERSAL_NEEDS_MAIN_SHIM
int main(int argc, char* argv[]) { return Stockfish::main(argc, argv); }
#endif
#endif
#ifdef __EMSCRIPTEN__
#ifdef __EMSCRIPTEN_SINGLE_THREADED__
// Single-threaded: the JS host processes commands on demand via this ccall
// (ASYNCIFY suspends/resumes around any blocking work). The multithreaded
// build does not use this; it pushes commands onto the glue queue (uci())
// which uciP->loop() on the (proxy) main thread consumes.
extern "C" void command(const char* cmd) {
uciP->process_command(cmd);
}
#endif
#ifndef __EMSCRIPTEN_SINGLE_THREADED__
extern "C" bool isReady() {
return ready;
}
#endif
#endif