First commit

This commit is contained in:
2024-12-28 14:38:00 -06:00
commit 9c27f339be
56 changed files with 289761 additions and 0 deletions

90
src/types/closure.cpp Normal file
View File

@ -0,0 +1,90 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TArgWrapper* TArgWrapper::Create(GCList& ls, TCallable* callable)
{
TArgWrapper* argWrapper = new TArgWrapper();
argWrapper->callable = callable;
GC* gc = ls.GetGC();
ls.Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TArgWrapper* TArgWrapper::Create(GCList* ls, TCallable* callable)
{
TArgWrapper* argWrapper = new TArgWrapper();
argWrapper->callable = callable;
GC* gc = ls->GetGC();
ls->Add(argWrapper);
gc->Watch(argWrapper);
return argWrapper;
}
TObject TArgWrapper::Call(GCList& ls,std::vector<TObject> args)
{
auto cse = current_function;
TList* argList = TList::Create(ls);
argList->items = args;
TObject v=this->callable->Call(ls,{argList});
current_function = cse;
return v;
}
void TArgWrapper::Mark()
{
if(this->marked) return;
this->marked = true;
this->callable->Mark();
}
void TClosure::Mark()
{
if(this->marked) return;
this->marked=true;
this->file->Mark();
this->env->Mark();
this->closure->Mark();
}
TClosure* TClosure::Create(GCList& ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
{
TClosure* closure = new TClosure();
closure->ownScope=ownScope;
GC* _gc = ls.GetGC();
ls.Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if(chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId];
else throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
}
TClosure* TClosure::Create(GCList* ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
{
TClosure* closure = new TClosure();
closure->ownScope=ownScope;
GC* _gc = ls->GetGC();
ls->Add(closure);
_gc->Watch(closure);
closure->chunkId = chunkId;
if(chunkId < file->chunks.size())
closure->closure = file->chunks[chunkId];
else throw VMException("ChunkId out of bounds.");
closure->env = env;
closure->file = file;
return closure;
}
TObject TClosure::Call(GCList& ls,std::vector<TObject> args)
{
auto cse = current_function;
InterperterThread* thrd=InterperterThread::Create(ls);
thrd->AddCallStackEntry(ls,this, args);
thrd->Execute(ls.GetGC());
TObject v= thrd->call_stack_entries[0]->Pop(ls);
current_function = cse;
return v;
}
}

108
src/types/dictionary.cpp Normal file
View File

@ -0,0 +1,108 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TObject TDictionary::CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
auto res = this->GetValue(key);
ls.GetGC()->BarrierEnd();
TCallable* callable;
if(GetObjectHeap(res,callable))
{
auto closure = dynamic_cast<TClosure*>(callable);
if(closure != nullptr && !closure->closure->args.empty() && closure->closure->args.front() == "this")
{
std::vector<TObject> args2;
args2.push_back(this);
args2.insert(args2.end(), args.begin(),args.end());
return closure->Call(ls,args2);
}
else
{
return callable->Call(ls,args);
}
}
return Undefined();
}
void TDictionary::DeclareFunction(GC* gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
gc->BarrierBegin();
GCList ls(gc);
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb));
gc->BarrierEnd();
}
void TDictionary::DeclareFunction(GC& gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
gc.BarrierBegin();
GCList ls(gc);
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb));
gc.BarrierEnd();
}
void TDictionary::DeclareFunction(GC* gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
gc->BarrierBegin();
GCList ls(gc);
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
gc->BarrierEnd();
}
void TDictionary::DeclareFunction(GC& gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
gc.BarrierBegin();
GCList ls(gc);
this->SetValue(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
gc.BarrierEnd();
}
TObject TDictionary::GetValue(std::string key)
{
if(this->items.empty()) return Undefined();
for(auto item : this->items)
{
if(item.first == key) return item.second;
}
return Undefined();
}
void TDictionary::SetValue(std::string key, TObject value)
{
if(std::holds_alternative<Undefined>(value))
{
if(this->items.contains(key))
this->items.erase(key);
}
else
{
this->items[key] = value;
}
}
bool TDictionary::HasValue(std::string key)
{
return this->items.contains(key);
}
void TDictionary::Mark()
{
if(this->marked) return;
this->marked = true;
for(auto item : this->items)
{
GC::Mark(item.second);
}
}
TDictionary* TDictionary::Create(GCList* gc)
{
TDictionary* dict=new TDictionary();
GC* _gc = gc->GetGC();
gc->Add(dict);
_gc->Watch(dict);
return dict;
}
TDictionary* TDictionary::Create(GCList& gc)
{
TDictionary* dict=new TDictionary();
GC* _gc = gc.GetGC();
gc.Add(dict);
_gc->Watch(dict);
return dict;
}
};

View File

@ -0,0 +1,54 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TExternalMethod::TExternalMethod(std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::string documentation, std::vector<std::string> argNames,std::function<void()> destroy)
{
this->cb = cb;
this->args = argNames;
this->documentation = documentation;
this->destroy = destroy;
}
TExternalMethod* TExternalMethod::Create(GCList& ls,std::string documentation,std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
auto gc = ls.GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,destroy);
ls.Add(method);
gc->Watch(method);
return method;
}
TExternalMethod* TExternalMethod::Create(GCList* ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
auto gc = ls->GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,destroy);
ls->Add(method);
gc->Watch(method);
return method;
}
TExternalMethod* TExternalMethod::Create(GCList& ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
auto gc = ls.GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,[]()->void{});
ls.Add(method);
gc->Watch(method);
return method;
}
TExternalMethod* TExternalMethod::Create(GCList* ls,std::string documentation, std::vector<std::string> argNames,std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
auto gc = ls->GetGC();
TExternalMethod* method = new TExternalMethod(cb,documentation,argNames,[]()->void{});
ls->Add(method);
gc->Watch(method);
return method;
}
TObject TExternalMethod::Call(GCList& ls, std::vector<TObject> args)
{
if(cb == nullptr) return Undefined();
return this->cb(ls,args);
}
TExternalMethod::~TExternalMethod()
{
if(this->destroy != nullptr)
this->destroy();
}
}

253
src/types/ittr.cpp Normal file
View File

@ -0,0 +1,253 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
bool TCustomEnumerator::MoveNext(GC* ls)
{
GCList ls2(ls);
auto res = this->dict->CallMethod(ls2,"MoveNext",{});
bool out;
if(GetObject(res,out)) return out;
return false;
}
TObject TCustomEnumerator::GetCurrent(GCList& ls)
{
TObject res=Undefined();
ls.GetGC()->BarrierBegin();
auto getCurrent = this->dict->GetValue("getCurrent");
TCallable* call;
if(GetObjectHeap(getCurrent,call))
{
ls.GetGC()->BarrierEnd();
res=call->Call(ls,{});
ls.GetGC()->BarrierBegin();
}else{
res=this->dict->GetValue("Current");
}
ls.GetGC()->BarrierEnd();
return res;
}
void TCustomEnumerator::Mark()
{
if(this->marked) return;
this->dict->Mark();
}
TCustomEnumerator* TCustomEnumerator::Create(GCList* ls, TDictionary* dict)
{
TCustomEnumerator* customEnum = new TCustomEnumerator();
customEnum->dict = dict;
GC* _gc = ls->GetGC();
ls->Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
}
TCustomEnumerator* TCustomEnumerator::Create(GCList& ls, TDictionary* dict)
{
TCustomEnumerator* customEnum = new TCustomEnumerator();
customEnum->dict = dict;
GC* _gc = ls.GetGC();
ls.Add(customEnum);
_gc->Watch(customEnum);
return customEnum;
}
TEnumerator* TEnumerator::CreateFromObject(GCList& ls, TObject obj)
{
std::string str;
TList* mls;
TDictionary* dict;
TEnumerator* enumerator;
if(GetObject(obj,str))
{
return TStringEnumerator::Create(ls, str);
}
else if(GetObjectHeap(obj,mls))
{
return TListEnumerator::Create(ls,mls);
}
else if(GetObjectHeap(obj,dict))
{
auto res=dict->CallMethod(ls,"GetEnumerator",{});
if(GetObjectHeap(res,dict))
{
return TCustomEnumerator::Create(ls,dict);
}
else if(GetObjectHeap(res,enumerator))
{
return enumerator;
}
}
return nullptr;
}
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList& ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
{
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator;
GC* _gc = ls.GetGC();
ls.Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
}
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList* ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
{
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
vfspathe->enumerator = enumerator;
GC* _gc = ls->GetGC();
ls->Add(vfspathe);
_gc->Watch(vfspathe);
return vfspathe;
}
bool TVFSPathEnumerator::MoveNext(GC* ls)
{
return enumerator.MoveNext();
}
TObject TVFSPathEnumerator::GetCurrent(GCList& ls)
{
return enumerator.Current;
}
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList& ls, TDictionary* dict)
{
TDictionaryEnumerator* dicte=new TDictionaryEnumerator();
dicte->dict = dict;
dicte->hasStarted=false;
GC* _gc = ls.GetGC();
ls.Add(dicte);
_gc->Watch(dicte);
return dicte;
}
TDictionaryEnumerator* TDictionaryEnumerator::Create(GCList* ls, TDictionary* dict)
{
TDictionaryEnumerator* dicte=new TDictionaryEnumerator();
dicte->dict = dict;
dicte->hasStarted=false;
GC* _gc = ls->GetGC();
ls->Add(dicte);
_gc->Watch(dicte);
return dicte;
}
bool TDictionaryEnumerator::MoveNext(GC* ls)
{
if(!this->hasStarted)
{
this->hasStarted=true;
this->ittr = this->dict->items.begin();
return !this->dict->items.empty();
}
else
{
this->ittr++;
return this->ittr != this->dict->items.end();
}
}
TObject TDictionaryEnumerator::GetCurrent(GCList& ls)
{
if(!this->hasStarted) return Undefined();
if(this->ittr != this->dict->items.end())
{
ls.GetGC()->BarrierBegin();
std::string key = this->ittr->first;
TObject value = this->ittr->second;
auto kvp = TDictionary::Create(ls);
kvp->SetValue("Key",key);
kvp->SetValue("Value",value);
ls.GetGC()->BarrierEnd();
return kvp;
}
return Undefined();
}
void TDictionaryEnumerator::Mark()
{
if(this->marked) return;
this->marked=true;
this->dict->Mark();
}
TListEnumerator* TListEnumerator::Create(GCList& ls, TList* list)
{
TListEnumerator* liste=new TListEnumerator();
liste->ls = list;
liste->index = -1;
GC* _gc = ls.GetGC();
ls.Add(liste);
_gc->Watch(liste);
return liste;
}
TListEnumerator* TListEnumerator::Create(GCList* ls, TList* list)
{
TListEnumerator* liste=new TListEnumerator();
liste->ls = list;
liste->index = -1;
GC* _gc = ls->GetGC();
ls->Add(liste);
_gc->Watch(liste);
return liste;
}
bool TListEnumerator::MoveNext(GC* ls)
{
this->index++;
return this->index >= 0 && this->index < this->ls->Count();
}
TObject TListEnumerator::GetCurrent(GCList& ls)
{
if(this->index < -1) return nullptr;
if(this->ls->Count() == 0) return nullptr;
if(this->index >= this->ls->Count()) return nullptr;
ls.GetGC()->BarrierBegin();
TObject o = this->ls->Get(index);
ls.GetGC()->BarrierEnd();
return o;
}
void TListEnumerator::Mark()
{
if(this->marked) return;
this->marked = true;
this->ls->Mark();
}
TStringEnumerator* TStringEnumerator::Create(GCList& ls,std::string str)
{
TStringEnumerator* stre=new TStringEnumerator();
stre->str = str;
stre->hasStarted=false;
GC* _gc = ls.GetGC();
ls.Add(stre);
_gc->Watch(stre);
return stre;
}
TStringEnumerator* TStringEnumerator::Create(GCList* ls,std::string str)
{
TStringEnumerator* stre=new TStringEnumerator();
stre->str = str;
stre->hasStarted=false;
GC* _gc = ls->GetGC();
ls->Add(stre);
_gc->Watch(stre);
return stre;
}
bool TStringEnumerator::MoveNext(GC* ls)
{
if(!this->hasStarted)
{
this->hasStarted=true;
this->index = 0;
return !this->str.empty();
}
else
{
if(this->index >= this->str.size()) return false;
this->index++;
return this->index < this->str.size();
}
}
TObject TStringEnumerator::GetCurrent(GCList& ls)
{
if(!this->hasStarted) return nullptr;
if(this->index < this->str.size()) return this->str[this->index];
return nullptr;
}
};

86
src/types/list.cpp Normal file
View File

@ -0,0 +1,86 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TByteArray* TByteArray::Create(GCList& ls)
{
TByteArray* arr=new TByteArray();
GC* _gc = ls.GetGC();
ls.Add(arr);
_gc->Watch(arr);
return arr;
}
TByteArray* TByteArray::Create(GCList* ls)
{
TByteArray* arr=new TByteArray();
GC* _gc = ls->GetGC();
ls->Add(arr);
_gc->Watch(arr);
return arr;
}
TList* TList::Create(GCList* gc)
{
TList* list=new TList();
GC* _gc = gc->GetGC();
gc->Add(list);
_gc->Watch(list);
return list;
}
TList* TList::Create(GCList& gc)
{
TList* list=new TList();
GC* _gc = gc.GetGC();
gc.Add(list);
_gc->Watch(list);
return list;
}
void TList::Add(TObject value)
{
this->items.push_back(value);
}
void TList::Set(int64_t index, TObject value)
{
if(index >= 0 && index < this->Count())
{
this->items[index] = value;
}
}
TObject TList::Get(int64_t index)
{
if(index >= 0 && index < this->Count())
{
return this->items[index];
}
return Undefined();
}
int64_t TList::Count()
{
return (int64_t)this->items.size();
}
void TList::Insert(int64_t index, TObject value)
{
if(index >= 0 && index <= this->Count())
{
this->items.insert(this->items.begin()+index,value);
}
}
void TList::RemoveAt(int64_t index)
{
if(index >= 0 && index < this->Count())
{
this->items.erase(this->items.begin()+index);
}
}
void TList::Clear()
{
this->items.clear();
}
void TList::Mark()
{
if(this->marked) return;
this->marked = true;
for(auto item : this->items)
{
GC::Mark(item);
}
}
};

58
src/types/native.cpp Normal file
View File

@ -0,0 +1,58 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TNative::TNative(void* ptr,std::function<void(void*)> destroy)
{
this->ptr = ptr;
this->destroyed=false;
this->destroy = destroy;
}
bool TNative::GetDestroyed()
{
return this->destroyed;
}
void* TNative::GetPointer()
{
return this->ptr;
}
void TNative::Mark()
{
if(this->marked) return;
this->marked=true;
GC::Mark(this->other);
}
void TNative::Destroy()
{
if(this->destroyed) return;
if(this->destroy != nullptr)
{
this->destroyed=true;
this->destroy(this->ptr);
}
}
TNative* TNative::Create(GCList& ls, void* ptr,std::function<void(void*)> destroy)
{
TNative* native = new TNative(ptr,destroy);
GC* gc = ls.GetGC();
ls.Add(native);
gc->Watch(native);
return native;
}
TNative* TNative::Create(GCList* ls, void* ptr,std::function<void(void*)> destroy)
{
TNative* native = new TNative(ptr,destroy);
GC* gc = ls->GetGC();
ls->Add(native);
gc->Watch(native);
return native;
}
TNative::~TNative()
{
this->Destroy();
}
}

View File

@ -0,0 +1,228 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
void TRootEnvironment::LoadDependency(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, std::pair<std::string,TVMVersion> dep)
{
for(auto item : this->dependencies)
if(item.first == dep.first && item.second.CompareTo(dep.second) >= 0) return;
std::string name = {};
name.append(dep.first);
name.push_back('-');
name.append(dep.second.ToString());
name.append(".crvm");
std::string filename="/" + name;
Tesses::Framework::Streams::Stream* file;
if(vfs->RegularFileExists(filename) && (file = vfs->OpenFile(filename,"rb")) != nullptr)
{
GCList ls(gc);
TFile* f = TFile::Create(ls);
f->Load(gc, file);
LoadFileWithDependencies(gc, vfs, f);
}
else throw VMException("Could not open file: \"" + name + "\".");
}
TObject TEnvironment::Eval(GCList& ls,std::string code)
{
std::stringstream strm(code);
std::vector<LexToken> tokens;
int res =Lex("eval.tcross",strm,tokens);
if(res != 0)
{
throw VMException("Lex error at line: " + std::to_string(res));
}
Parser parser(tokens);
SyntaxNode n = parser.ParseRoot();
CodeGen gen;
gen.GenRoot(n);
Tesses::Framework::Streams::MemoryStream ms(true);
gen.Save(nullptr, &ms);
ms.Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
TFile* f = TFile::Create(ls);
f->Load(ls.GetGC(),&ms);
return this->LoadFile(ls.GetGC(), f);
}
TObject TEnvironment::LoadFile(GC* gc, TFile* file)
{
for(auto fn : file->functions)
{
std::string name;
if(fn.first.size() < 2) throw VMException("No function name.");
std::vector<std::string> items(fn.first.begin()+1, fn.first.end());
if(fn.second >= file->chunks.size()) throw VMException("ChunkId out of bounds.");
TFileChunk* chunk = file->chunks[fn.second];
if(items.size() == 0)
throw VMException("Function name can't be empty.");
else if(items.size() == 1)
{
GCList ls(gc);
TClosure* closure=TClosure::Create(ls,this,file,fn.second);
closure->documentation = fn.first[0];
gc->BarrierBegin();
this->DeclareVariable(items[0],closure);
gc->BarrierEnd();
}
else
{
GCList ls(gc);
TClosure* closure=TClosure::Create(ls,this,file,fn.second);
closure->documentation = fn.first[0];
TObject v = this->GetVariable(items[0]);
TDictionary* dict=nullptr;
if(std::holds_alternative<THeapObjectHolder>(v))
{
dict=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
if(dict == nullptr)
{
dict = TDictionary::Create(ls);
gc->BarrierBegin();
this->SetVariable(items[0],dict);
gc->BarrierEnd();
}
}
else
{
dict = TDictionary::Create(ls);
gc->BarrierBegin();
this->DeclareVariable(items[0],dict);
gc->BarrierEnd();
}
for(size_t i = 1; i < items.size()-1; i++)
{
gc->BarrierBegin();
auto v = dict->GetValue(items[i]);
gc->BarrierEnd();
if(std::holds_alternative<THeapObjectHolder>(v))
{
auto dict2=dynamic_cast<TDictionary*>(std::get<THeapObjectHolder>(v).obj);
if(dict2 == nullptr)
{
dict2 = TDictionary::Create(ls);
gc->BarrierBegin();
dict->SetValue(items[i],dict2);
gc->BarrierEnd();
}
dict = dict2;
}
else
{
auto dict2 = TDictionary::Create(ls);
gc->BarrierBegin();
dict->SetValue(items[i],dict2);
gc->BarrierEnd();
dict = dict2;
}
}
gc->BarrierBegin();
dict->SetValue(items[items.size()-1],closure);
gc->BarrierEnd();
}
}
if(!file->chunks.empty())
{
GCList ls(gc);
TClosure* closure=TClosure::Create(ls,this,file,0);
return closure->Call(ls,{});
}
return nullptr;
}
void TRootEnvironment::LoadFileWithDependencies(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, TFile* file)
{
this->dependencies.push_back(std::pair<std::string,TVMVersion>(file->name,file->version));
for(auto item : file->dependencies)
{
LoadDependency(gc,vfs,item);
}
LoadFile(gc, file);
}
void TRootEnvironment::LoadFileWithDependencies(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path)
{
Tesses::Framework::Streams::Stream* file;
if(vfs->RegularFileExists(path) && (file = vfs->OpenFile(path,"rb")) != nullptr)
{
GCList ls(gc);
TFile* f = TFile::Create(ls);
f->Load(gc, file);
Tesses::Framework::Filesystem::SubdirFilesystem dir(vfs,path.GetParent(),false);
LoadFileWithDependencies(gc,vfs,f);
}
else throw VMException("Could not open file: \"" + path.GetFileName() + "\".");
}
TDictionary* TRootEnvironment::GetDictionary()
{
return this->dict;
}
TObject TRootEnvironment::GetVariable(std::string key)
{
return this->dict->GetValue(key);
}
void TRootEnvironment::SetVariable(std::string key, TObject value)
{
return this->dict->SetValue(key,value);
}
void TRootEnvironment::DeclareVariable(std::string key, TObject value)
{
return this->dict->SetValue(key,value);
}
bool TRootEnvironment::HasVariable(std::string key)
{
return this->dict->HasValue(key);
}
bool TRootEnvironment::HasVariableRecurse(std::string key)
{
return this->dict->HasValue(key);
}
TEnvironment* TRootEnvironment::GetParentEnvironment()
{
return this;
}
TRootEnvironment* TRootEnvironment::GetRootEnvironment()
{
return this;
}
TRootEnvironment::TRootEnvironment(TDictionary* dict)
{
this->dict = dict;
}
void TRootEnvironment::Mark()
{
if(this->marked) return;
this->marked = true;
this->dict->Mark();
for(auto defer : this->defers) defer->Mark();
}
TRootEnvironment* TRootEnvironment::Create(GCList* gc,TDictionary* dict)
{
TRootEnvironment* env=new TRootEnvironment(dict);
GC* _gc = gc->GetGC();
gc->Add(env);
_gc->Watch(env);
return env;
}
TRootEnvironment* TRootEnvironment::Create(GCList& gc,TDictionary* dict)
{
TRootEnvironment* env=new TRootEnvironment(dict);
GC* _gc = gc.GetGC();
gc.Add(env);
_gc->Watch(env);
return env;
}
};

View File

@ -0,0 +1,281 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
int64_t TObjectStream::_GetPosInternal()
{
return Tesses::Framework::Streams::Stream::GetLength();
}
TObjectStream::TObjectStream(GC* gc, TObject obj)
{
this->ls = new GCList(gc);
this->ls->Add(obj);
TDictionary* dict;
if(GetObjectHeap(obj,dict))
{
gc->BarrierBegin();
if(!dict->HasValue("Read"))
{
dict->DeclareFunction(gc,"Read","Read from stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return (int64_t)0;
});
}
if(!dict->HasValue("Write"))
{
dict->DeclareFunction(gc,"Write","Write to stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return (int64_t)0;
});
}
if(!dict->HasValue("getCanRead"))
{
dict->DeclareFunction(gc,"getCanRead","Can read from stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("getCanWrite"))
{
dict->DeclareFunction(gc,"getCanWrite","Can write to stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("getCanSeek"))
{
dict->DeclareFunction(gc,"getCanSeek","Can seek in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("getPosition"))
{
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
return (int64_t)0;
});
}
if(!dict->HasValue("getLength"))
{
dict->DeclareFunction(gc,"getPosition","Can get position in stream",{}, [this](GCList& ls, std::vector<TObject> args)->TObject {
return _GetPosInternal();
});
}
if(!dict->HasValue("getEndOfStream"))
{
dict->DeclareFunction(gc,"getEndOfStream","Is at end of stream",{}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
gc->BarrierEnd();
}
}
bool TObjectStream::EndOfStream()
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
bool r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->EndOfStream();
}
return false;
}
size_t TObjectStream::Read(uint8_t* buff, size_t sz)
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
GCList ls2(this->ls->GetGC());
TByteArray* arr=TByteArray::Create(ls2);
arr->data.resize(sz);
auto res = dict->CallMethod(ls2, "Read",{arr, (int64_t)0L, (int64_t)sz});
memcpy(buff,arr->data.data(),std::min(sz,arr->data.size()));
int64_t r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->Read(buff,sz);
}
return 0;
}
size_t TObjectStream::Write(const uint8_t* buff, size_t sz)
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
GCList ls2(this->ls->GetGC());
TByteArray* arr=TByteArray::Create(ls2);
arr->data.resize(sz);
memcpy(arr->data.data(), buff, sz);
auto res = dict->CallMethod(ls2, "Write",{arr, (int64_t)0L, (int64_t)sz});
int64_t r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->Write(buff,sz);
}
return 0;
}
bool TObjectStream::CanRead()
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getCanRead",{});
bool r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->CanRead();
}
return false;
}
bool TObjectStream::CanWrite()
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getCanWrite",{});
bool r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->CanWrite();
}
return false;
}
bool TObjectStream::CanSeek()
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getCanSeek",{});
bool r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->CanSeek();
}
return false;
}
int64_t TObjectStream::GetPosition()
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getPosition",{});
int64_t r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->GetPosition();
}
return 0;
}
int64_t TObjectStream::GetLength()
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
bool r;
if(GetObject(res,r)) return r;
}
else if(GetObjectHeap(this->obj, strm))
{
return strm->stream->GetLength();
}
return Tesses::Framework::Streams::Stream::GetLength();
}
void TObjectStream::Flush()
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls, "Flush",{});
}
else if(GetObjectHeap(this->obj, strm))
{
strm->stream->Flush();
}
}
void TObjectStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
{
TDictionary* dict;
TStreamHeapObject* strm;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls, "Seek",{pos,(int64_t)(whence == Tesses::Framework::Streams::SeekOrigin::Begin ? 0 : whence == Tesses::Framework::Streams::SeekOrigin::Current ? 1 : 2) });
}
else if(GetObjectHeap(this->obj, strm))
{
strm->stream->Seek(pos,whence);
}
}
TObjectStream::~TObjectStream()
{
delete this->ls;
}
TStreamHeapObject* TStreamHeapObject::Create(GCList& ls, Tesses::Framework::Streams::Stream* strm)
{
TStreamHeapObject* heapObj = new TStreamHeapObject();
GC* _gc = ls.GetGC();
ls.Add(heapObj);
_gc->Watch(heapObj);
heapObj->stream = strm;
return heapObj;
}
TStreamHeapObject* TStreamHeapObject::Create(GCList* ls, Tesses::Framework::Streams::Stream* strm)
{
TStreamHeapObject* heapObj = new TStreamHeapObject();
GC* _gc = ls->GetGC();
ls->Add(heapObj);
_gc->Watch(heapObj);
heapObj->stream = strm;
return heapObj;
}
TStreamHeapObject::~TStreamHeapObject()
{
if(this->stream != nullptr)
{
delete this->stream;
}
}
void TStreamHeapObject::Close()
{
if(this->stream != nullptr)
{
delete this->stream;
this->stream = nullptr;
}
}
}

View File

@ -0,0 +1,147 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TObject TSubEnvironment::GetVariable(std::string key)
{
if(this->dict->HasValue(key))
{
return this->dict->GetValue(key);
}
if(this->env->HasVariableRecurse(key))
{
return this->env->GetVariable(key);
}
return Undefined();
}
void TSubEnvironment::DeclareVariable(std::string key,TObject value)
{
this->dict->SetValue(key,value);
}
void TSubEnvironment::SetVariable(std::string key, TObject value)
{
if(this->dict->HasValue(key))
{
this->dict->SetValue(key,value);
return;
}
if(this->env->HasVariableRecurse(key))
{
this->env->SetVariable(key,value);
}
else
{
this->dict->SetValue(key,value);
}
}
bool TSubEnvironment::HasVariable(std::string key)
{
return this->dict->HasValue(key);
}
bool TSubEnvironment::HasVariableRecurse(std::string key)
{
if(this->dict->HasValue(key)) return true;
return this->env->HasVariableRecurse(key);
}
TSubEnvironment::TSubEnvironment(TEnvironment* env,TDictionary* dict)
{
this->env = env;
this->dict = dict;
}
TSubEnvironment* TEnvironment::GetSubEnvironment(TDictionary* dict)
{
TSubEnvironment* subEnv = new TSubEnvironment(this,dict);
return subEnv;
}
TObject TEnvironment::CallFunction(GCList& ls, std::string key, std::vector<TObject> args)
{
ls.GetGC()->BarrierBegin();
auto res = this->GetVariable(key);
ls.GetGC()->BarrierEnd();
TCallable* callable;
if(GetObjectHeap(res,callable))
{
return callable->Call(ls,args);
}
return Undefined();
}
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList* gc)
{
auto dict=TDictionary::Create(gc);
TSubEnvironment* sEnv = this->GetSubEnvironment(dict);
GC* _gc = gc->GetGC();
gc->Add(sEnv);
_gc->Watch(sEnv);
return sEnv;
}
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList& gc)
{
auto dict=TDictionary::Create(gc);
TSubEnvironment* sEnv = this->GetSubEnvironment(dict);
GC* _gc = gc.GetGC();
gc.Add(sEnv);
_gc->Watch(sEnv);
return sEnv;
}
TSubEnvironment* TSubEnvironment::Create(GCList* gc, TEnvironment* env, TDictionary* dict)
{
TSubEnvironment* senv = new TSubEnvironment(env,dict);
GC* _gc = gc->GetGC();
gc->Add(senv);
_gc->Watch(senv);
return senv;
}
TSubEnvironment* TSubEnvironment::Create(GCList& gc, TEnvironment* env, TDictionary* dict)
{
TSubEnvironment* senv = new TSubEnvironment(env,dict);
GC* _gc = gc.GetGC();
gc.Add(senv);
_gc->Watch(senv);
return senv;
}
TEnvironment* TSubEnvironment::GetParentEnvironment()
{
return this->env;
}
TRootEnvironment* TSubEnvironment::GetRootEnvironment()
{
return this->env->GetRootEnvironment();
}
void TSubEnvironment::Mark()
{
if(this->marked) return;
this->marked=true;
this->dict->Mark();
this->env->Mark();
for(auto defer : defers) defer->Mark();
}
void TEnvironment::DeclareFunction(GC* gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
gc->BarrierBegin();
GCList ls(gc);
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb));
gc->BarrierEnd();
}
void TEnvironment::DeclareFunction(GC& gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb)
{
gc.BarrierBegin();
GCList ls(gc);
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb));
gc.BarrierEnd();
}
void TEnvironment::DeclareFunction(GC* gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
gc->BarrierBegin();
GCList ls(gc);
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
gc->BarrierEnd();
}
void TEnvironment::DeclareFunction(GC& gc,std::string key,std::string documentation, std::vector<std::string> argNames, std::function<TObject(GCList& ls, std::vector<TObject> args)> cb,std::function<void()> destroy)
{
gc.BarrierBegin();
GCList ls(gc);
this->DeclareVariable(key, TExternalMethod::Create(ls,documentation,argNames,cb,destroy));
gc.BarrierEnd();
}
};

626
src/types/vfsheapobject.cpp Normal file
View File

@ -0,0 +1,626 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang {
TObjectVFS::TObjectVFS(GC* gc, TObject obj)
{
this->ls = new GCList(gc);
this->ls->Add(obj);
this->obj = obj;
TDictionary* dict;
if(GetObjectHeap(obj,dict))
{
gc->BarrierBegin();
if(!dict->HasValue("OpenFile"))
{
dict->DeclareFunction(gc,"OpenFile","Open a file",{"path","mode"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return nullptr;
});
}
if(!dict->HasValue("EnumeratePaths"))
{
dict->DeclareFunction(gc,"EnumeratePaths","Enumerate paths",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return TVFSPathEnumerator::Create(ls,Tesses::Framework::Filesystem::VFSPathEnumerator());
});
}
if(!dict->HasValue("ReadLink"))
{
dict->DeclareFunction(gc,"ReadLink","Read a symlink",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return Tesses::Framework::Filesystem::VFSPath();
});
}
if(!dict->HasValue("VFSPathToSystem"))
{
dict->DeclareFunction(gc,"VFSPathToSystem","Convert path to system",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
Tesses::Framework::Filesystem::VFSPath path;
if(GetArgumentAsPath(args,0,path))
{
return path.ToString();
}
return "/";
});
}
if(!dict->HasValue("SystemToVFSPath"))
{
dict->DeclareFunction(gc,"SystemToVFSPath","Convert system to path",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
std::string p;
if(GetArgument(args,0,p))
{
return Tesses::Framework::Filesystem::VFSPath(p);
}
return Tesses::Framework::Filesystem::VFSPath();
});
}
if(!dict->HasValue("GetDate"))
{
dict->DeclareFunction(gc,"GetDate","Get date from file",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
auto dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("LastWrite", (int64_t)time(NULL));
dict->SetValue("LastAccess", (int64_t)time(NULL));
ls.GetGC()->BarrierEnd();
return dict;
});
}
if(!dict->HasValue("RegularFileExists"))
{
dict->DeclareFunction(gc,"RegularFileExists","Regular file exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("SymlinkExists"))
{
dict->DeclareFunction(gc,"SymlinkExists","Symlink exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("CharacterDeviceExists"))
{
dict->DeclareFunction(gc,"CharacterDeviceExists","Character file exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("BlockDeviceExists"))
{
dict->DeclareFunction(gc,"BlockDeviceExists","Block file exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("SocketFileExists"))
{
dict->DeclareFunction(gc,"SocketFileExists","Socket file exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("FIFOFileExists"))
{
dict->DeclareFunction(gc,"FIFOFileExists","FIFO file exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("FileExists"))
{
dict->DeclareFunction(gc,"FileExists","File exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("SpecialFileExists"))
{
dict->DeclareFunction(gc,"SpecialFileExists","Special file exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
if(!dict->HasValue("DirectoryExists"))
{
dict->DeclareFunction(gc,"DirectoryExists","Directory exists",{"path"}, [](GCList& ls, std::vector<TObject> args)->TObject {
return false;
});
}
gc->BarrierEnd();
}
}
Tesses::Framework::Streams::Stream* TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->OpenFile(path,mode);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "OpenFile",{path,mode});
TStreamHeapObject* strm;
if(GetObjectHeap(res,strm))
{
return new TObjectStream(this->ls->GetGC(), strm);
}
}
return nullptr;
}
void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->CreateDirectory(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateDirectory",{path});
}
}
void TObjectVFS::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->DeleteDirectory(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteDirectory",{path});
}
}
bool TObjectVFS::RegularFileExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->RegularFileExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "RegularFileExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
bool TObjectVFS::SymlinkExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->SymlinkExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "SymlinkExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
bool TObjectVFS::CharacterDeviceExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->CharacterDeviceExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "CharacterDeviceExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
bool TObjectVFS::BlockDeviceExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->BlockDeviceExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "BlockDeviceExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
bool TObjectVFS::SocketFileExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->SocketFileExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "SocketFileExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
bool TObjectVFS::FIFOFileExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->FIFOFileExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "FIFOFileExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
bool TObjectVFS::FileExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->FileExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "FileExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
bool TObjectVFS::SpecialFileExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->SpecialFileExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "SpecialFileExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
void TObjectVFS::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->CreateSymlink(existingFile,symlinkFile);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateSymlink",{existingFile,symlinkFile});
}
}
void TObjectVFS::CreateHardlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath newName)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->CreateHardlink(existingFile,newName);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "CreateHardlink",{existingFile,newName});
}
}
bool TObjectVFS::DirectoryExists(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->DirectoryExists(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "DirectoryExists",{path});
bool out;
if(GetObject(res,out))
{
return out;
}
}
}
void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->DeleteFile(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteFile",{path});
}
}
void TObjectVFS::DeleteDirectoryRecurse(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->DeleteDirectoryRecurse(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "DeleteDirectoryRecurse",{path});
}
}
Tesses::Framework::Filesystem::VFSPathEnumerator TObjectVFS::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->EnumeratePaths(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList* ls=new GCList(this->ls->GetGC());
auto res = dict->CallMethod(*ls, "EnumeratePaths",{path});
auto enumerator = TEnumerator::CreateFromObject(*ls,res);
return Tesses::Framework::Filesystem::VFSPathEnumerator([path,enumerator,ls](Tesses::Framework::Filesystem::VFSPath& path0)->bool{
if(enumerator == nullptr) return false;
while(enumerator->MoveNext(ls->GetGC()))
{
auto res = enumerator->GetCurrent(*ls);
std::string name;
Tesses::Framework::Filesystem::VFSPath path1;
if(GetObject(res,path1))
{
path0 = path1;
return true;
}
else if(GetObject(res,name))
{
path0 = path / name;
return true;
}
}
return false;
},[ls]()->void{
delete ls;
});
}
}
void TObjectVFS::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->MoveFile(src,dest);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "MoveFile",{src,dest});
}
}
void TObjectVFS::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->MoveDirectory(src,dest);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "MoveDirectory",{src,dest});
}
}
Tesses::Framework::Filesystem::VFSPath TObjectVFS::ReadLink(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->ReadLink(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "ReadLink",{path});
Tesses::Framework::Filesystem::VFSPath myPath;
if(GetObject(res,myPath))
{
return myPath;
}
}
return Tesses::Framework::Filesystem::VFSPath();
}
std::string TObjectVFS::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->VFSPathToSystem(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "VFSPathToSystem",{path});
std::string myPath;
if(GetObject(res,myPath))
{
return myPath;
}
}
return "/";
}
Tesses::Framework::Filesystem::VFSPath TObjectVFS::SystemToVFSPath(std::string path)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
return vfs->vfs->SystemToVFSPath(path);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "SystemToVFSPath",{path});
Tesses::Framework::Filesystem::VFSPath myPath;
if(GetObject(res,myPath))
{
return myPath;
}
}
return Tesses::Framework::Filesystem::VFSPath();
}
void TObjectVFS::GetDate(Tesses::Framework::Filesystem::VFSPath path, time_t& lastWrite, time_t& lastAccess)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->GetDate(path,lastWrite,lastAccess);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
auto res = dict->CallMethod(ls, "GetDate",{path});
if(GetObjectHeap(res,dict))
{
this->ls->GetGC()->BarrierBegin();
res = dict->GetValue("LastWrite");
int64_t v;
if(GetObject(res,v)) lastWrite=(time_t)v;
res = dict->GetValue("LastAccess");
if(GetObject(res,v)) lastAccess=(time_t)v;
this->ls->GetGC()->BarrierEnd();
}
}
}
void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path, time_t lastWrite, time_t lastAccess)
{
TVFSHeapObject* vfs;
TDictionary* dict;
if(GetObjectHeap(this->obj, vfs))
{
vfs->vfs->SetDate(path,lastWrite,lastAccess);
}
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls, "SetDate",{path,(int64_t)lastWrite,(int64_t)lastAccess});
}
}
TObjectVFS::~TObjectVFS()
{
delete this->ls;
}
TVFSHeapObject* TVFSHeapObject::Create(GCList& ls, Tesses::Framework::Filesystem::VFS* vfs)
{
TVFSHeapObject* heapObj = new TVFSHeapObject();
GC* _gc = ls.GetGC();
ls.Add(heapObj);
_gc->Watch(heapObj);
heapObj->vfs = vfs;
return heapObj;
}
TVFSHeapObject* TVFSHeapObject::Create(GCList* ls, Tesses::Framework::Filesystem::VFS* vfs)
{
TVFSHeapObject* heapObj = new TVFSHeapObject();
GC* _gc = ls->GetGC();
ls->Add(heapObj);
_gc->Watch(heapObj);
heapObj->vfs = vfs;
return heapObj;
}
TVFSHeapObject::~TVFSHeapObject()
{
if(this->vfs != nullptr)
delete this->vfs;
}
void TVFSHeapObject::Close()
{
if(this->vfs != nullptr)
{
delete this->vfs;
this->vfs = nullptr;
}
}
}