First commit
This commit is contained in:
90
src/types/closure.cpp
Normal file
90
src/types/closure.cpp
Normal 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
108
src/types/dictionary.cpp
Normal 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;
|
||||
}
|
||||
};
|
||||
54
src/types/externalmethod.cpp
Normal file
54
src/types/externalmethod.cpp
Normal 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
253
src/types/ittr.cpp
Normal 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
86
src/types/list.cpp
Normal 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
58
src/types/native.cpp
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
228
src/types/rootenvironment.cpp
Normal file
228
src/types/rootenvironment.cpp
Normal 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;
|
||||
}
|
||||
};
|
||||
281
src/types/streamheapobject.cpp
Normal file
281
src/types/streamheapobject.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
147
src/types/subenvironment.cpp
Normal file
147
src/types/subenvironment.cpp
Normal 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
626
src/types/vfsheapobject.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user