Build and Deploy on Tag / 🔨 Build for PowerPC (push) Successful in 1m11s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-riscv64:latest, riscv64-linux-gnu, riscv64) (push) Successful in 3m22s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x64:latest, x86_64-linux-gnu, amd64) (push) Successful in 3m34s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm:latest, arm-linux-gnueabihf, arm7) (push) Successful in 3m37s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-arm64:latest, aarch64-linux-gnu, arm64) (push) Successful in 3m39s
Build and Deploy on Tag / 🔨 Build for everything else (git.tesses.org/tesses50/linux-x86:latest, i386-linux-gnu, 386) (push) Successful in 55s
Build and Deploy on Tag / update-tap (push) Failing after 4m8s
191 lines
5.9 KiB
C++
191 lines
5.9 KiB
C++
#include "CrossLang.hpp"
|
|
|
|
namespace Tesses::CrossLang {
|
|
TDynamicDictionary::TDynamicDictionary(TCallable *callable) : cb(callable) {}
|
|
TDynamicDictionary *TDynamicDictionary::Create(GCList &ls,
|
|
TCallable *callable) {
|
|
|
|
return ls.Create<TDynamicDictionary>(callable);
|
|
}
|
|
TDynamicDictionary *TDynamicDictionary::Create(GCList *ls,
|
|
TCallable *callable) {
|
|
return ls->Create<TDynamicDictionary>(callable);
|
|
}
|
|
|
|
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::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});
|
|
}
|
|
|
|
TEnumerator *TDynamicDictionary::GetEnumerator(GCList &ls) {
|
|
auto dict = TDictionary::Create(ls);
|
|
ls.GetGC()->BarrierBegin();
|
|
dict->SetValue("Type", "GetEnumerator");
|
|
|
|
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);
|
|
|
|
ls.GetGC()->BarrierEnd();
|
|
|
|
auto res = this->cb->Call(ls, {dict});
|
|
bool r2;
|
|
if (GetObject(res, r2))
|
|
return r2;
|
|
return false;
|
|
}
|
|
|
|
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;
|
|
|
|
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();
|
|
auto item = this->items.find(key);
|
|
if (item != this->items.end())
|
|
return item->second;
|
|
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) {
|
|
return gc->Create<TDictionary>();
|
|
}
|
|
TDictionary *TDictionary::Create(GCList &gc) {
|
|
return gc.Create<TDictionary>();
|
|
}
|
|
|
|
}; // namespace Tesses::CrossLang
|