Add uuid support

This commit is contained in:
2026-02-16 17:42:01 -06:00
parent 46850e8edf
commit 5be9d96b54
21 changed files with 5774 additions and 4838 deletions

769
src/vm/bc/getfield.cpp Normal file
View File

@@ -0,0 +1,769 @@
#include "CrossLang.hpp"
#include "TessesFramework/Serialization/BitConverter.hpp"
#include "TessesFramework/Streams/ByteReader.hpp"
#include "TessesFramework/Uuid.hpp"
#include <cstddef>
#include <exception>
#include <iostream>
#include <cmath>
#include <cstring>
#include <sstream>
#include <variant>
namespace Tesses::CrossLang {
bool InterperterThread::GetField(GC* gc)
{
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
if(!cse.empty())
{
auto stk = cse.back();
GCList ls(gc);
TObject _key = stk->Pop(ls);
TObject instance = stk->Pop(ls);
if(!std::holds_alternative<std::string>(_key))
{
stk->Push(gc,Undefined());
return false;
}
std::string key = std::get<std::string>(_key);
if(std::holds_alternative<std::string>(instance))
{
std::string str = std::get<std::string>(instance);
if(key == "Count" || key == "Length")
{
int64_t len = (int64_t)str.size();
if(len < 0) len = 0;
cse.back()->Push(gc, len);
return false;
}
cse.back()->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(instance))
{
auto vfs = std::get<std::shared_ptr<Tesses::Framework::Filesystem::VFS>>(instance);
auto tmpFS=std::dynamic_pointer_cast<Tesses::Framework::Filesystem::TempFS>(vfs);
if(tmpFS)
{
if(key == "TempDirectoryName")
{
cse.back()->Push(gc,tmpFS->TempDirectoryName());
return false;
}
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance))
{
auto writer = std::get<std::shared_ptr<Tesses::Framework::TextStreams::TextWriter>>(instance);
auto stringWriter = std::dynamic_pointer_cast<Tesses::Framework::TextStreams::StringWriter>(writer);
if(stringWriter != nullptr)
{
if(key == "Text")
{
cse.back()->Push(gc, stringWriter->GetString());
return false;
}
}
if(key == "NewLine")
{
cse.back()->Push(gc,writer->newline);
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::ByteReader>>(instance))
{
auto br = std::get<std::shared_ptr<Tesses::Framework::Streams::ByteReader>>(instance);
if(key == "Stream")
{
cse.back()->Push(gc,br->GetStream());
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::ByteWriter>>(instance))
{
auto bw = std::get<std::shared_ptr<Tesses::Framework::Streams::ByteWriter>>(instance);
if(key == "Stream")
{
cse.back()->Push(gc,bw->GetStream());
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance))
{
auto strm = std::get<std::shared_ptr<Tesses::Framework::Streams::Stream>>(instance);
if(strm != nullptr)
{
auto netStrm = std::dynamic_pointer_cast<Tesses::Framework::Streams::NetworkStream>(strm);
if(key == "CanRead")
{
cse.back()->Push(gc, strm->CanRead());
return false;
}
if(key == "CanWrite")
{
cse.back()->Push(gc, strm->CanWrite());
return false;
}
if(key == "CanSeek")
{
cse.back()->Push(gc, strm->CanSeek());
return false;
}
if(key == "EndOfStream")
{
cse.back()->Push(gc, strm->EndOfStream());
return false;
}
if(key == "Length")
{
cse.back()->Push(gc, strm->GetLength());
return false;
}
if(key == "Position")
{
cse.back()->Push(gc, strm->GetPosition());
return false;
}
if(netStrm != nullptr)
{
if(key == "Port")
{
cse.back()->Push(gc, netStrm->GetPort());
return false;
}
}
cse.back()->Push(gc, Undefined());
return false;
}
}
if(std::holds_alternative<TVMVersion>(instance))
{
TVMVersion& version = std::get<TVMVersion>(instance);
if(key == "Major")
{
stk->Push(gc, (int64_t)version.Major());
return false;
}
if(key == "Minor")
{
stk->Push(gc, (int64_t)version.Minor());
return false;
}
if(key == "Patch")
{
stk->Push(gc, (int64_t)version.Patch());
return false;
}
if(key == "Build")
{
stk->Push(gc, (int64_t)version.Build());
return false;
}
if(key == "VersionInt")
{
stk->Push(gc,(int64_t)version.AsLong());
return false;
}
if(key == "Stage")
{
switch(version.VersionStage())
{
case TVMVersionStage::DevVersion:
stk->Push(gc,"dev");
break;
case TVMVersionStage::AlphaVersion:
stk->Push(gc,"alpha");
break;
case TVMVersionStage::BetaVersion:
stk->Push(gc,"beta");
break;
case TVMVersionStage::ProductionVersion:
stk->Push(gc,"prod");
break;
}
return false;
}
stk->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance))
{
auto time = std::get<std::shared_ptr<Tesses::Framework::Date::TimeSpan>>(instance);
if(key == "Days")
{
stk->Push(gc, (int64_t)time->Days());
return false;
}
if(key == "Hours")
{
stk->Push(gc, (int64_t)time->Hours());
return false;
}
if(key == "Minutes")
{
stk->Push(gc, (int64_t)time->Minutes());
return false;
}
if(key == "Seconds")
{
stk->Push(gc, (int64_t)time->Seconds());
return false;
}
if(key == "TotalHours")
{
stk->Push(gc, time->TotalHours());
return false;
}
if(key == "TotalMinutes")
{
stk->Push(gc, time->TotalMinutes());
return false;
}
if(key == "TotalSeconds")
{
stk->Push(gc, time->TotalSeconds());
return false;
}
stk->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance))
{
auto& date = std::get<std::shared_ptr<Tesses::Framework::Date::DateTime>>(instance);
if(key == "IsLocal")
{
stk->Push(gc, date->IsLocal());
return false;
}
if(key == "Year")
{
stk->Push(gc, (int64_t)date->Year());
return false;
}
if(key == "Month")
{
stk->Push(gc, (int64_t)date->Month());
return false;
}
if(key == "Day")
{
stk->Push(gc, (int64_t)date->Day());
return false;
}
if(key == "Hour")
{
stk->Push(gc, (int64_t)date->Hour());
return false;
}
if(key == "Minute")
{
stk->Push(gc, (int64_t)date->Minute());
return false;
}
if(key == "Second")
{
stk->Push(gc, (int64_t)date->Second());
return false;
}
if(key == "DayOfWeek")
{
stk->Push(gc, (int64_t)date->DayOfWeek());
return false;
}
stk->Push(gc, Undefined());
return false;
}
if(std::holds_alternative<THeapObjectHolder>(instance))
{
auto obj = std::get<THeapObjectHolder>(instance).obj;
auto bA = dynamic_cast<TByteArray*>(obj);
auto list = dynamic_cast<TList*>(obj);
auto dict = dynamic_cast<TDictionary*>(obj);
auto dynDict = dynamic_cast<TDynamicDictionary*>(obj);
auto dynList = dynamic_cast<TDynamicList*>(obj);
auto tcallable = dynamic_cast<TCallable*>(obj);
auto closure = dynamic_cast<TClosure*>(obj);
auto externalMethod = dynamic_cast<TExternalMethod*>(obj);
auto ittr = dynamic_cast<TEnumerator*>(obj);
auto callstackEntry = dynamic_cast<CallStackEntry*>(obj);
auto file = dynamic_cast<TFile*>(obj);
auto chunk = dynamic_cast<TFileChunk*>(obj);
auto natObj = dynamic_cast<TNativeObject*>(obj);
auto cls = dynamic_cast<TClassObject*>(obj);
auto aarray = dynamic_cast<TAssociativeArray*>(obj);
auto task = dynamic_cast<TTask*>(obj);
if(task != nullptr)
{
if(key == "IsCompleted")
{
cse.back()->Push(gc,task->IsCompleted());
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(aarray != nullptr)
{
if(key == "Count" || key == "Length")
{
cse.back()->Push(gc,aarray->Count());
return false;
}
cse.back()->Push(gc, Undefined());
return false;
}
else if(cls != nullptr)
{
gc->BarrierBegin();
auto obj=cls->GetValue(cse.back()->callable->className,"get"+key);
gc->BarrierEnd();
TClosure* clos;
TCallable* callable;
if(GetObjectHeap(obj,clos))
{
this->AddCallStackEntry(ls,clos,{});
return true;
}
else if(GetObjectHeap(obj,callable))
{
cse.back()->Push(gc,callable->Call(ls,{}));
return false;
}
cse.back()->Push(gc,cls->GetValue(cse.back()->callable->className,key));
return false;
}
else
if(natObj != nullptr)
{
cse.back()->Push(gc,natObj->CallMethod(ls,"get"+key,{}));
return false;
}
if(file != nullptr)
{
if(key == "Version")
{
cse.back()->Push(gc,file->version);
return false;
}
else if(key == "Name")
{
cse.back()->Push(gc,file->name);
return false;
}
else if(key == "Info")
{
cse.back()->Push(gc, file->info);
return false;
}
else if(key == "Dependencies")
{
auto list = TList::Create(ls);
gc->BarrierBegin();
for(auto item : file->dependencies)
{
auto res = TDictionary::Create(ls);
res->SetValue("Name", item.first);
res->SetValue("Version", item.second);
list->Add(res);
}
gc->BarrierEnd();
cse.back()->Push(gc, list);
return false;
}
else if(key == "Tools")
{
auto list = TList::Create(ls);
gc->BarrierBegin();
for(auto item : file->tools)
{
auto res = TDictionary::Create(ls);
res->SetValue("Name", item.first);
res->SetValue("Version", item.second);
list->Add(res);
}
gc->BarrierEnd();
cse.back()->Push(gc, list);
return false;
}
else if(key == "Strings")
{
auto list = TList::Create(ls);
gc->BarrierBegin();
for(auto item : file->name)
{
list->Add(item);
}
gc->BarrierEnd();
cse.back()->Push(gc, list);
return false;
}
else if(key == "MetadataCount")
{
cse.back()->Push(gc, (int64_t)file->metadata.size());
return false;
}
else if(key == "Metadata")
{
TList* meta = TList::Create(ls);
gc->BarrierBegin();
for(size_t i = 0; i < file->metadata.size(); i++)
{
meta->Add(
TDictionary::Create(ls,
{
TDItem("Name", file->metadata[i].first),
TDItem("Index",(int64_t)i)
}
)
);
}
gc->BarrierEnd();
cse.back()->Push(gc, meta);
return false;
}
else if(key == "Sections")
{
TList* sections = TList::Create(ls);
gc->BarrierBegin();
for(auto& item : file->sections)
{
TByteArray* ba = TByteArray::Create(ls);
ba->data = item.second;
sections->Add(TDictionary::Create(ls,{
TDItem("Name", item.first),
TDItem("Data", ba)
}));
}
gc->BarrierEnd();
cse.back()->Push(gc, sections);
return false;
}
else if(key == "SupportedVMs")
{
TList* supported = TList::Create(ls);
gc->BarrierBegin();
if(file->vms.empty())
{
supported->Add(TDictionary::Create(ls,{
TDItem("Name",std::string(VMName)),
TDItem("HowToGet",std::string(VMHowToGet))
}));
}
else {
for(auto item : file->vms)
supported->Add(TDictionary::Create(ls,{
TDItem("Name",item.first),
TDItem("HowToGet",item.second)
}));
}
gc->BarrierEnd();
cse.back()->Push(gc, supported);
return false;
}
else if(key == "Chunks")
{
auto list = TList::Create(ls);
gc->BarrierBegin();
for(auto item : file->chunks)
{
list->Add(item);
}
gc->BarrierEnd();
cse.back()->Push(gc, list);
return false;
}
else if(key == "Classes")
{
auto list = TList::Create(ls);
gc->BarrierBegin();
for(uint32_t i = 0; i < (uint32_t)file->classes.size(); i++)
{
list->Add(GetClassInfo(ls,file,i));
}
cse.back()->Push(gc, list);
gc->BarrierEnd();
return false;
}
else if(key == "Functions")
{
auto list = TList::Create(ls);
gc->BarrierBegin();
for(auto& item : file->functions)
{
TDictionary* dict = TDictionary::Create(ls);
if(!item.first.empty())
dict->SetValue("Documentation", item.first[0]);
TList* nameParts = TList::Create(ls);
for(size_t i = 1; i < item.first.size(); i++)
{
nameParts->Add(item.first[i]);
}
dict->SetValue("NameParts", nameParts);
dict->SetValue("ChunkId", (int64_t)item.second);
list->Add(dict);
}
cse.back()->Push(gc, list);
gc->BarrierEnd();
return false;
}
else if(key == "Icon")
{
if(file->icon >= 0 && file->icon < file->resources.size())
{
TByteArray* ba = TByteArray::Create(ls);
ba->data = file->resources[file->icon];
cse.back()->Push(gc, ba);
return false;
}
else {
cse.back()->Push(gc, nullptr);
return false;
}
}
cse.back()->Push(gc, Undefined());
return false;
}
if(chunk != nullptr)
{
if(key == "Arguments")
{
auto myargs = TList::Create(ls);
gc->BarrierBegin();
for(auto item : chunk->args)
{
myargs->Add(item);
}
gc->BarrierEnd();
cse.back()->Push(gc, myargs);
return false;
}
if(key == "Code")
{
auto ba = TByteArray::Create(ls);
ba->data = chunk->code;
cse.back()->Push(gc, ba);
return false;
}
if(key == "File")
{
cse.back()->Push(gc, chunk->file);
return false;
}
cse.back()->Push(gc, Undefined());
return false;
}
if(callstackEntry != nullptr)
{
if(key == "IP")
{
cse.back()->Push(gc, (int64_t)callstackEntry->ip);
return false;
}
if(key == "IsDone")
{
cse.back()->Push(gc, callstackEntry->ip >= callstackEntry->callable->closure->code.size());
return false;
}
if(key == "Closure")
{
cse.back()->Push(gc, callstackEntry->callable);
return false;
}
if(key == "StackEmpty")
{
cse.back()->Push(gc, callstackEntry->stack.empty());
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(ittr != nullptr)
{
if(key == "Current")
{
cse.back()->Push(gc, ittr->GetCurrent(ls));
return false;
}
cse.back()->Push(gc, Undefined());
return false;
}
if(closure != nullptr)
{
if(key == "Arguments")
{
GCList ls2(gc);
TList* ls = TList::Create(ls2);
for(auto arg : closure->closure->args)
{
ls->Add(arg);
}
cse.back()->Push(gc,ls);
return false;
}
if(key == "File")
{
cse.back()->Push(gc,closure->file);
return false;
}
}
if(externalMethod != nullptr)
{
if(key == "Arguments")
{
GCList ls2(gc);
TList* ls = TList::Create(ls2);
for(auto arg : externalMethod->args)
{
ls->Add(arg);
}
cse.back()->Push(gc,ls);
return false;
}
}
if(tcallable != nullptr)
{
if(key == "Documentation")
{
cse.back()->Push(gc, tcallable->documentation);
return false;
}
if(key == "Tag")
{
gc->BarrierBegin();
cse.back()->Push(gc, tcallable->tag);
gc->BarrierEnd();
return false;
}
cse.back()->Push(gc,Undefined());
return false;
}
if(bA != nullptr)
{
if(key == "Count" || key == "Length")
{
int64_t len = (int64_t)bA->data.size();
if(len < 0) len = 0;
stk->Push(gc, len);
return false;
}
}
if(list != nullptr)
{
if(key == "Count" || key == "Length")
{
int64_t len = list->Count();
if(len < 0) len = 0;
stk->Push(gc, len);
return false;
}
}
if(dynList != nullptr)
{
if(key == "Count" || key == "Length")
{
int64_t len = dynList->Count(ls);
if(len < 0) len = 0;
stk->Push(gc, len);
return false;
}
}
if(dynDict != nullptr)
{
if(dynDict->MethodExists(ls,"get" + key))
{
cse.back()->Push(gc,dynDict->CallMethod(ls,"get" + key, {}));
}
else
{
cse.back()->Push(gc, dynDict->GetField(ls,key));
}
return false;
}
if(dict != nullptr)
{
gc->BarrierBegin();
TObject fn = dict->GetValue("get" + key);
gc->BarrierEnd();
if(std::holds_alternative<THeapObjectHolder>(fn) && dynamic_cast<TCallable*>(std::get<THeapObjectHolder>(fn).obj) != nullptr)
{
return InvokeOne(ls,fn, dict);
}
else
{
gc->BarrierBegin();
fn = dict->GetValue(key);
stk->Push(gc, fn);
gc->BarrierEnd();
return false;
}
}
}
stk->Push(gc, Undefined());
}
return false;
}
}