Rework for git.tesses.org, GC* is std::shared_ptr maybe will fix crash during exit
Some checks failed
Build and Deploy on Tag / update-tap (push) Has been cancelled
Build and Deploy on Tag / build-arch (push) Has been cancelled

This commit is contained in:
2026-04-30 16:00:00 -05:00
parent fca18e63a6
commit 991f2a217d
78 changed files with 1243 additions and 849 deletions

View File

@@ -226,7 +226,7 @@ namespace Tesses::CrossLang
return nullptr;
}
void TStd::RegisterClass(GC* gc, TRootEnvironment* env)
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
GCList ls(gc);
env->permissions.canRegisterClass=true;

View File

@@ -280,7 +280,7 @@ namespace Tesses::CrossLang {
return dict;
}
void TStd::RegisterConsole(GC* gc,TRootEnvironment* env)
void TStd::RegisterConsole(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterConsole=true;
if(env->permissions.customConsole != nullptr)

View File

@@ -99,7 +99,7 @@ namespace Tesses::CrossLang
}
return nullptr;
}
void TStd::RegisterCrypto(GC* gc,TRootEnvironment* env)
void TStd::RegisterCrypto(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterCrypto=true;

View File

@@ -129,7 +129,7 @@ namespace Tesses::CrossLang
}
return nullptr;
}
void TStd::RegisterDictionary(GC* gc,TRootEnvironment* env)
void TStd::RegisterDictionary(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterDictionary=true;

View File

@@ -136,7 +136,7 @@ namespace Tesses::CrossLang
{
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
}
void TStd::RegisterEnv(GC* gc, TRootEnvironment* env)
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
env->permissions.canRegisterEnv=true;

View File

@@ -49,7 +49,7 @@ namespace Tesses::CrossLang {
}
return Undefined();
}
void TStd::RegisterHelpers(GC* gc, TRootEnvironment* env)
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
auto helpers=env->EnsureDictionary(gc,"Helpers");
helpers->DeclareFunction(gc,"CopyToProgress","Copy Stream to another (but with progress event)",{"src","dest","progressCB","$precision"},Helpers_CopyToProgress);

View File

@@ -4,23 +4,6 @@
namespace Tesses::CrossLang
{
static TObject FS_MakeFull(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
if(path.relative)
{
Tesses::Framework::Filesystem::LocalFilesystem lfs;
auto curDir = std::filesystem::current_path();
auto myPath = lfs.SystemToVFSPath(curDir.string()) / path;
myPath = myPath.CollapseRelativeParents();
return myPath;
}
return path.CollapseRelativeParents();
}
return nullptr;
}
static TObject FS_CreateArchive(GCList& ls, std::vector<TObject> args)
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
@@ -160,17 +143,7 @@ namespace Tesses::CrossLang
return nullptr;
}
static TObject FS_getCurrentPath(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory();
}
static TObject FS_setCurrentPath(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
Tesses::Framework::Filesystem::VFSPath::SetAbsoluteCurrentDirectory(path);
return nullptr;
}
@@ -287,12 +260,22 @@ namespace Tesses::CrossLang
}
return nullptr;
}
void TStd::RegisterIO(GC* gc,TRootEnvironment* env,bool enableLocalFilesystem)
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env, bool enable)
{
if(enable)
{
RegisterIO(gc,env,std::make_shared<RelativeFilesystem>(Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
}
else
{
RegisterIO(gc,env,nullptr);
}
}
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env,std::shared_ptr<RelativeFilesystem> fs)
{
env->permissions.canRegisterIO=true;
env->permissions.canRegisterLocalFS = enableLocalFilesystem;
env->permissions.localfs = fs;
GCList ls(gc);
gc->BarrierBegin();
@@ -323,14 +306,36 @@ namespace Tesses::CrossLang
}
));
if(enableLocalFilesystem)
if(fs)
{
dict->SetValue("Local", Tesses::Framework::Filesystem::LocalFS);
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},FS_MakeFull);
dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},FS_getCurrentPath);
dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"},FS_setCurrentPath);
dict->SetValue("Local", fs);
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},[fs](GCList& ls, std::vector<TObject> args)->TObject{
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
if(path.relative)
{
auto myPath = fs->GetWorking() / path;
myPath = myPath.CollapseRelativeParents();
return myPath;
}
return path.CollapseRelativeParents();
}
return nullptr;
});
dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},[fs](GCList& ls, std::vector<TObject> args)->TObject{
return fs->GetWorking();
});
dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"}, [fs](GCList& ls, std::vector<TObject> args)->TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
fs->SetWorking(path);
}
return path;
});
}
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText);

View File

@@ -186,7 +186,7 @@ namespace Tesses::CrossLang
{
return JsonDeserialize(ls,Json::DocDecode(str));
}
void TStd::RegisterJson(GC* gc,TRootEnvironment* env)
void TStd::RegisterJson(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterJSON=true;

View File

@@ -379,6 +379,56 @@ namespace Tesses::CrossLang
ctx->WithLastModified(*da);
return this;
}
else if(key == "WithDebug")
{
bool debug=true;
GetArgument(args,0,debug);
ctx->WithDebug(debug);
return this;
}
else if(key == "getDebug")
{
return ctx->Debug();
}
else if(key == "SendServerSentEvents")
{
if(!args.empty() && std::holds_alternative<std::shared_ptr<Tesses::Framework::Http::ServerSentEvents>>(args[0]))
{
ctx->SendServerSentEvents(std::get<std::shared_ptr<Tesses::Framework::Http::ServerSentEvents>>(args[0]));
}
}
else if(key == "WithHeaderIntercepter")
{
TCallable* callable;
if(GetArgumentHeap(args, 0, callable))
{
auto marked = CreateMarkedTObject(ls.GetGC(),callable);
ctx->WithHeaderIntercepter([marked](ServerContext& ctx)->bool {
auto obj = marked->GetObject();
TCallable* callable;
if(GetObjectHeap(obj, callable))
{
GCList ls(marked->GetGC());
auto ptr=TNativeObject::Create<TServerContext>(ls, &ctx);
auto res = callable->Call(ls, {ptr});
ptr->Finish();
bool r0;
if(GetObject(res, r0)) return r0;
}
return false;
});
}
return this;
}
else if(key == "WithContentDisposition")
{
std::string filename;
@@ -589,7 +639,7 @@ namespace Tesses::CrossLang
}
};
TObjectHttpServer::TObjectHttpServer(GC* gc,TObject obj)
TObjectHttpServer::TObjectHttpServer(std::shared_ptr<GC> gc,TObject obj)
{
this->ls=new GCList(gc);
this->ls->Add(obj);
@@ -598,10 +648,10 @@ namespace Tesses::CrossLang
class TDictionaryHttpRequestBody : public HttpRequestBody
{
GC* gc;
std::shared_ptr<GC> gc;
TDictionary* req;
public:
TDictionaryHttpRequestBody(GC* gc,TDictionary* req)
TDictionaryHttpRequestBody(std::shared_ptr<GC> gc,TDictionary* req)
{
this->gc = gc;
this->req = req;
@@ -790,7 +840,7 @@ namespace Tesses::CrossLang
}
if(GetArgument(args,1,pathStr) && env->permissions.canRegisterLocalFS)
if(GetArgument(args,1,pathStr) && env->permissions.localfs)
{
std::shared_ptr<IHttpServer> httpSvr = ToHttpServer(ls.GetGC(),args[0]);
@@ -979,7 +1029,7 @@ namespace Tesses::CrossLang
GetObject(_obj,req.followRedirects);
_obj = options->GetValue("TrustedRootCertBundle");
GetObject(_obj,req.trusted_root_cert_bundle);
if(env->permissions.canRegisterLocalFS)
if(env->permissions.localfs)
{
_obj = options->GetValue("UnixSocket");
GetObject(_obj,req.unixSocket);
@@ -1403,7 +1453,7 @@ namespace Tesses::CrossLang
return false;
}
std::shared_ptr<IHttpServer> ToHttpServer(GC* gc, TObject obj)
std::shared_ptr<IHttpServer> ToHttpServer(std::shared_ptr<GC> gc, TObject obj)
{
if(std::holds_alternative<std::shared_ptr<IHttpServer>>(obj)) return std::get<std::shared_ptr<IHttpServer>>(obj);
TDictionary* dict;
@@ -1522,8 +1572,13 @@ namespace Tesses::CrossLang
return nullptr;
}
static TObject New_ServerSentEvents(GCList& ls, std::vector<TObject> args)
{
return std::make_shared<Tesses::Framework::Http::ServerSentEvents>();
}
void TStd::RegisterNet(GC* gc, TRootEnvironment* env)
void TStd::RegisterNet(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
env->permissions.canRegisterNet=true;
@@ -1545,6 +1600,7 @@ namespace Tesses::CrossLang
_new->DeclareFunction(gc, "MountableServer","Create a server you can mount to, must mount parents before child",{"root"}, New_MountableServer);
_new->DeclareFunction(gc, "NetworkStream","Create a network stream",{"ipv6","datagram"},New_NetworkStream);
_new->DeclareFunction(gc, "ServerSentEvents", "Create server sent events object",{""},New_ServerSentEvents);
TDictionary* http = TDictionary::Create(ls);
@@ -1617,7 +1673,7 @@ namespace Tesses::CrossLang
gc->BarrierEnd();
}
Tesses::Framework::Http::ServerRequestHandler TCallable::ToRouteServerRequestHandler(GC* gc)
Tesses::Framework::Http::ServerRequestHandler TCallable::ToRouteServerRequestHandler(std::shared_ptr<GC> gc)
{
auto value = CreateMarkedTObject(gc,this);
return [value,this](ServerContext& ctx)->bool {

View File

@@ -46,7 +46,7 @@ namespace Tesses::CrossLang
}
#endif
#endif
void TStd::RegisterOGC(GC* gc, TRootEnvironment* env)
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
GCList ls(gc);
#if defined(GEKKO)

View File

@@ -65,7 +65,7 @@ namespace Tesses::CrossLang
return nullptr;
}
void TStd::RegisterPath(GC* gc,TRootEnvironment* env)
void TStd::RegisterPath(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterPath=true;

View File

@@ -184,7 +184,7 @@ namespace Tesses::CrossLang
return Undefined();
}
};
static TObject Process_Start(GCList& ls, std::vector<TObject> args)
static TObject Process_Start(GCList& ls, std::vector<TObject> args, TRootEnvironment* env)
{
//Process.Start({
@@ -220,7 +220,11 @@ namespace Tesses::CrossLang
GetObject(name,process->process.name);
Tesses::Framework::Filesystem::VFSPath wdPath;
if(env->permissions.localfs)
{
process->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
}
if(GetObject(workingDirectory,wdPath))
{
process->process.workingDirectory= wdPath.MakeAbsolute().ToString();
@@ -274,23 +278,36 @@ namespace Tesses::CrossLang
return nullptr;
}
static TObject New_Process(GCList& ls, std::vector<TObject> args)
{
return TNativeObject::Create<ProcessObject>(ls,ls);
}
void TStd::RegisterProcess(GC* gc,TRootEnvironment* env)
void TStd::RegisterProcess(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterProcess=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc,"Start","Start a process",{"process_object"},Process_Start);
gc->BarrierBegin();
auto processStart = TExternalMethod::Create(ls,"Start a process",{"process_object"},[env](GCList& ls, std::vector<TObject> args)->TObject{
return Process_Start(ls,args,env);
});
processStart->watch.push_back(env);
dict->SetValue("Start",processStart);
env->SetVariable("Process",dict);
auto process = env->EnsureDictionary(gc,"New");
process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
auto newProcess = TExternalMethod::Create(ls, "Create process",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
auto obj= TNativeObject::Create<ProcessObject>(ls,ls);
if(env->permissions.localfs)
{
obj->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
}
return obj;
});
newProcess->watch.push_back(env);
process->SetValue("Process",newProcess);
//process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
process->DeclareFunction(gc, "CGIServer", "Create a CGI Server",{"path"},[](GCList& ls, std::vector<TObject> args)->TObject{
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))

View File

@@ -150,7 +150,7 @@ namespace Tesses::CrossLang {
}
#endif
void TStd::RegisterSqlite(GC* gc,TRootEnvironment* env)
void TStd::RegisterSqlite(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterSqlite=true;

View File

@@ -376,7 +376,7 @@ namespace Tesses::CrossLang
void RegisterFFI(GC* gc, TDictionary* dict)
void RegisterFFI(std::shared_ptr<GC> gc, TDictionary* dict)
{
dict->SetValue("SizeOfChar",(int64_t)sizeof(char));
dict->SetValue("SizeOfShort",(int64_t)sizeof(short));
@@ -485,14 +485,14 @@ namespace Tesses::CrossLang
}
void LoadPlugin(GC* gc, TRootEnvironment* env, Tesses::Framework::Filesystem::VFSPath sharedObjectPath)
void LoadPlugin(std::shared_ptr<GC> gc, TRootEnvironment* env, Tesses::Framework::Filesystem::VFSPath sharedObjectPath)
{
#if defined(CROSSLANG_ENABLE_SHARED)
auto ptr = std::make_shared<DL>(GetPluginPath(sharedObjectPath));
auto cb = ptr->Resolve<PluginFunction>("CrossLangPluginInit");
if(cb == nullptr) return;
gc->RegisterEverythingCallback([ptr,cb](GC* gc, TRootEnvironment* env)-> void{
gc->RegisterEverythingCallback([ptr,cb](std::shared_ptr<GC> gc, TRootEnvironment* env)-> void{
cb(gc,env);
});
cb(gc,env);
@@ -747,6 +747,9 @@ namespace Tesses::CrossLang
std::string GetObjectTypeString(TObject _obj)
{
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TF_Timer_Handle>>(_obj)) return "Timer";
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Http::ServerSentEvents>>(_obj)) return "ServerSentEvents";
if(std::holds_alternative<std::regex>(_obj)) return "Regex";
if(std::holds_alternative<Undefined>(_obj)) return "Undefined";
if(std::holds_alternative<std::nullptr_t>(_obj)) return "Null";
@@ -861,11 +864,20 @@ namespace Tesses::CrossLang
auto vfs = std::get<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(_obj);
if(vfs != nullptr)
{
auto rfs = std::dynamic_pointer_cast<RelativeFilesystem>(vfs);
auto localVFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::LocalFilesystem>(vfs);
auto mountableVFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::MountableFilesystem>(vfs);
auto subFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::SubdirFilesystem>(vfs);
auto tempFS = std::dynamic_pointer_cast<Tesses::Framework::Filesystem::TempFS>(vfs);
if(rfs)
{
auto fs=rfs->GetVFS();
if(fs)
{
return GetObjectTypeString(fs);
}
return "RelativeFilesystem";
}
if(localVFS != nullptr) return "LocalFilesystem";
if(subFS != nullptr) return "SubdirFilesystem";
if(mountableVFS != nullptr) return "MountableFilesystem";
@@ -897,6 +909,7 @@ namespace Tesses::CrossLang
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cobj = dynamic_cast<TClassObject*>(obj);
auto aarray = dynamic_cast<TAssociativeArray*>(obj);
auto file = dynamic_cast<TFile*>(obj);
if(rootEnv != nullptr) return "RootEnvironment";
if(subEnv != nullptr) return "SubEnvironment";
@@ -917,6 +930,7 @@ namespace Tesses::CrossLang
if(byteArray != nullptr) return "ByteArray";
if(native != nullptr) return "Native";
if(any != nullptr) return "Any";
if(file != nullptr) return "File";
return "HeapObject";
}
@@ -1013,7 +1027,6 @@ namespace Tesses::CrossLang
this->canRegisterEnv=false;
this->canRegisterIO=false;
this->canRegisterJSON=false;
this->canRegisterLocalFS=false;
this->canRegisterNet=false;
this->canRegisterOGC=false;
this->canRegisterPath=false;
@@ -1261,8 +1274,34 @@ namespace Tesses::CrossLang
return std::make_shared<Tesses::Framework::Streams::ByteWriter>(strm);
return nullptr;
}
static void empty(){}
static TObject New_Timer(GCList& ls, std::vector<TObject> args)
{
TCallable* callable;
if(GetArgumentHeap(args, 0, callable))
{
int64_t interval = 1000;
bool enabled=true;
GetArgument(args,1, interval);
GetArgument(args,2,enabled);
void TStd::RegisterRoot(GC* gc, TRootEnvironment* env)
auto obj = CreateMarkedTObject(ls.GetGC(), callable);
return Tesses::Framework::TF_Timer([obj]()->void {
TCallable* callable;
if(GetObjectHeap(obj->GetObject(), callable))
{
GCList ls(obj->GetGC());
callable->Call(ls,{});
}
}, interval , enabled);
}
return Tesses::Framework::TF_Timer(empty, 1000L, false);
}
void TStd::RegisterRoot(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
GCList ls(gc);
@@ -1325,8 +1364,9 @@ namespace Tesses::CrossLang
newTypes->DeclareFunction(gc, "MemoryStream","Create a memory stream",{"writable"}, New_MemoryStream);
newTypes->DeclareFunction(gc, "Filesystem","Create filesystem", {"fs"},New_Filesystem);
newTypes->DeclareFunction(gc, "TempFS","Create a temp directory",{"",""}, New_TempFS);
newTypes->DeclareFunction(gc, "Timer", "Create a timer",{"$cb","$interval","$enabled"}, New_Timer);
newTypes->DeclareFunction(gc, "Stream","Create stream", {"strm"},New_Stream);
newTypes->DeclareFunction(gc,"Version","Create a version object",{"$major","$minor","$patch","$build","$stage"},[](GCList& ls, std::vector<TObject> args)->TObject{
int64_t major=1;
@@ -1477,14 +1517,18 @@ namespace Tesses::CrossLang
gc->BarrierEnd();
}
void TStd::RegisterStd(GC* gc, TRootEnvironment* env)
void TStd::RegisterStd(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
RegisterStd(gc, env, std::make_shared<RelativeFilesystem>(Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
}
void TStd::RegisterStd(std::shared_ptr<GC> gc, TRootEnvironment* env,std::shared_ptr<RelativeFilesystem> localfs)
{
env->permissions.canRegisterEverything=true;
RegisterEnv(gc, env);
RegisterRoot(gc,env);
RegisterPath(gc,env);
RegisterConsole(gc, env);
RegisterIO(gc, env);
RegisterIO(gc, env, localfs);
RegisterNet(gc, env);
RegisterSqlite(gc, env);
RegisterVM(gc, env);

View File

@@ -27,7 +27,7 @@ namespace Tesses::CrossLang {
return nullptr;
}
void TStd::RegisterUuid(GC* gc, TRootEnvironment* env)
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment* env)
{
gc->BarrierBegin();
TDictionary* guid = env->EnsureDictionary(gc, "Uuid");

View File

@@ -317,7 +317,7 @@ namespace Tesses::CrossLang
}
return nullptr;
}
void TStd::RegisterVM(GC* gc,TRootEnvironment* env)
void TStd::RegisterVM(std::shared_ptr<GC> gc,TRootEnvironment* env)
{
env->permissions.canRegisterVM=true;
GCList ls(gc);