Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
This commit is contained in:
+23
-25
@@ -1,28 +1,26 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
TAny* TAny::Create(GCList& ls)
|
||||
{
|
||||
TAny* anyObj = new TAny();
|
||||
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(anyObj);
|
||||
gc->Watch(anyObj);
|
||||
return anyObj;
|
||||
}
|
||||
TAny* TAny::Create(GCList* ls)
|
||||
{
|
||||
TAny* anyObj = new TAny();
|
||||
|
||||
std::shared_ptr<GC> gc = ls->GetGC();
|
||||
ls->Add(anyObj);
|
||||
gc->Watch(anyObj);
|
||||
return anyObj;
|
||||
}
|
||||
void TAny::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
GC::Mark(this->other);
|
||||
}
|
||||
}
|
||||
TAny *TAny::Create(GCList &ls) {
|
||||
TAny *anyObj = new TAny();
|
||||
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(anyObj);
|
||||
gc->Watch(anyObj);
|
||||
return anyObj;
|
||||
}
|
||||
TAny *TAny::Create(GCList *ls) {
|
||||
TAny *anyObj = new TAny();
|
||||
|
||||
std::shared_ptr<GC> gc = ls->GetGC();
|
||||
ls->Add(anyObj);
|
||||
gc->Watch(anyObj);
|
||||
return anyObj;
|
||||
}
|
||||
void TAny::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->other);
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+89
-109
@@ -1,116 +1,96 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
|
||||
TAssociativeArray* TAssociativeArray::Create(GCList& ls)
|
||||
{
|
||||
TAssociativeArray* list=new TAssociativeArray();
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TAssociativeArray* TAssociativeArray::Create(GCList* ls)
|
||||
{
|
||||
TAssociativeArray* list=new TAssociativeArray();
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key, TObject value)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(key)) return;
|
||||
gc->BarrierBegin();
|
||||
for(auto index = this->items.begin(); index < this->items.end(); index++)
|
||||
{
|
||||
auto first= index->first;
|
||||
gc->BarrierEnd();
|
||||
auto eq = Equals(gc,key,first);
|
||||
gc->BarrierBegin();
|
||||
if(eq)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(value))
|
||||
{
|
||||
this->items.erase(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
index->second = value;
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->items.push_back(std::pair<TObject,TObject>(key,value));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
TObject TAssociativeArray::Get(std::shared_ptr<GC> gc, TObject key)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(key)) return Undefined();
|
||||
gc->BarrierBegin();
|
||||
for(auto& item : this->items)
|
||||
{
|
||||
auto first= item.first;
|
||||
gc->BarrierEnd();
|
||||
auto eq = Equals(gc,key,first);
|
||||
gc->BarrierBegin();
|
||||
if(eq)
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
return item.second;
|
||||
}
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
return Undefined();
|
||||
}
|
||||
TObject TAssociativeArray::GetKey(int64_t index)
|
||||
{
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
return this->items[index].first;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject TAssociativeArray::GetValue(int64_t index)
|
||||
{
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
return this->items[index].second;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TAssociativeArray::SetKey(int64_t index, TObject key)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
if(std::holds_alternative<Undefined>(key)) return;
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
this->items[index].first=key;
|
||||
}
|
||||
|
||||
}
|
||||
void TAssociativeArray::SetValue(int64_t index,TObject value)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(value)) return;
|
||||
if(index >= 0 && index < (int64_t)this->items.size())
|
||||
{
|
||||
this->items[index].first=value;
|
||||
TAssociativeArray *TAssociativeArray::Create(GCList &ls) {
|
||||
TAssociativeArray *list = new TAssociativeArray();
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TAssociativeArray *TAssociativeArray::Create(GCList *ls) {
|
||||
TAssociativeArray *list = new TAssociativeArray();
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
void TAssociativeArray::Set(std::shared_ptr<GC> gc, TObject key,
|
||||
TObject value) {
|
||||
if (std::holds_alternative<Undefined>(key))
|
||||
return;
|
||||
gc->BarrierBegin();
|
||||
for (auto index = this->items.begin(); index < this->items.end(); index++) {
|
||||
auto first = index->first;
|
||||
gc->BarrierEnd();
|
||||
auto eq = Equals(gc, key, first);
|
||||
gc->BarrierBegin();
|
||||
if (eq) {
|
||||
if (std::holds_alternative<Undefined>(value)) {
|
||||
this->items.erase(index);
|
||||
} else {
|
||||
index->second = value;
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
}
|
||||
int64_t TAssociativeArray::Count()
|
||||
{
|
||||
return (int64_t)this->items.size();
|
||||
}
|
||||
void TAssociativeArray::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
for(auto& item : this->items)
|
||||
{
|
||||
GC::Mark(item.first);
|
||||
GC::Mark(item.second);
|
||||
this->items.push_back(std::pair<TObject, TObject>(key, value));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
TObject TAssociativeArray::Get(std::shared_ptr<GC> gc, TObject key) {
|
||||
if (std::holds_alternative<Undefined>(key))
|
||||
return Undefined();
|
||||
gc->BarrierBegin();
|
||||
for (auto &item : this->items) {
|
||||
auto first = item.first;
|
||||
gc->BarrierEnd();
|
||||
auto eq = Equals(gc, key, first);
|
||||
gc->BarrierBegin();
|
||||
if (eq) {
|
||||
gc->BarrierEnd();
|
||||
return item.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
return Undefined();
|
||||
}
|
||||
TObject TAssociativeArray::GetKey(int64_t index) {
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
return this->items[index].first;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject TAssociativeArray::GetValue(int64_t index) {
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
return this->items[index].second;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TAssociativeArray::SetKey(int64_t index, TObject key) {
|
||||
|
||||
if (std::holds_alternative<Undefined>(key))
|
||||
return;
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
this->items[index].first = key;
|
||||
}
|
||||
}
|
||||
void TAssociativeArray::SetValue(int64_t index, TObject value) {
|
||||
if (std::holds_alternative<Undefined>(value))
|
||||
return;
|
||||
if (index >= 0 && index < (int64_t)this->items.size()) {
|
||||
this->items[index].first = value;
|
||||
}
|
||||
}
|
||||
int64_t TAssociativeArray::Count() { return (int64_t)this->items.size(); }
|
||||
void TAssociativeArray::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
for (auto &item : this->items) {
|
||||
GC::Mark(item.first);
|
||||
GC::Mark(item.second);
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+199
-232
@@ -1,261 +1,228 @@
|
||||
#include "CrossLang.hpp"
|
||||
//THANKS TO https://www.youtube.com/watch?v=R-z2Hv-7nxk
|
||||
// THANKS TO https://www.youtube.com/watch?v=R-z2Hv-7nxk
|
||||
namespace Tesses::CrossLang {
|
||||
TTask::TTask(std::shared_ptr<GC> gc)
|
||||
{
|
||||
this->gc = gc;
|
||||
}
|
||||
TTask* TTask::Create(GCList& ls)
|
||||
{
|
||||
TTask* task = new TTask(ls.GetGC());
|
||||
ls.Add(task);
|
||||
task->gc->Watch(task);
|
||||
return task;
|
||||
}
|
||||
bool TTask::IsCompleted()
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
bool r = this->isCompleted;
|
||||
gc->BarrierEnd();
|
||||
TTask::TTask(std::shared_ptr<GC> gc) { this->gc = gc; }
|
||||
TTask *TTask::Create(GCList &ls) {
|
||||
TTask *task = new TTask(ls.GetGC());
|
||||
ls.Add(task);
|
||||
task->gc->Watch(task);
|
||||
return task;
|
||||
}
|
||||
bool TTask::IsCompleted() {
|
||||
gc->BarrierBegin();
|
||||
bool r = this->isCompleted;
|
||||
gc->BarrierEnd();
|
||||
|
||||
return r;
|
||||
}
|
||||
TTask* TTask::ContinueWith(GCList& ls, TCallable* callable)
|
||||
{
|
||||
TTask* task = TTask::Create(ls);
|
||||
return r;
|
||||
}
|
||||
TTask *TTask::ContinueWith(GCList &ls, TCallable *callable) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
|
||||
TExternalMethod* em = TExternalMethod::Create(ls,"Internal async thing",{"_asyncObj"},[callable,task](GCList& ls,std::vector<TObject> args)->TObject{
|
||||
TExternalMethod *em = TExternalMethod::Create(
|
||||
ls, "Internal async thing", {"_asyncObj"},
|
||||
[callable, task](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
try {
|
||||
task->SetSucceeded(callable->Call(ls,args));
|
||||
} catch(...) {
|
||||
task->SetSucceeded(callable->Call(ls, args));
|
||||
} catch (...) {
|
||||
task->SetFailed(std::current_exception());
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
em->watch = {callable,task};
|
||||
|
||||
this->gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
this->gc->BarrierEnd();
|
||||
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
|
||||
auto cobj = this->obj;
|
||||
ls->Add(cobj);
|
||||
ls->Add(em);
|
||||
this->gc->GetPool()->Schedule([ls,em,cobj](size_t s)->void {
|
||||
em->Call(*ls,{cobj});
|
||||
});
|
||||
return task;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->cont = em;
|
||||
}
|
||||
em->watch = {callable, task};
|
||||
|
||||
this->gc->BarrierBegin();
|
||||
if (this->isCompleted) {
|
||||
this->gc->BarrierEnd();
|
||||
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||
auto cobj = this->obj;
|
||||
ls->Add(cobj);
|
||||
ls->Add(em);
|
||||
this->gc->GetPool()->Schedule(
|
||||
[ls, em, cobj](size_t s) -> void { em->Call(*ls, {cobj}); });
|
||||
return task;
|
||||
} else {
|
||||
this->cont = em;
|
||||
}
|
||||
void TTask::ContinueWith(TCallable* callable)
|
||||
{
|
||||
this->gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
this->gc->BarrierEnd();
|
||||
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
|
||||
auto cobj = this->obj;
|
||||
ls->Add(cobj);
|
||||
ls->Add(callable);
|
||||
this->gc->GetPool()->Schedule([ls,callable,cobj](size_t s)->void {
|
||||
callable->Call(*ls,{cobj});
|
||||
|
||||
});
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->cont = callable;
|
||||
}
|
||||
|
||||
this->gc->BarrierEnd();
|
||||
return task;
|
||||
}
|
||||
void TTask::ContinueWith(TCallable *callable) {
|
||||
this->gc->BarrierBegin();
|
||||
if (this->isCompleted) {
|
||||
this->gc->BarrierEnd();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TTask::SetFailed(std::exception_ptr ex)
|
||||
{
|
||||
this->ex = ex;
|
||||
this->SetSucceeded(nullptr);
|
||||
}
|
||||
void TTask::SetSucceeded(TObject v)
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
this->isCompleted=true;
|
||||
this->obj = v;
|
||||
auto cont = this->cont;
|
||||
gc->BarrierEnd();
|
||||
if(cont != nullptr)
|
||||
{
|
||||
std::shared_ptr<GCList> ls=std::make_shared<GCList>(gc);
|
||||
|
||||
auto callable = cont;
|
||||
ls->Add(v);
|
||||
ls->Add(callable);
|
||||
this->gc->GetPool()->Schedule([ls,callable,v](size_t s)->void {
|
||||
callable->Call(*ls,{v});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
TObject TTask::Wait()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
if(this->isCompleted)
|
||||
{
|
||||
if(this->ex)
|
||||
{
|
||||
auto error = this->ex;
|
||||
gc->BarrierEnd();
|
||||
std::rethrow_exception(error);
|
||||
}
|
||||
|
||||
auto o = this->obj;
|
||||
gc->BarrierEnd();
|
||||
return o;
|
||||
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
void TTask::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
GC::Mark(this->obj);
|
||||
if(this->cont != nullptr)
|
||||
this->cont->Mark();
|
||||
}
|
||||
|
||||
TTask* TTask::Run(GCList& ls, TCallable* callable)
|
||||
{
|
||||
TTask* task = TTask::Create(ls);
|
||||
std::shared_ptr<GCList> ls2=std::make_shared<GCList>(ls.GetGC());
|
||||
ls2->Add(callable);
|
||||
ls2->Add(task);
|
||||
|
||||
ls.GetGC()->GetPool()->Schedule([ls2,callable,task](size_t s)->void {
|
||||
try
|
||||
{
|
||||
task->SetSucceeded(callable->Call(*ls2,{}));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
task->SetFailed(std::current_exception());
|
||||
}
|
||||
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||
auto cobj = this->obj;
|
||||
ls->Add(cobj);
|
||||
ls->Add(callable);
|
||||
this->gc->GetPool()->Schedule([ls, callable, cobj](size_t s) -> void {
|
||||
callable->Call(*ls, {cobj});
|
||||
});
|
||||
|
||||
return task;
|
||||
return;
|
||||
} else {
|
||||
this->cont = callable;
|
||||
}
|
||||
|
||||
TTask* TTask::FromResult(GCList& ls, TObject v)
|
||||
{
|
||||
TTask* task = TTask::Create(ls);
|
||||
task->SetSucceeded(v);
|
||||
return task;
|
||||
}
|
||||
this->gc->BarrierEnd();
|
||||
}
|
||||
|
||||
class TTaskCseObj {
|
||||
std::shared_ptr<GC> gc;
|
||||
TTask* task;
|
||||
public:
|
||||
TTaskCseObj(std::shared_ptr<GC> gc, TTask* task)
|
||||
{
|
||||
this->gc = gc;
|
||||
this->task = task;
|
||||
void TTask::SetFailed(std::exception_ptr ex) {
|
||||
this->ex = ex;
|
||||
this->SetSucceeded(nullptr);
|
||||
}
|
||||
void TTask::SetSucceeded(TObject v) {
|
||||
gc->BarrierBegin();
|
||||
if (this->isCompleted) {
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
this->isCompleted = true;
|
||||
this->obj = v;
|
||||
auto cont = this->cont;
|
||||
gc->BarrierEnd();
|
||||
if (cont != nullptr) {
|
||||
std::shared_ptr<GCList> ls = std::make_shared<GCList>(gc);
|
||||
|
||||
auto callable = cont;
|
||||
ls->Add(v);
|
||||
ls->Add(callable);
|
||||
this->gc->GetPool()->Schedule(
|
||||
[ls, callable, v](size_t s) -> void { callable->Call(*ls, {v}); });
|
||||
}
|
||||
}
|
||||
|
||||
TObject TTask::Wait() {
|
||||
while (true) {
|
||||
gc->BarrierBegin();
|
||||
if (this->isCompleted) {
|
||||
if (this->ex) {
|
||||
auto error = this->ex;
|
||||
gc->BarrierEnd();
|
||||
std::rethrow_exception(error);
|
||||
}
|
||||
|
||||
void Invoke(std::shared_ptr<TTaskCseObj> shared_o,CallStackEntry* cse, TObject o)
|
||||
{
|
||||
try {
|
||||
GCList ls(gc);
|
||||
cse->Push(gc,o);
|
||||
auto res = cse->Resume(ls);
|
||||
CallStackEntry* cse2;
|
||||
if(GetObjectHeap(res,cse2))
|
||||
{
|
||||
auto taskPiece=cse2->Pop(ls);
|
||||
TTask* task;
|
||||
if(GetObjectHeap(taskPiece,task))
|
||||
{
|
||||
auto em = TExternalMethod::Create(ls,"",{"obj"},[cse2,task,shared_o](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
|
||||
shared_o->Invoke(shared_o,cse2,args.empty() ? (TObject)Undefined():args[0]);
|
||||
auto o = this->obj;
|
||||
gc->BarrierEnd();
|
||||
return o;
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
void TTask::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->obj);
|
||||
if (this->cont != nullptr)
|
||||
this->cont->Mark();
|
||||
}
|
||||
|
||||
TTask *TTask::Run(GCList &ls, TCallable *callable) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
std::shared_ptr<GCList> ls2 = std::make_shared<GCList>(ls.GetGC());
|
||||
ls2->Add(callable);
|
||||
ls2->Add(task);
|
||||
|
||||
ls.GetGC()->GetPool()->Schedule([ls2, callable, task](size_t s) -> void {
|
||||
try {
|
||||
task->SetSucceeded(callable->Call(*ls2, {}));
|
||||
} catch (...) {
|
||||
task->SetFailed(std::current_exception());
|
||||
}
|
||||
});
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
TTask *TTask::FromResult(GCList &ls, TObject v) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
task->SetSucceeded(v);
|
||||
return task;
|
||||
}
|
||||
|
||||
class TTaskCseObj {
|
||||
std::shared_ptr<GC> gc;
|
||||
TTask *task;
|
||||
|
||||
public:
|
||||
TTaskCseObj(std::shared_ptr<GC> gc, TTask *task) {
|
||||
this->gc = gc;
|
||||
this->task = task;
|
||||
}
|
||||
|
||||
void Invoke(std::shared_ptr<TTaskCseObj> shared_o, CallStackEntry *cse,
|
||||
TObject o) {
|
||||
try {
|
||||
GCList ls(gc);
|
||||
cse->Push(gc, o);
|
||||
auto res = cse->Resume(ls);
|
||||
CallStackEntry *cse2;
|
||||
if (GetObjectHeap(res, cse2)) {
|
||||
auto taskPiece = cse2->Pop(ls);
|
||||
TTask *task;
|
||||
if (GetObjectHeap(taskPiece, task)) {
|
||||
auto em = TExternalMethod::Create(
|
||||
ls, "", {"obj"},
|
||||
[cse2, task, shared_o](
|
||||
GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
shared_o->Invoke(shared_o, cse2,
|
||||
args.empty() ? (TObject)Undefined()
|
||||
: args[0]);
|
||||
|
||||
return nullptr;
|
||||
});
|
||||
em->watch.push_back(task);
|
||||
em->watch.push_back(cse2);
|
||||
|
||||
task->ContinueWith(em);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->task->SetSucceeded(res);
|
||||
}
|
||||
} catch(...) {
|
||||
this->task->SetFailed(std::current_exception());
|
||||
em->watch.push_back(task);
|
||||
em->watch.push_back(cse2);
|
||||
|
||||
task->ContinueWith(em);
|
||||
}
|
||||
} else {
|
||||
this->task->SetSucceeded(res);
|
||||
}
|
||||
};
|
||||
TTask* TTask::FromClosure(GCList& ls, TClosure* closure)
|
||||
{
|
||||
auto res = closure->Call(ls,{});
|
||||
CallStackEntry* ent;
|
||||
if(GetObjectHeap(res,ent))
|
||||
{
|
||||
return FromCallStackEntry(ls,ent);
|
||||
} catch (...) {
|
||||
this->task->SetFailed(std::current_exception());
|
||||
}
|
||||
return FromResult(ls,res);
|
||||
}
|
||||
TTask* TTask::FromCallStackEntry(GCList& ls, CallStackEntry* ent)
|
||||
{
|
||||
TTask* task = TTask::Create(ls);
|
||||
|
||||
//try {
|
||||
GCList ls2(ls.GetGC());
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
|
||||
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc,task);
|
||||
|
||||
|
||||
ls2.Add(task);
|
||||
auto res = ent->Pop(ls2);
|
||||
TTask* task2;
|
||||
if(GetObjectHeap(res,task2))
|
||||
{
|
||||
auto em = TExternalMethod::Create(ls2,"",{},[ent,task,obj](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
|
||||
obj->Invoke(obj,ent,args.empty() ? (TObject)Undefined():args[0]);
|
||||
|
||||
return nullptr;
|
||||
});
|
||||
em->watch.push_back(task);
|
||||
em->watch.push_back(ent);
|
||||
|
||||
task2->ContinueWith(em);
|
||||
}
|
||||
|
||||
/*} catch(...) {
|
||||
task->SetFailed(std::current_exception());
|
||||
}*/
|
||||
|
||||
return task;
|
||||
};
|
||||
TTask *TTask::FromClosure(GCList &ls, TClosure *closure) {
|
||||
auto res = closure->Call(ls, {});
|
||||
CallStackEntry *ent;
|
||||
if (GetObjectHeap(res, ent)) {
|
||||
return FromCallStackEntry(ls, ent);
|
||||
}
|
||||
}
|
||||
return FromResult(ls, res);
|
||||
}
|
||||
TTask *TTask::FromCallStackEntry(GCList &ls, CallStackEntry *ent) {
|
||||
TTask *task = TTask::Create(ls);
|
||||
|
||||
// try {
|
||||
GCList ls2(ls.GetGC());
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
|
||||
std::shared_ptr<TTaskCseObj> obj = std::make_shared<TTaskCseObj>(gc, task);
|
||||
|
||||
ls2.Add(task);
|
||||
auto res = ent->Pop(ls2);
|
||||
TTask *task2;
|
||||
if (GetObjectHeap(res, task2)) {
|
||||
auto em = TExternalMethod::Create(
|
||||
ls2, "", {},
|
||||
[ent, task, obj](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
obj->Invoke(obj, ent,
|
||||
args.empty() ? (TObject)Undefined() : args[0]);
|
||||
|
||||
return nullptr;
|
||||
});
|
||||
em->watch.push_back(task);
|
||||
em->watch.push_back(ent);
|
||||
|
||||
task2->ContinueWith(em);
|
||||
}
|
||||
|
||||
/*} catch(...) {
|
||||
task->SetFailed(std::current_exception());
|
||||
}*/
|
||||
|
||||
return task;
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+230
-229
@@ -1,247 +1,248 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
std::string TClassObject::TypeName()
|
||||
{
|
||||
std::string type = "class ";
|
||||
type += this->name;
|
||||
for(auto& item : this->inherit_tree) type += " : " + item;
|
||||
return type;
|
||||
namespace Tesses::CrossLang {
|
||||
std::string TClassObject::TypeName() {
|
||||
std::string type = "class ";
|
||||
type += this->name;
|
||||
for (auto &item : this->inherit_tree)
|
||||
type += " : " + item;
|
||||
return type;
|
||||
}
|
||||
TObject TClassObject::CallMethod(GCList &ls, std::string className,
|
||||
std::string name, std::vector<TObject> args) {
|
||||
auto value = this->GetValue(className, name);
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(value, callable)) {
|
||||
return callable->Call(ls, args);
|
||||
}
|
||||
TObject TClassObject::CallMethod(GCList& ls, std::string className, std::string name,std::vector<TObject> args)
|
||||
{
|
||||
auto value = this->GetValue(className,name);
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(value, callable))
|
||||
{
|
||||
return callable->Call(ls,args);
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TClassObjectEntry* TClassObject::GetEntry(std::string classN, std::string key)
|
||||
{
|
||||
for(auto& item : this->entries)
|
||||
{
|
||||
if(item.name == key)
|
||||
{
|
||||
switch(item.modifier)
|
||||
{
|
||||
case TClassModifier::Private:
|
||||
if(classN != item.owner) return nullptr;
|
||||
break;
|
||||
case TClassModifier::Protected:
|
||||
if(classN.empty()) return nullptr;
|
||||
if(classN != item.owner)
|
||||
{
|
||||
for(auto inh : this->inherit_tree)
|
||||
{
|
||||
if(inh == classN) {
|
||||
|
||||
return &item;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
//DO NOTHING
|
||||
break;
|
||||
}
|
||||
return &item;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
TClassObject* TClassObject::Create(GCList& ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector<TObject> args)
|
||||
{
|
||||
return Create(&ls,f,classIndex,env,args);
|
||||
}
|
||||
std::string JoinPeriod(std::vector<std::string>& p)
|
||||
{
|
||||
std::string newStr = "";
|
||||
for(size_t i = 0; i < p.size(); i++)
|
||||
{
|
||||
if(i > 0) newStr.push_back('.');
|
||||
newStr += p[i];
|
||||
}
|
||||
return newStr;
|
||||
}
|
||||
TClassObject* TClassObject::Create(GCList* ls, TFile* f, uint32_t classIndex, TEnvironment* env, std::vector<TObject> args)
|
||||
{
|
||||
if(ls == nullptr) return nullptr;
|
||||
TClassObject* obj = new TClassObject();
|
||||
obj->file = f;
|
||||
obj->classIndex = classIndex;
|
||||
obj->ogEnv=env;
|
||||
obj->env = TClassEnvironment::Create(ls,env,obj);
|
||||
obj->name = JoinPeriod(f->classes[classIndex].name);
|
||||
bool hasToString=false;
|
||||
|
||||
for(auto entry : f->classes[classIndex].entry)
|
||||
{
|
||||
if(entry.modifier == TClassModifier::Static) continue;
|
||||
TClassObjectEntry ent;
|
||||
ent.name = entry.name;
|
||||
ent.modifier = entry.modifier;
|
||||
ent.canSet = !entry.isFunction;
|
||||
ent.owner = obj->name;
|
||||
|
||||
if(entry.isFunction)
|
||||
{
|
||||
if(ent.name == "ToString") hasToString=true;
|
||||
if(entry.isAbstract)
|
||||
{
|
||||
delete obj;
|
||||
throw VMException("Method " + ent.name + " in " + ent.owner + " is abstract.");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
|
||||
clos->documentation = entry.documentation;
|
||||
clos->className = ent.owner;
|
||||
ent.value = clos;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(entry.isAbstract) ent.value = Undefined();
|
||||
else {
|
||||
auto clos = TClosure::Create(ls,obj->env,obj->file,entry.chunkId);
|
||||
|
||||
clos->className=ent.owner;
|
||||
ent.value = clos->Call(*ls,{});
|
||||
}
|
||||
}
|
||||
|
||||
obj->entries.push_back(ent);
|
||||
}
|
||||
|
||||
TClass* clsCur = &f->classes[classIndex];
|
||||
TRootEnvironment* rEnv = env->GetRootEnvironment();
|
||||
while(!clsCur->inherits.empty() && !(clsCur->inherits.size() == 1 && clsCur->inherits[0] == "ClassObject"))
|
||||
{
|
||||
obj->inherit_tree.push_back(JoinPeriod(clsCur->inherits));
|
||||
size_t idx;
|
||||
if(rEnv->TryFindClass(clsCur->inherits,idx))
|
||||
{
|
||||
auto file = rEnv->classes[idx].first;
|
||||
clsCur = &rEnv->classes[idx].first->classes.at(rEnv->classes[idx].second);
|
||||
auto ownerNow = JoinPeriod(clsCur->name);
|
||||
for(auto entry : clsCur->entry)
|
||||
{
|
||||
if(entry.modifier == TClassModifier::Static) continue;
|
||||
bool cont=false;
|
||||
for(auto e : obj->entries)
|
||||
if(e.name == entry.name)
|
||||
{
|
||||
cont=true;
|
||||
break;
|
||||
}
|
||||
if(cont) continue;
|
||||
return Undefined();
|
||||
}
|
||||
TClassObjectEntry *TClassObject::GetEntry(std::string classN, std::string key) {
|
||||
for (auto &item : this->entries) {
|
||||
if (item.name == key) {
|
||||
switch (item.modifier) {
|
||||
case TClassModifier::Private:
|
||||
if (classN != item.owner)
|
||||
return nullptr;
|
||||
break;
|
||||
case TClassModifier::Protected:
|
||||
if (classN.empty())
|
||||
return nullptr;
|
||||
if (classN != item.owner) {
|
||||
for (auto inh : this->inherit_tree) {
|
||||
if (inh == classN) {
|
||||
|
||||
TClassObjectEntry ent;
|
||||
ent.name = entry.name;
|
||||
ent.modifier = entry.modifier;
|
||||
ent.canSet = !entry.isFunction;
|
||||
ent.owner = ownerNow;
|
||||
|
||||
if(entry.isFunction)
|
||||
{
|
||||
|
||||
if(ent.name == "ToString") hasToString=true;
|
||||
if(entry.isAbstract)
|
||||
{
|
||||
delete obj;
|
||||
throw VMException("Method " + ent.name + " in " + ownerNow + " is abstract.");
|
||||
return &item;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
// DO NOTHING
|
||||
break;
|
||||
}
|
||||
return &item;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
TClassObject *TClassObject::Create(GCList &ls, TFile *f, uint32_t classIndex,
|
||||
TEnvironment *env,
|
||||
std::vector<TObject> args) {
|
||||
return Create(&ls, f, classIndex, env, args);
|
||||
}
|
||||
std::string JoinPeriod(std::vector<std::string> &p) {
|
||||
std::string newStr = "";
|
||||
for (size_t i = 0; i < p.size(); i++) {
|
||||
if (i > 0)
|
||||
newStr.push_back('.');
|
||||
newStr += p[i];
|
||||
}
|
||||
return newStr;
|
||||
}
|
||||
TClassObject *TClassObject::Create(GCList *ls, TFile *f, uint32_t classIndex,
|
||||
TEnvironment *env,
|
||||
std::vector<TObject> args) {
|
||||
if (ls == nullptr)
|
||||
return nullptr;
|
||||
TClassObject *obj = new TClassObject();
|
||||
obj->file = f;
|
||||
obj->classIndex = classIndex;
|
||||
obj->ogEnv = env;
|
||||
obj->env = TClassEnvironment::Create(ls, env, obj);
|
||||
obj->name = JoinPeriod(f->classes[classIndex].name);
|
||||
|
||||
bool hasToString = false;
|
||||
|
||||
for (auto &entry : f->classes[classIndex].entry) {
|
||||
if (entry.modifier == TClassModifier::Static)
|
||||
continue;
|
||||
TClassObjectEntry ent;
|
||||
ent.name = entry.name;
|
||||
ent.modifier = entry.modifier;
|
||||
ent.canSet = !entry.isFunction;
|
||||
ent.owner = obj->name;
|
||||
|
||||
if (entry.isFunction) {
|
||||
if (entry.name == "ToString")
|
||||
hasToString = true;
|
||||
if (entry.isAbstract) {
|
||||
delete obj;
|
||||
throw VMException("Method " + ent.name + " in " + ent.owner +
|
||||
" is abstract.");
|
||||
} else {
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
|
||||
clos->documentation = entry.documentation;
|
||||
clos->className = ent.owner;
|
||||
ent.value = clos;
|
||||
}
|
||||
} else {
|
||||
if (entry.isAbstract)
|
||||
ent.value = Undefined();
|
||||
else {
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, obj->file, entry.chunkId);
|
||||
|
||||
clos->className = ent.owner;
|
||||
ent.value = clos->Call(*ls, {});
|
||||
}
|
||||
}
|
||||
|
||||
obj->entries.push_back(ent);
|
||||
}
|
||||
|
||||
TClass *clsCur = &f->classes[classIndex];
|
||||
TRootEnvironment *rEnv = env->GetRootEnvironment();
|
||||
while (!clsCur->inherits.empty() &&
|
||||
!(clsCur->inherits.size() == 1 &&
|
||||
clsCur->inherits[0] == "ClassObject")) {
|
||||
obj->inherit_tree.push_back(JoinPeriod(clsCur->inherits));
|
||||
size_t idx;
|
||||
if (rEnv->TryFindClass(clsCur->inherits, idx)) {
|
||||
auto file = rEnv->classes[idx].first;
|
||||
clsCur = &rEnv->classes[idx].first->classes.at(
|
||||
rEnv->classes[idx].second);
|
||||
auto ownerNow = JoinPeriod(clsCur->name);
|
||||
for (auto &entry : clsCur->entry) {
|
||||
if (entry.modifier == TClassModifier::Static)
|
||||
continue;
|
||||
bool cont = false;
|
||||
for (auto e : obj->entries)
|
||||
if (e.name == entry.name) {
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
if (cont)
|
||||
continue;
|
||||
|
||||
TClassObjectEntry ent;
|
||||
ent.name = entry.name;
|
||||
ent.modifier = entry.modifier;
|
||||
ent.canSet = !entry.isFunction;
|
||||
ent.owner = ownerNow;
|
||||
|
||||
if (entry.isFunction) {
|
||||
|
||||
if (entry.name == "ToString")
|
||||
hasToString = true;
|
||||
if (entry.isAbstract) {
|
||||
delete obj;
|
||||
throw VMException("Method " + ent.name + " in " +
|
||||
ownerNow + " is abstract.");
|
||||
} else {
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, file, entry.chunkId);
|
||||
clos->closure->name = obj->name + "::" + ent.name;
|
||||
clos->className = ownerNow;
|
||||
clos->documentation = entry.documentation;
|
||||
ent.value = clos;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(entry.isAbstract) ent.value = Undefined();
|
||||
} else {
|
||||
if (entry.isAbstract)
|
||||
ent.value = Undefined();
|
||||
else {
|
||||
auto clos = TClosure::Create(ls,obj->env,file,entry.chunkId);
|
||||
auto clos =
|
||||
TClosure::Create(ls, obj->env, file, entry.chunkId);
|
||||
clos->closure->name = obj->name + "::" + ent.name;
|
||||
clos->className = ownerNow;
|
||||
ent.value = clos->Call(*ls,{});
|
||||
ent.value = clos->Call(*ls, {});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
obj->entries.push_back(ent);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(!hasToString)
|
||||
{
|
||||
TClassObjectEntry ent;
|
||||
ent.canSet=false;
|
||||
ent.modifier = TClassModifier::Public;
|
||||
ent.name = "ToString";
|
||||
ent.owner = obj->name;
|
||||
ent.value = TExternalMethod::Create(ls,"The ToString",{},[obj](GCList& ls,std::vector<TObject> args)->TObject { return obj->TypeName();});
|
||||
obj->entries.push_back(ent);
|
||||
}
|
||||
TCallable* call=nullptr;
|
||||
std::string fnName = f->classes[classIndex].name[f->classes[classIndex].name.size()-1];
|
||||
for(auto& item : obj->entries)
|
||||
if(item.name == fnName)
|
||||
{
|
||||
GetObjectHeap(item.value,call);
|
||||
break;
|
||||
}
|
||||
ls->Add(obj);
|
||||
ls->GetGC()->Watch(obj);
|
||||
|
||||
if(call != nullptr) call->Call(*ls,args);
|
||||
return obj;
|
||||
}
|
||||
if (!hasToString) {
|
||||
TClassObjectEntry ent;
|
||||
ent.canSet = false;
|
||||
ent.modifier = TClassModifier::Public;
|
||||
ent.name = "ToString";
|
||||
ent.owner = obj->name;
|
||||
ent.value = TExternalMethod::Create(
|
||||
ls, "The ToString", {},
|
||||
[obj](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return obj->TypeName();
|
||||
});
|
||||
obj->entries.push_back(ent);
|
||||
}
|
||||
TCallable *call = nullptr;
|
||||
std::string fnName =
|
||||
f->classes[classIndex].name[f->classes[classIndex].name.size() - 1];
|
||||
for (auto &item : obj->entries)
|
||||
if (item.name == fnName) {
|
||||
GetObjectHeap(item.value, call);
|
||||
break;
|
||||
}
|
||||
ls->Add(obj);
|
||||
ls->GetGC()->Watch(obj);
|
||||
|
||||
TObject TClassObject::GetValue(std::string className, std::string key)
|
||||
{
|
||||
auto ent = GetEntry(className,key);
|
||||
if(ent == nullptr) return Undefined();
|
||||
return ent->value;
|
||||
}
|
||||
void TClassObject::SetValue(std::string className, std::string key,TObject value)
|
||||
{
|
||||
auto ent = GetEntry(className,key);
|
||||
if(ent == nullptr) return;
|
||||
if(ent->canSet) ent->value = value;
|
||||
}
|
||||
bool TClassObject::HasValue(std::string className,std::string key)
|
||||
{
|
||||
auto ent = GetEntry(className,key);
|
||||
return ent != nullptr;
|
||||
|
||||
}
|
||||
bool TClassObject::HasField(std::string className,std::string key)
|
||||
{
|
||||
auto ent = GetEntry(className,key);
|
||||
if(ent == nullptr) return false;
|
||||
return ent->canSet;
|
||||
}
|
||||
bool TClassObject::HasMethod(std::string className,std::string key)
|
||||
{
|
||||
auto ent = GetEntry(className,key);
|
||||
if(ent == nullptr) return false;
|
||||
TCallable* call;
|
||||
return GetObjectHeap(ent->value,call);
|
||||
}
|
||||
void TClassObject::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
this->env->Mark();
|
||||
this->file->Mark();
|
||||
this->ogEnv->Mark();
|
||||
for(auto& item : this->entries) GC::Mark(item.value);
|
||||
|
||||
}
|
||||
}
|
||||
if (call != nullptr)
|
||||
call->Call(*ls, args);
|
||||
return obj;
|
||||
}
|
||||
|
||||
TObject TClassObject::GetValue(std::string className, std::string key) {
|
||||
auto ent = GetEntry(className, key);
|
||||
if (ent == nullptr)
|
||||
return Undefined();
|
||||
return ent->value;
|
||||
}
|
||||
void TClassObject::SetValue(std::string className, std::string key,
|
||||
TObject value) {
|
||||
auto ent = GetEntry(className, key);
|
||||
if (ent == nullptr)
|
||||
return;
|
||||
if (ent->canSet)
|
||||
ent->value = value;
|
||||
}
|
||||
bool TClassObject::HasValue(std::string className, std::string key) {
|
||||
auto ent = GetEntry(className, key);
|
||||
return ent != nullptr;
|
||||
}
|
||||
bool TClassObject::HasField(std::string className, std::string key) {
|
||||
auto ent = GetEntry(className, key);
|
||||
if (ent == nullptr)
|
||||
return false;
|
||||
return ent->canSet;
|
||||
}
|
||||
bool TClassObject::HasMethod(std::string className, std::string key) {
|
||||
auto ent = GetEntry(className, key);
|
||||
if (ent == nullptr)
|
||||
return false;
|
||||
TCallable *call;
|
||||
return GetObjectHeap(ent->value, call);
|
||||
}
|
||||
void TClassObject::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->env->Mark();
|
||||
this->file->Mark();
|
||||
this->ogEnv->Mark();
|
||||
for (auto &item : this->entries)
|
||||
GC::Mark(item.value);
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+132
-120
@@ -1,130 +1,142 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang {
|
||||
bool TClassEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
return false;
|
||||
bool TClassEnvironment::HasConstForSet(std::string key) {
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
TClassEnvironment* TClassEnvironment::Create(GCList* gc,TEnvironment* env,TClassObject* obj)
|
||||
{
|
||||
|
||||
TClassEnvironment* env2=new TClassEnvironment(env,obj);
|
||||
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(env2);
|
||||
_gc->Watch(env2);
|
||||
return env2;
|
||||
}
|
||||
TClassEnvironment* TClassEnvironment::Create(GCList& gc,TEnvironment* env,TClassObject* obj)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TClassEnvironment *TClassEnvironment::Create(GCList *gc, TEnvironment *env,
|
||||
TClassObject *obj) {
|
||||
|
||||
TClassEnvironment* env2=new TClassEnvironment(env,obj);
|
||||
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(env2);
|
||||
_gc->Watch(env2);
|
||||
return env2;
|
||||
}
|
||||
TClassEnvironment::TClassEnvironment(TEnvironment* env,TClassObject* obj)
|
||||
{
|
||||
this->env = env;
|
||||
this->clsObj=obj;
|
||||
}
|
||||
bool TClassEnvironment::HasVariable(std::string key)
|
||||
{
|
||||
if(key == "this") return true;
|
||||
if(this->clsObj->HasValue(current_function == nullptr ? "" : current_function->callable->className,key)) return true;
|
||||
return false;
|
||||
}
|
||||
bool TClassEnvironment::HasVariableRecurse(std::string key)
|
||||
{
|
||||
if(HasVariable(key)) return true;
|
||||
return this->env->HasVariableRecurse(key);
|
||||
}
|
||||
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key, bool setting)
|
||||
{
|
||||
if(key == "this") return true;
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
if(clsObj->HasMethod(clsName,(setting ? "set" : "get")+key)) return true;
|
||||
if(clsObj->HasValue(clsName,key)) return true;
|
||||
return env->HasVariableOrFieldRecurse(key,setting);
|
||||
}
|
||||
|
||||
TObject TClassEnvironment::GetVariable(std::string key)
|
||||
{
|
||||
if(key == "this") return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
|
||||
if(clsObj->HasValue(clsName,key)) return this->clsObj->GetValue(clsName,key);
|
||||
return env->GetVariable(key);
|
||||
}
|
||||
void TClassEnvironment::SetVariable(std::string key, TObject value)
|
||||
{
|
||||
if(key == "this") return;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
|
||||
if(clsObj->HasValue(clsName,key))
|
||||
{
|
||||
this->clsObj->SetValue(clsName,key,value);
|
||||
return;
|
||||
}
|
||||
this->env->SetVariable(key,value);
|
||||
TClassEnvironment *env2 = new TClassEnvironment(env, obj);
|
||||
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(env2);
|
||||
_gc->Watch(env2);
|
||||
return env2;
|
||||
}
|
||||
TClassEnvironment *TClassEnvironment::Create(GCList &gc, TEnvironment *env,
|
||||
TClassObject *obj) {
|
||||
|
||||
TClassEnvironment *env2 = new TClassEnvironment(env, obj);
|
||||
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(env2);
|
||||
_gc->Watch(env2);
|
||||
return env2;
|
||||
}
|
||||
TClassEnvironment::TClassEnvironment(TEnvironment *env, TClassObject *obj) {
|
||||
this->env = env;
|
||||
this->clsObj = obj;
|
||||
}
|
||||
bool TClassEnvironment::HasVariable(std::string key) {
|
||||
if (key == "this")
|
||||
return true;
|
||||
if (this->clsObj->HasValue(current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className,
|
||||
key))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool TClassEnvironment::HasVariableRecurse(std::string key) {
|
||||
if (HasVariable(key))
|
||||
return true;
|
||||
return this->env->HasVariableRecurse(key);
|
||||
}
|
||||
bool TClassEnvironment::HasVariableOrFieldRecurse(std::string key,
|
||||
bool setting) {
|
||||
if (key == "this")
|
||||
return true;
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
if (clsObj->HasMethod(clsName, (setting ? "set" : "get") + key))
|
||||
return true;
|
||||
if (clsObj->HasValue(clsName, key))
|
||||
return true;
|
||||
return env->HasVariableOrFieldRecurse(key, setting);
|
||||
}
|
||||
|
||||
TObject TClassEnvironment::GetVariable(std::string key) {
|
||||
if (key == "this")
|
||||
return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
|
||||
if (clsObj->HasValue(clsName, key))
|
||||
return this->clsObj->GetValue(clsName, key);
|
||||
return env->GetVariable(key);
|
||||
}
|
||||
void TClassEnvironment::SetVariable(std::string key, TObject value) {
|
||||
if (key == "this")
|
||||
return;
|
||||
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
|
||||
if (clsObj->HasValue(clsName, key)) {
|
||||
this->clsObj->SetValue(clsName, key, value);
|
||||
return;
|
||||
}
|
||||
TObject TClassEnvironment::GetVariable(GCList& ls, std::string key)
|
||||
{
|
||||
if(key == "this") return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
if(this->clsObj->HasMethod(clsName,"get"+key))
|
||||
{
|
||||
auto res=this->clsObj->GetValue(clsName,"get"+key);
|
||||
TCallable* call;
|
||||
if(GetObjectHeap(res,call)) return call->Call(ls,{});
|
||||
}
|
||||
if(this->clsObj->HasValue(clsName,key)) return this->clsObj->GetValue(clsName,key);
|
||||
return this->env->GetVariable(ls,key);
|
||||
}
|
||||
TObject TClassEnvironment::SetVariable(GCList& ls, std::string key, TObject v)
|
||||
{
|
||||
if(key == "this") return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr ? "" : current_function->callable->className;
|
||||
if(this->clsObj->HasMethod(clsName,"set"+key))
|
||||
{
|
||||
auto res=this->clsObj->GetValue(clsName,"set"+key);
|
||||
TCallable* call;
|
||||
if(GetObjectHeap(res,call)) return call->Call(ls,{v});
|
||||
}
|
||||
if(this->clsObj->HasValue(clsName,key)) { this->clsObj->SetValue(clsName,key,v); return v;}
|
||||
|
||||
return this->env->SetVariable(ls,key,v);
|
||||
}
|
||||
|
||||
void TClassEnvironment::DeclareVariable(std::string key, TObject value)
|
||||
{
|
||||
this->env->SetVariable(key, value);
|
||||
return;
|
||||
}
|
||||
TObject TClassEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||
if (key == "this")
|
||||
return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
if (this->clsObj->HasMethod(clsName, "get" + key)) {
|
||||
auto res = this->clsObj->GetValue(clsName, "get" + key);
|
||||
TCallable *call;
|
||||
if (GetObjectHeap(res, call))
|
||||
return call->Call(ls, {});
|
||||
}
|
||||
TRootEnvironment* TClassEnvironment::GetRootEnvironment()
|
||||
{
|
||||
return this->env->GetRootEnvironment();
|
||||
if (this->clsObj->HasValue(clsName, key))
|
||||
return this->clsObj->GetValue(clsName, key);
|
||||
return this->env->GetVariable(ls, key);
|
||||
}
|
||||
TObject TClassEnvironment::SetVariable(GCList &ls, std::string key, TObject v) {
|
||||
if (key == "this")
|
||||
return this->clsObj;
|
||||
|
||||
std::string clsName = current_function == nullptr
|
||||
? ""
|
||||
: current_function->callable->className;
|
||||
if (this->clsObj->HasMethod(clsName, "set" + key)) {
|
||||
auto res = this->clsObj->GetValue(clsName, "set" + key);
|
||||
TCallable *call;
|
||||
if (GetObjectHeap(res, call))
|
||||
return call->Call(ls, {v});
|
||||
}
|
||||
TEnvironment* TClassEnvironment::GetParentEnvironment()
|
||||
{
|
||||
return this->env;
|
||||
if (this->clsObj->HasValue(clsName, key)) {
|
||||
this->clsObj->SetValue(clsName, key, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
void TClassEnvironment::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
this->clsObj->Mark();
|
||||
this->env->Mark();
|
||||
for(auto item : this->defers) item->Mark();
|
||||
}
|
||||
}
|
||||
|
||||
return this->env->SetVariable(ls, key, v);
|
||||
}
|
||||
|
||||
void TClassEnvironment::DeclareVariable(std::string key, TObject value) {}
|
||||
TRootEnvironment *TClassEnvironment::GetRootEnvironment() {
|
||||
return this->env->GetRootEnvironment();
|
||||
}
|
||||
TEnvironment *TClassEnvironment::GetParentEnvironment() { return this->env; }
|
||||
|
||||
void TClassEnvironment::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->clsObj->Mark();
|
||||
this->env->Mark();
|
||||
for (auto item : this->defers)
|
||||
item->Mark();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+91
-93
@@ -1,99 +1,97 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang {
|
||||
TArgWrapper* TArgWrapper::Create(GCList& ls, TCallable* callable)
|
||||
{
|
||||
TArgWrapper* argWrapper = new TArgWrapper();
|
||||
argWrapper->callable = callable;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<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();
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
void TCallable::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
void TClosure::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
this->file->Mark();
|
||||
this->env->Mark();
|
||||
this->closure->Mark();
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
TClosure* TClosure::Create(GCList& ls,TEnvironment* env,TFile* file,uint32_t chunkId,bool ownScope)
|
||||
{
|
||||
TClosure* closure = new TClosure();
|
||||
closure->className="";
|
||||
closure->ownScope=ownScope;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(closure);
|
||||
_gc->Watch(closure);
|
||||
closure->chunkId = chunkId;
|
||||
if(chunkId < file->chunks.size())
|
||||
TArgWrapper *TArgWrapper::Create(GCList &ls, TCallable *callable) {
|
||||
TArgWrapper *argWrapper = new TArgWrapper();
|
||||
argWrapper->callable = callable;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<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();
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
void TCallable::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
void TClosure::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->file->Mark();
|
||||
this->env->Mark();
|
||||
this->closure->Mark();
|
||||
GC::Mark(this->tag);
|
||||
}
|
||||
TClosure *TClosure::Create(GCList &ls, TEnvironment *env, TFile *file,
|
||||
uint32_t chunkId, bool ownScope) {
|
||||
TClosure *closure = new TClosure();
|
||||
closure->className = "";
|
||||
closure->ownScope = ownScope;
|
||||
std::shared_ptr<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->className="";
|
||||
closure->ownScope=ownScope;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(closure);
|
||||
_gc->Watch(closure);
|
||||
closure->chunkId = chunkId;
|
||||
if(chunkId < file->chunks.size())
|
||||
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->className = "";
|
||||
closure->ownScope = ownScope;
|
||||
std::shared_ptr<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);
|
||||
else
|
||||
throw VMException("ChunkId out of bounds.");
|
||||
closure->env = env;
|
||||
closure->file = file;
|
||||
|
||||
thrd->Execute(ls.GetGC());
|
||||
return closure;
|
||||
}
|
||||
|
||||
TObject v= thrd->call_stack_entries[0]->Pop(ls);
|
||||
current_function = cse;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+186
-201
@@ -1,221 +1,206 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
TDynamicDictionary* TDynamicDictionary::Create(GCList& ls,TCallable* callable)
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TDynamicDictionary *TDynamicDictionary::Create(GCList &ls,
|
||||
TCallable *callable) {
|
||||
|
||||
TDynamicDictionary* dict=new TDynamicDictionary();
|
||||
dict->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
TDynamicDictionary* TDynamicDictionary::Create(GCList* ls,TCallable* callable)
|
||||
{
|
||||
TDynamicDictionary* dict=new TDynamicDictionary();
|
||||
dict->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
TDynamicDictionary *dict = new TDynamicDictionary();
|
||||
dict->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
TDynamicDictionary *TDynamicDictionary::Create(GCList *ls,
|
||||
TCallable *callable) {
|
||||
TDynamicDictionary *dict = new TDynamicDictionary();
|
||||
dict->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
|
||||
void TDynamicDictionary::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
this->cb->Mark();
|
||||
}
|
||||
void TDynamicDictionary::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->cb->Mark();
|
||||
}
|
||||
|
||||
TObject TDynamicDictionary::GetField(GCList& ls, std::string key)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetField");
|
||||
dict->SetValue("Key", key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->cb->Call(ls,{dict});
|
||||
}
|
||||
TObject TDynamicDictionary::GetField(GCList &ls, std::string key) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetField");
|
||||
dict->SetValue("Key", key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TObject TDynamicDictionary::SetField(GCList& ls, std::string key, TObject value)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "SetField");
|
||||
dict->SetValue("Key", key);
|
||||
dict->SetValue("Value", value);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->cb->Call(ls,{dict});
|
||||
}
|
||||
TObject TDynamicDictionary::SetField(GCList &ls, std::string key,
|
||||
TObject value) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "SetField");
|
||||
dict->SetValue("Key", key);
|
||||
dict->SetValue("Value", value);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TObject TDynamicDictionary::CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "CallMethod");
|
||||
dict->SetValue("Name", name);
|
||||
auto argVal = TList::Create(ls);
|
||||
argVal->items = args;
|
||||
dict->SetValue("Arguments", argVal);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->cb->Call(ls,{dict});
|
||||
}
|
||||
TObject TDynamicDictionary::CallMethod(GCList &ls, std::string name,
|
||||
std::vector<TObject> args) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "CallMethod");
|
||||
dict->SetValue("Name", name);
|
||||
auto argVal = TList::Create(ls);
|
||||
argVal->items = args;
|
||||
dict->SetValue("Arguments", argVal);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TEnumerator* TDynamicDictionary::GetEnumerator(GCList& ls)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetEnumerator");
|
||||
TEnumerator *TDynamicDictionary::GetEnumerator(GCList &ls) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetEnumerator");
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return TEnumerator::CreateFromObject(ls,this->cb->Call(ls,{dict}));
|
||||
}
|
||||
bool TDictionary::MethodExists(GCList& ls,std::string method)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto r = this->GetValue(method);
|
||||
TCallable* callable;
|
||||
bool res = GetObjectHeap(r,callable);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
bool TDynamicDictionary::MethodExists(GCList& ls,std::string name)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "MethodExists");
|
||||
dict->SetValue("Name", name);
|
||||
return TEnumerator::CreateFromObject(ls, this->cb->Call(ls, {dict}));
|
||||
}
|
||||
bool TDictionary::MethodExists(GCList &ls, std::string method) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto r = this->GetValue(method);
|
||||
TCallable *callable;
|
||||
bool res = GetObjectHeap(r, callable);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
bool TDynamicDictionary::MethodExists(GCList &ls, std::string name) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "MethodExists");
|
||||
dict->SetValue("Name", name);
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
auto res = this->cb->Call(ls,{dict});
|
||||
bool r2;
|
||||
if(GetObject(res,r2)) return r2;
|
||||
return false;
|
||||
}
|
||||
auto res = this->cb->Call(ls, {dict});
|
||||
bool r2;
|
||||
if (GetObject(res, r2))
|
||||
return r2;
|
||||
return false;
|
||||
}
|
||||
|
||||
TDynamicDictionary::~TDynamicDictionary()
|
||||
{
|
||||
TDynamicDictionary::~TDynamicDictionary() {}
|
||||
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;
|
||||
|
||||
}
|
||||
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);
|
||||
|
||||
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();
|
||||
}
|
||||
TObject TDictionary::CallMethodWithFatalError(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->CallWithFatalError(ls,args2);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return callable->CallWithFatalError(ls,args);
|
||||
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
void TDictionary::DeclareFunction(std::shared_ptr<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(std::shared_ptr<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();
|
||||
if(this->items.count(key) > 0)
|
||||
return this->items[key];
|
||||
return Undefined();
|
||||
}
|
||||
void TDictionary::SetValue(std::string key, TObject value)
|
||||
{
|
||||
if(std::holds_alternative<Undefined>(value))
|
||||
{
|
||||
if(this->items.count(key) > 0)
|
||||
this->items.erase(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->items[key] = value;
|
||||
} else {
|
||||
return callable->Call(ls, args);
|
||||
}
|
||||
}
|
||||
bool TDictionary::HasValue(std::string key)
|
||||
{
|
||||
return this->items.count(key) > 0;
|
||||
}
|
||||
void TDictionary::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked = true;
|
||||
for(auto item : this->items)
|
||||
{
|
||||
GC::Mark(item.second);
|
||||
return Undefined();
|
||||
}
|
||||
TObject TDictionary::CallMethodWithFatalError(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->CallWithFatalError(ls, args2);
|
||||
|
||||
} else {
|
||||
return callable->CallWithFatalError(ls, args);
|
||||
}
|
||||
}
|
||||
TDictionary* TDictionary::Create(GCList* gc)
|
||||
{
|
||||
TDictionary* dict=new TDictionary();
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
TDictionary* TDictionary::Create(GCList& gc)
|
||||
{
|
||||
TDictionary* dict=new TDictionary();
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
};
|
||||
void TDictionary::DeclareFunction(
|
||||
std::shared_ptr<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(
|
||||
std::shared_ptr<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();
|
||||
if (this->items.count(key) > 0)
|
||||
return this->items[key];
|
||||
return Undefined();
|
||||
}
|
||||
void TDictionary::SetValue(std::string key, TObject value) {
|
||||
if (std::holds_alternative<Undefined>(value)) {
|
||||
if (this->items.count(key) > 0)
|
||||
this->items.erase(key);
|
||||
} else {
|
||||
this->items[key] = value;
|
||||
}
|
||||
}
|
||||
bool TDictionary::HasValue(std::string key) {
|
||||
return this->items.count(key) > 0;
|
||||
}
|
||||
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();
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
TDictionary *TDictionary::Create(GCList &gc) {
|
||||
TDictionary *dict = new TDictionary();
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(dict);
|
||||
_gc->Watch(dict);
|
||||
return dict;
|
||||
}
|
||||
|
||||
}; // namespace Tesses::CrossLang
|
||||
|
||||
+183
-217
@@ -2,166 +2,146 @@
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
EmbedStream::EmbedStream(std::shared_ptr<GC> gc, TFile* file, uint32_t resource)
|
||||
{
|
||||
this->offset = 0;
|
||||
this->resource = resource;
|
||||
this->file = CreateMarkedTObject(gc,file);
|
||||
}
|
||||
bool EmbedStream::CanRead()
|
||||
{
|
||||
TFile* file;
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return false;
|
||||
if(this->offset >= file->resources[this->resource].size()) return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool EmbedStream::CanSeek()
|
||||
{
|
||||
EmbedStream::EmbedStream(std::shared_ptr<GC> gc, TFile *file,
|
||||
uint32_t resource) {
|
||||
this->offset = 0;
|
||||
this->resource = resource;
|
||||
this->file = CreateMarkedTObject(gc, file);
|
||||
}
|
||||
bool EmbedStream::CanRead() {
|
||||
TFile *file;
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return false;
|
||||
if (this->offset >= file->resources[this->resource].size())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool EmbedStream::EndOfStream()
|
||||
{
|
||||
return !CanRead();
|
||||
}
|
||||
size_t EmbedStream::Read(uint8_t* buff, size_t len)
|
||||
{
|
||||
TFile* file;
|
||||
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return 0;
|
||||
auto flen = file->resources[this->resource].size();
|
||||
if(this->offset >= flen) return 0;
|
||||
|
||||
len = std::min(len, std::min(
|
||||
flen,
|
||||
flen - this->offset
|
||||
));
|
||||
return false;
|
||||
}
|
||||
bool EmbedStream::CanSeek() { return true; }
|
||||
bool EmbedStream::EndOfStream() { return !CanRead(); }
|
||||
size_t EmbedStream::Read(uint8_t *buff, size_t len) {
|
||||
TFile *file;
|
||||
|
||||
memcpy(buff,file->resources[this->resource].data() + this->offset,len);
|
||||
this->offset += len;
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return 0;
|
||||
auto flen = file->resources[this->resource].size();
|
||||
if (this->offset >= flen)
|
||||
return 0;
|
||||
|
||||
len = std::min(len, std::min(flen, flen - this->offset));
|
||||
|
||||
memcpy(buff, file->resources[this->resource].data() + this->offset,
|
||||
len);
|
||||
this->offset += len;
|
||||
return len;
|
||||
}
|
||||
int64_t EmbedStream::GetPosition()
|
||||
{
|
||||
return (int64_t)this->offset;
|
||||
return 0;
|
||||
}
|
||||
int64_t EmbedStream::GetPosition() { return (int64_t)this->offset; }
|
||||
int64_t EmbedStream::GetLength() {
|
||||
TFile *file;
|
||||
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return 0;
|
||||
return (int64_t)file->resources[this->resource].size();
|
||||
}
|
||||
int64_t EmbedStream::GetLength()
|
||||
{
|
||||
TFile* file;
|
||||
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return 0;
|
||||
return (int64_t)file->resources[this->resource].size();
|
||||
return 0;
|
||||
}
|
||||
void EmbedStream::Seek(int64_t pos,
|
||||
Tesses::Framework::Streams::SeekOrigin whence) {
|
||||
switch (whence) {
|
||||
case Tesses::Framework::Streams::SeekOrigin::Begin:
|
||||
this->offset = (uint32_t)pos;
|
||||
break;
|
||||
case Tesses::Framework::Streams::SeekOrigin::Current: {
|
||||
int64_t cur = this->offset;
|
||||
cur += pos;
|
||||
this->offset = (uint32_t)cur;
|
||||
} break;
|
||||
case Tesses::Framework::Streams::SeekOrigin::End: {
|
||||
TFile *file;
|
||||
|
||||
if (GetObjectHeap(this->file->GetObject(), file)) {
|
||||
if (this->resource >= file->resources.size())
|
||||
return;
|
||||
int64_t cur = (int64_t)file->resources[this->resource].size();
|
||||
cur += pos;
|
||||
this->offset = (uint32_t)cur;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
void EmbedStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
|
||||
{
|
||||
switch(whence)
|
||||
{
|
||||
case Tesses::Framework::Streams::SeekOrigin::Begin:
|
||||
this->offset = (uint32_t)pos;
|
||||
break;
|
||||
case Tesses::Framework::Streams::SeekOrigin::Current:
|
||||
{
|
||||
int64_t cur = this->offset;
|
||||
cur += pos;
|
||||
this->offset = (uint32_t)cur;
|
||||
}
|
||||
break;
|
||||
case Tesses::Framework::Streams::SeekOrigin::End:
|
||||
{
|
||||
TFile* file;
|
||||
|
||||
if(GetObjectHeap(this->file->GetObject(),file))
|
||||
{
|
||||
if(this->resource >= file->resources.size()) return;
|
||||
int64_t cur = (int64_t)file->resources[this->resource].size();
|
||||
cur += pos;
|
||||
this->offset = (uint32_t)cur;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
path = path.CollapseRelativeParents();
|
||||
auto curEntry = this->dir->GetObject();
|
||||
for(auto item : path.path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(curEntry,dict) && dict->HasValue(item))
|
||||
{
|
||||
curEntry = dict->GetValue(item);
|
||||
continue; //don't want to return undefined now do we
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
return curEntry;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
|
||||
{
|
||||
if(mode != "r" && mode != "rb") return nullptr;
|
||||
|
||||
auto ent = getEntry(path);
|
||||
TCallable* call;
|
||||
if(GetObjectHeap(ent,call))
|
||||
{
|
||||
GCList ls(this->dir->GetGC());
|
||||
auto fileO = call->Call(ls,{});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if(GetObject(fileO,strm)) return strm;
|
||||
}
|
||||
TObject EmbedDirectory::getEntry(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
path = path.CollapseRelativeParents();
|
||||
auto curEntry = this->dir->GetObject();
|
||||
for (auto item : path.path) {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(curEntry, dict) && dict->HasValue(item)) {
|
||||
curEntry = dict->GetValue(item);
|
||||
continue; // don't want to return undefined now do we
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
return curEntry;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream>
|
||||
EmbedDirectory::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
|
||||
std::string mode) {
|
||||
if (mode != "r" && mode != "rb")
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool EmbedDirectory::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data)
|
||||
{
|
||||
auto ent = getEntry(path);
|
||||
|
||||
auto ent = getEntry(path);
|
||||
TCallable *call;
|
||||
if (GetObjectHeap(ent, call)) {
|
||||
GCList ls(this->dir->GetGC());
|
||||
auto fileO = call->Call(ls, {});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if (GetObject(fileO, strm))
|
||||
return strm;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(ent,dict))
|
||||
{
|
||||
data.Size = 0;
|
||||
data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755;
|
||||
data.BlockCount = 0;
|
||||
data.BlockSize = 0;
|
||||
data.Device = 0;
|
||||
data.DeviceId = 0;
|
||||
data.GroupId = 0;
|
||||
data.HardLinks = 1;
|
||||
data.Inode = 0;
|
||||
data.LastAccess = Tesses::Framework::Date::DateTime(0);
|
||||
data.LastModified = Tesses::Framework::Date::DateTime(0);
|
||||
data.LastStatus = Tesses::Framework::Date::DateTime(0);
|
||||
data.UserId = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
TCallable* cal;
|
||||
if(GetObjectHeap(ent, cal))
|
||||
{
|
||||
GCList ls(this->dir->GetGC());
|
||||
auto fileO= cal->Call(ls, {});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if(GetObject(fileO,strm)) {
|
||||
bool EmbedDirectory::Stat(Tesses::Framework::Filesystem::VFSPath path,
|
||||
Tesses::Framework::Filesystem::StatData &data) {
|
||||
auto ent = getEntry(path);
|
||||
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(ent, dict)) {
|
||||
data.Size = 0;
|
||||
data.Mode = Tesses::Framework::Filesystem::MODE_DIRECTORY | 0755;
|
||||
data.BlockCount = 0;
|
||||
data.BlockSize = 0;
|
||||
data.Device = 0;
|
||||
data.DeviceId = 0;
|
||||
data.GroupId = 0;
|
||||
data.HardLinks = 1;
|
||||
data.Inode = 0;
|
||||
data.LastAccess = Tesses::Framework::Date::DateTime(0);
|
||||
data.LastModified = Tesses::Framework::Date::DateTime(0);
|
||||
data.LastStatus = Tesses::Framework::Date::DateTime(0);
|
||||
data.UserId = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
TCallable *cal;
|
||||
if (GetObjectHeap(ent, cal)) {
|
||||
GCList ls(this->dir->GetGC());
|
||||
auto fileO = cal->Call(ls, {});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if (GetObject(fileO, strm)) {
|
||||
|
||||
data.Size = (uint64_t)strm->GetLength();
|
||||
data.Mode = Tesses::Framework::Filesystem::MODE_REGULAR | 0755;
|
||||
data.Mode = Tesses::Framework::Filesystem::MODE_REGULAR | 0755;
|
||||
data.BlockSize = 512;
|
||||
data.BlockCount = data.Size / data.BlockSize;
|
||||
|
||||
|
||||
data.Device = 0;
|
||||
data.DeviceId = 0;
|
||||
data.GroupId = 0;
|
||||
@@ -171,84 +151,70 @@ namespace Tesses::CrossLang {
|
||||
data.LastModified = Tesses::Framework::Date::DateTime(0);
|
||||
data.LastStatus = Tesses::Framework::Date::DateTime(0);
|
||||
data.UserId = 0;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class DICT_DIRENUM
|
||||
{
|
||||
GCList ls;
|
||||
TDictionary* dict;
|
||||
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
|
||||
bool hasStarted = false;
|
||||
public:
|
||||
std::string GetCurrent()
|
||||
{
|
||||
return this->current->first;
|
||||
}
|
||||
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary* dict) : ls(gc), dict(dict)
|
||||
{
|
||||
ls.Add(dict);
|
||||
}
|
||||
bool MoveNext()
|
||||
{
|
||||
if(!this->hasStarted)
|
||||
{
|
||||
this->hasStarted=true;
|
||||
this->current = this->dict->items.begin();
|
||||
return !this->dict->items.empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current++;
|
||||
return this->current != this->dict->items.end();
|
||||
}
|
||||
}
|
||||
class DICT_DIRENUM {
|
||||
GCList ls;
|
||||
TDictionary *dict;
|
||||
std::map<std::string, Tesses::CrossLang::TObject>::iterator current;
|
||||
bool hasStarted = false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
auto ent = getEntry(path);
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(ent,dict))
|
||||
{
|
||||
DICT_DIRENUM* dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator er(
|
||||
[dir2,path](Tesses::Framework::Filesystem::VFSPath& path2)->bool {
|
||||
if(dir2->MoveNext())
|
||||
{
|
||||
path2 = path / dir2->GetCurrent();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[dir2]()->void {
|
||||
delete dir2;
|
||||
}
|
||||
);
|
||||
|
||||
return er;
|
||||
public:
|
||||
std::string GetCurrent() { return this->current->first; }
|
||||
DICT_DIRENUM(std::shared_ptr<GC> gc, TDictionary *dict)
|
||||
: ls(gc), dict(dict) {
|
||||
ls.Add(dict);
|
||||
}
|
||||
bool MoveNext() {
|
||||
if (!this->hasStarted) {
|
||||
this->hasStarted = true;
|
||||
this->current = this->dict->items.begin();
|
||||
return !this->dict->items.empty();
|
||||
} else {
|
||||
this->current++;
|
||||
return this->current != this->dict->items.end();
|
||||
}
|
||||
return Tesses::Framework::Filesystem::VFSPathEnumerator();
|
||||
}
|
||||
};
|
||||
|
||||
EmbedDirectory::EmbedDirectory(std::shared_ptr<GC> gc, TDictionary* dict)
|
||||
{
|
||||
this->dir = CreateMarkedTObject(gc, dict);
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator
|
||||
EmbedDirectory::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
auto ent = getEntry(path);
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(ent, dict)) {
|
||||
DICT_DIRENUM *dir2 = new DICT_DIRENUM(this->dir->GetGC(), dict);
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator er(
|
||||
[dir2,
|
||||
path](Tesses::Framework::Filesystem::VFSPath &path2) -> bool {
|
||||
if (dir2->MoveNext()) {
|
||||
path2 = path / dir2->GetCurrent();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[dir2]() -> void { delete dir2; });
|
||||
|
||||
return er;
|
||||
}
|
||||
|
||||
std::string EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
return path.ToString();
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath EmbedDirectory::SystemToVFSPath(std::string path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return Tesses::Framework::Filesystem::VFSPathEnumerator();
|
||||
}
|
||||
|
||||
EmbedDirectory::EmbedDirectory(std::shared_ptr<GC> gc, TDictionary *dict) {
|
||||
this->dir = CreateMarkedTObject(gc, dict);
|
||||
}
|
||||
|
||||
std::string
|
||||
EmbedDirectory::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
return path.ToString();
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath
|
||||
EmbedDirectory::SystemToVFSPath(std::string path) {
|
||||
return path;
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,54 +1,64 @@
|
||||
#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)
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+371
-411
@@ -1,433 +1,393 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
CallStackEntry* ent;
|
||||
GCList ls2(ls);
|
||||
if(!this->hasStarted)
|
||||
{
|
||||
TClosure* clos;
|
||||
if(!GetObjectHeap(this->enumerator,clos)) return false;
|
||||
auto _enumerator= clos->Call(ls2,{});
|
||||
namespace Tesses::CrossLang {
|
||||
bool TYieldEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
CallStackEntry *ent;
|
||||
GCList ls2(ls);
|
||||
if (!this->hasStarted) {
|
||||
TClosure *clos;
|
||||
if (!GetObjectHeap(this->enumerator, clos))
|
||||
return false;
|
||||
auto _enumerator = clos->Call(ls2, {});
|
||||
ls->BarrierBegin();
|
||||
this->enumerator = _enumerator;
|
||||
this->hasStarted = true;
|
||||
ls->BarrierEnd();
|
||||
} else {
|
||||
|
||||
if (GetObjectHeap(this->enumerator, ent)) {
|
||||
auto _enumerator = ent->Resume(ls2);
|
||||
ls->BarrierBegin();
|
||||
this->enumerator = _enumerator;
|
||||
this->hasStarted=true;
|
||||
ls->BarrierEnd();
|
||||
}
|
||||
else {
|
||||
|
||||
if(GetObjectHeap(this->enumerator,ent))
|
||||
{
|
||||
auto _enumerator= ent->Resume(ls2);
|
||||
ls->BarrierBegin();
|
||||
this->enumerator = _enumerator;
|
||||
ls->BarrierEnd();
|
||||
|
||||
} else return false;
|
||||
}
|
||||
|
||||
if(GetObjectHeap(this->enumerator,ent))
|
||||
{
|
||||
ls->BarrierBegin();
|
||||
this->current = ent->Pop(ls2);
|
||||
ls->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject TYieldEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
ls.Add(this->current);
|
||||
return this->current;
|
||||
}
|
||||
void TYieldEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
GC::Mark(this->current);
|
||||
GC::Mark(this->enumerator);
|
||||
}
|
||||
TYieldEnumerator* TYieldEnumerator::Create(GCList& ls,TObject v)
|
||||
{
|
||||
TYieldEnumerator* yieldEnum = new TYieldEnumerator();
|
||||
yieldEnum->current=nullptr;
|
||||
yieldEnum->hasStarted=false;
|
||||
yieldEnum->enumerator = v;
|
||||
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(yieldEnum);
|
||||
_gc->Watch(yieldEnum);
|
||||
return yieldEnum;
|
||||
}
|
||||
TYieldEnumerator* TYieldEnumerator::Create(GCList* ls,TObject v)
|
||||
{
|
||||
|
||||
TYieldEnumerator* yieldEnum = new TYieldEnumerator();
|
||||
yieldEnum->current=nullptr;
|
||||
yieldEnum->hasStarted=false;
|
||||
yieldEnum->enumerator = v;
|
||||
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(yieldEnum);
|
||||
_gc->Watch(yieldEnum);
|
||||
return yieldEnum;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TCustomEnumerator::MoveNext(std::shared_ptr<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");
|
||||
}
|
||||
if (GetObjectHeap(this->enumerator, ent)) {
|
||||
ls->BarrierBegin();
|
||||
this->current = ent->Pop(ls2);
|
||||
ls->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject TYieldEnumerator::GetCurrent(GCList &ls) {
|
||||
ls.Add(this->current);
|
||||
return this->current;
|
||||
}
|
||||
void TYieldEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
GC::Mark(this->current);
|
||||
GC::Mark(this->enumerator);
|
||||
}
|
||||
TYieldEnumerator *TYieldEnumerator::Create(GCList &ls, TObject v) {
|
||||
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
|
||||
yieldEnum->current = nullptr;
|
||||
yieldEnum->hasStarted = false;
|
||||
yieldEnum->enumerator = v;
|
||||
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(yieldEnum);
|
||||
_gc->Watch(yieldEnum);
|
||||
return yieldEnum;
|
||||
}
|
||||
TYieldEnumerator *TYieldEnumerator::Create(GCList *ls, TObject v) {
|
||||
|
||||
TYieldEnumerator *yieldEnum = new TYieldEnumerator();
|
||||
yieldEnum->current = nullptr;
|
||||
yieldEnum->hasStarted = false;
|
||||
yieldEnum->enumerator = v;
|
||||
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(yieldEnum);
|
||||
_gc->Watch(yieldEnum);
|
||||
return yieldEnum;
|
||||
}
|
||||
|
||||
bool TCustomEnumerator::MoveNext(std::shared_ptr<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();
|
||||
return res;
|
||||
res = call->Call(ls, {});
|
||||
ls.GetGC()->BarrierBegin();
|
||||
} else {
|
||||
|
||||
res = this->dict->GetValue("Current");
|
||||
}
|
||||
void TCustomEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->dict->Mark();
|
||||
}
|
||||
TCustomEnumerator* TCustomEnumerator::Create(GCList* ls, TDictionary* dict)
|
||||
{
|
||||
TCustomEnumerator* customEnum = new TCustomEnumerator();
|
||||
customEnum->dict = dict;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(customEnum);
|
||||
_gc->Watch(customEnum);
|
||||
return customEnum;
|
||||
}
|
||||
TEnumerator* TEnumerator::CreateFromObject(GCList& ls, TObject obj)
|
||||
{
|
||||
std::string str;
|
||||
TList* mls;
|
||||
TDynamicList* dynList;
|
||||
TDynamicDictionary* dynDict;
|
||||
TDictionary* dict;
|
||||
TEnumerator* enumerator;
|
||||
TQueryable* q;
|
||||
if(GetObject(obj,str))
|
||||
{
|
||||
return TStringEnumerator::Create(ls, str);
|
||||
}
|
||||
else if(GetObjectHeap(obj,mls))
|
||||
{
|
||||
return TListEnumerator::Create(ls,mls);
|
||||
}
|
||||
else if(GetObjectHeap(obj,dynList))
|
||||
{
|
||||
return TDynamicListEnumerator::Create(ls,dynList);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if(GetObjectHeap(obj, q))
|
||||
{
|
||||
return q->GetEnumerator(ls);
|
||||
}
|
||||
else if(GetObjectHeap(obj, enumerator))
|
||||
{
|
||||
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;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(customEnum);
|
||||
_gc->Watch(customEnum);
|
||||
return customEnum;
|
||||
}
|
||||
TEnumerator *TEnumerator::CreateFromObject(GCList &ls, TObject obj) {
|
||||
std::string str;
|
||||
TList *mls;
|
||||
TDynamicList *dynList;
|
||||
TDynamicDictionary *dynDict;
|
||||
TDictionary *dict;
|
||||
TEnumerator *enumerator;
|
||||
TQueryable *q;
|
||||
if (GetObject(obj, str)) {
|
||||
return TStringEnumerator::Create(ls, str);
|
||||
} else if (GetObjectHeap(obj, mls)) {
|
||||
return TListEnumerator::Create(ls, mls);
|
||||
} else if (GetObjectHeap(obj, dynList)) {
|
||||
return TDynamicListEnumerator::Create(ls, dynList);
|
||||
} 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;
|
||||
} else if (GetObjectHeap(obj, q)) {
|
||||
return q->GetEnumerator(ls);
|
||||
} else if (GetObjectHeap(obj, enumerator)) {
|
||||
return enumerator;
|
||||
}
|
||||
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList& ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
|
||||
{
|
||||
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
|
||||
vfspathe->enumerator = enumerator;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(vfspathe);
|
||||
_gc->Watch(vfspathe);
|
||||
return vfspathe;
|
||||
return nullptr;
|
||||
}
|
||||
TVFSPathEnumerator *TVFSPathEnumerator::Create(
|
||||
GCList &ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator) {
|
||||
TVFSPathEnumerator *vfspathe = new TVFSPathEnumerator();
|
||||
vfspathe->enumerator = enumerator;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(vfspathe);
|
||||
_gc->Watch(vfspathe);
|
||||
return vfspathe;
|
||||
}
|
||||
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<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;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(dicte);
|
||||
_gc->Watch(dicte);
|
||||
return dicte;
|
||||
}
|
||||
|
||||
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<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();
|
||||
}
|
||||
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList* ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
|
||||
{
|
||||
TVFSPathEnumerator* vfspathe = new TVFSPathEnumerator();
|
||||
vfspathe->enumerator = enumerator;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(vfspathe);
|
||||
_gc->Watch(vfspathe);
|
||||
return vfspathe;
|
||||
}
|
||||
bool TVFSPathEnumerator::MoveNext(std::shared_ptr<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;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(dicte);
|
||||
_gc->Watch(dicte);
|
||||
return dicte;
|
||||
}
|
||||
|
||||
bool TDictionaryEnumerator::MoveNext(std::shared_ptr<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;
|
||||
}
|
||||
}
|
||||
TObject TDictionaryEnumerator::GetCurrent(GCList &ls) {
|
||||
if (!this->hasStarted)
|
||||
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;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TListEnumerator::MoveNext(std::shared_ptr<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;
|
||||
if (this->ittr != this->dict->items.end()) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TObject o = this->ls->Get(index);
|
||||
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 o;
|
||||
}
|
||||
void TListEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked = true;
|
||||
this->ls->Mark();
|
||||
return kvp;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TDictionaryEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->dict->Mark();
|
||||
}
|
||||
|
||||
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList& ls, TAssociativeArray* list)
|
||||
{
|
||||
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
TAssociativeArrayEnumerator* TAssociativeArrayEnumerator::Create(GCList* ls, TAssociativeArray* list)
|
||||
{
|
||||
TAssociativeArrayEnumerator* liste=new TAssociativeArrayEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
this->index++;
|
||||
return this->index >= 0 && this->index < this->ls->Count();
|
||||
}
|
||||
TObject TAssociativeArrayEnumerator::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();
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->SetValue("Key",this->ls->GetKey(this->index));
|
||||
dict->SetValue("Value",this->ls->GetValue(this->index));
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
void TAssociativeArrayEnumerator::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked = true;
|
||||
this->ls->Mark();
|
||||
}
|
||||
TListEnumerator *TListEnumerator::Create(GCList &ls, TList *list) {
|
||||
TListEnumerator *liste = new TListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
this->index++;
|
||||
return this->index >= 0 && this->index < this->ls->Count();
|
||||
}
|
||||
TObject TListEnumerator::GetCurrent(GCList &ls) {
|
||||
|
||||
|
||||
|
||||
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList& ls, TDynamicList* list)
|
||||
{
|
||||
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
TDynamicListEnumerator* TDynamicListEnumerator::Create(GCList* ls, TDynamicList* list)
|
||||
{
|
||||
TDynamicListEnumerator* liste=new TDynamicListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
this->index++;
|
||||
GCList ls2(ls);
|
||||
return this->index >= 0 && this->index < this->ls->Count(ls2);
|
||||
}
|
||||
TObject TDynamicListEnumerator::GetCurrent(GCList& ls)
|
||||
{
|
||||
|
||||
if(this->index < -1) return nullptr;
|
||||
auto r = this->ls->Count(ls);
|
||||
if(r == 0) return nullptr;
|
||||
if(this->index >= r) return nullptr;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TObject o = this->ls->GetAt(ls,index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return o;
|
||||
}
|
||||
void TDynamicListEnumerator::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;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(stre);
|
||||
_gc->Watch(stre);
|
||||
return stre;
|
||||
}
|
||||
bool TStringEnumerator::MoveNext(std::shared_ptr<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];
|
||||
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();
|
||||
}
|
||||
|
||||
};
|
||||
TAssociativeArrayEnumerator *
|
||||
TAssociativeArrayEnumerator::Create(GCList &ls, TAssociativeArray *list) {
|
||||
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
TAssociativeArrayEnumerator *
|
||||
TAssociativeArrayEnumerator::Create(GCList *ls, TAssociativeArray *list) {
|
||||
TAssociativeArrayEnumerator *liste = new TAssociativeArrayEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TAssociativeArrayEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
this->index++;
|
||||
return this->index >= 0 && this->index < this->ls->Count();
|
||||
}
|
||||
TObject TAssociativeArrayEnumerator::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();
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->SetValue("Key", this->ls->GetKey(this->index));
|
||||
dict->SetValue("Value", this->ls->GetValue(this->index));
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
void TAssociativeArrayEnumerator::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->ls->Mark();
|
||||
}
|
||||
|
||||
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList &ls,
|
||||
TDynamicList *list) {
|
||||
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
TDynamicListEnumerator *TDynamicListEnumerator::Create(GCList *ls,
|
||||
TDynamicList *list) {
|
||||
TDynamicListEnumerator *liste = new TDynamicListEnumerator();
|
||||
liste->ls = list;
|
||||
liste->index = -1;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(liste);
|
||||
_gc->Watch(liste);
|
||||
return liste;
|
||||
}
|
||||
bool TDynamicListEnumerator::MoveNext(std::shared_ptr<GC> ls) {
|
||||
this->index++;
|
||||
GCList ls2(ls);
|
||||
return this->index >= 0 && this->index < this->ls->Count(ls2);
|
||||
}
|
||||
TObject TDynamicListEnumerator::GetCurrent(GCList &ls) {
|
||||
|
||||
if (this->index < -1)
|
||||
return nullptr;
|
||||
auto r = this->ls->Count(ls);
|
||||
if (r == 0)
|
||||
return nullptr;
|
||||
if (this->index >= r)
|
||||
return nullptr;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TObject o = this->ls->GetAt(ls, index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return o;
|
||||
}
|
||||
void TDynamicListEnumerator::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;
|
||||
std::shared_ptr<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;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(stre);
|
||||
_gc->Watch(stre);
|
||||
return stre;
|
||||
}
|
||||
bool TStringEnumerator::MoveNext(std::shared_ptr<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;
|
||||
}
|
||||
|
||||
}; // namespace Tesses::CrossLang
|
||||
+168
-207
@@ -1,223 +1,184 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang {
|
||||
TDynamicList* TDynamicList::Create(GCList& ls,TCallable* callable)
|
||||
{
|
||||
TDynamicList* list=new TDynamicList();
|
||||
list->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TDynamicList* TDynamicList::Create(GCList* ls,TCallable* callable)
|
||||
{
|
||||
TDynamicList* list=new TDynamicList();
|
||||
list->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TDynamicList *TDynamicList::Create(GCList &ls, TCallable *callable) {
|
||||
TDynamicList *list = new TDynamicList();
|
||||
list->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TDynamicList *TDynamicList::Create(GCList *ls, TCallable *callable) {
|
||||
TDynamicList *list = new TDynamicList();
|
||||
list->cb = callable;
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
void TDynamicList::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
this->cb->Mark();
|
||||
}
|
||||
void TDynamicList::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
this->cb->Mark();
|
||||
}
|
||||
|
||||
int64_t TDynamicList::Count(GCList& ls)
|
||||
{
|
||||
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Count");
|
||||
ls.GetGC()->BarrierEnd();
|
||||
auto res = cb->Call(ls,{dict});
|
||||
int64_t n;
|
||||
if(GetObject(res,n)) return n;
|
||||
return 0;
|
||||
}
|
||||
TObject TDynamicList::Add(GCList& ls, TObject v)
|
||||
{
|
||||
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Add");
|
||||
dict->SetValue("Value",v);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls,{dict});
|
||||
|
||||
}
|
||||
TObject TDynamicList::Insert(GCList& ls, int64_t index, TObject v)
|
||||
{
|
||||
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Insert");
|
||||
dict->SetValue("Index",index);
|
||||
dict->SetValue("Value",v);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls,{dict});
|
||||
|
||||
}
|
||||
TObject TDynamicList::Clear(GCList& ls)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Clear");
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls,{dict});
|
||||
}
|
||||
TObject TDynamicList::Remove(GCList& ls, TObject obj)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Remove");
|
||||
dict->SetValue("Value", obj);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return cb->Call(ls,{dict});
|
||||
}
|
||||
TObject TDynamicList::RemoveAllEqual(GCList& ls, TObject obj)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "RemoveAllEqual");
|
||||
dict->SetValue("Value", obj);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return cb->Call(ls,{dict});
|
||||
}
|
||||
TObject TDynamicList::RemoveAt(GCList& ls, int64_t index)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "RemoveAt");
|
||||
dict->SetValue("Index", index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return cb->Call(ls,{dict});
|
||||
}
|
||||
TObject TDynamicList::ToString(GCList& ls)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "ToString");
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return cb->Call(ls,{dict});
|
||||
}
|
||||
int64_t TDynamicList::Count(GCList &ls) {
|
||||
|
||||
TObject TDynamicList::GetAt(GCList& ls, int64_t index)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Count");
|
||||
ls.GetGC()->BarrierEnd();
|
||||
auto res = cb->Call(ls, {dict});
|
||||
int64_t n;
|
||||
if (GetObject(res, n))
|
||||
return n;
|
||||
return 0;
|
||||
}
|
||||
TObject TDynamicList::Add(GCList &ls, TObject v) {
|
||||
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetAt");
|
||||
dict->SetValue("Index",index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls,{dict});
|
||||
}
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Add");
|
||||
dict->SetValue("Value", v);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::Insert(GCList &ls, int64_t index, TObject v) {
|
||||
|
||||
TObject TDynamicList::SetAt(GCList& ls, int64_t index, TObject val)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "SetAt");
|
||||
dict->SetValue("Index",index);
|
||||
dict->SetValue("Value",val);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls,{dict});
|
||||
}
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Insert");
|
||||
dict->SetValue("Index", index);
|
||||
dict->SetValue("Value", v);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::Clear(GCList &ls) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Clear");
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::Remove(GCList &ls, TObject obj) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "Remove");
|
||||
dict->SetValue("Value", obj);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
TDynamicList::~TDynamicList()
|
||||
{
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::RemoveAllEqual(GCList &ls, TObject obj) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "RemoveAllEqual");
|
||||
dict->SetValue("Value", obj);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
}
|
||||
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::RemoveAt(GCList &ls, int64_t index) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "RemoveAt");
|
||||
dict->SetValue("Index", index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
TByteArray* TByteArray::Create(GCList& ls)
|
||||
{
|
||||
TByteArray* arr=new TByteArray();
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(arr);
|
||||
_gc->Watch(arr);
|
||||
return arr;
|
||||
}
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
TObject TDynamicList::ToString(GCList &ls) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "ToString");
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
TByteArray* TByteArray::Create(GCList* ls)
|
||||
{
|
||||
TByteArray* arr=new TByteArray();
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(arr);
|
||||
_gc->Watch(arr);
|
||||
return arr;
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TObject TDynamicList::GetAt(GCList &ls, int64_t index) {
|
||||
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "GetAt");
|
||||
dict->SetValue("Index", index);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TObject TDynamicList::SetAt(GCList &ls, int64_t index, TObject val) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type", "SetAt");
|
||||
dict->SetValue("Index", index);
|
||||
dict->SetValue("Value", val);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return cb->Call(ls, {dict});
|
||||
}
|
||||
|
||||
TDynamicList::~TDynamicList() {}
|
||||
|
||||
TByteArray *TByteArray::Create(GCList &ls) {
|
||||
TByteArray *arr = new TByteArray();
|
||||
std::shared_ptr<GC> _gc = ls.GetGC();
|
||||
ls.Add(arr);
|
||||
_gc->Watch(arr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
TByteArray *TByteArray::Create(GCList *ls) {
|
||||
TByteArray *arr = new TByteArray();
|
||||
std::shared_ptr<GC> _gc = ls->GetGC();
|
||||
ls->Add(arr);
|
||||
_gc->Watch(arr);
|
||||
return arr;
|
||||
}
|
||||
TList *TList::Create(GCList *gc) {
|
||||
TList *list = new TList();
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TList *TList::Create(GCList &gc) {
|
||||
TList *list = new TList();
|
||||
std::shared_ptr<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;
|
||||
}
|
||||
TList* TList::Create(GCList* gc)
|
||||
{
|
||||
TList* list=new TList();
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
}
|
||||
TObject TList::Get(int64_t index) {
|
||||
if (index >= 0 && index < this->Count()) {
|
||||
return this->items[index];
|
||||
}
|
||||
TList* TList::Create(GCList& gc)
|
||||
{
|
||||
TList* list=new TList();
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(list);
|
||||
_gc->Watch(list);
|
||||
return list;
|
||||
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::Add(TObject value)
|
||||
{
|
||||
this->items.push_back(value);
|
||||
}
|
||||
void TList::RemoveAt(int64_t index) {
|
||||
if (index >= 0 && index < this->Count()) {
|
||||
this->items.erase(this->items.begin() + index);
|
||||
}
|
||||
void TList::Set(int64_t index, TObject value)
|
||||
{
|
||||
if(index >= 0 && index < this->Count())
|
||||
{
|
||||
this->items[index] = value;
|
||||
}
|
||||
}
|
||||
void TList::Clear() { this->items.clear(); }
|
||||
void TList::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
for (auto item : this->items) {
|
||||
GC::Mark(item);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}; // namespace Tesses::CrossLang
|
||||
+49
-71
@@ -1,75 +1,53 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TNativeObject::~TNativeObject()
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TNativeObject::~TNativeObject() {}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
bool TNativeObject::ToBool()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right)
|
||||
{
|
||||
if(std::holds_alternative<THeapObjectHolder>(right))
|
||||
{
|
||||
return this == std::get<THeapObjectHolder>(right).obj;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TNative* TNative::Create(GCList& ls, void* ptr,std::function<void(void*)> destroy)
|
||||
{
|
||||
TNative* native = new TNative(ptr,destroy);
|
||||
std::shared_ptr<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);
|
||||
std::shared_ptr<GC> gc = ls->GetGC();
|
||||
ls->Add(native);
|
||||
gc->Watch(native);
|
||||
return native;
|
||||
}
|
||||
TNative::~TNative()
|
||||
{
|
||||
this->Destroy();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
bool TNativeObject::ToBool() { return true; }
|
||||
bool TNativeObject::Equals(std::shared_ptr<GC> gc, TObject right) {
|
||||
if (std::holds_alternative<THeapObjectHolder>(right)) {
|
||||
return this == std::get<THeapObjectHolder>(right).obj;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TNative *TNative::Create(GCList &ls, void *ptr,
|
||||
std::function<void(void *)> destroy) {
|
||||
TNative *native = new TNative(ptr, destroy);
|
||||
std::shared_ptr<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);
|
||||
std::shared_ptr<GC> gc = ls->GetGC();
|
||||
ls->Add(native);
|
||||
gc->Watch(native);
|
||||
return native;
|
||||
}
|
||||
TNative::~TNative() { this->Destroy(); }
|
||||
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
+452
-498
@@ -1,522 +1,476 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TQueryable::TQueryable(TObject parent) : TQueryable(parent,TQueryableMode::Passthrough, {})
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TQueryable::TQueryable(TObject parent)
|
||||
: TQueryable(parent, TQueryableMode::Passthrough, {}) {}
|
||||
TQueryable::TQueryable(TObject parent, TQueryableMode mode,
|
||||
std::vector<TObject> args)
|
||||
: parent(parent), mode(mode), args(args) {}
|
||||
|
||||
}
|
||||
TQueryable::TQueryable(TObject parent, TQueryableMode mode, std::vector<TObject> args): parent(parent), mode(mode), args(args)
|
||||
{
|
||||
TQueryable *TQueryable::Skip(GCList &ls, int64_t no) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Skip, {no});
|
||||
}
|
||||
TQueryable *TQueryable::SkipWhile(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::SkipWhile, {call});
|
||||
}
|
||||
TQueryable *TQueryable::Take(GCList &ls, int64_t no) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Take, {no});
|
||||
}
|
||||
TQueryable *TQueryable::TakeWhile(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::TakeWhile, {call});
|
||||
}
|
||||
TQueryable *TQueryable::Select(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Select, {call});
|
||||
}
|
||||
TQueryable *TQueryable::Where(GCList &ls, TCallable *call) {
|
||||
return TQueryable::Create(ls, this, TQueryableMode::Where, {call});
|
||||
}
|
||||
|
||||
TList *TQueryable::ToList(GCList &ls) {
|
||||
auto gc = ls.GetGC();
|
||||
GCList ls2(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return nullptr;
|
||||
auto list = TList::Create(ls);
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
gc->BarrierBegin();
|
||||
list->Add(enumerator->GetCurrent(ls));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
TQueryable *TQueryable::Create(GCList &ls, TObject parent) {
|
||||
TQueryable *queryable = new TQueryable(parent);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
TQueryable *TQueryable::Create(GCList &ls, TObject parent, TQueryableMode mode,
|
||||
std::vector<TObject> args) {
|
||||
TQueryable *queryable = new TQueryable(parent, mode, args);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
|
||||
TQueryable* TQueryable::Skip(GCList& ls,int64_t no)
|
||||
{
|
||||
return TQueryable::Create(ls,this,TQueryableMode::Skip, {no});
|
||||
}
|
||||
TQueryable* TQueryable::SkipWhile(GCList& ls, TCallable* call)
|
||||
{
|
||||
return TQueryable::Create(ls,this,TQueryableMode::SkipWhile, {call});
|
||||
}
|
||||
TQueryable* TQueryable::Take(GCList& ls, int64_t no)
|
||||
{
|
||||
return TQueryable::Create(ls,this,TQueryableMode::Take, {no});
|
||||
}
|
||||
TQueryable* TQueryable::TakeWhile(GCList& ls, TCallable* call)
|
||||
{
|
||||
return TQueryable::Create(ls,this,TQueryableMode::TakeWhile, {call});
|
||||
}
|
||||
TQueryable* TQueryable::Select(GCList& ls, TCallable* call)
|
||||
{
|
||||
return TQueryable::Create(ls,this,TQueryableMode::Select, {call});
|
||||
}
|
||||
TQueryable* TQueryable::Where(GCList& ls, TCallable* call)
|
||||
{
|
||||
return TQueryable::Create(ls,this,TQueryableMode::Where, {call});
|
||||
}
|
||||
|
||||
TList* TQueryable::ToList(GCList& ls)
|
||||
{
|
||||
auto gc = ls.GetGC();
|
||||
void TQueryable::Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
GC::Mark(this->parent);
|
||||
for (auto &item : args)
|
||||
GC::Mark(item);
|
||||
}
|
||||
|
||||
void TQueryable::ForEach(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if(enumerator == nullptr) return nullptr;
|
||||
auto list = TList::Create(ls);
|
||||
while(enumerator->MoveNext(gc))
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
list->Add(enumerator->GetCurrent(ls));
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
return list;
|
||||
call->Call(ls2, {enumerator->GetCurrent(ls2)});
|
||||
}
|
||||
TQueryable* TQueryable::Create(GCList& ls, TObject parent)
|
||||
{
|
||||
TQueryable* queryable = new TQueryable(parent);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
TQueryable* TQueryable::Create(GCList& ls, TObject parent, TQueryableMode mode, std::vector<TObject> args)
|
||||
{
|
||||
TQueryable* queryable = new TQueryable(parent, mode,args);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
|
||||
|
||||
void TQueryable::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
|
||||
GC::Mark(this->parent);
|
||||
for(auto& item : args)
|
||||
GC::Mark(item);
|
||||
}
|
||||
|
||||
void TQueryable::ForEach(std::shared_ptr<GC> gc, TCallable* call)
|
||||
{
|
||||
if(call == nullptr) return;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if(enumerator == nullptr) return;
|
||||
while(enumerator->MoveNext(gc))
|
||||
{
|
||||
GCList ls2(gc);
|
||||
call->Call(ls2,{enumerator->GetCurrent(ls2)});
|
||||
}
|
||||
}
|
||||
int64_t TQueryable::Count(std::shared_ptr<GC> gc, TCallable* call)
|
||||
{
|
||||
if(call == nullptr) return 0;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if(enumerator == nullptr) return 0;
|
||||
int64_t count=0;
|
||||
while(enumerator->MoveNext(gc))
|
||||
{
|
||||
GCList ls2(gc);
|
||||
if(ToBool(call->Call(ls2,{enumerator->GetCurrent(ls2)}))) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
int64_t TQueryable::Count(std::shared_ptr<GC> gc)
|
||||
{
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if(enumerator == nullptr) return 0;
|
||||
int64_t count=0;
|
||||
while(enumerator->MoveNext(gc))
|
||||
{
|
||||
}
|
||||
int64_t TQueryable::Count(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return 0;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return 0;
|
||||
int64_t count = 0;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
if (ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
bool TQueryable::Contains(std::shared_ptr<GC> gc, TObject value)
|
||||
{
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if(enumerator == nullptr) return false;
|
||||
while(enumerator->MoveNext(gc))
|
||||
{
|
||||
GCList ls2(gc);
|
||||
|
||||
return count;
|
||||
}
|
||||
int64_t TQueryable::Count(std::shared_ptr<GC> gc) {
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return 0;
|
||||
int64_t count = 0;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
bool TQueryable::Contains(std::shared_ptr<GC> gc, TObject value) {
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return false;
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
|
||||
if(Equals(gc,value,enumerator->GetCurrent(ls2)))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
if (Equals(gc, value, enumerator->GetCurrent(ls2)))
|
||||
return true;
|
||||
}
|
||||
bool TQueryable::Any(std::shared_ptr<GC> gc, TCallable* call)
|
||||
{
|
||||
if(call == nullptr) return false;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if(enumerator == nullptr) return false;
|
||||
|
||||
while(enumerator->MoveNext(gc))
|
||||
{
|
||||
GCList ls2(gc);
|
||||
if(ToBool(call->Call(ls2,{enumerator->GetCurrent(ls2)}))) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TQueryable::Any(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return false;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return false;
|
||||
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
if (ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
|
||||
return true;
|
||||
}
|
||||
bool TQueryable::All(std::shared_ptr<GC> gc, TCallable* call)
|
||||
{
|
||||
if(call == nullptr) return true;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if(enumerator == nullptr) return true;
|
||||
|
||||
while(enumerator->MoveNext(gc))
|
||||
{
|
||||
GCList ls2(gc);
|
||||
if(!ToBool(call->Call(ls2,{enumerator->GetCurrent(ls2)}))) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TQueryable::All(std::shared_ptr<GC> gc, TCallable *call) {
|
||||
if (call == nullptr)
|
||||
return true;
|
||||
GCList ls(gc);
|
||||
auto enumerator = this->GetEnumerator(ls);
|
||||
if (enumerator == nullptr)
|
||||
return true;
|
||||
|
||||
while (enumerator->MoveNext(gc)) {
|
||||
GCList ls2(gc);
|
||||
if (!ToBool(call->Call(ls2, {enumerator->GetCurrent(ls2)})))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class SkipItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator* parentEnum;
|
||||
int64_t skipCount;
|
||||
SkipItterator(TEnumerator* parentEnum, int64_t skipCount) : parentEnum(parentEnum), skipCount(skipCount)
|
||||
{
|
||||
class SkipItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
int64_t skipCount;
|
||||
SkipItterator(TEnumerator *parentEnum, int64_t skipCount)
|
||||
: parentEnum(parentEnum), skipCount(skipCount) {}
|
||||
|
||||
}
|
||||
public:
|
||||
static SkipItterator* Create(GCList& ls, TEnumerator* parentEnum, int64_t skipCount)
|
||||
{
|
||||
SkipItterator* queryable = new SkipItterator(parentEnum, skipCount);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(this->parentEnum == nullptr) return false;
|
||||
while(skipCount > 0)
|
||||
{
|
||||
if(!this->parentEnum->MoveNext(ls)) {
|
||||
skipCount=0;
|
||||
return false;
|
||||
}
|
||||
skipCount--;
|
||||
}
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
TObject GetCurrent(GCList& ls)
|
||||
{
|
||||
return this->parentEnum->GetCurrent(ls);
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
|
||||
if(parentEnum != nullptr) parentEnum->Mark();
|
||||
}
|
||||
};
|
||||
class TakeItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator* parentEnum;
|
||||
int64_t takeCount;
|
||||
TakeItterator(TEnumerator* parentEnum, int64_t takeCount) : parentEnum(parentEnum), takeCount(takeCount)
|
||||
{
|
||||
|
||||
}
|
||||
public:
|
||||
static TakeItterator* Create(GCList& ls, TEnumerator* parentEnum, int64_t takeCount)
|
||||
{
|
||||
TakeItterator* queryable = new TakeItterator(parentEnum, takeCount);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(this->parentEnum == nullptr) return false;
|
||||
if(takeCount > 0)
|
||||
{
|
||||
takeCount--;
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
public:
|
||||
static SkipItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
int64_t skipCount) {
|
||||
SkipItterator *queryable = new SkipItterator(parentEnum, skipCount);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
while (skipCount > 0) {
|
||||
if (!this->parentEnum->MoveNext(ls)) {
|
||||
skipCount = 0;
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList& ls)
|
||||
{
|
||||
return this->parentEnum->GetCurrent(ls);
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
|
||||
if(parentEnum != nullptr) parentEnum->Mark();
|
||||
}
|
||||
};
|
||||
class SkipWhileItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator* parentEnum;
|
||||
TCallable* callable;
|
||||
SkipWhileItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
|
||||
{
|
||||
|
||||
}
|
||||
public:
|
||||
static SkipWhileItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
|
||||
{
|
||||
SkipWhileItterator* queryable = new SkipWhileItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(this->parentEnum == nullptr) return false;
|
||||
ls->BarrierBegin();
|
||||
auto callable = this->callable;
|
||||
ls->BarrierEnd();
|
||||
|
||||
if(callable != nullptr)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
if(this->parentEnum->MoveNext(ls))
|
||||
{
|
||||
GCList ls2(ls);
|
||||
auto result = callable->Call(ls2,{this->parentEnum->GetCurrent(ls2)});
|
||||
if(!ToBool(result))
|
||||
{
|
||||
ls->BarrierBegin();
|
||||
this->callable=nullptr;
|
||||
ls->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ls->BarrierBegin();
|
||||
this->callable=nullptr;
|
||||
ls->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList& ls)
|
||||
{
|
||||
return this->parentEnum->GetCurrent(ls);
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
|
||||
if(parentEnum != nullptr) parentEnum->Mark();
|
||||
if(callable != nullptr) callable->Mark();
|
||||
}
|
||||
};
|
||||
class TakeWhileItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator* parentEnum;
|
||||
TCallable* callable;
|
||||
TakeWhileItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
|
||||
{
|
||||
|
||||
}
|
||||
public:
|
||||
static TakeWhileItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
|
||||
{
|
||||
TakeWhileItterator* queryable = new TakeWhileItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(this->parentEnum == nullptr) return false;
|
||||
ls->BarrierBegin();
|
||||
auto callable = this->callable;
|
||||
ls->BarrierEnd();
|
||||
if(callable != nullptr)
|
||||
{
|
||||
if(this->parentEnum->MoveNext(ls))
|
||||
{
|
||||
GCList ls2(ls);
|
||||
auto result = callable->Call(ls2,{this->parentEnum->GetCurrent(ls2)});
|
||||
if(!ToBool(result))
|
||||
{
|
||||
ls->BarrierBegin();
|
||||
this->callable=nullptr;
|
||||
ls->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList& ls)
|
||||
{
|
||||
return this->parentEnum->GetCurrent(ls);
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
|
||||
if(parentEnum != nullptr) parentEnum->Mark();
|
||||
if(callable != nullptr) callable->Mark();
|
||||
}
|
||||
};
|
||||
class WhereItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator* parentEnum;
|
||||
TCallable* callable;
|
||||
WhereItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
|
||||
{
|
||||
|
||||
}
|
||||
public:
|
||||
static WhereItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
|
||||
{
|
||||
WhereItterator* queryable = new WhereItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(this->parentEnum == nullptr || this->callable == nullptr) return false;
|
||||
while(this->parentEnum->MoveNext(ls))
|
||||
{
|
||||
GCList ls2(ls);
|
||||
auto cur = this->parentEnum->GetCurrent(ls2);
|
||||
if(ToBool(callable->Call(ls2,{cur})))
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList& ls)
|
||||
{
|
||||
return this->parentEnum->GetCurrent(ls);
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
|
||||
if(parentEnum != nullptr) parentEnum->Mark();
|
||||
if(callable != nullptr) callable->Mark();
|
||||
}
|
||||
};
|
||||
class SelectItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator* parentEnum;
|
||||
TCallable* callable;
|
||||
TObject value;
|
||||
SelectItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
|
||||
{
|
||||
|
||||
}
|
||||
public:
|
||||
static SelectItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
|
||||
{
|
||||
SelectItterator* queryable = new SelectItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls)
|
||||
{
|
||||
if(this->parentEnum == nullptr || this->callable == nullptr) return false;
|
||||
if(this->parentEnum->MoveNext(ls))
|
||||
{
|
||||
GCList ls2(ls);
|
||||
auto cur = this->parentEnum->GetCurrent(ls2);
|
||||
auto value = this->callable->Call(ls2,{cur});
|
||||
|
||||
ls->BarrierBegin();
|
||||
this->value = value;
|
||||
ls->BarrierEnd();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList& ls)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto value=this->value;
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
|
||||
if(parentEnum != nullptr) parentEnum->Mark();
|
||||
if(callable != nullptr) callable->Mark();
|
||||
|
||||
GC::Mark(this->value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEnumerator* TQueryable::GetEnumerator(GCList& ls)
|
||||
{
|
||||
switch(this->mode)
|
||||
{
|
||||
case TQueryableMode::Skip:
|
||||
{
|
||||
int64_t skipCount;
|
||||
if(GetArgument(args,0,skipCount))
|
||||
return SkipItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), skipCount);
|
||||
}
|
||||
break;
|
||||
case TQueryableMode::Take:
|
||||
{
|
||||
int64_t takeCount;
|
||||
if(GetArgument(args,0,takeCount))
|
||||
return TakeItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), takeCount);
|
||||
|
||||
}
|
||||
break;
|
||||
case TQueryableMode::SkipWhile:
|
||||
{
|
||||
TCallable* callable;
|
||||
if(GetArgumentHeap(args,0,callable))
|
||||
return SkipWhileItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
}
|
||||
break;
|
||||
case TQueryableMode::TakeWhile:
|
||||
{
|
||||
TCallable* callable;
|
||||
if(GetArgumentHeap(args,0,callable))
|
||||
return TakeWhileItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
}
|
||||
break;
|
||||
case TQueryableMode::Select:
|
||||
{
|
||||
TCallable* callable;
|
||||
if(GetArgumentHeap(args,0,callable))
|
||||
return SelectItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
}
|
||||
break;
|
||||
case TQueryableMode::Where:
|
||||
{
|
||||
TCallable* callable;
|
||||
if(GetArgumentHeap(args,0,callable))
|
||||
return WhereItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
}
|
||||
break;
|
||||
skipCount--;
|
||||
}
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
return TEnumerator::CreateFromObject(ls, this->parent);
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
}
|
||||
};
|
||||
class TakeItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
int64_t takeCount;
|
||||
TakeItterator(TEnumerator *parentEnum, int64_t takeCount)
|
||||
: parentEnum(parentEnum), takeCount(takeCount) {}
|
||||
|
||||
public:
|
||||
static TakeItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
int64_t takeCount) {
|
||||
TakeItterator *queryable = new TakeItterator(parentEnum, takeCount);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
if (takeCount > 0) {
|
||||
takeCount--;
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
}
|
||||
};
|
||||
class SkipWhileItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
SkipWhileItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static SkipWhileItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
SkipWhileItterator *queryable =
|
||||
new SkipWhileItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
ls->BarrierBegin();
|
||||
auto callable = this->callable;
|
||||
ls->BarrierEnd();
|
||||
|
||||
if (callable != nullptr) {
|
||||
while (true) {
|
||||
if (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto result = callable->Call(
|
||||
ls2, {this->parentEnum->GetCurrent(ls2)});
|
||||
if (!ToBool(result)) {
|
||||
ls->BarrierBegin();
|
||||
this->callable = nullptr;
|
||||
ls->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
ls->BarrierBegin();
|
||||
this->callable = nullptr;
|
||||
ls->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this->parentEnum->MoveNext(ls);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
}
|
||||
};
|
||||
class TakeWhileItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
TakeWhileItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static TakeWhileItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
TakeWhileItterator *queryable =
|
||||
new TakeWhileItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr)
|
||||
return false;
|
||||
ls->BarrierBegin();
|
||||
auto callable = this->callable;
|
||||
ls->BarrierEnd();
|
||||
if (callable != nullptr) {
|
||||
if (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto result =
|
||||
callable->Call(ls2, {this->parentEnum->GetCurrent(ls2)});
|
||||
if (!ToBool(result)) {
|
||||
ls->BarrierBegin();
|
||||
this->callable = nullptr;
|
||||
ls->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
}
|
||||
};
|
||||
class WhereItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
WhereItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static WhereItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
WhereItterator *queryable = new WhereItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr || this->callable == nullptr)
|
||||
return false;
|
||||
while (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto cur = this->parentEnum->GetCurrent(ls2);
|
||||
if (ToBool(callable->Call(ls2, {cur})))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) { return this->parentEnum->GetCurrent(ls); }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
}
|
||||
};
|
||||
class SelectItterator : public TEnumerator {
|
||||
private:
|
||||
TEnumerator *parentEnum;
|
||||
TCallable *callable;
|
||||
TObject value;
|
||||
SelectItterator(TEnumerator *parentEnum, TCallable *callable)
|
||||
: parentEnum(parentEnum), callable(callable) {}
|
||||
|
||||
public:
|
||||
static SelectItterator *Create(GCList &ls, TEnumerator *parentEnum,
|
||||
TCallable *callable) {
|
||||
SelectItterator *queryable = new SelectItterator(parentEnum, callable);
|
||||
std::shared_ptr<GC> gc = ls.GetGC();
|
||||
ls.Add(queryable);
|
||||
gc->Watch(queryable);
|
||||
return queryable;
|
||||
}
|
||||
bool MoveNext(std::shared_ptr<GC> ls) {
|
||||
if (this->parentEnum == nullptr || this->callable == nullptr)
|
||||
return false;
|
||||
if (this->parentEnum->MoveNext(ls)) {
|
||||
GCList ls2(ls);
|
||||
auto cur = this->parentEnum->GetCurrent(ls2);
|
||||
auto value = this->callable->Call(ls2, {cur});
|
||||
|
||||
ls->BarrierBegin();
|
||||
this->value = value;
|
||||
ls->BarrierEnd();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject GetCurrent(GCList &ls) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto value = this->value;
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
|
||||
if (parentEnum != nullptr)
|
||||
parentEnum->Mark();
|
||||
if (callable != nullptr)
|
||||
callable->Mark();
|
||||
|
||||
GC::Mark(this->value);
|
||||
}
|
||||
};
|
||||
|
||||
TEnumerator *TQueryable::GetEnumerator(GCList &ls) {
|
||||
switch (this->mode) {
|
||||
case TQueryableMode::Skip: {
|
||||
int64_t skipCount;
|
||||
if (GetArgument(args, 0, skipCount))
|
||||
return SkipItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), skipCount);
|
||||
} break;
|
||||
case TQueryableMode::Take: {
|
||||
int64_t takeCount;
|
||||
if (GetArgument(args, 0, takeCount))
|
||||
return TakeItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), takeCount);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::SkipWhile: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return SkipWhileItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::TakeWhile: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return TakeWhileItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::Select: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return SelectItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
case TQueryableMode::Where: {
|
||||
TCallable *callable;
|
||||
if (GetArgumentHeap(args, 0, callable))
|
||||
return WhereItterator::Create(
|
||||
ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
return TEnumerator::CreateFromObject(ls, this->parent);
|
||||
}
|
||||
|
||||
} // namespace Tesses::CrossLang
|
||||
+25
-40
@@ -1,47 +1,32 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TRandom::TRandom() : random()
|
||||
{
|
||||
|
||||
}
|
||||
TRandom::TRandom(uint64_t seed) : random(seed)
|
||||
{
|
||||
|
||||
}
|
||||
std::string TRandom::TypeName()
|
||||
{
|
||||
return "Random";
|
||||
}
|
||||
TObject TRandom::CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
|
||||
{
|
||||
if(name == "Next")
|
||||
{
|
||||
int64_t first;
|
||||
int64_t second;
|
||||
if(GetArgument(args,0,first))
|
||||
{
|
||||
if(GetArgument(args,1,second))
|
||||
{
|
||||
return (int64_t)random.Next((int32_t)first,(int32_t)second);
|
||||
}
|
||||
|
||||
return (int64_t)random.Next((uint32_t)first);
|
||||
namespace Tesses::CrossLang {
|
||||
TRandom::TRandom() : random() {}
|
||||
TRandom::TRandom(uint64_t seed) : random(seed) {}
|
||||
std::string TRandom::TypeName() { return "Random"; }
|
||||
TObject TRandom::CallMethod(GCList &ls, std::string name,
|
||||
std::vector<TObject> args) {
|
||||
if (name == "Next") {
|
||||
int64_t first;
|
||||
int64_t second;
|
||||
if (GetArgument(args, 0, first)) {
|
||||
if (GetArgument(args, 1, second)) {
|
||||
return (int64_t)random.Next((int32_t)first, (int32_t)second);
|
||||
}
|
||||
|
||||
return random.Next();
|
||||
|
||||
return (int64_t)random.Next((uint32_t)first);
|
||||
}
|
||||
|
||||
if(name == "NextByte")
|
||||
{
|
||||
return (int64_t)random.NextByte();
|
||||
}
|
||||
|
||||
if(name == "ToString") {
|
||||
return "";
|
||||
}
|
||||
return Undefined();
|
||||
return random.Next();
|
||||
}
|
||||
}
|
||||
|
||||
if (name == "NextByte") {
|
||||
return (int64_t)random.NextByte();
|
||||
}
|
||||
|
||||
if (name == "ToString") {
|
||||
return "";
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
+368
-385
@@ -2,394 +2,377 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
namespace Tesses::CrossLang {
|
||||
void ThrowConstError(std::string key)
|
||||
{
|
||||
throw std::runtime_error("Cannot set \"" + key + "\" because it is a const");
|
||||
}
|
||||
void ThrowConstError(std::string key) {
|
||||
throw std::runtime_error("Cannot set \"" + key +
|
||||
"\" because it is a const");
|
||||
}
|
||||
|
||||
void TEnvironment::DeclareConstVariable(std::string key, TObject value)
|
||||
{
|
||||
this->DeclareVariable(key,value);
|
||||
this->consts.push_back(key);
|
||||
}
|
||||
bool TEnvironment::HasConstForDeclare(std::string key)
|
||||
{
|
||||
for(auto item : this->consts)
|
||||
if(item == key)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool TEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
return HasConstForDeclare(key);
|
||||
}
|
||||
bool TRootEnvironment::TryFindClass(std::vector<std::string>& name, size_t& index)
|
||||
{
|
||||
for(size_t i = 0; i < this->classes.size(); i++)
|
||||
{
|
||||
if(classes[i].first->classes.at(classes[i].second).name.size() != name.size()) continue;
|
||||
for(size_t j = 0; j < name.size(); j++)
|
||||
if(classes[i].first->classes.at(classes[i].second).name[j] != name[j]) continue;
|
||||
index=i;
|
||||
void TEnvironment::DeclareConstVariable(std::string key, TObject value) {
|
||||
this->DeclareVariable(key, value);
|
||||
this->consts.push_back(key);
|
||||
}
|
||||
bool TEnvironment::HasConstForDeclare(std::string key) {
|
||||
for (auto item : this->consts)
|
||||
if (item == key)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,bool setting)
|
||||
{
|
||||
std::string property=(setting? "set":"get") + key;
|
||||
if(this->HasVariable(property))
|
||||
{
|
||||
auto res = this->GetVariable(property);
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(res,callable)) return true;
|
||||
}
|
||||
|
||||
return this->HasVariable(key);
|
||||
}
|
||||
TObject TRootEnvironment::GetVariable(GCList& ls, std::string key)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if(this->HasVariable("get" + key))
|
||||
{
|
||||
auto item = this->GetVariable("get"+key);
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls,{});
|
||||
return false;
|
||||
}
|
||||
bool TEnvironment::HasConstForSet(std::string key) {
|
||||
return HasConstForDeclare(key);
|
||||
}
|
||||
bool TRootEnvironment::TryFindClass(std::vector<std::string> &name,
|
||||
size_t &index) {
|
||||
for (size_t i = 0; i < this->classes.size(); i++) {
|
||||
bool conUp = false;
|
||||
if (classes[i].first->classes.at(classes[i].second).name.size() !=
|
||||
name.size())
|
||||
continue;
|
||||
for (size_t j = 0; j < name.size(); j++)
|
||||
if (classes[i].first->classes.at(classes[i].second).name[j] !=
|
||||
name[j]) {
|
||||
conUp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto item = this->GetVariable(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return item;
|
||||
}
|
||||
TObject TRootEnvironment::SetVariable(GCList& ls, std::string key, TObject value)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if(this->HasVariable("set" + key))
|
||||
{
|
||||
auto item = this->GetVariable("set"+key);
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls,{value});
|
||||
}
|
||||
}
|
||||
|
||||
this->SetVariable(key,value);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void TRootEnvironment::LoadDependency(std::shared_ptr<GC> gc,std::shared_ptr<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;
|
||||
|
||||
if(vfs->RegularFileExists(filename))
|
||||
{
|
||||
auto file = vfs->OpenFile(filename,"rb");
|
||||
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);
|
||||
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
||||
gen.Save(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);
|
||||
}
|
||||
TDictionary* TEnvironment::EnsureDictionary(std::shared_ptr<GC> gc, std::string key)
|
||||
{
|
||||
TObject item = this->GetVariable(key);
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(item,dict)) return dict;
|
||||
GCList ls(gc);
|
||||
dict = TDictionary::Create(ls);
|
||||
this->DeclareVariable(key, dict);
|
||||
return dict;
|
||||
}
|
||||
void TEnvironment::DeclareVariable(std::shared_ptr<GC> gc, std::vector<std::string> name, TObject o)
|
||||
{
|
||||
if(name.size() == 0)
|
||||
throw VMException("name can't be empty.");
|
||||
|
||||
else if(name.size() == 1)
|
||||
{
|
||||
GCList ls(gc);
|
||||
|
||||
gc->BarrierBegin();
|
||||
this->DeclareVariable(name[0],o);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
GCList ls(gc);
|
||||
|
||||
TObject v = this->GetVariable(name[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(name[0],dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dict = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
this->DeclareVariable(name[0],dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
for(size_t i = 1; i < name.size()-1; i++)
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
auto v = dict->GetValue(name[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(name[i],dict2);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
dict = dict2;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto dict2 = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue(name[i],dict2);
|
||||
gc->BarrierEnd();
|
||||
dict = dict2;
|
||||
}
|
||||
}
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue(name[name.size()-1],o);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
|
||||
TObject TEnvironment::LoadFile(std::shared_ptr<GC> gc, TFile* file)
|
||||
{
|
||||
file->EnsureCanRunInCrossLang();
|
||||
for(size_t i = 0; i < file->classes.size(); i++)
|
||||
{
|
||||
this->GetRootEnvironment()->classes.push_back(std::pair<TFile*,uint32_t>(file,(uint32_t)i));
|
||||
std::vector<std::string> clsPart={"New"};
|
||||
clsPart.insert(clsPart.end(),file->classes[i].name.begin(),file->classes[i].name.end());
|
||||
GCList ls(gc);
|
||||
std::vector<std::string> name=file->classes[i].name;
|
||||
auto rootEnv = this->GetRootEnvironment();
|
||||
this->DeclareVariable(gc, clsPart, TExternalMethod::Create(ls,"Create instance of the class",{"$$args"},[rootEnv,file,i](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
return TClassObject::Create(ls, file,i,rootEnv,args);
|
||||
}));
|
||||
for(auto meth : file->classes[i].entry)
|
||||
{
|
||||
|
||||
if(meth.isFunction && meth.modifier == TClassModifier::Static)
|
||||
{
|
||||
std::vector<std::string> method=file->classes[i].name;
|
||||
method.push_back(meth.name);
|
||||
auto clo = TClosure::Create(ls,this,file,meth.chunkId);
|
||||
clo->closure->name = JoinPeriod(method);
|
||||
|
||||
|
||||
clo->documentation = meth.documentation;
|
||||
this->DeclareVariable(gc, method, clo);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for(auto fn : file->functions)
|
||||
{
|
||||
|
||||
|
||||
|
||||
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];
|
||||
chunk->name = JoinPeriod(items);
|
||||
GCList ls(gc);
|
||||
TClosure* closure=TClosure::Create(ls,this,file,fn.second);
|
||||
closure->documentation = fn.first[0];
|
||||
this->DeclareVariable(gc,items,closure);
|
||||
|
||||
}
|
||||
if(!file->chunks.empty())
|
||||
{
|
||||
GCList ls(gc);
|
||||
TClosure* closure=TClosure::Create(ls,this,file,0);
|
||||
return closure->Call(ls,{});
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TRootEnvironment::LoadFileWithDependencies(std::shared_ptr<GC> gc,std::shared_ptr<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(std::shared_ptr<GC> gc,std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
|
||||
|
||||
if(vfs->RegularFileExists(path))
|
||||
{
|
||||
auto file=vfs->OpenFile(path,"rb");
|
||||
GCList ls(gc);
|
||||
TFile* f = TFile::Create(ls);
|
||||
f->Load(gc, file);
|
||||
|
||||
auto dir = std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(vfs,path.GetParent());
|
||||
LoadFileWithDependencies(gc,dir,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)
|
||||
{
|
||||
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();
|
||||
if(this->permissions.customConsole != nullptr) this->permissions.customConsole->Mark();
|
||||
for(auto defer : this->defers) defer->Mark();
|
||||
if(this->error != nullptr) this->error->Mark();
|
||||
for(auto cls : this->classes) cls.first->Mark();
|
||||
}
|
||||
TRootEnvironment* TRootEnvironment::Create(GCList* gc,TDictionary* dict)
|
||||
{
|
||||
TRootEnvironment* env=new TRootEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(env);
|
||||
_gc->Watch(env);
|
||||
return env;
|
||||
}
|
||||
TRootEnvironment* TRootEnvironment::Create(GCList& gc,TDictionary* dict)
|
||||
{
|
||||
TRootEnvironment* env=new TRootEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(env);
|
||||
_gc->Watch(env);
|
||||
return env;
|
||||
}
|
||||
|
||||
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,TEnvironment* env, TObject err)
|
||||
{
|
||||
if(error != nullptr)
|
||||
{
|
||||
GCList ls(gc);
|
||||
return ToBool(error->Call(ls, {
|
||||
TDictionary::Create(ls,{
|
||||
TDItem("IsBreakpoint",false),
|
||||
TDItem("Exception",err),
|
||||
TDItem("Environment", env)
|
||||
})
|
||||
}));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TRootEnvironment::HandleBreakpoint(std::shared_ptr<GC> gc,TEnvironment* env, TObject err)
|
||||
{
|
||||
if(error != nullptr)
|
||||
{
|
||||
GCList ls(gc);
|
||||
return ToBool(error->Call(ls, {
|
||||
TDictionary::Create(ls,{
|
||||
TDItem("IsBreakpoint",true),
|
||||
TDItem("Breakpoint",err),
|
||||
TDItem("Environment", env)
|
||||
})
|
||||
}));
|
||||
}
|
||||
if (conUp)
|
||||
continue;
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
void TRootEnvironment::RegisterOnError(TCallable* call)
|
||||
{
|
||||
this->error = call;
|
||||
return false;
|
||||
}
|
||||
TDictionary *TRootEnvironment::GetPrivateFromFile(std::shared_ptr<GC> gc,
|
||||
TFile *file) {
|
||||
auto index = reinterpret_cast<uint64_t>(file);
|
||||
gc->BarrierBegin();
|
||||
TDictionary *obj;
|
||||
if (this->private_file_data.count(index) > 0) {
|
||||
obj = this->private_file_data[index];
|
||||
} else {
|
||||
GCList ls(gc);
|
||||
obj = TDictionary::Create(ls);
|
||||
this->private_file_data[index] = obj;
|
||||
}
|
||||
};
|
||||
gc->BarrierEnd();
|
||||
|
||||
return obj;
|
||||
}
|
||||
bool TRootEnvironment::HasVariableOrFieldRecurse(std::string key,
|
||||
bool setting) {
|
||||
std::string property = (setting ? "set" : "get") + key;
|
||||
if (this->HasVariable(property)) {
|
||||
auto res = this->GetVariable(property);
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(res, callable))
|
||||
return true;
|
||||
}
|
||||
|
||||
return this->HasVariable(key);
|
||||
}
|
||||
TObject TRootEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if (this->HasVariable("get" + key)) {
|
||||
auto item = this->GetVariable("get" + key);
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {});
|
||||
}
|
||||
}
|
||||
|
||||
auto item = this->GetVariable(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return item;
|
||||
}
|
||||
TObject TRootEnvironment::SetVariable(GCList &ls, std::string key,
|
||||
TObject value) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if (this->HasVariable("set" + key)) {
|
||||
auto item = this->GetVariable("set" + key);
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {value});
|
||||
}
|
||||
}
|
||||
|
||||
this->SetVariable(key, value);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void TRootEnvironment::LoadDependency(
|
||||
std::shared_ptr<GC> gc,
|
||||
std::shared_ptr<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;
|
||||
|
||||
if (vfs->RegularFileExists(filename)) {
|
||||
auto file = vfs->OpenFile(filename, "rb");
|
||||
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);
|
||||
auto ms = std::make_shared<Tesses::Framework::Streams::MemoryStream>(true);
|
||||
gen.Save(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);
|
||||
}
|
||||
TDictionary *TEnvironment::EnsureDictionary(std::shared_ptr<GC> gc,
|
||||
std::string key) {
|
||||
TObject item = this->GetVariable(key);
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(item, dict))
|
||||
return dict;
|
||||
GCList ls(gc);
|
||||
dict = TDictionary::Create(ls);
|
||||
this->DeclareVariable(key, dict);
|
||||
return dict;
|
||||
}
|
||||
void TEnvironment::DeclareVariable(std::shared_ptr<GC> gc,
|
||||
std::vector<std::string> name, TObject o) {
|
||||
if (name.size() == 0)
|
||||
throw VMException("name can't be empty.");
|
||||
|
||||
else if (name.size() == 1) {
|
||||
GCList ls(gc);
|
||||
|
||||
gc->BarrierBegin();
|
||||
this->DeclareVariable(name[0], o);
|
||||
gc->BarrierEnd();
|
||||
} else {
|
||||
GCList ls(gc);
|
||||
|
||||
TObject v = this->GetVariable(name[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(name[0], dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} else {
|
||||
dict = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
this->DeclareVariable(name[0], dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < name.size() - 1; i++) {
|
||||
gc->BarrierBegin();
|
||||
auto v = dict->GetValue(name[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(name[i], dict2);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
dict = dict2;
|
||||
} else {
|
||||
auto dict2 = TDictionary::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue(name[i], dict2);
|
||||
gc->BarrierEnd();
|
||||
dict = dict2;
|
||||
}
|
||||
}
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue(name[name.size() - 1], o);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
|
||||
TObject TEnvironment::LoadFile(std::shared_ptr<GC> gc, TFile *file) {
|
||||
file->EnsureCanRunInCrossLang();
|
||||
for (size_t i = 0; i < file->classes.size(); i++) {
|
||||
this->GetRootEnvironment()->classes.push_back(
|
||||
std::pair<TFile *, uint32_t>(file, (uint32_t)i));
|
||||
std::vector<std::string> clsPart = {"New"};
|
||||
clsPart.insert(clsPart.end(), file->classes[i].name.begin(),
|
||||
file->classes[i].name.end());
|
||||
GCList ls(gc);
|
||||
std::vector<std::string> name = file->classes[i].name;
|
||||
auto rootEnv = this->GetRootEnvironment();
|
||||
this->DeclareVariable(
|
||||
gc, clsPart,
|
||||
TExternalMethod::Create(
|
||||
ls, "Create instance of the class", {"$$args"},
|
||||
[rootEnv, file, i](GCList &ls,
|
||||
std::vector<TObject> args) -> TObject {
|
||||
return TClassObject::Create(ls, file, i, rootEnv, args);
|
||||
}));
|
||||
for (auto meth : file->classes[i].entry) {
|
||||
|
||||
if (meth.isFunction && meth.modifier == TClassModifier::Static) {
|
||||
std::vector<std::string> method = file->classes[i].name;
|
||||
method.push_back(meth.name);
|
||||
auto clo = TClosure::Create(ls, this, file, meth.chunkId);
|
||||
clo->closure->name = JoinPeriod(method);
|
||||
|
||||
clo->documentation = meth.documentation;
|
||||
this->DeclareVariable(gc, method, clo);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto fn : file->functions) {
|
||||
|
||||
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];
|
||||
chunk->name = JoinPeriod(items);
|
||||
GCList ls(gc);
|
||||
TClosure *closure = TClosure::Create(ls, this, file, fn.second);
|
||||
closure->documentation = fn.first[0];
|
||||
this->DeclareVariable(gc, items, closure);
|
||||
}
|
||||
if (!file->chunks.empty()) {
|
||||
GCList ls(gc);
|
||||
TClosure *closure = TClosure::Create(ls, this, file, 0);
|
||||
return closure->Call(ls, {});
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TRootEnvironment::LoadFileWithDependencies(
|
||||
std::shared_ptr<GC> gc,
|
||||
std::shared_ptr<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(
|
||||
std::shared_ptr<GC> gc,
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
|
||||
Tesses::Framework::Filesystem::VFSPath path) {
|
||||
|
||||
if (vfs->RegularFileExists(path)) {
|
||||
auto file = vfs->OpenFile(path, "rb");
|
||||
GCList ls(gc);
|
||||
TFile *f = TFile::Create(ls);
|
||||
f->Load(gc, file);
|
||||
|
||||
auto dir =
|
||||
std::make_shared<Tesses::Framework::Filesystem::SubdirFilesystem>(
|
||||
vfs, path.GetParent());
|
||||
LoadFileWithDependencies(gc, dir, 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) {
|
||||
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();
|
||||
if (this->permissions.customConsole != nullptr)
|
||||
this->permissions.customConsole->Mark();
|
||||
for (auto priv : this->private_file_data)
|
||||
priv.second->Mark();
|
||||
for (auto defer : this->defers)
|
||||
defer->Mark();
|
||||
if (this->error != nullptr)
|
||||
this->error->Mark();
|
||||
for (auto cls : this->classes)
|
||||
cls.first->Mark();
|
||||
}
|
||||
TRootEnvironment *TRootEnvironment::Create(GCList *gc, TDictionary *dict) {
|
||||
TRootEnvironment *env = new TRootEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(env);
|
||||
_gc->Watch(env);
|
||||
return env;
|
||||
}
|
||||
TRootEnvironment *TRootEnvironment::Create(GCList &gc, TDictionary *dict) {
|
||||
TRootEnvironment *env = new TRootEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(env);
|
||||
_gc->Watch(env);
|
||||
return env;
|
||||
}
|
||||
|
||||
bool TRootEnvironment::HandleException(std::shared_ptr<GC> gc,
|
||||
TEnvironment *env, TObject err) {
|
||||
if (error != nullptr) {
|
||||
GCList ls(gc);
|
||||
return ToBool(error->Call(
|
||||
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", false),
|
||||
TDItem("Exception", err),
|
||||
TDItem("Environment", env)})}));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TRootEnvironment::HandleBreakpoint(std::shared_ptr<GC> gc,
|
||||
TEnvironment *env, TObject err) {
|
||||
if (error != nullptr) {
|
||||
GCList ls(gc);
|
||||
return ToBool(error->Call(
|
||||
ls, {TDictionary::Create(ls, {TDItem("IsBreakpoint", true),
|
||||
TDItem("Breakpoint", err),
|
||||
TDItem("Environment", env)})}));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void TRootEnvironment::RegisterOnError(TCallable *call) { this->error = call; }
|
||||
}; // namespace Tesses::CrossLang
|
||||
|
||||
+193
-200
@@ -1,224 +1,217 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
int64_t TObjectStream::_GetPosInternal()
|
||||
{
|
||||
return Tesses::Framework::Streams::Stream::GetLength();
|
||||
}
|
||||
TObjectStream::TObjectStream(std::shared_ptr<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("Read"))
|
||||
{
|
||||
dict->DeclareFunction(gc,"Read","Read from stream",{"buff","off","len"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
namespace Tesses::CrossLang {
|
||||
int64_t TObjectStream::_GetPosInternal() {
|
||||
return Tesses::Framework::Streams::Stream::GetLength();
|
||||
}
|
||||
TObjectStream::TObjectStream(std::shared_ptr<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("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 {
|
||||
}
|
||||
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 {
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
}
|
||||
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 {
|
||||
}
|
||||
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 {
|
||||
}
|
||||
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 {
|
||||
}
|
||||
if (!dict->HasValue("getEndOfStream")) {
|
||||
dict->DeclareFunction(
|
||||
gc, "getEndOfStream", "Is at end of stream", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
bool TObjectStream::EndOfStream()
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
size_t TObjectStream::Read(uint8_t* buff, size_t sz)
|
||||
{
|
||||
TDictionary* dict;
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
size_t TObjectStream::Write(const uint8_t* buff, size_t sz)
|
||||
{
|
||||
TDictionary* dict;
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
bool TObjectStream::CanRead()
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
auto res = dict->CallMethod(*ls, "getCanRead",{});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool TObjectStream::CanWrite()
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
auto res = dict->CallMethod(*ls, "getCanWrite",{});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TObjectStream::CanSeek()
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
auto res = dict->CallMethod(*ls, "getCanSeek",{});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
int64_t TObjectStream::GetPosition()
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
auto res = dict->CallMethod(*ls, "getPosition",{});
|
||||
int64_t r;
|
||||
if(GetObject(res,r)) return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int64_t TObjectStream::GetLength()
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
auto res = dict->CallMethod(*ls, "getEndOfStream",{});
|
||||
bool r;
|
||||
if(GetObject(res,r)) return r;
|
||||
}
|
||||
|
||||
return Tesses::Framework::Streams::Stream::GetLength();
|
||||
}
|
||||
void TObjectStream::Flush()
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
dict->CallMethod(*ls, "Flush",{});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void TObjectStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence)
|
||||
{
|
||||
TDictionary* dict;
|
||||
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) });
|
||||
}
|
||||
|
||||
}
|
||||
void TObjectStream::Close()
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
dict->CallMethod(*ls,"Dispose",{});
|
||||
}
|
||||
}
|
||||
TObjectStream::~TObjectStream()
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
dict->CallMethod(*ls,"Dispose",{});
|
||||
}
|
||||
delete this->ls;
|
||||
}
|
||||
bool TObjectStream::EndOfStream() {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
|
||||
bool r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
size_t TObjectStream::Read(uint8_t *buff, size_t sz) {
|
||||
TDictionary *dict;
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
size_t TObjectStream::Write(const uint8_t *buff, size_t sz) {
|
||||
TDictionary *dict;
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
bool TObjectStream::CanRead() {
|
||||
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getCanRead", {});
|
||||
bool r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool TObjectStream::CanWrite() {
|
||||
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getCanWrite", {});
|
||||
bool r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool TObjectStream::CanSeek() {
|
||||
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getCanSeek", {});
|
||||
bool r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
int64_t TObjectStream::GetPosition() {
|
||||
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getPosition", {});
|
||||
int64_t r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int64_t TObjectStream::GetLength() {
|
||||
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
auto res = dict->CallMethod(*ls, "getEndOfStream", {});
|
||||
bool r;
|
||||
if (GetObject(res, r))
|
||||
return r;
|
||||
}
|
||||
|
||||
return Tesses::Framework::Streams::Stream::GetLength();
|
||||
}
|
||||
void TObjectStream::Flush() {
|
||||
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
dict->CallMethod(*ls, "Flush", {});
|
||||
}
|
||||
}
|
||||
void TObjectStream::Seek(int64_t pos,
|
||||
Tesses::Framework::Streams::SeekOrigin whence) {
|
||||
TDictionary *dict;
|
||||
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)});
|
||||
}
|
||||
}
|
||||
void TObjectStream::Close() {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
dict->CallMethod(*ls, "Dispose", {});
|
||||
}
|
||||
}
|
||||
TObjectStream::~TObjectStream() {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
dict->CallMethod(*ls, "Dispose", {});
|
||||
}
|
||||
delete this->ls;
|
||||
}
|
||||
|
||||
} // namespace Tesses::CrossLang
|
||||
+192
-225
@@ -1,246 +1,213 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
TDictionary* TSubEnvironment::GetDictionary()
|
||||
{
|
||||
return this->dict;
|
||||
namespace Tesses::CrossLang {
|
||||
TDictionary *TSubEnvironment::GetDictionary() { return this->dict; }
|
||||
bool TSubEnvironment::HasVariableOrFieldRecurse(std::string key, bool setting) {
|
||||
std::string property = (setting ? "set" : "get") + key;
|
||||
if (this->HasVariable(property)) {
|
||||
auto res = this->GetVariable(property);
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(res, callable))
|
||||
return true;
|
||||
}
|
||||
bool TSubEnvironment::HasVariableOrFieldRecurse(std::string key,bool setting)
|
||||
{
|
||||
std::string property=(setting? "set":"get") + key;
|
||||
if(this->HasVariable(property))
|
||||
{
|
||||
auto res = this->GetVariable(property);
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(res,callable)) return true;
|
||||
|
||||
if (this->HasVariable(key))
|
||||
return true;
|
||||
|
||||
return this->env->HasVariableOrFieldRecurse(key, setting);
|
||||
}
|
||||
TObject TSubEnvironment::GetVariable(GCList &ls, std::string key) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if (this->HasVariable("get" + key)) {
|
||||
auto item = this->GetVariable("get" + key);
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {});
|
||||
}
|
||||
|
||||
if(this->HasVariable(key)) return true;
|
||||
|
||||
return this->env->HasVariableOrFieldRecurse(key,setting);
|
||||
}
|
||||
TObject TSubEnvironment::GetVariable(GCList& ls, std::string key)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if(this->HasVariable("get" + key))
|
||||
{
|
||||
auto item = this->GetVariable("get"+key);
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls,{});
|
||||
}
|
||||
}
|
||||
|
||||
if(this->HasVariable(key))
|
||||
{
|
||||
auto item = this->GetVariable(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return item;
|
||||
}
|
||||
if(this->env->HasVariableOrFieldRecurse(key))
|
||||
{
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->env->GetVariable(ls,key);
|
||||
}
|
||||
|
||||
if (this->HasVariable(key)) {
|
||||
auto item = this->GetVariable(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
|
||||
|
||||
return Undefined();
|
||||
return item;
|
||||
}
|
||||
bool TSubEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
if(this->dict->HasValue(key))
|
||||
{
|
||||
return this->HasConstForDeclare(key);
|
||||
}
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject TSubEnvironment::SetVariable(GCList& ls, std::string key, TObject value)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if(this->HasVariable("set" + key))
|
||||
{
|
||||
auto item = this->GetVariable("set"+key);
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(item,callable))
|
||||
{
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls,{value});
|
||||
}
|
||||
}
|
||||
|
||||
if(this->HasVariable(key))
|
||||
{
|
||||
this->SetVariable(key,value);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
if(this->env->HasVariableOrFieldRecurse(key,true))
|
||||
{
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->env->SetVariable(ls,key,value);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->env->SetVariable(key,value);
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
if (this->env->HasVariableOrFieldRecurse(key)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
|
||||
return this->env->GetVariable(ls, key);
|
||||
}
|
||||
|
||||
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;
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
if(GetObjectHeap(res,callable))
|
||||
{
|
||||
return callable->Call(ls,args);
|
||||
return Undefined();
|
||||
}
|
||||
bool TSubEnvironment::HasConstForSet(std::string key) {
|
||||
if (this->dict->HasValue(key)) {
|
||||
return this->HasConstForDeclare(key);
|
||||
}
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject TSubEnvironment::SetVariable(GCList &ls, std::string key,
|
||||
TObject value) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
if (this->HasVariable("set" + key)) {
|
||||
auto item = this->GetVariable("set" + key);
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(item, callable)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return callable->Call(ls, {value});
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject TEnvironment::CallFunctionWithFatalError(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->CallWithFatalError(ls,args);
|
||||
}
|
||||
return Undefined();
|
||||
if (this->HasVariable(key)) {
|
||||
this->SetVariable(key, value);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList* gc)
|
||||
{
|
||||
auto dict=TDictionary::Create(gc);
|
||||
TSubEnvironment* sEnv = this->GetSubEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(sEnv);
|
||||
_gc->Watch(sEnv);
|
||||
return sEnv;
|
||||
if (this->env->HasVariableOrFieldRecurse(key, true)) {
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return this->env->SetVariable(ls, key, value);
|
||||
} else {
|
||||
this->env->SetVariable(key, value);
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return value;
|
||||
}
|
||||
TSubEnvironment* TEnvironment::GetSubEnvironment(GCList& gc)
|
||||
{
|
||||
auto dict=TDictionary::Create(gc);
|
||||
TSubEnvironment* sEnv = this->GetSubEnvironment(dict);
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(sEnv);
|
||||
_gc->Watch(sEnv);
|
||||
return sEnv;
|
||||
ls.GetGC()->BarrierEnd();
|
||||
}
|
||||
|
||||
TObject TSubEnvironment::GetVariable(std::string key) {
|
||||
if (this->dict->HasValue(key)) {
|
||||
return this->dict->GetValue(key);
|
||||
}
|
||||
TSubEnvironment* TSubEnvironment::Create(GCList* gc, TEnvironment* env, TDictionary* dict)
|
||||
{
|
||||
TSubEnvironment* senv = new TSubEnvironment(env,dict);
|
||||
std::shared_ptr<GC> _gc = gc->GetGC();
|
||||
gc->Add(senv);
|
||||
_gc->Watch(senv);
|
||||
return senv;
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
return this->env->GetVariable(key);
|
||||
}
|
||||
TSubEnvironment* TSubEnvironment::Create(GCList& gc, TEnvironment* env, TDictionary* dict)
|
||||
{
|
||||
TSubEnvironment* senv = new TSubEnvironment(env,dict);
|
||||
std::shared_ptr<GC> _gc = gc.GetGC();
|
||||
gc.Add(senv);
|
||||
_gc->Watch(senv);
|
||||
return senv;
|
||||
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;
|
||||
}
|
||||
TEnvironment* TSubEnvironment::GetParentEnvironment()
|
||||
{
|
||||
return this->env;
|
||||
if (this->env->HasVariableRecurse(key)) {
|
||||
this->env->SetVariable(key, value);
|
||||
} else {
|
||||
this->dict->SetValue(key, value);
|
||||
}
|
||||
TRootEnvironment* TSubEnvironment::GetRootEnvironment()
|
||||
{
|
||||
return this->env->GetRootEnvironment();
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void TSubEnvironment::Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
this->dict->Mark();
|
||||
this->env->Mark();
|
||||
for(auto defer : defers) defer->Mark();
|
||||
return Undefined();
|
||||
}
|
||||
TObject TEnvironment::CallFunctionWithFatalError(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->CallWithFatalError(ls, args);
|
||||
}
|
||||
void TEnvironment::DeclareFunction(std::shared_ptr<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(std::shared_ptr<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();
|
||||
}
|
||||
|
||||
};
|
||||
return Undefined();
|
||||
}
|
||||
TSubEnvironment *TEnvironment::GetSubEnvironment(GCList *gc) {
|
||||
auto dict = TDictionary::Create(gc);
|
||||
TSubEnvironment *sEnv = this->GetSubEnvironment(dict);
|
||||
std::shared_ptr<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);
|
||||
std::shared_ptr<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);
|
||||
std::shared_ptr<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);
|
||||
std::shared_ptr<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(
|
||||
std::shared_ptr<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(
|
||||
std::shared_ptr<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();
|
||||
}
|
||||
|
||||
}; // namespace Tesses::CrossLang
|
||||
|
||||
+332
-363
@@ -2,402 +2,371 @@
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
TObjectVFS::TObjectVFS(std::shared_ptr<GC> gc, TObject obj)
|
||||
{
|
||||
this->ls = new GCList(gc);
|
||||
this->ls->Add(obj);
|
||||
this->obj = obj;
|
||||
|
||||
|
||||
TObjectVFS::TObjectVFS(std::shared_ptr<GC> gc, TObject obj) {
|
||||
this->ls = new GCList(gc);
|
||||
this->ls->Add(obj);
|
||||
this->obj = obj;
|
||||
}
|
||||
Tesses::Framework::Filesystem::FIFOCreationResult
|
||||
TObjectVFS::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "CreateFIFO", {path});
|
||||
int64_t n = 0;
|
||||
if (GetObject(res, n))
|
||||
return (Tesses::Framework::Filesystem::FIFOCreationResult)n;
|
||||
}
|
||||
Tesses::Framework::Filesystem::FIFOCreationResult TObjectVFS::CreateFIFO(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "CreateFIFO",{path});
|
||||
int64_t n=0;
|
||||
if(GetObject(res, n)) return (Tesses::Framework::Filesystem::FIFOCreationResult)n;
|
||||
}
|
||||
return Tesses::Framework::Filesystem::FIFOCreationResult::UnknownError;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "OpenFile",{path,mode});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if(GetObject(res,strm))
|
||||
{
|
||||
return strm;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "CreateDirectory",{path});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void TObjectVFS::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteDirectory",{path});
|
||||
|
||||
return Tesses::Framework::Filesystem::FIFOCreationResult::UnknownError;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream>
|
||||
TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path,
|
||||
std::string mode) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "OpenFile", {path, mode});
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if (GetObject(res, strm)) {
|
||||
return strm;
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Lock(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Lock",{path});
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "CreateDirectory", {path});
|
||||
}
|
||||
void TObjectVFS::Unlock(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Unlock",{path});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteDirectory", {path});
|
||||
}
|
||||
void TObjectVFS::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "CreateSymlink",{existingFile,symlinkFile});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Lock(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Lock", {path});
|
||||
}
|
||||
void TObjectVFS::CreateHardlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath newName)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "CreateHardlink",{existingFile,newName});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Unlock(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Unlock", {path});
|
||||
}
|
||||
void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteFile",{path});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::CreateSymlink(
|
||||
Tesses::Framework::Filesystem::VFSPath existingFile,
|
||||
Tesses::Framework::Filesystem::VFSPath symlinkFile) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "CreateSymlink", {existingFile, symlinkFile});
|
||||
}
|
||||
void TObjectVFS::DeleteDirectoryRecurse(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteDirectoryRecurse",{path});
|
||||
|
||||
}
|
||||
}
|
||||
void TObjectVFS::CreateHardlink(
|
||||
Tesses::Framework::Filesystem::VFSPath existingFile,
|
||||
Tesses::Framework::Filesystem::VFSPath newName) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "CreateHardlink", {existingFile, newName});
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPathEnumerator TObjectVFS::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
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()))
|
||||
{
|
||||
}
|
||||
void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "DeleteFile", {path});
|
||||
}
|
||||
}
|
||||
void TObjectVFS::DeleteDirectoryRecurse(
|
||||
Tesses::Framework::Filesystem::VFSPath path) {
|
||||
TDictionary *dict;
|
||||
|
||||
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) {
|
||||
TDictionary *dict;
|
||||
|
||||
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))
|
||||
{
|
||||
if (GetObject(res, path1)) {
|
||||
path0 = path1;
|
||||
return true;
|
||||
}
|
||||
else if(GetObject(res,name))
|
||||
{
|
||||
} else if (GetObject(res, name)) {
|
||||
path0 = path / name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},[ls]()->void{
|
||||
delete ls;
|
||||
});
|
||||
}
|
||||
return Tesses::Framework::Filesystem::VFSPathEnumerator();
|
||||
},
|
||||
[ls]() -> void { delete ls; });
|
||||
}
|
||||
void TObjectVFS::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
|
||||
{
|
||||
return Tesses::Framework::Filesystem::VFSPathEnumerator();
|
||||
}
|
||||
void TObjectVFS::MoveFile(Tesses::Framework::Filesystem::VFSPath src,
|
||||
Tesses::Framework::Filesystem::VFSPath dest) {
|
||||
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "MoveFile",{src,dest});
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
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) {
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
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) {
|
||||
|
||||
TDictionary *dict;
|
||||
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;
|
||||
}
|
||||
}
|
||||
void TObjectVFS::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest)
|
||||
{
|
||||
return Tesses::Framework::Filesystem::VFSPath();
|
||||
}
|
||||
std::string
|
||||
TObjectVFS::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "MoveDirectory",{src,dest});
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath TObjectVFS::ReadLink(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
return "/";
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath
|
||||
TObjectVFS::SystemToVFSPath(std::string path) {
|
||||
TDictionary *dict;
|
||||
|
||||
TDictionary* dict;
|
||||
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)
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
|
||||
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)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
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::SetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime lastWrite, Tesses::Framework::Date::DateTime lastAccess)
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "SetDate",{path,std::make_shared<Tesses::Framework::Date::DateTime>(lastWrite),std::make_shared<Tesses::Framework::Date::DateTime>(lastAccess)});
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Chmod(Tesses::Framework::Filesystem::VFSPath path, uint32_t mode)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Chmod",{path,(int64_t)mode});
|
||||
|
||||
return Tesses::Framework::Filesystem::VFSPath();
|
||||
}
|
||||
void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path,
|
||||
Tesses::Framework::Date::DateTime lastWrite,
|
||||
Tesses::Framework::Date::DateTime lastAccess) {
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(
|
||||
ls, "SetDate",
|
||||
{path,
|
||||
std::make_shared<Tesses::Framework::Date::DateTime>(lastWrite),
|
||||
std::make_shared<Tesses::Framework::Date::DateTime>(lastAccess)});
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Chmod(Tesses::Framework::Filesystem::VFSPath path,
|
||||
uint32_t mode) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Chmod", {path, (int64_t)mode});
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Chown(Tesses::Framework::Filesystem::VFSPath path,
|
||||
uint32_t uid, uint32_t gid) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Chown", {path, (int64_t)uid, (int64_t)gid});
|
||||
}
|
||||
}
|
||||
bool TObjectVFS::Stat(Tesses::Framework::Filesystem::VFSPath path,
|
||||
Tesses::Framework::Filesystem::StatData &data) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "Stat", {path});
|
||||
int64_t _num;
|
||||
TDictionary *_dict;
|
||||
TObject _o;
|
||||
if (GetObjectHeap(res, _dict)) {
|
||||
this->ls->GetGC()->BarrierBegin();
|
||||
_o = _dict->GetValue("BlockSize");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlockSize = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("BlockCount");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlockCount = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("Device");
|
||||
if (GetObject(_o, _num))
|
||||
data.Device = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("DeviceId");
|
||||
if (GetObject(_o, _num))
|
||||
data.DeviceId = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("GroupId");
|
||||
if (GetObject(_o, _num))
|
||||
data.GroupId = (uint32_t)_num;
|
||||
|
||||
_o = _dict->GetValue("HardLinks");
|
||||
if (GetObject(_o, _num))
|
||||
data.HardLinks = (uint64_t)_num;
|
||||
std::shared_ptr<Tesses::Framework::Date::DateTime> dt;
|
||||
_o = _dict->GetValue("LastAccess");
|
||||
if (GetObject(_o, dt))
|
||||
data.LastAccess =
|
||||
dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
_o = _dict->GetValue("LastModified");
|
||||
if (GetObject(_o, dt))
|
||||
data.LastModified =
|
||||
dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
_o = _dict->GetValue("LastStatus");
|
||||
if (GetObject(_o, dt))
|
||||
data.LastStatus =
|
||||
dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
_o = _dict->GetValue("Mode");
|
||||
if (GetObject(_o, _num))
|
||||
data.Mode = (uint32_t)_num;
|
||||
|
||||
_o = _dict->GetValue("Size");
|
||||
if (GetObject(_o, _num))
|
||||
data.Size = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("UserId");
|
||||
if (GetObject(_o, _num))
|
||||
data.UserId = (uint32_t)_num;
|
||||
|
||||
this->ls->GetGC()->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void TObjectVFS::Chown(Tesses::Framework::Filesystem::VFSPath path, uint32_t uid, uint32_t gid)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Chown",{path,(int64_t)uid, (int64_t)gid});
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
bool TObjectVFS::StatVFS(Tesses::Framework::Filesystem::VFSPath path,
|
||||
Tesses::Framework::Filesystem::StatVFSData &data) {
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "StatVFS", {path});
|
||||
int64_t _num;
|
||||
TDictionary *_dict;
|
||||
TObject _o;
|
||||
if (GetObjectHeap(res, _dict)) {
|
||||
this->ls->GetGC()->BarrierBegin();
|
||||
_o = _dict->GetValue("BlockSize");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlockSize = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("FragmentSize");
|
||||
if (GetObject(_o, _num))
|
||||
data.FragmentSize = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Blocks");
|
||||
if (GetObject(_o, _num))
|
||||
data.Blocks = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlocksFree");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlocksFree = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlocksAvailable");
|
||||
if (GetObject(_o, _num))
|
||||
data.BlocksAvailable = (uint64_t)_num;
|
||||
_o = _dict->GetValue("TotalInodes");
|
||||
if (GetObject(_o, _num))
|
||||
data.TotalInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("FreeInodes");
|
||||
if (GetObject(_o, _num))
|
||||
data.FreeInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("AvailableInodes");
|
||||
if (GetObject(_o, _num))
|
||||
data.AvailableInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Id");
|
||||
if (GetObject(_o, _num))
|
||||
data.Id = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Flags");
|
||||
if (GetObject(_o, _num))
|
||||
data.Flags = (uint64_t)_num;
|
||||
_o = _dict->GetValue("MaxNameLength");
|
||||
if (GetObject(_o, _num))
|
||||
data.MaxNameLength = (uint64_t)_num;
|
||||
|
||||
this->ls->GetGC()->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool TObjectVFS::Stat(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatData& data)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "Stat",{path});
|
||||
int64_t _num;
|
||||
TDictionary* _dict;
|
||||
TObject _o;
|
||||
if(GetObjectHeap(res,_dict))
|
||||
{
|
||||
this->ls->GetGC()->BarrierBegin();
|
||||
_o = _dict->GetValue("BlockSize");
|
||||
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("BlockCount");
|
||||
if(GetObject(_o,_num)) data.BlockCount = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("Device");
|
||||
if(GetObject(_o,_num)) data.Device = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("DeviceId");
|
||||
if(GetObject(_o,_num)) data.DeviceId = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("GroupId");
|
||||
if(GetObject(_o,_num)) data.GroupId = (uint32_t)_num;
|
||||
|
||||
_o = _dict->GetValue("HardLinks");
|
||||
if(GetObject(_o,_num)) data.HardLinks = (uint64_t)_num;
|
||||
std::shared_ptr<Tesses::Framework::Date::DateTime> dt;
|
||||
_o = _dict->GetValue("LastAccess");
|
||||
if(GetObject(_o,dt)) data.LastAccess = dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
|
||||
_o = _dict->GetValue("LastModified");
|
||||
if(GetObject(_o,dt)) data.LastModified = dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
|
||||
|
||||
_o = _dict->GetValue("LastStatus");
|
||||
if(GetObject(_o,dt)) data.LastStatus = dt ? *dt : Tesses::Framework::Date::DateTime(0);
|
||||
|
||||
|
||||
|
||||
_o = _dict->GetValue("Mode");
|
||||
if(GetObject(_o,_num)) data.Mode = (uint32_t)_num;
|
||||
|
||||
_o = _dict->GetValue("Size");
|
||||
if(GetObject(_o,_num)) data.Size = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("UserId");
|
||||
if(GetObject(_o,_num)) data.UserId = (uint32_t)_num;
|
||||
|
||||
|
||||
this->ls->GetGC()->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
void TObjectVFS::Close() {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Dispose", {});
|
||||
}
|
||||
bool TObjectVFS::StatVFS(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Filesystem::StatVFSData& data)
|
||||
{
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
auto res = dict->CallMethod(ls, "StatVFS",{path});
|
||||
int64_t _num;
|
||||
TDictionary* _dict;
|
||||
TObject _o;
|
||||
if(GetObjectHeap(res,_dict))
|
||||
{
|
||||
this->ls->GetGC()->BarrierBegin();
|
||||
_o = _dict->GetValue("BlockSize");
|
||||
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
|
||||
|
||||
_o = _dict->GetValue("FragmentSize");
|
||||
if(GetObject(_o,_num)) data.FragmentSize = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Blocks");
|
||||
if(GetObject(_o,_num)) data.Blocks = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlocksFree");
|
||||
if(GetObject(_o,_num)) data.BlocksFree = (uint64_t)_num;
|
||||
_o = _dict->GetValue("BlocksAvailable");
|
||||
if(GetObject(_o,_num)) data.BlocksAvailable = (uint64_t)_num;
|
||||
_o = _dict->GetValue("TotalInodes");
|
||||
if(GetObject(_o,_num)) data.TotalInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("FreeInodes");
|
||||
if(GetObject(_o,_num)) data.FreeInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("AvailableInodes");
|
||||
if(GetObject(_o,_num)) data.AvailableInodes = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Id");
|
||||
if(GetObject(_o,_num)) data.Id = (uint64_t)_num;
|
||||
_o = _dict->GetValue("Flags");
|
||||
if(GetObject(_o,_num)) data.Flags = (uint64_t)_num;
|
||||
_o = _dict->GetValue("MaxNameLength");
|
||||
if(GetObject(_o,_num)) data.MaxNameLength = (uint64_t)_num;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this->ls->GetGC()->BarrierEnd();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
TObjectVFS::~TObjectVFS() {
|
||||
TDictionary *dict;
|
||||
if (GetObjectHeap(this->obj, dict)) {
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls, "Dispose", {});
|
||||
}
|
||||
void TObjectVFS::Close()
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls,"Dispose",{});
|
||||
}
|
||||
}
|
||||
TObjectVFS::~TObjectVFS()
|
||||
{
|
||||
TDictionary* dict;
|
||||
if(GetObjectHeap(this->obj, dict))
|
||||
{
|
||||
GCList ls(this->ls->GetGC());
|
||||
dict->CallMethod(ls,"Dispose",{});
|
||||
}
|
||||
delete this->ls;
|
||||
}
|
||||
|
||||
}
|
||||
delete this->ls;
|
||||
}
|
||||
|
||||
} // namespace Tesses::CrossLang
|
||||
Reference in New Issue
Block a user