Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs

This commit is contained in:
2026-05-29 20:52:26 -05:00
parent d26e357448
commit abea319ea0
110 changed files with 25716 additions and 31016 deletions

View File

@@ -3,12 +3,15 @@
namespace Tesses::CrossLang::Programs {
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::Framework::Streams;
static void Help(std::string& filename)
{
std::cout << "USAGE: " << filename << " [OPTIONS] <dirasroot> <archive.crvm>" << std::endl;
static void Help(std::string &filename) {
std::cout << "USAGE: " << filename
<< " [OPTIONS] <dirasroot> <archive.crvm>" << std::endl;
printf("OPTIONS:\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": \"https://example.com/\", \"homepage\": \"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon name (relative to dirasroot), should be a 128x128 png\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": "
"\"https://example.com/\", \"homepage\": "
"\"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon name (relative to dirasroot), should be a 128x128 "
"png\n");
printf(" -v: Set version (1.0.0.0-prod defaults to 1.0.0.0-dev)\n");
printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
printf(" -h, --help: Prints help\n");
@@ -16,80 +19,66 @@ static void Help(std::string& filename)
exit(1);
}
int64_t CrossArchiveCreate(std::vector<std::string>& argv)
{
int64_t CrossArchiveCreate(std::vector<std::string> &argv) {
Tesses::Framework::TF_Init();
std::string name="out";
std::string info="{}";
TVMVersion version;
std::string icon="";
std::vector<std::string> args;
for(int i = 1; i < argv.size(); i++)
{
if(argv[i] == "--help" || argv[i] == "-h")
{
std::string name = "out";
std::string info = "{}";
TVMVersion version;
std::string icon = "";
std::vector<std::string> args;
for (int i = 1; i < argv.size(); i++) {
if (argv[i] == "--help" || argv[i] == "-h") {
Help(argv[0]);
}
else if(argv[i] == "-i")
{
} else if (argv[i] == "-i") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
info = argv[i];
}
}
else if(argv[i] == "-I")
{
} else if (argv[i] == "-I") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
icon = argv[i];
}
}
else if(argv[i] == "-n")
{
} else if (argv[i] == "-n") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
name = argv[i];
}
}
else if(argv[i] == "-v")
{
} else if (argv[i] == "-v") {
i++;
if(i < argv.size())
{
if(!TVMVersion::TryParse(argv[i],version))
{
if (i < argv.size()) {
if (!TVMVersion::TryParse(argv[i], version)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
"]]]\n");
exit(1);
}
}
}
else {
} else {
args.push_back(argv[i]);
}
}
}
if(args.size() < 2) Help(argv[0]);
auto path = Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
if (args.size() < 2)
Help(argv[0]);
auto path =
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]);
Tesses::Framework::Filesystem::LocalFS->CreateDirectory(path);
auto sdfs = std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,path);
auto sdfs = std::make_shared<SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, path);
FILE* f = fopen(args[1].c_str(),"wb");
if(f == NULL)
{
FILE *f = fopen(args[1].c_str(), "wb");
if (f == NULL) {
printf("ERROR: could not open %s\n", args[1].c_str());
return 1;
}
auto strm = std::make_shared<FileStream>(f,true,"wb",true);
CrossArchiveCreate(sdfs,strm,name,version,info,icon);
auto strm = std::make_shared<FileStream>(f, true, "wb", true);
CrossArchiveCreate(sdfs, strm, name, version, info, icon);
return 0;
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -5,25 +5,23 @@ namespace Tesses::CrossLang::Programs {
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::Framework::Streams;
int64_t CrossArchiveExtract(std::vector<std::string>& argv)
{
int64_t CrossArchiveExtract(std::vector<std::string> &argv) {
Tesses::Framework::TF_Init();
if(argv.size() < 3)
{
std::cout << "USAGE: " << argv[0] << " <archive.crvm> <dirasroot>" << std::endl;
if (argv.size() < 3) {
std::cout << "USAGE: " << argv[0] << " <archive.crvm> <dirasroot>"
<< std::endl;
return 1;
}
auto sdfs= std::make_shared<SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,std::string(argv[2]));
auto strm= LocalFS->OpenFile(argv[1], "rb");
if(strm->CanRead())
{
auto sdfs = std::make_shared<SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, std::string(argv[2]));
auto strm = LocalFS->OpenFile(argv[1], "rb");
if (!strm->CanRead()) {
std::cout << "ERROR: could not open " << argv[1] << std::endl;
return 1;
}
auto res = Tesses::CrossLang::CrossArchiveExtract(strm,sdfs);
auto res = Tesses::CrossLang::CrossArchiveExtract(strm, sdfs);
std::cout << "Crvm Name: " << res.first.first << std::endl;
std::cout << "Crvm Version: " << res.first.second.ToString() << std::endl;
@@ -31,4 +29,4 @@ int64_t CrossArchiveExtract(std::vector<std::string>& argv)
return 0;
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,38 +1,37 @@
#include "CrossLang.hpp"
#include <iostream>
namespace Tesses::CrossLang::Programs {
static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,uint8_t* buffer, size_t len)
{
if(strm->ReadBlock(buffer,len) != len)
{
throw VMException("Could not read " + std::to_string(len) + " byte(s).");
static void Ensure(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
uint8_t *buffer, size_t len) {
if (strm->ReadBlock(buffer, len) != len) {
throw VMException("Could not read " + std::to_string(len) +
" byte(s).");
}
}
static uint32_t EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
{
static uint32_t
EnsureInt(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
uint8_t buff[4];
Ensure(strm,buff,sizeof(buff));
Ensure(strm, buff, sizeof(buff));
return BitConverter::ToUint32BE(buff[0]);
}
static std::string EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
{
static std::string
EnsureString(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
size_t len = (size_t)EnsureInt(strm);
std::string myStr={};
std::string myStr = {};
myStr.resize(len);
Ensure(strm,(uint8_t*)myStr.data(), len);
Ensure(strm, (uint8_t *)myStr.data(), len);
return myStr;
}
void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
{
void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) {
uint8_t main_header[18];
Ensure(strm,main_header,sizeof(main_header));
if(strncmp((const char*)main_header,"TCROSSVM",8) != 0) throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header+8);
if(version.CompareToRuntime() == 1)
{
Ensure(strm, main_header, sizeof(main_header));
if (strncmp((const char *)main_header, "TCROSSVM", 8) != 0)
throw VMException("Invalid TCrossVM image.");
TVMVersion version(main_header + 8);
if (version.CompareToRuntime() == 1) {
throw VMException("Runtime is too old.");
}
TVMVersion v2(main_header+13);
TVMVersion v2(main_header + 13);
std::cout << "Version: " << v2.ToString() << std::endl;
size_t _len = (size_t)EnsureInt(strm);
@@ -41,215 +40,188 @@ void CrossLangDump(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)
std::vector<std::string> strs;
std::unordered_map<uint32_t, std::vector<std::string>> funs;
std::vector<std::vector<std::string>> closures;
std::unordered_map<uint32_t, std::vector<std::string>> funs;
std::vector<std::vector<std::string>> closures;
char table_name[4];
bool hasIcon = false;
char table_name[4];
bool hasIcon=false;
for (size_t i = 0; i < _len; i++) {
Ensure(strm, (uint8_t *)table_name, sizeof(table_name));
size_t tableLen = (size_t)EnsureInt(strm);
std::string tableName(table_name, 4);
if (tableName == "ICON") {
hasIcon = true;
} else if (tableName == "STRS") {
size_t strsLen = (size_t)EnsureInt(strm);
for (size_t j = 0; j < strsLen; j++) {
strs.push_back(EnsureString(strm));
}
} else if (tableName == "DEPS") {
for(size_t i = 0; i < _len; i++)
{
Ensure(strm,(uint8_t*)table_name,sizeof(table_name));
size_t tableLen = (size_t)EnsureInt(strm);
std::string tableName(table_name,4);
if(tableName == "ICON")
{
hasIcon=true;
std::string name = strs.at((size_t)EnsureInt(strm));
uint8_t version_bytes[5];
Ensure(strm, version_bytes, sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
std::cout << "Dependency: " << name << "-" << depVersion.ToString()
<< std::endl;
} else if (tableName == "NAME") {
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm))
<< std::endl;
} else if (tableName == "CLSS") {
std::cout << "Classes:\n";
uint32_t clss_cnt = EnsureInt(strm);
for (uint32_t j = 0; j < clss_cnt; j++) {
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/"
<< std::endl;
uint32_t fnPartsC = EnsureInt(strm);
std::cout << "\tName: ";
for (uint32_t k = 0; k < fnPartsC; k++) {
if (k > 0)
std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
else if(tableName == "STRS")
{
size_t strsLen = (size_t)EnsureInt(strm);
for(size_t j = 0;j < strsLen;j++)
{
strs.push_back(EnsureString(strm));
std::cout << std::endl;
fnPartsC = EnsureInt(strm);
std::cout << "\tInherits: ";
for (uint32_t k = 0; k < fnPartsC; k++) {
if (k > 0)
std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
std::cout << std::endl;
uint32_t ents = EnsureInt(strm);
for (uint8_t k = 0; k < ents; k++) {
Ensure(strm, main_header, 1);
uint8_t flags = main_header[0];
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/"
<< std::endl;
std::string fnname = strs.at(EnsureInt(strm));
std::string fnargs;
uint32_t argParts = EnsureInt(strm);
for (uint32_t l = 0; l < argParts; l++) {
if (l > 0)
fnargs += ", ";
fnargs += strs.at(EnsureInt(strm));
}
}
else if(tableName == "DEPS")
{
std::string name = strs.at((size_t)EnsureInt(strm));
uint8_t version_bytes[5];
Ensure(strm,version_bytes,sizeof(version_bytes));
TVMVersion depVersion(version_bytes);
std::cout << "Dependency: " << name << "-" << depVersion.ToString() << std::endl;
}
else if(tableName == "NAME")
{
std::cout << "Name: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
}
else if(tableName == "CLSS")
{
std::cout << "Classes:\n";
uint32_t clss_cnt= EnsureInt(strm);
for(uint32_t j = 0; j < clss_cnt; j++)
{
std::cout << "\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
uint32_t fnPartsC = EnsureInt(strm);
std::cout << "\tName: ";
for(uint32_t k = 0; k < fnPartsC; k++)
{
if(k > 0) std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
std::cout << std::endl;
fnPartsC = EnsureInt(strm);
std::cout << "\tInherits: ";
for(uint32_t k = 0; k < fnPartsC; k++)
{
if(k > 0) std::cout << ".";
std::cout << strs.at(EnsureInt(strm));
}
std::cout << std::endl;
uint32_t ents = EnsureInt(strm);
for(uint8_t k = 0; k < ents; k++)
{
Ensure(strm,main_header,1);
uint8_t flags = main_header[0];
std::cout << "\t\t/^" << strs.at(EnsureInt(strm)) << "^/" << std::endl;
std::string fnname = strs.at(EnsureInt(strm));
std::string fnargs;
uint32_t argParts = EnsureInt(strm);
for(uint32_t l = 0; l < argParts; l++)
{
if(l > 0) fnargs += ", ";
fnargs += strs.at(EnsureInt(strm));
}
uint32_t fnchunk = EnsureInt(strm);
switch(flags & 3)
{
case 0:
std::cout << "\t\tprivate ";
break;
case 1:
std::cout << "\t\tprotected ";
break;
case 2:
std::cout << "\t\tpublic ";
break;
case 3:
std::cout << "\t\tstatic ";
break;
}
switch((flags >> 2) & 3)
{
case 0:
std::cout << "func " << fnname << "(" << fnargs << "), chunk = " << fnchunk << std::endl;
break;
case 1:
std::cout << "field " << fnname << ", chunk = " << fnchunk << std::endl;
break;
case 2:
std::cout << "abstract " << fnname << "(" << fnargs << ")" << std::endl;
break;
case 3:
std::cout << "unset_field " << fnname << std::endl;
break;
}
std::cout << std::endl;
}
}
}
else if(tableName == "CHKS")
{
size_t chunkCount = (size_t)EnsureInt(strm);
for(size_t j = 0; j < chunkCount; j++)
{
std::vector<std::string> args;
size_t argCount = (size_t)EnsureInt(strm);
for(size_t k = 0; k < argCount; k++)
{
args.push_back(strs.at(EnsureInt(strm)));
}
auto len = EnsureInt(strm);
strm->Seek(len,Tesses::Framework::Streams::SeekOrigin::Current);
closures.push_back(args);
}
}
else if(tableName == "FUNS")
{
size_t funLength = (size_t)EnsureInt(strm);
for(size_t j = 0; j < funLength;j++)
{
std::vector<std::string> fnParts;
uint32_t fnPartsC = EnsureInt(strm);
for(uint32_t k = 0; k < fnPartsC; k++)
{
fnParts.push_back(strs.at(EnsureInt(strm)));
uint32_t fnchunk = EnsureInt(strm);
switch (flags & 3) {
case 0:
std::cout << "\t\tprivate ";
break;
case 1:
std::cout << "\t\tprotected ";
break;
case 2:
std::cout << "\t\tpublic ";
break;
case 3:
std::cout << "\t\tstatic ";
break;
}
uint32_t fnNumber = EnsureInt(strm);
funs[fnNumber] = fnParts;
}
}
else if(tableName == "INFO")
{
switch ((flags >> 2) & 3) {
case 0:
std::cout << "func " << fnname << "(" << fnargs
<< "), chunk = " << fnchunk << std::endl;
std::cout << "Info: " << strs.at((size_t)EnsureInt(strm)) << std::endl;
}
else
{
strm->Seek((int64_t)tableLen,Tesses::Framework::Streams::SeekOrigin::Current);
break;
case 1:
std::cout << "field " << fnname
<< ", chunk = " << fnchunk << std::endl;
break;
case 2:
std::cout << "abstract " << fnname << "(" << fnargs
<< ")" << std::endl;
break;
case 3:
std::cout << "unset_field " << fnname << std::endl;
break;
}
std::cout << std::endl;
}
}
if(hasIcon)
std::cout << "Has Icon: yes" << std::endl;
else
std::cout << "Has Icon: no" << std::endl;
} else if (tableName == "CHKS") {
size_t chunkCount = (size_t)EnsureInt(strm);
for(size_t i = 1; i < closures.size(); i++)
{
if(funs.count((uint32_t)i) > 0)
{
std::cout << "Func: ";
auto res = funs[(uint32_t)i];
if(!res.empty()) {
std::cout << "/^" << res[0] << "^/ ";
}
for(size_t i = 1; i < res.size(); i++)
{
if(i > 1) std::cout << ".";
std::cout << res[i];
}
for (size_t j = 0; j < chunkCount; j++) {
std::vector<std::string> args;
size_t argCount = (size_t)EnsureInt(strm);
for (size_t k = 0; k < argCount; k++) {
args.push_back(strs.at(EnsureInt(strm)));
}
else
{
std::cout << "Closure: ";
}
std::cout << "(";
bool first=true;
for(auto arg : closures[i])
{
if(!first) std::cout << ", ";
std::cout << arg;
auto len = EnsureInt(strm);
if(first) first=false;
}
std::cout << ")" << std::endl;
strm->Seek(len,
Tesses::Framework::Streams::SeekOrigin::Current);
closures.push_back(args);
}
std::cout << std::endl;
std::cout << "String Table:" << std::endl;
} else if (tableName == "FUNS") {
size_t funLength = (size_t)EnsureInt(strm);
for(auto str : strs) {
std::cout << EscapeString(str, true) << std::endl;
for (size_t j = 0; j < funLength; j++) {
std::vector<std::string> fnParts;
uint32_t fnPartsC = EnsureInt(strm);
for (uint32_t k = 0; k < fnPartsC; k++) {
fnParts.push_back(strs.at(EnsureInt(strm)));
}
uint32_t fnNumber = EnsureInt(strm);
funs[fnNumber] = fnParts;
}
} else if (tableName == "INFO") {
std::cout << "Info: " << strs.at((size_t)EnsureInt(strm))
<< std::endl;
} else {
strm->Seek((int64_t)tableLen,
Tesses::Framework::Streams::SeekOrigin::Current);
}
}
if (hasIcon)
std::cout << "Has Icon: yes" << std::endl;
else
std::cout << "Has Icon: no" << std::endl;
for (size_t i = 1; i < closures.size(); i++) {
if (funs.count((uint32_t)i) > 0) {
std::cout << "Func: ";
auto res = funs[(uint32_t)i];
if (!res.empty()) {
std::cout << "/^" << res[0] << "^/ ";
}
for (size_t i = 1; i < res.size(); i++) {
if (i > 1)
std::cout << ".";
std::cout << res[i];
}
} else {
std::cout << "Closure: ";
}
std::cout << "(";
bool first = true;
for (auto arg : closures[i]) {
if (!first)
std::cout << ", ";
std::cout << arg;
if (first)
first = false;
}
std::cout << ")" << std::endl;
}
std::cout << std::endl;
std::cout << "String Table:" << std::endl;
for (auto str : strs) {
std::cout << EscapeString(str, true) << std::endl;
}
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -6,153 +6,150 @@
using namespace Tesses::Framework;
using namespace Tesses::Framework::Http;
namespace Tesses::CrossLang::Programs
{
namespace Tesses::CrossLang::Programs {
static bool Download(Tesses::Framework::Filesystem::VFSPath filename,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs)
{
auto inContainer=Platform::Environment::GetVariable("CROSSLANG_CONTAINER");
if(inContainer && (*inContainer=="1" || *inContainer=="y" || *inContainer=="Y"))
{
static bool Download(Tesses::Framework::Filesystem::VFSPath filename,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs) {
auto inContainer =
Platform::Environment::GetVariable("CROSSLANG_CONTAINER");
if (inContainer &&
(*inContainer == "1" || *inContainer == "y" || *inContainer == "Y")) {
HttpRequest req;
req.followRedirects=true;
req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK)
{
if (resp.statusCode == StatusCode::OK) {
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, vfs);
return true;
}
else
{
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
} else {
std::cout << "Error when fetching the script error: "
<< std::to_string(resp.statusCode) << " "
<< HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return false;
}
}
while(true)
{
std::cout << "File " << filename.ToString() << " not found, do you want to download the installer from: https://redirect.tesses.net/crosslang-shell (this may install other stuff as well) (Y/n)? ";
while (true) {
std::cout << "File " << filename.ToString()
<< " not found, do you want to download the installer from: "
"https://redirect.tesses.net/crosslang-shell (this may "
"install other stuff as well) (Y/n)? ";
std::string line;
std::getline(std::cin,line);
if(line == "Y" || line == "y")
{
std::getline(std::cin, line);
if (line == "Y" || line == "y") {
HttpRequest req;
req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK)
{
if (resp.statusCode == StatusCode::OK) {
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, vfs);
return true;
}
else
{
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
} else {
std::cout << "Error when fetching the script error: "
<< std::to_string(resp.statusCode) << " "
<< HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return false;
}
}
else if(line == "N" || line == "n")
{
std::cout << "Looks like you will need to install manually" << std::endl;
} else if (line == "N" || line == "n") {
std::cout << "Looks like you will need to install manually"
<< std::endl;
return false;
}
else
{
} else {
std::cout << "Please use Y or N (case insensitive)" << std::endl;
}
}
return false;
}
TObject CrossLangShell(GCList& ls, std::vector<std::string>& argv)
{
TObject CrossLangShell(GCList &ls, std::vector<std::string> &argv) {
Tesses::Framework::Filesystem::VFSPath dir = GetCrossLangConfigDir();
Tesses::Framework::Filesystem::VFSPath filename = dir / "Shell" / "Shell.crvm";
Tesses::Framework::Filesystem::VFSPath filename =
dir / "Shell" / "Shell.crvm";
auto p = Tesses::Framework::Platform::Environment::GetRealExecutablePath(Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[0])).GetParent().GetParent() / "share" / "Tesses" / "CrossLang" / "Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm";
if(argv.size() == 2 && argv[1] == "configdir")
{
auto p =
Tesses::Framework::Platform::Environment::GetRealExecutablePath(
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[0]))
.GetParent()
.GetParent() /
"share" / "Tesses" / "CrossLang" /
"Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm";
if (argv.size() == 2 && argv[1] == "configdir") {
std::cout << dir.ToString() << std::endl;
return 0;
}
if(argv.size() > 1 && argv[1] == "update-shell")
{
if (argv.size() > 1 && argv[1] == "update-shell") {
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir);
auto subdir =
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, dir);
HttpRequest req;
req.followRedirects=true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if(resp.statusCode == StatusCode::OK)
{
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, subdir);
req.followRedirects = true;
req.url = "https://redirect.tesses.net/crosslang-shell";
req.method = "GET";
HttpResponse resp(req);
if (resp.statusCode == StatusCode::OK) {
auto strm = resp.ReadAsStream();
CrossLang::CrossArchiveExtract(strm, subdir);
return 0;
}
else
{
std::cout << "Error when fetching the script error: " << std::to_string(resp.statusCode) << " " << HttpUtils::StatusCodeString(resp.statusCode) << std::endl;
return 1;
}
return 0;
} else {
std::cout << "Error when fetching the script error: "
<< std::to_string(resp.statusCode) << " "
<< HttpUtils::StatusCodeString(resp.statusCode)
<< std::endl;
return 1;
}
return 0;
}
if(!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename))
{
auto subdir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(Tesses::Framework::Filesystem::LocalFS,dir);
if(Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p))
{
std::cout << "Installing " << p.ToString() << " -> " << dir.ToString() << std::endl;
auto strm = Tesses::Framework::Filesystem::LocalFS->OpenFile(p,"rb");
if(strm != nullptr)
{
if (!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) {
auto subdir =
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
Tesses::Framework::Filesystem::LocalFS, dir);
if (Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p)) {
std::cout << "Installing " << p.ToString() << " -> "
<< dir.ToString() << std::endl;
auto strm =
Tesses::Framework::Filesystem::LocalFS->OpenFile(p, "rb");
if (strm != nullptr) {
CrossLang::CrossArchiveExtract(strm, subdir);
}
else
{
} else {
return 1;
}
}
else
{
if(!Download(filename,subdir)) return 1;
} else {
if (!Download(filename, subdir))
return 1;
return 0;
}
}
TRootEnvironment *env =
TRootEnvironment::Create(ls, TDictionary::Create(ls));
TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls));
TStd::RegisterStd(ls.GetGC(), env);
env->LoadFileWithDependencies(
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
TStd::RegisterStd(ls.GetGC(),env);
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, filename);
TList* args = TList::Create(ls);
TList *args = TList::Create(ls);
args->Add(filename.ToString());
for(size_t arg=1;arg<argv.size();arg++)
for (size_t arg = 1; arg < argv.size(); arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls,"main",{args});
return env->CallFunctionWithFatalError(ls, "main", {args});
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,16 +1,20 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <iostream>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Filesystem;
namespace Tesses::CrossLang::Programs {
static void Help(std::string filename)
{
std::cout << "USAGE: " << filename << " [OPTIONS] source_file1 source_file2 source_file_n" << std::endl;
static void Help(std::string filename) {
std::cout << "USAGE: " << filename
<< " [OPTIONS] source_file1 source_file2 source_file_n"
<< std::endl;
printf("OPTIONS:\n");
printf(" -o: Output directory (OUTDIR, defaults to ./bin)\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": \"https://example.com/\", \"homepage\": \"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon resource name (in the resource folder), should be a 128x128 png\n");
printf(" -i: Set info (ex {\"maintainer\": \"Mike Nolan\", \"repo\": "
"\"https://example.com/\", \"homepage\": "
"\"https://example.com/\",\"license\":\"MIT\"})\n");
printf(" -I: Set icon resource name (in the resource folder), should be "
"a 128x128 png\n");
printf(" -v: Set version (1.0.0.0-prod defaults to 1.0.0.0-dev)\n");
printf(" -d: Add dependency (DependencyName-1.0.0.0-prod)\n");
printf(" -D: enable debug)\n");
@@ -18,12 +22,14 @@ static void Help(std::string filename)
printf(" -n: Set name (MyAppOrLibName defaults to out)\n");
printf(" -r: Set resource directory (RESDIR defaults to res)\n");
printf(" -h, --help: Prints help\n");
printf(" -e: Set comptime permissions defaults to none, none for no support, \"secure\" for sane without file access, \"secure_file\" for sane with file access to current directory and sub directories, \"full\" has full runtime.\n");
printf(" -e: Set comptime permissions defaults to none, none for no "
"support, \"secure\" for sane without file access, \"secure_file\" "
"for sane with file access to current directory and sub "
"directories, \"full\" has full runtime.\n");
printf("Options except for help have flag with arg like this: -F ARG\n");
exit(1);
}
void CrossLangCompiler(std::vector<std::string>& argv)
{
void CrossLangCompiler(std::vector<std::string> &argv) {
/*std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
std::vector<LexToken> tokens;
Lex(argv[1],strm,tokens);
@@ -36,228 +42,189 @@ void CrossLangCompiler(std::vector<std::string>& argv)
ByteCodeVectorWriter w(data);
gen.Save(std::filesystem::current_path(),w);
*/
TF_InitWithConsole();
std::filesystem::path outputDir = std::filesystem::current_path() / "bin";
std::vector<std::filesystem::path> source;
std::filesystem::path resourceDir = std::filesystem::current_path() / "res";
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
std::string name="out";
std::string info="{}";
std::string icon="";
std::string comptime="none";
TVMVersion version;
bool debug=false;
TF_InitWithConsole();
std::filesystem::path outputDir = std::filesystem::current_path() / "bin";
std::vector<std::filesystem::path> source;
std::filesystem::path resourceDir = std::filesystem::current_path() / "res";
std::vector<std::pair<std::string, TVMVersion>> dependencies;
std::vector<std::pair<std::string, TVMVersion>> tools;
std::string name = "out";
std::string info = "{}";
std::string icon = "";
std::string comptime = "none";
TVMVersion version;
bool debug = false;
for(size_t i = 1; i < argv.size(); i++)
{
if(argv[i] == "--help" || argv[i] == "-h")
{
for (size_t i = 1; i < argv.size(); i++) {
if (argv[i] == "--help" || argv[i] == "-h") {
Help(argv[0]);
}
else if(argv[i] == "-o")
{
else if (argv[i] == "-o") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
outputDir = argv[i];
}
}
else if(argv[i] == "-r")
{
} else if (argv[i] == "-r") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
resourceDir = argv[i];
}
}
else if(argv[i] == "-e")
{
} else if (argv[i] == "-e") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
comptime = argv[i];
}
}
else if(argv[i] == "-i")
{
else if (argv[i] == "-i") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
info = argv[i];
}
}
else if(argv[i] == "-I")
{
} else if (argv[i] == "-I") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
icon = argv[i];
}
}
else if(argv[i] == "-d")
{
} else if (argv[i] == "-d") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
std::string str = argv[i];
auto lastDash = str.find_last_of('-');
if(lastDash < str.size())
{
std::string str2 = str.substr(lastDash+1);
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
{
lastDash = str.find_last_of('-',lastDash-1);
if (lastDash < str.size()) {
std::string str2 = str.substr(lastDash + 1);
if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
str2 == "prod") {
lastDash = str.find_last_of('-', lastDash - 1);
}
std::string str1 = str.substr(0,lastDash);
str2 = str.substr(lastDash+1);
std::string str1 = str.substr(0, lastDash);
str2 = str.substr(lastDash + 1);
TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2))
{
if (!TVMVersion::TryParse(str2, v2)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
"prod]]]]\n");
exit(1);
}
dependencies.push_back(std::pair<std::string,TVMVersion>(str1,v2));
}
else
{
dependencies.push_back(
std::pair<std::string, TVMVersion>(str1, v2));
} else {
printf("ERROR: Dependency must have version\n");
exit(1);
}
}
}
else if(argv[i] == "-t")
{
} else if (argv[i] == "-t") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
std::string str = argv[i];
auto lastDash = str.find_last_of('-');
if(lastDash < str.size())
{
std::string str2 = str.substr(lastDash+1);
if(str2 == "dev" || str2 == "alpha" || str2 == "beta" || str2 == "prod")
{
lastDash = str.find_last_of('-',lastDash-1);
if (lastDash < str.size()) {
std::string str2 = str.substr(lastDash + 1);
if (str2 == "dev" || str2 == "alpha" || str2 == "beta" ||
str2 == "prod") {
lastDash = str.find_last_of('-', lastDash - 1);
}
std::string str1 = str.substr(0,lastDash);
str2 = str.substr(lastDash+1);
std::string str1 = str.substr(0, lastDash);
str2 = str.substr(lastDash + 1);
TVMVersion v2;
if(!TVMVersion::TryParse(str2,v2))
{
if (!TVMVersion::TryParse(str2, v2)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-"
"prod]]]]\n");
exit(1);
}
tools.push_back(std::pair<std::string,TVMVersion>(str1,v2));
}
else
{
tools.push_back(
std::pair<std::string, TVMVersion>(str1, v2));
} else {
printf("ERROR: Tool must have version\n");
exit(1);
}
}
}
else if(argv[i] == "-n")
{
} else if (argv[i] == "-n") {
i++;
if(i < argv.size())
{
if (i < argv.size()) {
name = argv[i];
}
}
else if(argv[i] == "-v")
{
} else if (argv[i] == "-v") {
i++;
if(i < argv.size())
{
if(!TVMVersion::TryParse(argv[i],version))
{
if (i < argv.size()) {
if (!TVMVersion::TryParse(argv[i], version)) {
printf("ERROR: Invalid syntax for version\n");
printf("Expected MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]]]]\n");
printf("Expected "
"MAJOR[.MINOR[.PATCH[.BUILD[-dev,-alpha,-beta,-prod]"
"]]]\n");
exit(1);
}
}
}
else if(argv[i] == "-D" || argv[i] == "--debug")
{
} else if (argv[i] == "-D" || argv[i] == "--debug") {
debug = true;
}
else {
} else {
source.push_back(argv[i]);
}
}
if(source.empty())
{
}
if (source.empty()) {
Help(argv[0]);
}
}
std::vector<LexToken> tokens;
for(auto src : source)
{
std::ifstream strm(src,std::ios_base::in|std::ios_base::binary);
int res = Lex(std::filesystem::absolute(src).string(),strm,tokens);
for (auto src : source) {
std::ifstream strm(src, std::ios_base::in | std::ios_base::binary);
int res = Lex(std::filesystem::absolute(src).string(), strm, tokens);
}
std::shared_ptr<GC> gc;
std::shared_ptr<GCList> ls;
TRootEnvironment* env=nullptr;
if(comptime != "none")
{
std::shared_ptr<GC> gc= std::make_shared<GC>();
TRootEnvironment *env = nullptr;
if (comptime != "none") {
std::shared_ptr<GC> gc = std::make_shared<GC>();
gc->Start();
ls = std::make_shared<GCList>(gc);
env = TRootEnvironment::Create(*ls,TDictionary::Create(*ls));
env = TRootEnvironment::Create(*ls, TDictionary::Create(*ls));
if(comptime == "secure")
{
TStd::RegisterConsole(gc,env);
TStd::RegisterClass(gc,env);
TStd::RegisterCrypto(gc,env);
TStd::RegisterDictionary(gc,env);
TStd::RegisterJson(gc,env);
TStd::RegisterRoot(gc,env);
TStd::RegisterIO(gc,env,false);
env->permissions.locked=true;
}
else if(comptime == "secure_file")
{
TStd::RegisterConsole(gc,env);
TStd::RegisterClass(gc,env);
TStd::RegisterCrypto(gc,env);
TStd::RegisterDictionary(gc,env);
TStd::RegisterJson(gc,env);
TStd::RegisterRoot(gc,env);
TStd::RegisterIO(gc,env,false);
env->permissions.locked=true;
auto fs = env->EnsureDictionary(gc,"FS");
fs->SetValue("Local", std::make_shared<SubdirFilesystem>(LocalFS,Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
}
else if(comptime == "full")
{
TStd::RegisterStd(gc,env);
env->permissions.locked=true;
if (comptime == "secure") {
TStd::RegisterConsole(gc, env);
TStd::RegisterClass(gc, env);
TStd::RegisterCrypto(gc, env);
TStd::RegisterDictionary(gc, env);
TStd::RegisterJson(gc, env);
TStd::RegisterRoot(gc, env);
TStd::RegisterIO(gc, env, false);
env->permissions.locked = true;
} else if (comptime == "secure_file") {
TStd::RegisterConsole(gc, env);
TStd::RegisterClass(gc, env);
TStd::RegisterCrypto(gc, env);
TStd::RegisterDictionary(gc, env);
TStd::RegisterJson(gc, env);
TStd::RegisterRoot(gc, env);
TStd::RegisterIO(gc, env, false);
env->permissions.locked = true;
auto fs = env->EnsureDictionary(gc, "FS");
fs->SetValue("Local",
std::make_shared<SubdirFilesystem>(
LocalFS, Tesses::Framework::Filesystem::VFSPath::
GetAbsoluteCurrentDirectory()));
} else if (comptime == "full") {
TStd::RegisterStd(gc, env);
env->permissions.locked = true;
}
}
Parser parser(tokens,gc,env);
Parser parser(tokens, gc, env);
parser.debug = debug;
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,LocalFS->SystemToVFSPath(resourceDir.string()));
auto sfs = std::make_shared<SubdirFilesystem>(
LocalFS, LocalFS->SystemToVFSPath(resourceDir.string()));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
@@ -265,21 +232,20 @@ void CrossLangCompiler(std::vector<std::string>& argv)
gen.version = version;
gen.info = info;
gen.icon = icon;
for(auto deps : dependencies)
{
for (auto deps : dependencies) {
gen.dependencies.push_back(deps);
}
for(auto tool : tools)
{
for (auto tool : tools) {
gen.tools.push_back(tool);
}
std::filesystem::create_directory(outputDir);
{
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(outputDir / (name + "-" + version.ToString() + ".crvm"),"wb");
auto strm = std::make_shared<Tesses::Framework::Streams::FileStream>(
outputDir / (name + "-" + version.ToString() + ".crvm"), "wb");
gen.Save(strm);
}
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,124 +1,114 @@
#include "CrossLang.hpp"
#include <iostream>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Filesystem;
namespace Tesses::CrossLang::Programs {
TObject CrossLangInterperter(GCList& ls,TRootEnvironment* env,std::vector<std::string>& argv)
{
std::shared_ptr<GC> gc = ls.GetGC();
if(argv.size() > 1)
{
std::ifstream strm(argv[1],std::ios_base::in|std::ios_base::binary);
TObject CrossLangInterperter(GCList &ls, TRootEnvironment *env,
std::vector<std::string> &argv) {
std::shared_ptr<GC> gc = ls.GetGC();
if (argv.size() > 1) {
std::ifstream strm(argv[1], std::ios_base::in | std::ios_base::binary);
std::vector<LexToken> tokens;
Lex(argv[1],strm,tokens);
Lex(argv[1], strm, tokens);
Parser parser(tokens);
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
std::vector<uint8_t> data;
{
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
auto strm2 =
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
true);
gen.Save(strm2);
{
TFile* file = TFile::Create(ls);
TFile *file = TFile::Create(ls);
strm2->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc, strm2);
strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc,strm2);
env->LoadFile(gc, file);
}
}
TList* args = TList::Create(ls);
for(int arg=1;arg<argv.size();arg++)
TList *args = TList::Create(ls);
for (int arg = 1; arg < argv.size(); arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls,"main",{args});
}
else
{
while(true)
{
return env->CallFunctionWithFatalError(ls, "main", {args});
} else {
while (true) {
std::cout << "> ";
std::string source;
std::getline(std::cin,source);
std::getline(std::cin, source);
auto strm2 = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
auto strm2 =
std::make_shared<Tesses::Framework::Streams::MemoryStream>(
true);
if(source.find("loadfile ") == 0)
{
if (source.find("loadfile ") == 0) {
std::string filename = source.substr(9);
std::ifstream strm(filename,std::ios_base::in|std::ios_base::binary);
std::ifstream strm(filename,
std::ios_base::in | std::ios_base::binary);
std::vector<LexToken> tokens;
Lex(filename,strm,tokens);
Lex(filename, strm, tokens);
Parser parser(tokens);
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
auto sfs =
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
gen.Save(strm2);
}
else if(source == "exit")
{
} else if (source == "exit") {
return (int64_t)0;
}
else
{
} else {
std::vector<LexToken> tokens;
std::stringstream strm(source,std::ios_base::in | std::ios_base::binary);
Lex("lexed.tcross",strm,tokens);
std::stringstream strm(source, std::ios_base::in |
std::ios_base::binary);
Lex("lexed.tcross", strm, tokens);
Parser parser(tokens);
CodeGen gen;
auto sfs = std::make_shared<SubdirFilesystem>(LocalFS,VFSPath("."));
auto sfs =
std::make_shared<SubdirFilesystem>(LocalFS, VFSPath("."));
gen.embedFS = sfs;
gen.GenRoot(parser.ParseRoot());
gen.Save(strm2);
}
{
TFile* file = TFile::Create(ls);
strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc,strm2);
env->LoadFile(gc, file);
TFile *file = TFile::Create(ls);
}
strm2->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin);
file->Load(gc, strm2);
env->LoadFile(gc, file);
}
}
}
return (int64_t)0;
}
}
} // namespace Tesses::CrossLang::Programs

View File

@@ -1,61 +1,58 @@
#include "CrossLang.hpp"
using namespace Tesses::Framework;
namespace Tesses::CrossLang::Programs {
TObject CrossLangVM(GCList& ls,TRootEnvironment* env, std::vector<std::string>& argv)
{
if(argv.size() < 2)
{
std::cout << "USAGE: " << (argv.empty() ? (std::string)"crossvm" : argv[0]) << " <filename.crvm> <args...>" << std::endl;
return 1;
}
env->LoadFileWithDependencies(ls.GetGC(), Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
if(env->HasVariable("WebAppMain"))
{
Args args(argv);
int port = 4206;
for(auto& item : args.options)
{
if(item.first == "port")
{
port = std::stoi(item.second);
}
}
env->EnsureDictionary(ls.GetGC(),"Net")->SetValue("WebServerPort", (int64_t)port);
TList* args2 = TList::Create(ls);
for(auto& item : args.positional)
{
args2->Add(item);
}
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(),res);
if(svr2 == nullptr) return 1;
Tesses::Framework::Http::HttpServer svr(port,svr2);
svr.StartAccepting();
TF_RunEventLoop();
TDictionary* _dict;
TClassObject* _co;
if(GetObjectHeap(res,_dict))
{
_dict->CallMethod(ls,"Close",{});
}
if(GetObjectHeap(res,_co))
{
_co->CallMethod(ls,"","Close",{});
}
TF_Quit();
return 0;
}
else {
TList* args = TList::Create(ls);
for(size_t arg=1;arg<argv.size();arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls,"main",{args});
}
TObject CrossLangVM(GCList &ls, TRootEnvironment *env,
std::vector<std::string> &argv) {
if (argv.size() < 2) {
std::cout << "USAGE: "
<< (argv.empty() ? (std::string) "crossvm" : argv[0])
<< " <filename.crvm> <args...>" << std::endl;
return 1;
}
}
env->LoadFileWithDependencies(
ls.GetGC(), Tesses::Framework::Filesystem::LocalFS,
Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1]));
if (env->HasVariable("WebAppMain")) {
Args args(argv);
int port = 4206;
for (auto &item : args.options) {
if (item.first == "port") {
port = std::stoi(item.second);
}
}
env->EnsureDictionary(ls.GetGC(), "Net")
->SetValue("WebServerPort", (int64_t)port);
TList *args2 = TList::Create(ls);
for (auto &item : args.positional) {
args2->Add(item);
}
auto res = env->CallFunctionWithFatalError(ls, "WebAppMain", {args2});
auto svr2 = Tesses::CrossLang::ToHttpServer(ls.GetGC(), res);
if (svr2 == nullptr)
return 1;
Tesses::Framework::Http::HttpServer svr(port, svr2);
svr.StartAccepting();
TF_RunEventLoop();
TDictionary *_dict;
TClassObject *_co;
if (GetObjectHeap(res, _dict)) {
_dict->CallMethod(ls, "Close", {});
}
if (GetObjectHeap(res, _co)) {
_co->CallMethod(ls, "", "Close", {});
}
TF_Quit();
return 0;
} else {
TList *args = TList::Create(ls);
for (size_t arg = 1; arg < argv.size(); arg++)
args->Add(std::string(argv[arg]));
return env->CallFunctionWithFatalError(ls, "main", {args});
}
}
} // namespace Tesses::CrossLang::Programs