#include <xs/basic.h>
#include <thread>
#include <vector>
#include <xs/Sub.h>
#include <xs/Simple.h>
#include <panda/string.h>
namespace xs {
using panda::string;
#ifdef PERL_IMPLICIT_CONTEXT
PerlInterpreter* my_perl_auto_t::main_interp = PERL_GET_THX;
#endif
my_perl_auto_t my_perl;
static std::vector<panda::function<void()>> end_cbs;
static const auto mt_id = std::this_thread::get_id();
void at_perl_destroy (const panda::function<void()>& f) {
end_cbs.push_back(f);
}
void __call_at_perl_destroy () {
for (auto& f : end_cbs) f();
Sv::__at_perl_destroy();
Scalar::__at_perl_destroy();
Simple::__at_perl_destroy();
}
void __call_at_thread_create () {
#ifdef PERL_IMPLICIT_CONTEXT
my_perl_auto_t::main_interp = nullptr;
#endif
}
void __boot_module (const char* rawmod, void (*bootfunc)(pTHX_ CV*), const char* version, const char* file) {
string bs("::bootstrap");
string module(strlen(rawmod) + bs.length() + 1);
module.assign(rawmod);
auto len = module.length();
auto ptr = module.buf();
for (size_t i = 0; i < len; ++i) {
if (ptr[i] != '_' || i >= len - 1 || ptr[i+1] != '_') continue;
ptr[i] = ':';
ptr[i+1] = ':';
++i;
}
auto xsname = module + bs;
Sub sub = newXS(xsname.c_str(), bootfunc, file);
sub.call<void>(Simple(module), Simple(version));
}
bool is_perl_thread () {
if (std::this_thread::get_id() == mt_id) return true;
#ifndef PERL_IMPLICIT_CONTEXT
return false;
#else
return (PerlInterpreter*)my_perl;
#endif
}
}